@@ -86,6 +86,8 @@ typedef struct _spl_SplObjectStorage { /* {{{ */
86
86
long flags ;
87
87
zend_function * fptr_get_hash ;
88
88
HashTable * debug_info ;
89
+ zval * * gcdata ;
90
+ long gcdata_len ;
89
91
} spl_SplObjectStorage ; /* }}} */
90
92
91
93
/* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */
@@ -107,6 +109,10 @@ void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */
107
109
efree (intern -> debug_info );
108
110
}
109
111
112
+ if (intern -> gcdata != NULL ) {
113
+ efree (intern -> gcdata );
114
+ }
115
+
110
116
efree (object );
111
117
} /* }}} */
112
118
@@ -263,6 +269,9 @@ static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type,
263
269
zend_object_std_init (& intern -> std , class_type TSRMLS_CC );
264
270
object_properties_init (& intern -> std , class_type );
265
271
272
+ intern -> gcdata = NULL ;
273
+ intern -> gcdata_len = 0 ;
274
+
266
275
zend_hash_init (& intern -> storage , 0 , NULL , (void (* )(void * ))spl_object_storage_dtor , 0 );
267
276
268
277
retval .handle = zend_objects_store_put (intern , (zend_objects_store_dtor_t )zend_objects_destroy_object , (zend_objects_free_object_storage_t ) spl_SplOjectStorage_free_storage , NULL TSRMLS_CC );
@@ -324,7 +333,6 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
324
333
* is_temp = 0 ;
325
334
326
335
props = Z_OBJPROP_P (obj );
327
- zend_hash_del (props , "\x00gcdata" , sizeof ("\x00gcdata" ));
328
336
329
337
if (intern -> debug_info == NULL ) {
330
338
ALLOC_HASHTABLE (intern -> debug_info );
@@ -360,46 +368,31 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
360
368
}
361
369
/* }}} */
362
370
363
- /* overriden for garbage collection
364
- * This is very hacky */
371
+ /* overriden for garbage collection */
365
372
static HashTable * spl_object_storage_get_gc (zval * obj , zval * * * table , int * n TSRMLS_DC ) /* {{{ */
366
373
{
367
374
spl_SplObjectStorage * intern = (spl_SplObjectStorage * )zend_object_store_get_object (obj TSRMLS_CC );
368
375
spl_SplObjectStorageElement * element ;
369
- HashTable * props ;
370
376
HashPosition pos ;
371
- zval * gcdata_arr = NULL ,
372
- * * gcdata_arr_pp ;
373
-
374
- props = std_object_handlers .get_properties (obj TSRMLS_CC );
375
-
376
- * table = NULL ;
377
- * n = 0 ;
377
+ long i = 0 ;
378
+ long requiredLength = intern -> storage .nNumOfElements * 2 ;
378
379
379
- /* clean \x00gcdata, as it may be out of date */
380
- if (zend_hash_find (props , "\x00gcdata" , sizeof ("\x00gcdata" ), (void * * ) & gcdata_arr_pp ) == SUCCESS ) {
381
- gcdata_arr = * gcdata_arr_pp ;
382
- zend_hash_clean (Z_ARRVAL_P (gcdata_arr ));
383
- }
384
-
385
- if (gcdata_arr == NULL ) {
386
- MAKE_STD_ZVAL (gcdata_arr );
387
- array_init (gcdata_arr );
388
- /* don't decrease refcount of members when destroying */
389
- Z_ARRVAL_P (gcdata_arr )-> pDestructor = NULL ;
390
-
391
- /* name starts with \x00 to make tampering in user-land more difficult */
392
- zend_hash_add (props , "\x00gcdata" , sizeof ("\x00gcdata" ), & gcdata_arr , sizeof (gcdata_arr ), NULL );
380
+ if (requiredLength > intern -> gcdata_len ) {
381
+ intern -> gcdata = (zval * * )erealloc (intern -> gcdata , sizeof (zval * ) * requiredLength );
382
+ intern -> gcdata_len = requiredLength ;
393
383
}
394
384
395
385
zend_hash_internal_pointer_reset_ex (& intern -> storage , & pos );
396
386
while (zend_hash_get_current_data_ex (& intern -> storage , (void * * )& element , & pos ) == SUCCESS ) {
397
- add_next_index_zval ( gcdata_arr , element -> obj ) ;
398
- add_next_index_zval ( gcdata_arr , element -> inf ) ;
387
+ intern -> gcdata [ i ++ ] = element -> obj ;
388
+ intern -> gcdata [ i ++ ] = element -> inf ;
399
389
zend_hash_move_forward_ex (& intern -> storage , & pos );
400
390
}
401
391
402
- return props ;
392
+ * table = intern -> gcdata ;
393
+ * n = i ;
394
+
395
+ return std_object_handlers .get_properties (obj TSRMLS_CC );
403
396
}
404
397
/* }}} */
405
398
@@ -782,7 +775,7 @@ SPL_METHOD(SplObjectStorage, serialize)
782
775
INIT_PZVAL (& members );
783
776
Z_ARRVAL (members ) = zend_std_get_properties (getThis () TSRMLS_CC );
784
777
Z_TYPE (members ) = IS_ARRAY ;
785
- zend_hash_del ( Z_ARRVAL ( members ), "\x00gcdata" , sizeof ( "\x00gcdata" ));
778
+
786
779
pmembers = & members ;
787
780
php_var_serialize (& buf , & pmembers , & var_hash TSRMLS_CC ); /* finishes the string */
788
781
0 commit comments