@@ -87,6 +87,8 @@ typedef struct _spl_SplObjectStorage { /* {{{ */
87
87
long flags ;
88
88
zend_function * fptr_get_hash ;
89
89
HashTable * debug_info ;
90
+ zval * * gcdata ;
91
+ long gcdata_num ;
90
92
} spl_SplObjectStorage ; /* }}} */
91
93
92
94
/* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */
@@ -108,6 +110,10 @@ void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */
108
110
efree (intern -> debug_info );
109
111
}
110
112
113
+ if (intern -> gcdata != NULL ) {
114
+ efree (intern -> gcdata );
115
+ }
116
+
111
117
efree (object );
112
118
} /* }}} */
113
119
@@ -325,7 +331,6 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
325
331
* is_temp = 0 ;
326
332
327
333
props = Z_OBJPROP_P (obj );
328
- zend_hash_del (props , "\x00gcdata" , sizeof ("\x00gcdata" ));
329
334
330
335
if (intern -> debug_info == NULL ) {
331
336
ALLOC_HASHTABLE (intern -> debug_info );
@@ -361,46 +366,30 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
361
366
}
362
367
/* }}} */
363
368
364
- /* overriden for garbage collection
365
- * This is very hacky */
369
+ /* overriden for garbage collection */
366
370
static HashTable * spl_object_storage_get_gc (zval * obj , zval * * * table , int * n TSRMLS_DC ) /* {{{ */
367
371
{
372
+ long i = 0 ;
368
373
spl_SplObjectStorage * intern = (spl_SplObjectStorage * )zend_object_store_get_object (obj TSRMLS_CC );
369
374
spl_SplObjectStorageElement * element ;
370
- HashTable * props ;
371
375
HashPosition pos ;
372
- zval * gcdata_arr = NULL ,
373
- * * gcdata_arr_pp ;
374
-
375
- props = std_object_handlers .get_properties (obj TSRMLS_CC );
376
-
377
- * table = NULL ;
378
- * n = 0 ;
379
376
380
- /* clean \x00gcdata, as it may be out of date */
381
- if (zend_hash_find (props , "\x00gcdata" , sizeof ("\x00gcdata" ), (void * * ) & gcdata_arr_pp ) == SUCCESS ) {
382
- gcdata_arr = * gcdata_arr_pp ;
383
- zend_hash_clean (Z_ARRVAL_P (gcdata_arr ));
384
- }
385
-
386
- if (gcdata_arr == NULL ) {
387
- MAKE_STD_ZVAL (gcdata_arr );
388
- array_init (gcdata_arr );
389
- /* don't decrease refcount of members when destroying */
390
- Z_ARRVAL_P (gcdata_arr )-> pDestructor = NULL ;
391
-
392
- /* name starts with \x00 to make tampering in user-land more difficult */
393
- zend_hash_add (props , "\x00gcdata" , sizeof ("\x00gcdata" ), & gcdata_arr , sizeof (gcdata_arr ), NULL );
377
+ if (intern -> storage .nNumOfElements > intern -> gcdata_num ) {
378
+ intern -> gcdata_num = intern -> storage .nNumOfElements * 2 ;
379
+ intern -> gcdata = (zval * * )erealloc (intern -> gcdata , sizeof (zval * ) * intern -> gcdata_num );
394
380
}
395
381
396
382
zend_hash_internal_pointer_reset_ex (& intern -> storage , & pos );
397
383
while (zend_hash_get_current_data_ex (& intern -> storage , (void * * )& element , & pos ) == SUCCESS ) {
398
- add_next_index_zval ( gcdata_arr , element -> obj ) ;
399
- add_next_index_zval ( gcdata_arr , element -> inf ) ;
384
+ intern -> gcdata [ i ++ ] = element -> obj ;
385
+ intern -> gcdata [ i ++ ] = element -> inf ;
400
386
zend_hash_move_forward_ex (& intern -> storage , & pos );
401
387
}
402
388
403
- return props ;
389
+ * table = intern -> gcdata ;
390
+ * n = i ;
391
+
392
+ return std_object_handlers .get_properties (obj TSRMLS_CC );
404
393
}
405
394
/* }}} */
406
395
@@ -799,7 +788,7 @@ SPL_METHOD(SplObjectStorage, serialize)
799
788
INIT_PZVAL (& members );
800
789
Z_ARRVAL (members ) = zend_std_get_properties (getThis () TSRMLS_CC );
801
790
Z_TYPE (members ) = IS_ARRAY ;
802
- zend_hash_del ( Z_ARRVAL ( members ), "\x00gcdata" , sizeof ( "\x00gcdata" ));
791
+
803
792
pmembers = & members ;
804
793
php_var_serialize (& buf , & pmembers , & var_hash TSRMLS_CC ); /* finishes the string */
805
794
0 commit comments