]> granicus.if.org Git - php/commitdiff
Revert "Use ZEND_CLOSURE_OBJECT() macro to resolve closure op_array to closure object...
authorDmitry Stogov <dmitry@zend.com>
Thu, 11 Jan 2018 14:27:26 +0000 (17:27 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 11 Jan 2018 14:27:26 +0000 (17:27 +0300)
This reverts commit 781e1573afdc7c336b3577ceabc9c65cafea17e8.

Zend/zend_closures.c
Zend/zend_closures.h
Zend/zend_execute.c
Zend/zend_execute_API.c
Zend/zend_generators.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/reflection/php_reflection.c

index d4717187837498b75479635583671b98aecea1b4..b60107c9e5198c1c27ee0716c9829e07df7e4a8c 100644 (file)
@@ -639,7 +639,7 @@ void zend_register_closure_ce(void) /* {{{ */
 
 static ZEND_NAMED_FUNCTION(zend_closure_internal_handler) /* {{{ */
 {
-       zend_closure *closure = (zend_closure*)ZEND_CLOSURE_OBJECT(EX(func));
+       zend_closure *closure = (zend_closure*)EX(func)->common.prototype;
        closure->orig_internal_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
        OBJ_RELEASE((zend_object*)closure);
        EX(func) = NULL;
@@ -662,6 +662,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
 
        if (func->type == ZEND_USER_FUNCTION) {
                memcpy(&closure->func, func, sizeof(zend_op_array));
+               closure->func.common.prototype = (zend_function*)closure;
                closure->func.common.fn_flags |= ZEND_ACC_CLOSURE;
                if (closure->func.op_array.static_variables) {
                        closure->func.op_array.static_variables =
@@ -676,6 +677,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
                }
        } else {
                memcpy(&closure->func, func, sizeof(zend_internal_function));
+               closure->func.common.prototype = (zend_function*)closure;
                closure->func.common.fn_flags |= ZEND_ACC_CLOSURE;
                /* wrap internal function handler to avoid memory leak */
                if (UNEXPECTED(closure->func.internal_function.handler == zend_closure_internal_handler)) {
index c8b447e49838dde591065dccbaa90abc108979ae..4c7c041da8842b1b1ad9859627652713b2f01826 100644 (file)
 
 BEGIN_EXTERN_C()
 
-/* This macro depends on zend_closure structure layout */
-#define ZEND_CLOSURE_OBJECT(op_array) \
-       ((zend_object*)((char*)(op_array) - sizeof(zend_object)))
-
 void zend_register_closure_ce(void);
 void zend_closure_bind_var(zval *closure_zv, zend_string *var_name, zval *var);
 
index 4de6ba0c072295f4c77eb4bdd00d23c0afbad29d..9b7cbf294dafce9ad8aa929ef1900576135ec592 100644 (file)
@@ -2554,7 +2554,7 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o
                                OBJ_RELEASE(Z_OBJ(call->This));
                        }
                        if (call->func->common.fn_flags & ZEND_ACC_CLOSURE) {
-                               zend_object_release(ZEND_CLOSURE_OBJECT(call->func));
+                               zend_object_release((zend_object *) call->func->common.prototype);
                        } else if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
                                zend_string_release(call->func->common.function_name);
                                zend_free_trampoline(call->func);
@@ -2735,7 +2735,8 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zval *
 
                if (fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
                        /* Delay closure destruction until its invocation */
-                       GC_ADDREF(ZEND_CLOSURE_OBJECT(fbc));
+                       ZEND_ASSERT(GC_TYPE((zend_object*)fbc->common.prototype) == IS_OBJECT);
+                       GC_ADDREF((zend_object*)fbc->common.prototype);
                        call_info |= ZEND_CALL_CLOSURE;
                        if (fbc->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
                                call_info |= ZEND_CALL_FAKE_CLOSURE;
index f66bd663045a8152b0f78ab500f0f8047c4287db..61d92914bb11d3f5bc7f9cceaebf63aed4eb7f92 100644 (file)
@@ -776,7 +776,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
        if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
                uint32_t call_info;
 
-               GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
+               ZEND_ASSERT(GC_TYPE((zend_object*)func->op_array.prototype) == IS_OBJECT);
+               GC_ADDREF((zend_object*)func->op_array.prototype);
                call_info = ZEND_CALL_CLOSURE;
                if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
                        call_info |= ZEND_CALL_FAKE_CLOSURE;
index 6c2495d69d5d100b15d145e98731d8aa318a9e52..755300f92bb97adee8be2086af6d4f0b96f9e6b8 100644 (file)
@@ -24,7 +24,6 @@
 #include "zend_interfaces.h"
 #include "zend_exceptions.h"
 #include "zend_generators.h"
-#include "zend_closures.h"
 
 ZEND_API zend_class_entry *zend_ce_generator;
 ZEND_API zend_class_entry *zend_ce_ClosedGeneratorException;
@@ -146,7 +145,7 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
 
                /* Free closure object */
                if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) {
-                       OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+                       OBJ_RELEASE((zend_object *) EX(func)->common.prototype);
                }
 
                /* Free GC buffer. GC for closed generators doesn't need an allocated buffer */
@@ -336,7 +335,7 @@ static HashTable *zend_generator_get_gc(zval *object, zval **table, int *n) /* {
                ZVAL_OBJ(gc_buffer++, Z_OBJ(execute_data->This));
        }
        if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) {
-               ZVAL_OBJ(gc_buffer++, ZEND_CLOSURE_OBJECT(EX(func)));
+               ZVAL_OBJ(gc_buffer++, (zend_object *) EX(func)->common.prototype);
        }
 
        if (generator->node.children == 0) {
index 9627c045d3dc65096a899286907c7c3316f91b70..cd0a769f3410dd7d9b7168c896692781bf671cbb 100644 (file)
@@ -2374,7 +2374,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
                        }
                        OBJ_RELEASE(object);
                } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
-                       OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+                       OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype);
                }
                EG(vm_stack_top) = (zval*)execute_data;
                execute_data = EX(prev_execute_data);
@@ -2405,7 +2405,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
                        }
                        OBJ_RELEASE(object);
                } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
-                       OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+                       OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype);
                }
 
                zend_vm_stack_free_extra_args_ex(call_info, execute_data);
@@ -2447,7 +2447,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
                        }
                        EG(current_execute_data) = EX(prev_execute_data);
                        if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
-                               OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+                               OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
                        }
                        ZEND_VM_RETURN();
                } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ {
@@ -3356,7 +3356,8 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM)
                }
                if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
                        /* Delay closure destruction until its invocation */
-                       GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
+                       ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT);
+                       GC_ADDREF((zend_object*)func->common.prototype);
                        call_info |= ZEND_CALL_CLOSURE;
                        if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
                                call_info |= ZEND_CALL_FAKE_CLOSURE;
@@ -3369,7 +3370,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM)
                FREE_OP2();
                if ((OP2_TYPE & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
                        if (call_info & ZEND_CALL_CLOSURE) {
-                               zend_object_release(ZEND_CLOSURE_OBJECT(func));
+                               zend_object_release((zend_object*)func->common.prototype);
                        }
                        if (call_info & ZEND_CALL_RELEASE_THIS) {
                                zend_object_release(object);
@@ -4531,7 +4532,7 @@ ZEND_VM_HANDLER(119, ZEND_SEND_ARRAY, ANY, ANY, NUM)
                }
                zend_internal_type_error(EX_USES_STRICT_TYPES(), "call_user_func_array() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(args)));
                if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
-                       OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(call)->func));
+                       OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
                }
                if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
                        OBJ_RELEASE(Z_OBJ(EX(call)->This));
index 3845f454da182d4443e82551b4534bf0111c63de..8747a299e88c32129eac9bdcebc2f18cb89b2f9f 100644 (file)
@@ -457,7 +457,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
                        }
                        OBJ_RELEASE(object);
                } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
