summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_execute.h
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2011-04-20 12:59:18 +0000
committerDmitry Stogov <dmitry@php.net>2011-04-20 12:59:18 +0000
commitc157f4b4e666077431f6638809735f4740a82681 (patch)
tree71e71747abf8c8975ff4f457dd68dc29eb28fbab /Zend/zend_vm_execute.h
parent1dd5690af2958478ff0ec8fe95a4be0ca6a86419 (diff)
downloadphp-git-c157f4b4e666077431f6638809735f4740a82681.tar.gz
Fixed bug #54367 (Use of closure causes problem in ArrayAccess).
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r--Zend/zend_vm_execute.h40
1 files changed, 34 insertions, 6 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 7e377902b8..888ba953da 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -163,6 +163,10 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
}
}
+ if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
+ zval_ptr_dtor((zval**)&op_array->prototype);
+ }
+
nested = EX(nested);
zend_vm_stack_free(execute_data TSRMLS_CC);
@@ -750,14 +754,20 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
} else {
function_name = &opline->op2.u.constant;
- if (IS_CONST != IS_CONST &&
+ if (IS_CONST != IS_CONST && IS_CONST != IS_TMP_VAR &&
Z_TYPE_P(function_name) == IS_OBJECT &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
if (EX(object)) {
Z_ADDREF_P(EX(object));
}
+ if (IS_CONST == IS_VAR && 0 &&
+ EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ /* Delay closure destruction until its invocation */
+ EX(fbc)->common.prototype = (zend_function*)function_name;
+ } else {
+ }
ZEND_VM_NEXT_OPCODE();
}
@@ -944,14 +954,20 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
} else {
function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (IS_TMP_VAR != IS_CONST &&
+ if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_TMP_VAR &&
Z_TYPE_P(function_name) == IS_OBJECT &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
if (EX(object)) {
Z_ADDREF_P(EX(object));
}
- zval_dtor(free_op2.var);
+ if (IS_TMP_VAR == IS_VAR && 1 &&
+ EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ /* Delay closure destruction until its invocation */
+ EX(fbc)->common.prototype = (zend_function*)function_name;
+ } else {
+ zval_dtor(free_op2.var);
+ }
ZEND_VM_NEXT_OPCODE();
}
@@ -1045,14 +1061,20 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
} else {
function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (IS_VAR != IS_CONST &&
+ if (IS_VAR != IS_CONST && IS_VAR != IS_TMP_VAR &&
Z_TYPE_P(function_name) == IS_OBJECT &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
if (EX(object)) {
Z_ADDREF_P(EX(object));
}
- if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ if (IS_VAR == IS_VAR && (free_op2.var != NULL) &&
+ EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ /* Delay closure destruction until its invocation */
+ EX(fbc)->common.prototype = (zend_function*)function_name;
+ } else {
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ }
ZEND_VM_NEXT_OPCODE();
}
@@ -1169,14 +1191,20 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
} else {
function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- if (IS_CV != IS_CONST &&
+ if (IS_CV != IS_CONST && IS_CV != IS_TMP_VAR &&
Z_TYPE_P(function_name) == IS_OBJECT &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
if (EX(object)) {
Z_ADDREF_P(EX(object));
}
+ if (IS_CV == IS_VAR && 0 &&
+ EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ /* Delay closure destruction until its invocation */
+ EX(fbc)->common.prototype = (zend_function*)function_name;
+ } else {
+ }
ZEND_VM_NEXT_OPCODE();
}