summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_execute.h
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r--Zend/zend_vm_execute.h134
1 files changed, 79 insertions, 55 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index c0ff942e20..1ec6d97343 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -414,11 +414,15 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC);
}
}
- zval_ptr_dtor(&EG(This));
+ if (!Z_DELREF(EG(This))) {
+ _zval_dtor_func_for_ptr(Z_COUNTED(EG(This)) ZEND_FILE_LINE_CC);
+ } else if (UNEXPECTED(!Z_GC_INFO(EG(This)))) {
+ gc_possible_root(Z_COUNTED(EG(This)) TSRMLS_CC);
+ }
}
- Z_OBJ(EG(This)) = EX(current_this);
- EG(scope) = EX(current_scope);
- EG(called_scope) = EX(current_called_scope);
+ Z_OBJ(EG(This)) = EX(object);
+ EG(scope) = EX(scope);
+ EG(called_scope) = EX(called_scope);
EX(call)--;
@@ -487,12 +491,12 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_bool should_change_scope = 0;
zend_function *fbc = EX(function_state).function;
+ zend_object *object;
zend_uint num_args;
SAVE_OPLINE();
- EX(object) = EX(call)->object;
+ object = EX(call)->object;
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
@@ -509,7 +513,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
}
if (fbc->common.scope &&
!(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
- !EX(object)) {
+ !object) {
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
/* FIXME: output identifiers properly */
@@ -524,17 +528,6 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
}
}
- if (fbc->type == ZEND_USER_FUNCTION || fbc->common.scope) {
- should_change_scope = 1;
- EX(current_this) = Z_OBJ(EG(This));
- EX(current_scope) = EG(scope);
- EX(current_called_scope) = EG(called_scope);
- Z_OBJ(EG(This)) = EX(object);
-//??? EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL;
- EG(scope) = fbc->common.scope;
- EG(called_scope) = EX(call)->called_scope;
- }
-
if (UNEXPECTED(EX(call)->num_additional_args != 0)) {
num_args = opline->extended_value + EX(call)->num_additional_args;
EX(function_state).arguments = zend_vm_stack_push_args(num_args TSRMLS_CC);
@@ -549,6 +542,17 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
LOAD_OPLINE();
if (fbc->type == ZEND_INTERNAL_FUNCTION) {
+ int should_change_scope = 0;
+ zval *ret;
+
+ if (fbc->common.scope) {
+ should_change_scope = 1;
+ Z_OBJ(EG(This)) = object;
+//??? EG(scope) = (object) ? NULL : fbc->common.scope;
+ EG(scope) = fbc->common.scope;
+ EG(called_scope) = EX(call)->called_scope;
+ }
+
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_uint i;
zval *p = EX(function_state).arguments - num_args;
@@ -556,30 +560,44 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
for (i = 0; i < num_args; ++i, ++p) {
zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC);
}
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
+ }
+ if (UNEXPECTED(should_change_scope)) {
+ goto fcall_end_change_scope;
+ } else {
+ goto fcall_end;
+ }
+ }
}
- if (EXPECTED(EG(exception) == NULL)) {
- zval *ret = EX_VAR(opline->result.var);
+ ret = EX_VAR(opline->result.var);
+ ZVAL_NULL(ret);
+ Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
- ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
+ if (!zend_execute_internal) {
+ /* saves one function call if zend_execute_internal is not used */
+ fbc->internal_function.handler(num_args, ret TSRMLS_CC);
+ } else {
+ zend_execute_internal(execute_data, NULL TSRMLS_CC);
+ }
- if (!zend_execute_internal) {
- /* saves one function call if zend_execute_internal is not used */
- fbc->internal_function.handler(num_args, ret TSRMLS_CC);
- } else {
- zend_execute_internal(execute_data, NULL TSRMLS_CC);
- }
+ if (!RETURN_VALUE_USED(opline)) {
+ zval_ptr_dtor(ret);
+ }
- if (!RETURN_VALUE_USED(opline)) {
- zval_ptr_dtor(ret);
- }
- } else if (RETURN_VALUE_USED(opline)) {
- ZVAL_UNDEF(EX_VAR(opline->result.var));
+ if (UNEXPECTED(should_change_scope)) {
+ goto fcall_end_change_scope;
+ } else {
+ goto fcall_end;
}
} else if (fbc->type == ZEND_USER_FUNCTION) {
zval *return_value = NULL;
+ Z_OBJ(EG(This)) = object;
+ EG(scope) = fbc->common.scope;
+ EG(called_scope) = EX(call)->called_scope;
EG(active_symbol_table) = NULL;
EG(active_op_array) = &fbc->op_array;
if (RETURN_VALUE_USED(opline)) {
@@ -609,11 +627,16 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
}
EG(active_symbol_table) = EX(symbol_table);
} else { /* ZEND_OVERLOADED_FUNCTION */
+ Z_OBJ(EG(This)) = object;
+//??? EG(scope) = NULL;
+ EG(scope) = fbc->common.scope;
+ EG(called_scope) = EX(call)->called_scope;
+
ZVAL_NULL(EX_VAR(opline->result.var));
/* Not sure what should be done here if it's a static method */
- if (EXPECTED(EX(object) != NULL)) {
- EX(object)->handlers->call_method(fbc->common.function_name, EX(object), num_args, EX_VAR(opline->result.var) TSRMLS_CC);
+ if (EXPECTED(object != NULL)) {
+ object->handlers->call_method(fbc->common.function_name, object, num_args, EX_VAR(opline->result.var) TSRMLS_CC);
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
@@ -632,26 +655,31 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
}
}
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
-
- if (should_change_scope) {
- if (Z_OBJ(EG(This))) {
- if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
- if (EX(call)->is_ctor_result_used) {
- Z_DELREF(EG(This));
- }
- if (Z_REFCOUNT(EG(This)) == 1) {
- zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC);
- }
+fcall_end_change_scope:
+ if (Z_OBJ(EG(This))) {
+ if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
+ if (EX(call)->is_ctor_result_used) {
+ Z_DELREF(EG(This));
+ }
+ if (Z_REFCOUNT(EG(This)) == 1) {
+ zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC);
}
- zval_ptr_dtor(&EG(This));
}
- Z_OBJ(EG(This)) = EX(current_this);
- EG(scope) = EX(current_scope);
- EG(called_scope) = EX(current_called_scope);
+ if (!Z_DELREF(EG(This))) {
+ EX(function_state).function = (zend_function *) EX(op_array);
+ EX(function_state).arguments = NULL;
+ _zval_dtor_func_for_ptr(Z_COUNTED(EG(This)) ZEND_FILE_LINE_CC);
+ } else if (UNEXPECTED(!Z_GC_INFO(EG(This)))) {
+ gc_possible_root(Z_COUNTED(EG(This)) TSRMLS_CC);
+ }
}
+ Z_OBJ(EG(This)) = EX(object);
+ EG(scope) = EX(scope);
+ EG(called_scope) = EX(called_scope);
+fcall_end:
+ EX(function_state).function = (zend_function *) EX(op_array);
+ EX(function_state).arguments = NULL;
EX(call)--;
zend_vm_stack_clear_multiple(1 TSRMLS_CC);
@@ -2916,7 +2944,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
}
EX(function_state).function = (zend_function *) new_op_array;
- EX(object) = NULL;
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
@@ -7953,7 +7980,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
}
EX(function_state).function = (zend_function *) new_op_array;
- EX(object) = NULL;
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
@@ -13058,7 +13084,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
}
EX(function_state).function = (zend_function *) new_op_array;
- EX(object) = NULL;
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
@@ -29866,7 +29891,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
}
EX(function_state).function = (zend_function *) new_op_array;
- EX(object) = NULL;
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);