]> granicus.if.org Git - php/commitdiff
Use better data structures (incomplete)
authorDmitry Stogov <dmitry@zend.com>
Wed, 12 Feb 2014 14:08:11 +0000 (18:08 +0400)
committerDmitry Stogov <dmitry@zend.com>
Wed, 12 Feb 2014 14:08:11 +0000 (18:08 +0400)
13 files changed:
Zend/zend_API.c
Zend/zend_execute_API.c
Zend/zend_hash.c
Zend/zend_iterators.c
Zend/zend_iterators.h
Zend/zend_object_handlers.c
Zend/zend_objects_API.c
Zend/zend_objects_API.h
Zend/zend_operators.c
Zend/zend_types.h
Zend/zend_variables.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index cc9275ead45239793c077f5024c1e273c0db5ee8..08d525d15e9c7c75a9ab097d4741b9ab93965606 100644 (file)
@@ -1887,7 +1887,7 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TS
 {
        int name_len;
        zend_string *lcname;
-//???  zend_module_entry *module_ptr;
+       zend_module_entry *module_ptr;
 
        if (!module) {
                return NULL;
@@ -1923,13 +1923,13 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TS
        lcname = STR_ALLOC(name_len, 1);
        zend_str_tolower_copy(lcname->val, module->name, name_len);
 
-       if (zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry)) == NULL) {
+       if ((module_ptr = zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry))) == NULL) {
                zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
                STR_RELEASE(lcname);
                return NULL;
        }
        STR_RELEASE(lcname);
-//???  module = module_ptr;
+       module = module_ptr;
        EG(current_module) = module;
 
        if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type TSRMLS_CC)==FAILURE) {
@@ -2798,7 +2798,6 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
                        EG(scope) = ce_org;
                }
 
-//???          if (!zend_is_callable_check_class(Z_STRVAL_P(callable), clen, fcc, &strict_class, error TSRMLS_CC)) {
                if (!zend_is_callable_check_class(Z_STR_P(callable), fcc, &strict_class, error TSRMLS_CC)) {
                        EG(scope) = last_scope;
                        return 0;
@@ -3035,11 +3034,12 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
        if (object_ptr && Z_TYPE_P(object_ptr) != IS_OBJECT) {
                object_ptr = NULL;
        }
-//???  if (object_ptr &&
-//???      (!EG(objects_store).object_buckets || 
-//???       !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(object_ptr)].valid)) {
-//???          return 0;
-//???  }
+
+       if (object_ptr &&
+           (!EG(objects_store).object_buckets ||
+            !IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(object_ptr)]))) {
+               return 0;
+       }
 
        switch (Z_TYPE_P(callable)) {
                case IS_STRING:
@@ -3117,10 +3117,10 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
                                                }
 
                                        } else {
-//???                                          if (!EG(objects_store).object_buckets || 
-//???                                              !EG(objects_store).object_buckets[Z_OBJ_HANDLE_PP(obj)].valid) {
-//???                                                  return 0;
-//???                                          }
+                                               if (!!EG(objects_store).object_buckets ||
+                                                   !IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(obj)])) {
+                                                       return 0;
+                                               }
 
                                                fcc->calling_scope = Z_OBJCE_P(obj); /* TBFixed: what if it's overloaded? */
 
