Use temporary debug_info for closures
authorNikita Popov <nikic@php.net>
Thu, 16 Apr 2015 08:01:55 +0000 (10:01 +0200)
committerNikita Popov <nikic@php.net>
Thu, 16 Apr 2015 13:33:47 +0000 (15:33 +0200)
Zend/zend_closures.c

index 3f0f53da67e2fad3f375b01165b75c7133097827..843254c6ef02e1158536015b59bff28e7e8954f1 100644 (file)
@@ -38,7 +38,6 @@ typedef struct _zend_closure {
        zend_object    std;
        zend_function  func;
        zval           this_ptr;
-       HashTable     *debug_info;
 } zend_closure;
 
 /* non-static since it needs to be referenced */
@@ -269,11 +268,6 @@ static void zend_closure_free_storage(zend_object *object) /* {{{ */
                destroy_op_array(&closure->func.op_array);
        }
 
-       if (closure->debug_info != NULL) {
-               zend_hash_destroy(closure->debug_info);
-               efree(closure->debug_info);
-       }
-
        if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
                zval_ptr_dtor(&closure->this_ptr);
        }
@@ -335,58 +329,56 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{
        zend_closure *closure = (zend_closure *)Z_OBJ_P(object);
        zval val;
        struct _zend_arg_info *arg_info = closure->func.common.arg_info;
+       HashTable *debug_info;
+
+       *is_temp = 1;
 
-       *is_temp = 0;
+       ALLOC_HASHTABLE(debug_info);
+       zend_hash_init(debug_info, 8, NULL, ZVAL_PTR_DTOR, 0);
 
-       if (closure->debug_info == NULL) {
-               ALLOC_HASHTABLE(closure->debug_info);
-               zend_hash_init(closure->debug_info, 8, NULL, ZVAL_PTR_DTOR, 0);
+       if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
+               HashTable *static_variables = closure->func.op_array.static_variables;
+               ZVAL_ARR(&val, zend_array_dup(static_variables));
+               zend_hash_str_update(debug_info, "static", sizeof("static")-1, &val);
        }
-       if (closure->debug_info->u.v.nApplyCount == 0) {
-               if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
-                       HashTable *static_variables = closure->func.op_array.static_variables;
-                       ZVAL_ARR(&val, zend_array_dup(static_variables));
-                       zend_hash_str_update(closure->debug_info, "static", sizeof("static")-1, &val);
-               }
 
-               if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
-                       Z_ADDREF(closure->this_ptr);
-                       zend_hash_str_update(closure->debug_info, "this", sizeof("this")-1, &closure->this_ptr);
-               }
+       if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
+               Z_ADDREF(closure->this_ptr);
+               zend_hash_str_update(debug_info, "this", sizeof("this")-1, &closure->this_ptr);
+       }
 
-               if (arg_info &&
-                   (closure->func.common.num_args ||
-                    (closure->func.common.fn_flags & ZEND_ACC_VARIADIC))) {
-                       uint32_t i, num_args, required = closure->func.common.required_num_args;
+       if (arg_info &&
+               (closure->func.common.num_args ||
+                (closure->func.common.fn_flags & ZEND_ACC_VARIADIC))) {
+               uint32_t i, num_args, required = closure->func.common.required_num_args;
 
-                       array_init(&val);
+               array_init(&val);
 
-                       num_args = closure->func.common.num_args;
-                       if (closure->func.common.fn_flags & ZEND_ACC_VARIADIC) {
-                               num_args++;
-                       }
-                       for (i = 0; i < num_args; i++) {
-                               zend_string *name;
-                               zval info;
-                               if (arg_info->name) {
-                                       name = zend_strpprintf(0, "%s$%s",
-                                                       arg_info->pass_by_reference ? "&" : "",
-                                                       arg_info->name->val);
-                               } else {
-                                       name = zend_strpprintf(0, "%s$param%d",
-                                                       arg_info->pass_by_reference ? "&" : "",
-                                                       i + 1);
-                               }
-                               ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
-                               zend_hash_update(Z_ARRVAL(val), name, &info);
-                               zend_string_release(name);
-                               arg_info++;
+               num_args = closure->func.common.num_args;
+               if (closure->func.common.fn_flags & ZEND_ACC_VARIADIC) {
+                       num_args++;
+               }
+               for (i = 0; i < num_args; i++) {
+                       zend_string *name;
+                       zval info;
+                       if (arg_info->name) {
+                               name = zend_strpprintf(0, "%s$%s",
+                                               arg_info->pass_by_reference ? "&" : "",
+                                               arg_info->name->val);
+                       } else {
+                               name = zend_strpprintf(0, "%s$param%d",
+                                               arg_info->pass_by_reference ? "&" : "",
+                                               i + 1);
                        }
-                       zend_hash_str_update(closure->debug_info, "parameter", sizeof("parameter")-1, &val);
+                       ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
+                       zend_hash_update(Z_ARRVAL(val), name, &info);
+                       zend_string_release(name);
+                       arg_info++;
                }
+               zend_hash_str_update(debug_info, "parameter", sizeof("parameter")-1, &val);
        }
 
-       return closure->debug_info;
+       return debug_info;
 }
 /* }}} */
 
@@ -394,12 +386,6 @@ static HashTable *zend_closure_get_gc(zval *obj, zval **table, int *n) /* {{{ */
 {
        zend_closure *closure = (zend_closure *)Z_OBJ_P(obj);
 
-       if (closure->debug_info != NULL) {
-               zend_hash_destroy(closure->debug_info);
-               efree(closure->debug_info);
-               closure->debug_info = NULL;
-       }
-
        *table = Z_TYPE(closure->this_ptr) != IS_NULL ? &closure->this_ptr : NULL;
        *n = Z_TYPE(closure->this_ptr) != IS_NULL ? 1 : 0;
        return (closure->func.type == ZEND_USER_FUNCTION) ?