-                       OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+                       OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype);
                }
                EG(vm_stack_top) = (zval*)execute_data;
                execute_data = EX(prev_execute_data);
@@ -488,7 +488,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
                        }
                        OBJ_RELEASE(object);
                } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
-                       OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+                       OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype);
                }
 
                zend_vm_stack_free_extra_args_ex(call_info, execute_data);
@@ -530,7 +530,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
                        }
                        EG(current_execute_data) = EX(prev_execute_data);
                        if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
-                               OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+                               OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
                        }
                        ZEND_VM_RETURN();
                } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ {
@@ -1361,7 +1361,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O
                }
                zend_internal_type_error(EX_USES_STRICT_TYPES(), "call_user_func_array() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(args)));
                if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
-                       OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(call)->func));
+                       OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
                }
                if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
                        OBJ_RELEASE(Z_OBJ(EX(call)->This));
@@ -5585,7 +5585,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
                }
                if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
                        /* Delay closure destruction until its invocation */
-                       GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
+                       ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT);
+                       GC_ADDREF((zend_object*)func->common.prototype);
                        call_info |= ZEND_CALL_CLOSURE;
                        if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
                                call_info |= ZEND_CALL_FAKE_CLOSURE;
@@ -5597,7 +5598,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
 
                if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
                        if (call_info & ZEND_CALL_CLOSURE) {
-                               zend_object_release(ZEND_CLOSURE_OBJECT(func));
+                               zend_object_release((zend_object*)func->common.prototype);
                        }
                        if (call_info & ZEND_CALL_RELEASE_THIS) {
                                zend_object_release(object);
@@ -7795,7 +7796,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
                }
                if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
                        /* Delay closure destruction until its invocation */
-                       GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
+                       ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT);
+                       GC_ADDREF((zend_object*)func->common.prototype);
                        call_info |= ZEND_CALL_CLOSURE;
                        if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
                                call_info |= ZEND_CALL_FAKE_CLOSURE;
@@ -7808,7 +7810,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
                zval_ptr_dtor_nogc(free_op2);
                if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
                        if (call_info & ZEND_CALL_CLOSURE) {
-                               zend_object_release(ZEND_CLOSURE_OBJECT(func));
+                               zend_object_release((zend_object*)func->common.prototype);
                        }
                        if (call_info & ZEND_CALL_RELEASE_THIS) {
                                zend_object_release(object);
@@ -10931,7 +10933,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
                }
                if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
                        /* Delay closure destruction until its invocation */
-                       GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
+                       ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT);
+                       GC_ADDREF((zend_object*)func->common.prototype);
                        call_info |= ZEND_CALL_CLOSURE;
                        if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
                                call_info |= ZEND_CALL_FAKE_CLOSURE;
@@ -10943,7 +10946,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
 
                if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
                        if (call_info & ZEND_CALL_CLOSURE) {
-                               zend_object_release(ZEND_CLOSURE_OBJECT(func));
+                               zend_object_release((zend_object*)func->common.prototype);
                        }
                        if (call_info & ZEND_CALL_RELEASE_THIS) {
                                zend_object_release(object);
index 6749003c46dd5b14c9f1eaf27ea44373849c9ed3..458d5c2c065dd852ff1d6b70881743423b299b29 100644 (file)
@@ -2218,7 +2218,7 @@ ZEND_METHOD(reflection_generator, getFunction)
 
        if (ex->func->common.fn_flags & ZEND_ACC_CLOSURE) {
                zval closure;
-               ZVAL_OBJ(&closure, ZEND_CLOSURE_OBJECT(ex->func));
+               ZVAL_OBJ(&closure, (zend_object *) ex->func->common.prototype);
                reflection_function_factory(ex->func, &closure, return_value);
        } else if (ex->func->op_array.scope) {
                reflection_method_factory(ex->func->op_array.scope, ex->func, NULL, return_value);