@@ -3711,7 +3711,7 @@ ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *na
                                ZVAL_COPY_VALUE(property, value);
                                if (Z_REFCOUNT_P(value) > 0) {
                                        zval_copy_ctor(property);
-                               } else {
+//???                          } else {
 //???                                  efree(value);
                                }
                        } else {
@@ -3849,12 +3849,12 @@ ZEND_API void zend_restore_error_handling(zend_error_handling *saved TSRMLS_DC)
 {
        EG(error_handling) = saved->handling;
        EG(exception_class) = saved->handling == EH_THROW ? saved->exception : NULL;
-       if (Z_TYPE(saved->user_handler) != IS_UNDEF) {
-//???          && saved->user_handler != EG(user_error_handler)) {
+       if (Z_TYPE(saved->user_handler) != IS_UNDEF
+               && memcmp(&saved->user_handler, &EG(user_error_handler), sizeof(zval)) != 0) {
                zval_ptr_dtor(&EG(user_error_handler));
                ZVAL_COPY_VALUE(&EG(user_error_handler), &saved->user_handler);
-//???  } else if (saved->user_handler) {
-//???          zval_ptr_dtor(&saved->user_handler);
+       } else if (Z_TYPE(saved->user_handler)) {
+               zval_ptr_dtor(&saved->user_handler);
        }
        ZVAL_UNDEF(&saved->user_handler);
 }
index df91e5f0faf118ed857f05e11293a4b9bfb20326..489425082795f21c828b9c75e405495be6556ac0 100644 (file)
@@ -797,10 +797,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
        called_scope = fci_cache->called_scope;
        fci->object_ptr = fci_cache->object_ptr;
        ZVAL_COPY_VALUE(&EX(object), fci->object_ptr);
-//???  if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT &&
-//???      (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)].valid)) {
-//???          return FAILURE;
-//???  }
+       if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT &&
+           (!EG(objects_store).object_buckets ||
+            !IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)]))) {
+               return FAILURE;
+       }
 
        if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
                if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
index 901f6de43ab0345813b1386e7fb9abc839e9694d..c3ec0349da18a279b211416db55def715eeb05c8 100644 (file)
@@ -510,9 +510,6 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint idx, Buc
        if (ht->pDestructor) {
                ht->pDestructor(&p->val);
        }
-//???  if (ht->flags & HASH_FLAG_BIG_DATA) {
-//???          pefree(p->xData, ht->flags & HASH_FLAG_PERSISTENT);
-//???  }
        if (p->key) {
                STR_RELEASE(p->key);
        }
@@ -665,9 +662,6 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
                if (ht->pDestructor) {
                        ht->pDestructor(&p->val);
                }
-//???          if (ht->flags & HASH_FLAG_BIG_DATA) {
-//???                  pefree(p->xData, ht->flags & HASH_FLAG_PERSISTENT);
-//???          }
                if (p->key) {
                        STR_RELEASE(p->key);
                }
@@ -696,9 +690,6 @@ ZEND_API void zend_hash_clean(HashTable *ht)
                if (ht->pDestructor) {
                        ht->pDestructor(&p->val);
                }
-//???          if (ht->flags & HASH_FLAG_BIG_DATA) {
-//???                  pefree(p->xData, ht->flags & HASH_FLAG_PERSISTENT);
-//???          }
                if (p->key) {
                        STR_RELEASE(p->key);
                }
index b433cbe1abb8e7c85bad29a4c48296df820b2525..bb41ab9000ac003d1b3c74ec94ba315fdab69784 100644 (file)
 
 static zend_class_entry zend_iterator_class_entry;
 
+static void iter_wrapper_dtor(zend_object *object TSRMLS_DC);
+
 static zend_object_handlers iterator_object_handlers = {
-       ZEND_OBJECTS_STORE_HANDLERS,
+       iter_wrapper_dtor,
+       NULL,
+       NULL,
        NULL, /* prop read */
        NULL, /* prop write */
        NULL, /* read dim */
@@ -61,20 +65,9 @@ static void iter_wrapper_dtor(zend_object *object TSRMLS_DC)
        iter->funcs->dtor(iter TSRMLS_CC);
 }
 
-ZEND_API zval *zend_iterator_wrap(zend_object_iterator *iter TSRMLS_DC)
+ZEND_API void zend_iterator_wrap(zend_object_iterator *iter, zval *wrapped TSRMLS_DC)
 {
-//???
-       return NULL;
-#if 0
-       zval *wrapped;
-
-       MAKE_STD_ZVAL(wrapped);
-       Z_TYPE_P(wrapped) = IS_OBJECT;
-       Z_OBJ_HANDLE_P(wrapped) = zend_objects_store_put(iter, iter_wrapper_dtor, NULL, NULL TSRMLS_CC);
-       Z_OBJ_HT_P(wrapped) = &iterator_object_handlers;
-
-       return wrapped;
-#endif
+       ZVAL_OBJ(wrapped, &iter->std); 
 }
 
 ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(
index c0b71e7e37a471f9010ba3f11fd3d4eee890e19e..0ab5bef82a8d230cb050668af86219bc74fbf337 100644 (file)
@@ -55,6 +55,7 @@ typedef struct _zend_object_iterator_funcs {
 } zend_object_iterator_funcs;
 
 struct _zend_object_iterator {
+       zend_object std;
        void *data;
        zend_object_iterator_funcs *funcs;
        ulong index; /* private to fe_reset/fe_fetch opcodes */
@@ -82,7 +83,7 @@ BEGIN_EXTERN_C()
 ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(zval *array_ptr, zend_object_iterator **iter TSRMLS_DC);
 
 /* given an iterator, wrap it up as a zval for use by the engine opcodes */
-ZEND_API zval *zend_iterator_wrap(zend_object_iterator *iter TSRMLS_DC);
+ZEND_API void zend_iterator_wrap(zend_object_iterator *iter, zval *zv TSRMLS_DC);
 
 ZEND_API void zend_register_iterator_wrapper(TSRMLS_D);
 END_EXTERN_C()
index d05c6b302cdb5b74baab7d70a39533a5c63b284f..4df8c27fb76293ed72e44d65b9abd2e56e5e1e11 100644 (file)
 
 #define Z_OBJ_PROTECT_RECURSION(zval_p) \
        do { \
-               if (EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zval_p)].apply_count++ >= 3) { \
+               if (Z_OBJ_APPLY_COUNT_P(zval_p) >= 3) { \
                        zend_error(E_ERROR, "Nesting level too deep - recursive dependency?"); \
                } \
+               Z_OBJ_INC_APPLY_COUNT_P(zval_p); \
        } while (0)
 
 
 #define Z_OBJ_UNPROTECT_RECURSION(zval_p) \
-       EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zval_p)].apply_count--
+       Z_OBJ_DEC_APPLY_COUNT_P(zval_p)
 
 /*
   __X accessors explanation:
@@ -1010,8 +1011,6 @@ static union _zend_function *zend_std_get_method(zval *object, zend_string *meth
        if (EXPECTED(key != NULL)) {
                lc_method_name = Z_STR(key->constant);
        } else {
-               /* Create a zend_copy_str_tolower(dest, src, src_length); */
-//???          lc_method_name = do_alloca(method_len+1, use_heap);
                lc_method_name = STR_ALLOC(method_name->len, 0);
                zend_str_tolower_copy(lc_method_name->val, method_name->val, method_name->len);
        }
@@ -1146,8 +1145,6 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
        if (EXPECTED(key != NULL)) {
                lc_function_name = Z_STR(key->constant);
        } else {
-               //???lc_function_name = do_alloca(function_name_strlen+1, use_heap);
-               /* Create a zend_copy_str_tolower(dest, src, src_length); */
                lc_function_name = STR_ALLOC(function_name->len, 0);
                zend_str_tolower_copy(lc_function_name->val, function_name->val, function_name->len);
        }
@@ -1334,38 +1331,38 @@ static int zend_std_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
        if (!zobj1->properties && !zobj2->properties) {
                int i;
 
-//???          Z_OBJ_PROTECT_RECURSION(o1);
-//???          Z_OBJ_PROTECT_RECURSION(o2);
+               Z_OBJ_PROTECT_RECURSION(o1);
+               Z_OBJ_PROTECT_RECURSION(o2);
                for (i = 0; i < zobj1->ce->default_properties_count; i++) {
                        if (Z_TYPE(zobj1->properties_table[i]) != IS_UNDEF) {
                                if (Z_TYPE(zobj2->properties_table[i]) != IS_UNDEF) {
                                        zval result;
 
                                        if (compare_function(&result, &zobj1->properties_table[i], &zobj2->properties_table[i] TSRMLS_CC)==FAILURE) {
-//???                                          Z_OBJ_UNPROTECT_RECURSION(o1);
-//???                                          Z_OBJ_UNPROTECT_RECURSION(o2);
+                                               Z_OBJ_UNPROTECT_RECURSION(o1);
+                                               Z_OBJ_UNPROTECT_RECURSION(o2);
                                                return 1;
                                        }
                                        if (Z_LVAL(result) != 0) {
-//???                                          Z_OBJ_UNPROTECT_RECURSION(o1);
-//???                                          Z_OBJ_UNPROTECT_RECURSION(o2);
+                                               Z_OBJ_UNPROTECT_RECURSION(o1);
+                                               Z_OBJ_UNPROTECT_RECURSION(o2);
                                                return Z_LVAL(result);
                                        }
                                } else {
-//???                                  Z_OBJ_UNPROTECT_RECURSION(o1);
-//???                                  Z_OBJ_UNPROTECT_RECURSION(o2);
+                                       Z_OBJ_UNPROTECT_RECURSION(o1);
+                                       Z_OBJ_UNPROTECT_RECURSION(o2);
                                        return 1;
                                }
                        } else {
                                if (Z_TYPE(zobj2->properties_table[i]) != IS_UNDEF) {
-//???                                  Z_OBJ_UNPROTECT_RECURSION(o1);
-//???                                  Z_OBJ_UNPROTECT_RECURSION(o2);
+                                       Z_OBJ_UNPROTECT_RECURSION(o1);
+                                       Z_OBJ_UNPROTECT_RECURSION(o2);
                                        return 1;
                                }
                        }
                }
-//???          Z_OBJ_UNPROTECT_RECURSION(o1);
-//???          Z_OBJ_UNPROTECT_RECURSION(o2);
+               Z_OBJ_UNPROTECT_RECURSION(o1);
+               Z_OBJ_UNPROTECT_RECURSION(o2);
                return 0;
        } else {
                if (!zobj1->properties) {
index 04de616f44e63a95237af1cdd6d1941ebdf6eafc..4480512f391c4dfb8270649a5b587e59c6aaf7c0 100644 (file)
 #include "zend_globals.h"
 #include "zend_variables.h"
 #include "zend_API.h"
-#include "zend_objects_API.h"
-
-#define FREE_BUCKET                            1
-
-#define IS_VALID(o)                            (!(((zend_uintptr_t)(o)) & FREE_BUCKET))
-
-#define GET_BUCKET_NUMBER(o)   (((zend_uintptr_t)(o)) >> 1)
-
-#define SET_BUCKET_NUMBER(o, n)        do { \
-               (o) = (((zend_uintptr_t)(n)) << 1) | FREE_BUCKET); \
-       } while (0)
-
-       
+#include "zend_objects_API.h"  
 
 ZEND_API void zend_objects_store_init(zend_objects_store *objects, zend_uint init_size)
 {
@@ -99,7 +87,7 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects
 
                if (IS_VALID(obj)) {
                        gc_remove_zval_from_buffer((zend_refcounted*)obj TSRMLS_CC);
-//???                  objects->object_buckets[i].valid = 0;
+                       objects->object_buckets[i] = SET_INVALID(obj);
                        if (obj->handlers->free_obj) {
                                obj->handlers->free_obj(obj TSRMLS_CC);
                        }
@@ -129,72 +117,55 @@ ZEND_API void zend_objects_store_put(zend_object *object TSRMLS_DC)
        EG(objects_store).object_buckets[handle] = object;
 }
 
-#define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST()                                                                                                                                  \
-                       EG(objects_store).object_buckets[handle].bucket.free_list.next = EG(objects_store).free_list_head;      \
-                       EG(objects_store).free_list_head = handle;                                                                                                                      \
-                       EG(objects_store).object_buckets[handle].valid = 0;
+#define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(handle)                                                                                                                    \
+            SET_BUCKET_NUMBER(EG(objects_store).object_buckets[handle], EG(objects_store).free_list_head);     \
+                       EG(objects_store).free_list_head = handle;
 
-/*
- * Delete a reference to an objects store entry given the object handle.
- */
-//???
-#if 0
-ZEND_API void zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle, const zend_object_handlers *handlers TSRMLS_DC) /* {{{ */
+ZEND_API void zend_objects_store_del(zend_object *object TSRMLS_DC) /* {{{ */
 {
-       struct _store_object *obj;
-       int failure = 0;
-
-       if (!EG(objects_store).object_buckets) {
-               return;
-       }
-
-       obj = &EG(objects_store).object_buckets[handle].bucket.obj;
-
        /*      Make sure we hold a reference count during the destructor call
                otherwise, when the destructor ends the storage might be freed
                when the refcount reaches 0 a second time
         */
-       if (EG(objects_store).object_buckets[handle].valid) {
-               if (obj->refcount == 1) {
-                       if (!EG(objects_store).object_buckets[handle].destructor_called) {
-                               EG(objects_store).object_buckets[handle].destructor_called = 1;
-
-                               if (obj->dtor) {
-                                       if (handlers && !obj->handlers) {
-                                               obj->handlers = handlers;
-                                       }
+       if (EG(objects_store).object_buckets &&
+           IS_VALID(EG(objects_store).object_buckets[object->handle])) {
+               if (object->gc.refcount == 0) {
+                       int failure = 0;
+
+                       if (!(object->gc.u.v.flags & IS_OBJ_DESTRUCTOR_CALLED)) {
+                               object->gc.u.v.flags |= IS_OBJ_DESTRUCTOR_CALLED;
+
+                               if (object->handlers->dtor_obj) {
+                                       object->gc.refcount++;
                                        zend_try {
-                                               obj->dtor(obj->object, handle TSRMLS_CC);
+                                               object->handlers->dtor_obj(object TSRMLS_CC);
                                        } zend_catch {
                                                failure = 1;
                                        } zend_end_try();
+                                       object->gc.refcount--;
                                }
                        }
                        
-                       /* re-read the object from the object store as the store might have been reallocated in the dtor */
-                       obj = &EG(objects_store).object_buckets[handle].bucket.obj;
-
-                       if (obj->refcount == 1) {
+                       if (object->gc.refcount == 0) {
 //???                          GC_REMOVE_ZOBJ_FROM_BUFFER(obj);
-                               if (obj->free_storage) {
+                               if (object->handlers->free_obj) {
                                        zend_try {
-                                               obj->free_storage(obj->object TSRMLS_CC);
+                                               object->handlers->free_obj(object TSRMLS_CC);
                                        } zend_catch {
                                                failure = 1;
                                        } zend_end_try();
                                }
-                               ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST();
+                               ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(object->handle);
                        }
+                       
+                       if (failure) {
+                               zend_bailout();
+                       }
+               } else {
+                       object->gc.refcount--;
                }
        }
-
-       obj->refcount--;
-
-       if (failure) {
-               zend_bailout();
-       }
 }
-#endif
 /* }}} */
 
 //???
@@ -230,28 +201,18 @@ ZEND_API zend_object *zend_objects_store_clone_obj(zval *zobject TSRMLS_DC)
  * from the constructor function.  You MUST NOT use this function for any other
  * weird games, or call it at any other time after the object is constructed.
  * */
-//???
-#if 0
-ZEND_API void zend_object_store_set_object(zval *zobject, void *object TSRMLS_DC)
+ZEND_API void zend_object_store_set_object(zval *zobject, zend_object *object TSRMLS_DC)
 {
-       zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
-
-       EG(objects_store).object_buckets[handle].bucket.obj.object = object;
+       EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zobject)] = object;
 }
-#endif
 
 /* Called when the ctor was terminated by an exception */
-//???
-#if 0
 ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC)
 {
-       zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
-       zend_object_store_bucket *obj_bucket = &EG(objects_store).object_buckets[handle];
-       
-       obj_bucket->bucket.obj.handlers = Z_OBJ_HT_P(zobject);;
-       obj_bucket->destructor_called = 1;
+       zend_object *obj = Z_OBJ_P(zobject);
+
+       obj->gc.u.v.flags |= IS_OBJ_DESTRUCTOR_CALLED;
 }
-#endif
 
 /* Proxy objects workings */
 typedef struct _zend_proxy_object {
index 9c69e97ed47192a401ad600c00bc83f6a3f2094a..3119ee99326d3616b26f3d3de30763fe417a318e 100644 (file)
 //???  } bucket;
 //???} zend_object_store_bucket;
 
+#define FREE_BUCKET                            1
+
+#define IS_VALID(o)                            (!(((zend_uintptr_t)(o)) & FREE_BUCKET))
+
+#define SET_INVALID(o)                 ((zend_object*)((((zend_uintptr_t)(o)) | FREE_BUCKET)))
+
+#define GET_BUCKET_NUMBER(o)   (((zend_uintptr_t)(o)) >> 1)
+
+#define SET_BUCKET_NUMBER(o, n)        do { \
+               (o) = (zend_object*)((((zend_uintptr_t)(n)) << 1) | FREE_BUCKET); \
+       } while (0)
+
 typedef struct _zend_objects_store {
        zend_object **object_buckets;
        zend_uint top;
@@ -67,20 +79,10 @@ ZEND_API void zend_objects_store_destroy(zend_objects_store *objects);
 
 /* Store API functions */
 ZEND_API void zend_objects_store_put(zend_object *object TSRMLS_DC);
+ZEND_API void zend_objects_store_del(zend_object *object TSRMLS_DC);
 
-//???ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC);
-//???ZEND_API void zend_objects_store_del_ref(zval *object TSRMLS_DC);
-//???ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC);
-//???ZEND_API void zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle, const zend_object_handlers *handlers TSRMLS_DC);
-//???static zend_always_inline void zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC) {
-//???  zend_objects_store_del_ref_by_handle_ex(handle, NULL TSRMLS_CC);
-//???}
-//???ZEND_API zend_uint zend_objects_store_get_refcount(zval *object TSRMLS_DC);
-//???ZEND_API zend_object *zend_objects_store_clone_obj(zval *object TSRMLS_DC);
-//???ZEND_API void *zend_object_store_get_object(const zval *object TSRMLS_DC);
-//???ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle TSRMLS_DC);
 /* See comment in zend_objects_API.c before you use this */
-//???ZEND_API void zend_object_store_set_object(zval *zobject, void *object TSRMLS_DC);
+ZEND_API void zend_object_store_set_object(zval *zobject, zend_object *object TSRMLS_DC);
 ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC);
 
 ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects TSRMLS_DC);
index 2f964d2b89e0d9414b81fb4efc3457190454ea50..f0e3a5f98fa68367421f82a9f1cf813a4516f712 100644 (file)
@@ -1484,7 +1484,6 @@ static inline void zend_free_obj_get_result(zval *op TSRMLS_DC) /* {{{ */
        if (Z_REFCOUNT_P(op) == 0) {
                GC_REMOVE_ZVAL_FROM_BUFFER(op);
                zval_dtor(op);
-//???          FREE_ZVAL(op);
        } else {
                zval_ptr_dtor(op);
        }
index ddf35bcf7131c66555a08ab9395e16229f8547e0..5d143ed11de8c13be9e37ee15d5825cbbf336ade 100644 (file)
@@ -217,8 +217,28 @@ struct _zend_ast_ref {
 #define IS_STR_INTERNED                                (1<<1) /* interned string          */
 #define IS_STR_PERMANENT               (1<<2) /* relives request boundary */
 
-/* string flags (zval.value->gc.u.vflags) */
-#define IS_OBJ_DESTRUCTOR_CALLED       (1<<0)
+/* object flags (zval.value->gc.u.vflags) */
+#define IS_OBJ_APPLY_COUNT                     0x07
+#define IS_OBJ_DESTRUCTOR_CALLED       (1<<3)
+
+#define Z_OBJ_APPLY_COUNT(zval) \
+       (Z_OBJ(zval)->gc.u.v.flags & IS_OBJ_APPLY_COUNT)
+
+#define Z_OBJ_INC_APPLY_COUNT(zval) do { \
+               Z_OBJ(zval)->gc.u.v.flags = \
+                       (Z_OBJ(zval)->gc.u.v.flags & ~IS_OBJ_APPLY_COUNT) | \
+                       ((Z_OBJ(zval)->gc.u.v.flags & IS_OBJ_APPLY_COUNT) + 1); \
+       } while (0)
+       
+#define Z_OBJ_DEC_APPLY_COUNT(zval) do { \
+               Z_OBJ(zval)->gc.u.v.flags = \
+                       (Z_OBJ(zval)->gc.u.v.flags & ~IS_OBJ_APPLY_COUNT) | \
+                       ((Z_OBJ(zval)->gc.u.v.flags & IS_OBJ_APPLY_COUNT) - 1); \
+       } while (0)
+
+#define Z_OBJ_APPLY_COUNT_P(zv)     Z_OBJ_APPLY_COUNT(*(zv))
+#define Z_OBJ_INC_APPLY_COUNT_P(zv) Z_OBJ_INC_APPLY_COUNT(*(zv))
+#define Z_OBJ_DEC_APPLY_COUNT_P(zv) Z_OBJ_DEC_APPLY_COUNT(*(zv))
 
 #define Z_REFCOUNTED(zval)                     IS_REFCOUNTED(Z_TYPE(zval))
 #define Z_REFCOUNTED_P(zval_p)         Z_REFCOUNTED(*(zval_p))
index ea31bd5708b9319ab2a87b4603cf1d3f7975a2b2..799d8e49a3ea32751e07ed6e4ce18d8c963cd1b4 100644 (file)
@@ -39,23 +39,24 @@ ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
                case IS_CONSTANT_ARRAY: {
                                TSRMLS_FETCH();
 
-//???                          if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
+                               if (Z_ARRVAL_P(zvalue) != &EG(symbol_table).ht) {
                                        /* break possible cycles */
                                        Z_TYPE_P(zvalue) = IS_NULL;
                                        zend_hash_destroy(Z_ARRVAL_P(zvalue));
-                                       FREE_HASHTABLE(Z_ARR_P(zvalue));
-//???                          }
+                                       efree(Z_ARR_P(zvalue));
+                               }
                        }
                        break;
                case IS_CONSTANT_AST:
                        zend_ast_destroy(Z_AST_P(zvalue)->ast);
+                       efree(Z_AST_P(zvalue));
                        break;
                case IS_OBJECT:
                        {
                                TSRMLS_FETCH();
 
                                if (Z_DELREF_P(zvalue) == 0) {
-                                       // TODO: release object???                                      
+                                       zend_objects_store_del(Z_OBJ_P(zvalue) TSRMLS_CC);
                                }
                        }
                        break;
@@ -216,7 +217,7 @@ ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args,
                        }
                } else {
                        if (is_ref) {
-//???                          SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
+                               SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
                                if (!Z_ISREF_P(p)) {
                                        if (IS_REFCOUNTED(Z_TYPE_P(p)) && Z_REFCOUNT_P(p) > 1) {
                                                Z_DELREF_P(p);
@@ -228,8 +229,7 @@ ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args,
                                        }
                                }
                        } else if (Z_ISREF_P(p)) {
-//???
-                               tmp = *Z_REFVAL_P(p);
+                               ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(p));
                                if (Z_REFCOUNTED(tmp) && Z_REFCOUNT(tmp) > 1) {
                                        zval_copy_ctor(&tmp);
                                        Z_SET_REFCOUNT(tmp, 0);
index 7324c1aa64c87985effaf3ec66a3729340c4e20f..b52ef6abacffd8de6975ec0ac38dd7e06ef97277 100644 (file)
@@ -4158,7 +4158,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
                        FREE_OP1_IF_VAR();
                }
                if (iter && EXPECTED(EG(exception) == NULL)) {
-                       array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
+                       zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
                } else {
                        if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
                                FREE_OP1_VAR_PTR();
index 0de8cc1669bc149572e4a8f4a1ed86ae5569e12c..ebb0b810927c61b7bd37c4bec6806a1052a69fa5 100644 (file)
@@ -3021,7 +3021,7 @@ static int ZEND_FASTCALL  ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
 
                }
                if (iter && EXPECTED(EG(exception) == NULL)) {
-                       array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
+                       zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
                } else {
                        if (IS_CONST == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
 
@@ -7995,7 +7995,7 @@ static int ZEND_FASTCALL  ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
 
                }
                if (iter && EXPECTED(EG(exception) == NULL)) {
-                       array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
+                       zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
                } else {
                        if (IS_TMP_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
 
@@ -12989,7 +12989,7 @@ static int ZEND_FASTCALL  ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
                        zval_ptr_dtor_nogc(free_op1.var);
                }
                if (iter && EXPECTED(EG(exception) == NULL)) {
-                       array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
+                       zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
                } else {
                        if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
                                if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
@@ -29534,7 +29534,7 @@ static int ZEND_FASTCALL  ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 
                }
                if (iter && EXPECTED(EG(exception) == NULL)) {
-                       array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
+                       zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
                } else {
                        if (IS_CV == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {