summaryrefslogtreecommitdiff
path: root/ext/spl/spl_observer.c
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2015-03-14 00:53:32 +0800
committerXinchen Hui <laruence@php.net>2015-03-14 00:53:32 +0800
commit396bc00caa528e71158c3808478f5a10a8db0f06 (patch)
tree0118083a1b5519530a30e9cc34dcd37ef955abc0 /ext/spl/spl_observer.c
parent4b930e156f161d3e9f7526fd9ba840923833a316 (diff)
parented59370f0a8a2c1ea8164afcde827c4fba74693d (diff)
downloadphp-git-396bc00caa528e71158c3808478f5a10a8db0f06.tar.gz
Merge branch 'PHP-5.5' into PHP-5.6
Diffstat (limited to 'ext/spl/spl_observer.c')
-rw-r--r--ext/spl/spl_observer.c47
1 files changed, 18 insertions, 29 deletions
diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c
index 6cde449df7..56d1a16ac0 100644
--- a/ext/spl/spl_observer.c
+++ b/ext/spl/spl_observer.c
@@ -87,6 +87,8 @@ typedef struct _spl_SplObjectStorage { /* {{{ */
long flags;
zend_function *fptr_get_hash;
HashTable *debug_info;
+ zval **gcdata;
+ long gcdata_num;
} spl_SplObjectStorage; /* }}} */
/* {{{ 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) /* {{{ */
efree(intern->debug_info);
}
+ if (intern->gcdata != NULL) {
+ efree(intern->gcdata);
+ }
+
efree(object);
} /* }}} */
@@ -325,7 +331,6 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
*is_temp = 0;
props = Z_OBJPROP_P(obj);
- zend_hash_del(props, "\x00gcdata", sizeof("\x00gcdata"));
if (intern->debug_info == NULL) {
ALLOC_HASHTABLE(intern->debug_info);
@@ -361,46 +366,30 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
}
/* }}} */
-/* overriden for garbage collection
- * This is very hacky */
+/* overriden for garbage collection */
static HashTable *spl_object_storage_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{ */
{
+ long i = 0;
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
spl_SplObjectStorageElement *element;
- HashTable *props;
HashPosition pos;
- zval *gcdata_arr = NULL,
- **gcdata_arr_pp;
-
- props = std_object_handlers.get_properties(obj TSRMLS_CC);
-
- *table = NULL;
- *n = 0;
- /* clean \x00gcdata, as it may be out of date */
- if (zend_hash_find(props, "\x00gcdata", sizeof("\x00gcdata"), (void**) &gcdata_arr_pp) == SUCCESS) {
- gcdata_arr = *gcdata_arr_pp;
- zend_hash_clean(Z_ARRVAL_P(gcdata_arr));
- }
-
- if (gcdata_arr == NULL) {
- MAKE_STD_ZVAL(gcdata_arr);
- array_init(gcdata_arr);
- /* don't decrease refcount of members when destroying */
- Z_ARRVAL_P(gcdata_arr)->pDestructor = NULL;
-
- /* name starts with \x00 to make tampering in user-land more difficult */
- zend_hash_add(props, "\x00gcdata", sizeof("\x00gcdata"), &gcdata_arr, sizeof(gcdata_arr), NULL);
+ if (intern->storage.nNumOfElements > intern->gcdata_num) {
+ intern->gcdata_num = intern->storage.nNumOfElements * 2;
+ intern->gcdata = (zval**)erealloc(intern->gcdata, sizeof(zval*) * intern->gcdata_num);
}
zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) {
- add_next_index_zval(gcdata_arr, element->obj);
- add_next_index_zval(gcdata_arr, element->inf);
+ intern->gcdata[i++] = element->obj;
+ intern->gcdata[i++] = element->inf;
zend_hash_move_forward_ex(&intern->storage, &pos);
}
- return props;
+ *table = intern->gcdata;
+ *n = i;
+
+ return std_object_handlers.get_properties(obj TSRMLS_CC);
}
/* }}} */
@@ -799,7 +788,7 @@ SPL_METHOD(SplObjectStorage, serialize)
INIT_PZVAL(&members);
Z_ARRVAL(members) = zend_std_get_properties(getThis() TSRMLS_CC);
Z_TYPE(members) = IS_ARRAY;
- zend_hash_del(Z_ARRVAL(members), "\x00gcdata", sizeof("\x00gcdata"));
+
pmembers = &members;
php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */