Now EG(current_execute_data) always point to the call frame of the currently executed function.
#define USED_RET() \
(!EG(current_execute_data) || \
- !EG(current_execute_data)->opline || \
- !(EG(current_execute_data)->opline->result_type & EXT_TYPE_UNUSED))
+ !EG(current_execute_data)->prev_execute_data || \
+ !EG(current_execute_data)->prev_execute_data->opline || \
+ !(EG(current_execute_data)->prev_execute_data->opline->result_type & EXT_TYPE_UNUSED))
#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((noreturn));
zval **param, *param_ptr;
TSRMLS_FETCH();
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
- arg_count = EG(current_execute_data)->call->num_args;
+ param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
+ arg_count = EG(current_execute_data)->num_args;
if (param_count>arg_count) {
return FAILURE;
zval **param, *param_ptr;
TSRMLS_FETCH();
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
- arg_count = EG(current_execute_data)->call->num_args;
+ param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
+ arg_count = EG(current_execute_data)->num_args;
if (param_count>arg_count) {
return FAILURE;
zval *param_ptr;
int arg_count;
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
- arg_count = EG(current_execute_data)->call->num_args;
+ param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
+ arg_count = EG(current_execute_data)->num_args;
if (param_count>arg_count) {
return FAILURE;
zval *param_ptr;
int arg_count;
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
- arg_count = EG(current_execute_data)->call->num_args;
+ param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
+ arg_count = EG(current_execute_data)->num_args;
if (param_count>arg_count) {
return FAILURE;
case '+':
if (have_varargs) {
if (!quiet) {
- zend_function *active_function = EG(current_execute_data)->call->func;
+ zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
zend_error(E_WARNING, "%s%s%s(): only one varargs specifier (* or +) is permitted",
class_name,
default:
if (!quiet) {
- zend_function *active_function = EG(current_execute_data)->call->func;
+ zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
zend_error(E_WARNING, "%s%s%s(): bad type specifier while parsing parameters",
class_name,
if (num_args < min_num_args || (num_args > max_num_args && max_num_args > 0)) {
if (!quiet) {
- zend_function *active_function = EG(current_execute_data)->call->func;
+ zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
zend_error(E_WARNING, "%s%s%s() expects %s %d parameter%s, %d given",
class_name,
return FAILURE;
}
- arg_count = EG(current_execute_data)->call->num_args;
+ arg_count = EG(current_execute_data)->num_args;
if (num_args > arg_count) {
zend_error(E_WARNING, "%s(): could not obtain parameters for parsing",
if (num_varargs > 0) {
*n_varargs = num_varargs;
- *varargs = ZEND_CALL_ARG(EG(current_execute_data)->call, i + 1);
+ *varargs = ZEND_CALL_ARG(EG(current_execute_data), i + 1);
/* adjust how many args we have left and restart loop */
num_args += 1 - num_varargs;
i += num_varargs;
}
}
- arg = ZEND_CALL_ARG(EG(current_execute_data)->call, i + 1);
+ arg = ZEND_CALL_ARG(EG(current_execute_data), i + 1);
if (zend_parse_arg(i+1, arg, va, &type_spec, quiet TSRMLS_CC) == FAILURE) {
/* clean up varargs array if it was used */
* Z_OBJ(EG(This)) to NULL when calling an internal function with common.scope == NULL.
* In that case EG(This) would still be the $this from the calling code and we'd take the
* wrong branch here. */
- zend_bool is_method = EG(current_execute_data)->call->func->common.scope != NULL;
+ zend_bool is_method = EG(current_execute_data)->func->common.scope != NULL;
if (!is_method || !this_ptr || Z_TYPE_P(this_ptr) != IS_OBJECT) {
RETURN_IF_ZERO_ARGS(num_args, p, 0);
Get the number of arguments that were passed to the function */
ZEND_FUNCTION(func_num_args)
{
- zend_execute_data *ex = EG(current_execute_data);
+ zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
if (ex->frame_kind == VM_FRAME_NESTED_FUNCTION || ex->frame_kind == VM_FRAME_TOP_FUNCTION) {
RETURN_LONG(ex->num_args);
RETURN_FALSE;
}
- ex = EG(current_execute_data);
+ ex = EG(current_execute_data)->prev_execute_data;
if (ex->frame_kind != VM_FRAME_NESTED_FUNCTION && ex->frame_kind != VM_FRAME_TOP_FUNCTION) {
zend_error(E_WARNING, "func_get_arg(): Called from the global scope - no function context");
RETURN_FALSE;
zval *p;
int arg_count, first_extra_arg;
int i;
- zend_execute_data *ex = EG(current_execute_data);
+ zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
if (ex->frame_kind != VM_FRAME_NESTED_FUNCTION && ex->frame_kind != VM_FRAME_TOP_FUNCTION) {
zend_error(E_WARNING, "func_get_args(): Called from the global scope - no function context");
}
ZVAL_UNDEF(&arg_array);
- ptr = EG(current_execute_data);
+ ptr = EG(current_execute_data)->prev_execute_data;
/* skip debug_backtrace() */
object = ptr->object;
if (skip->func && ZEND_USER_CODE(skip->func->common.type)) {
filename = skip->func->op_array.filename->val;
- lineno = skip->opline->lineno;
+ if (skip->opline->opcode == ZEND_HANDLE_EXCEPTION) {
+ if (EG(opline_before_exception)) {
+ lineno = EG(opline_before_exception)->lineno;
+ } else {
+ lineno = skip->func->op_array.line_end;
+ }
+ } else {
+ lineno = skip->opline->lineno;
+ }
} else {
filename = NULL;
lineno = 0;
zval stack_frame;
ptr = EG(current_execute_data);
-
- /* skip "new Exception()" */
- if (ptr && (skip_last == 0) && ptr->opline && (ptr->opline->opcode == ZEND_NEW)) {
- object = ptr->object;
+ if (!ptr->opline) {
ptr = ptr->prev_execute_data;
}
- /* skip debug_backtrace() */
- if (skip_last-- && ptr) {
- object = ptr->object;
- ptr = ptr->prev_execute_data;
+ if (ptr) {
+ if (skip_last) {
+ /* skip debug_backtrace() */
+ object = ptr->object;
+ ptr = ptr->prev_execute_data;
+ } else {
+ /* skip "new Exception()" */
+ if (ptr->opline && (ptr->opline->opcode == ZEND_NEW)) {
+ object = ptr->object;
+ ptr = ptr->prev_execute_data;
+ }
+ }
}
array_init(return_value);
if (skip->func && ZEND_USER_CODE(skip->func->common.type)) {
filename = skip->func->op_array.filename->val;
- lineno = skip->opline->lineno;
+ if (skip->opline->opcode == ZEND_HANDLE_EXCEPTION) {
+ if (EG(opline_before_exception)) {
+ lineno = EG(opline_before_exception)->lineno;
+ } else {
+ lineno = skip->func->op_array.line_end;
+ }
+ } else {
+ lineno = skip->opline->lineno;
+ }
add_assoc_string_ex(&stack_frame, "file", sizeof("file")-1, (char*)filename);
add_assoc_long_ex(&stack_frame, "line", sizeof("line")-1, lineno);
ZEND_METHOD(Closure, __invoke) /* {{{ */
{
- zend_function *func = EG(current_execute_data)->call->func;
+ zend_function *func = EG(current_execute_data)->func;
zval *arguments;
arguments = emalloc(sizeof(zval) * ZEND_NUM_ARGS());
ZVAL_UNDEF(arg);
}
- if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
+ if (zf->common.type == ZEND_USER_FUNCTION && ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->func->op_array.filename->val, ptr->opline->lineno);
} else {
zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
}
}
-static zend_always_inline int zend_vm_stack_get_args_count_ex(zend_execute_data *ex)
-{
- return ex->call->num_args;
-}
-
-static zend_always_inline zval* zend_vm_stack_get_arg_ex(zend_execute_data *ex, int requested_arg)
-{
- int arg_count = ex->call->num_args;
-
- if (UNEXPECTED(requested_arg > arg_count)) {
- return NULL;
- }
- return ZEND_CALL_ARG(ex->call, requested_arg);
-}
-
-static zend_always_inline int zend_vm_stack_get_args_count(TSRMLS_D)
-{
- if (EG(current_execute_data)->prev_execute_data) {
- return zend_vm_stack_get_args_count_ex(EG(current_execute_data)->prev_execute_data);
- } else {
- return 0;
- }
-}
-
-static zend_always_inline zval* zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
-{
- return zend_vm_stack_get_arg_ex(EG(current_execute_data)->prev_execute_data, requested_arg);
-}
-
void execute_new_code(TSRMLS_D);
return "";
}
- if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) {
- func = EG(current_execute_data)->call->func;
- } else {
- func = EG(current_execute_data)->func;
- }
+ func = EG(current_execute_data)->func;
switch (func->type) {
case ZEND_USER_FUNCTION:
case ZEND_INTERNAL_FUNCTION:
if (!zend_is_executing(TSRMLS_C)) {
return NULL;
}
- if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) {
- func = EG(current_execute_data)->call->func;
- } else {
- func = EG(current_execute_data)->func;
- }
+ func = EG(current_execute_data)->func;
switch (func->type) {
case ZEND_USER_FUNCTION: {
zend_string *function_name = func->common.function_name;
zend_op **original_opline_ptr;
zend_class_entry *calling_scope = NULL;
zend_class_entry *called_scope = NULL;
- zend_execute_data execute_data;
+ zend_execute_data *call, dummy_execute_data;
zend_fcall_info_cache fci_cache_local;
zend_function *func;
+ zend_object *orig_object;
+ zend_class_entry *orig_scope, *orig_called_scope;
zval tmp;
ZVAL_UNDEF(fci->retval);
break;
}
+ orig_object = Z_OBJ(EG(This));
+ orig_scope = EG(scope);
+ orig_called_scope = EG(called_scope);
+
/* Initialize execute_data */
- if (EG(current_execute_data)) {
- execute_data = *EG(current_execute_data);
- EX(object) = Z_OBJ(EG(This));
- EX(scope) = EG(scope);
- EX(called_scope) = EG(called_scope);
- EX(func) = NULL;
- EX(opline) = NULL;
- } else {
+ if (!EG(current_execute_data)) {
/* This only happens when we're called outside any execute()'s
* It shouldn't be strictly necessary to NULL execute_data out,
* but it may make bugs easier to spot
*/
- memset(&execute_data, 0, sizeof(zend_execute_data));
+ memset(&dummy_execute_data, 0, sizeof(zend_execute_data));
+ EG(current_execute_data) = &dummy_execute_data;
+ } else if (EG(current_execute_data)->opline &&
+ EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL) {
+ /* Insert fake frame in case of include or magic calls */
+ dummy_execute_data = *EG(current_execute_data);
+ dummy_execute_data.prev_execute_data = EG(current_execute_data);
+ dummy_execute_data.call = NULL;
+ dummy_execute_data.prev_nested_call = NULL;
+ dummy_execute_data.opline = NULL;
+ dummy_execute_data.func = NULL;
+ EG(current_execute_data) = &dummy_execute_data;
}
if (!fci_cache || !fci_cache->initialized) {
if (callable_name) {
STR_RELEASE(callable_name);
}
+ if (EG(current_execute_data) == &dummy_execute_data) {
+ EG(current_execute_data) = dummy_execute_data.prev_execute_data;
+ }
return FAILURE;
} else if (error) {
/* Capitalize the first latter of the error message */
}
func = fci_cache->function_handler;
- EX(call) = zend_vm_stack_push_call_frame(func, fci->param_count, ZEND_CALL_DONE, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC);
+ call = zend_vm_stack_push_call_frame(func, fci->param_count, ZEND_CALL_DONE, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC);
calling_scope = fci_cache->calling_scope;
called_scope = fci_cache->called_scope;
fci->object = fci_cache->object;
if (fci->object &&
(!EG(objects_store).object_buckets ||
!IS_OBJ_VALID(EG(objects_store).object_buckets[fci->object->handle]))) {
+ if (EG(current_execute_data) == &dummy_execute_data) {
+ EG(current_execute_data) = dummy_execute_data.prev_execute_data;
+ }
return FAILURE;
}
!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
if (i) {
/* hack to clean up the stack */
- EX(call)->num_args = i;
- zend_vm_stack_free_args(EX(call) TSRMLS_CC);
+ call->num_args = i;
+ zend_vm_stack_free_args(call TSRMLS_CC);
}
- zend_vm_stack_free_call_frame(EX(call) TSRMLS_CC);
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
i+1,
func->common.scope ? func->common.scope->name->val : "",
func->common.scope ? "::" : "",
func->common.function_name->val);
+ if (EG(current_execute_data) == &dummy_execute_data) {
+ EG(current_execute_data) = dummy_execute_data.prev_execute_data;
+ }
return FAILURE;
}
} else if (Z_REFCOUNTED(fci->params[i])) {
Z_ADDREF(fci->params[i]);
}
- param = ZEND_CALL_ARG(EX(call), i+1);
+ param = ZEND_CALL_ARG(call, i+1);
ZVAL_COPY_VALUE(param, &fci->params[i]);
} else if (Z_ISREF(fci->params[i]) &&
/* don't separate references for __call */
(func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) {
param = &tmp;
- param = ZEND_CALL_ARG(EX(call), i+1);
+ param = ZEND_CALL_ARG(call, i+1);
ZVAL_DUP(param, Z_REFVAL(fci->params[i]));
} else {
- param = ZEND_CALL_ARG(EX(call), i+1);
+ param = ZEND_CALL_ARG(call, i+1);
ZVAL_COPY(param, &fci->params[i]);
}
}
- EX(call)->num_args = fci->param_count;
+ call->num_args = fci->param_count;
EG(scope) = calling_scope;
EG(called_scope) = called_scope;
if (!fci->object ||
(func->common.fn_flags & ZEND_ACC_STATIC)) {
- Z_OBJ(EG(This)) = EX(call)->object = NULL;
+ Z_OBJ(EG(This)) = call->object = NULL;
} else {
Z_OBJ(EG(This)) = fci->object;
Z_ADDREF(EG(This));
}
- EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = &execute_data;
+ call->prev_nested_call = EG(current_execute_data)->call;
+ EG(current_execute_data)->call = call;
if (func->type == ZEND_USER_FUNCTION) {
calling_symbol_table = EG(active_symbol_table);
if (func->common.scope) {
EG(scope) = func->common.scope;
}
+ call->opline = NULL;
+ call->call = NULL;
+ call->prev_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = call;
if (EXPECTED(zend_execute_internal == NULL)) {
/* saves one function call if zend_execute_internal is not used */
func->internal_function.handler(fci->param_count, fci->retval TSRMLS_CC);
} else {
- zend_execute_internal(&execute_data, fci TSRMLS_CC);
+ zend_execute_internal(call->prev_execute_data, fci TSRMLS_CC);
}
- zend_vm_stack_free_args(EX(call) TSRMLS_CC);
- zend_vm_stack_free_call_frame(EX(call) TSRMLS_CC);
+ EG(current_execute_data) = call->prev_execute_data;
+ zend_vm_stack_free_args(call TSRMLS_CC);
+ EG(current_execute_data)->call = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
/* We shouldn't fix bad extensions here,
because it can break proper ones (Bug #34045)
/* Not sure what should be done here if it's a static method */
if (fci->object) {
+ call->opline = NULL;
+ call->call = NULL;
+ call->prev_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = call;
fci->object->handlers->call_method(func->common.function_name, fci->object, fci->param_count, fci->retval TSRMLS_CC);
+ EG(current_execute_data) = call->prev_execute_data;
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
+ zend_vm_stack_free_args(call TSRMLS_CC);
+ EG(current_execute_data)->call = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+
if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
STR_RELEASE(func->common.function_name);
}
zval_ptr_dtor(&EG(This));
}
- Z_OBJ(EG(This)) = EX(object);
- EG(scope) = EX(scope);
- EG(called_scope) = EX(called_scope);
- EG(current_execute_data) = EX(prev_execute_data);
+ Z_OBJ(EG(This)) = orig_object;
+ EG(scope) = orig_scope;
+ EG(called_scope) = orig_called_scope;
+ if (EG(current_execute_data) == &dummy_execute_data) {
+ EG(current_execute_data) = dummy_execute_data.prev_execute_data;
+ }
if (EG(exception)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
if (!EG(active_symbol_table)) {
int i;
zend_execute_data *execute_data = EG(current_execute_data);
- zend_op_array *op_array = &execute_data->func->op_array;
+ zend_op_array *op_array;
zend_ulong h = STR_HASH_VAL(name);
- if (op_array) {
+ while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
+ execute_data = execute_data->prev_execute_data;
+ }
+
+ if (execute_data && execute_data->func) {
+ op_array = &execute_data->func->op_array;
for (i = 0; i < op_array->last_var; i++) {
if (op_array->vars[i]->h == h &&
op_array->vars[i]->len == name->len &&
if (!EG(active_symbol_table)) {
int i;
zend_execute_data *execute_data = EG(current_execute_data);
- zend_op_array *op_array = &execute_data->func->op_array;
+ zend_op_array *op_array;
zend_ulong h = zend_hash_func(name, len);
- if (op_array) {
+ while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
+ execute_data = execute_data->prev_execute_data;
+ }
+
+ if (execute_data && execute_data->func) {
+ op_array = &execute_data->func->op_array;
for (i = 0; i < op_array->last_var; i++) {
if (op_array->vars[i]->h == h &&
op_array->vars[i]->len == len &&
zend_class_entry *original_scope = EG(scope);
zend_class_entry *original_called_scope = EG(called_scope);
zend_vm_stack original_stack = EG(argument_stack);
- zend_execute_data *prev_execute_data;
original_This = Z_OBJ(EG(This));
* called from whatever method we are current running (e.g. next()).
* So we have to link generator call frame with caller call frames */
- prev_execute_data = original_execute_data;
- if (prev_execute_data &&
- prev_execute_data->call &&
- (prev_execute_data->call->flags & ZEND_CALL_DONE)) {
- prev_execute_data->call->prev_execute_data = prev_execute_data;
- prev_execute_data = prev_execute_data->call;
- }
- generator->execute_data->prev_execute_data = prev_execute_data;
- if (prev_execute_data) {
- generator->execute_data->prev_nested_call = prev_execute_data->call;
- prev_execute_data->call = generator->execute_data;
+ generator->execute_data->prev_execute_data = original_execute_data;
+ if (original_execute_data) {
+ generator->execute_data->prev_nested_call = original_execute_data->call;
+ original_execute_data->call = generator->execute_data;
}
/* Resume execution */
ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
{
- zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->call->func;
+ zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->func;
zval method_name, method_args;
zval method_result;
zend_class_entry *ce = Z_OBJCE_P(getThis());
ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
{
- zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->call->func;
+ zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->func;
zval method_name, method_args;
zval method_result;
zend_class_entry *ce = EG(scope);
vm_frame_kind frame_kind = EX(frame_kind);
zend_execute_data *prev_nested_call;
- EG(current_execute_data) = EX(prev_execute_data);
-
if (frame_kind == VM_FRAME_NESTED_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
if (UNEXPECTED(EX(symbol_table) != NULL)) {
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
+ EG(current_execute_data) = EX(prev_execute_data);
prev_nested_call = EX(prev_nested_call);
zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
zend_detach_symbol_table(execute_data);
destroy_op_array(&EX(func)->op_array TSRMLS_CC);
efree(EX(func));
+ EG(current_execute_data) = EX(prev_execute_data);
prev_nested_call = EX(prev_nested_call);
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
if ((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) && EX(func)->op_array.prototype) {
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
+ EG(current_execute_data) = EX(prev_execute_data);
prev_nested_call = EX(prev_nested_call);
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
EG(called_scope) = call->called_scope;
}
+ call->opline = NULL;
+ call->call = NULL;
+ call->prev_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = call;
+
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_uint i;
zval *p = ZEND_CALL_ARG(call, 1);
p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
+ EG(current_execute_data) = call->prev_execute_data;
+ zend_vm_stack_free_args(call TSRMLS_CC);
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
}
} else {
zend_execute_internal(execute_data, NULL TSRMLS_CC);
}
-
+ EG(current_execute_data) = call->prev_execute_data;
zend_vm_stack_free_args(call TSRMLS_CC);
-
EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
/* Not sure what should be done here if it's a static method */
if (EXPECTED(call->object != NULL)) {
+ call->opline = NULL;
+ call->call = NULL;
+ call->prev_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = call;
call->object->handlers->call_method(fbc->common.function_name, call->object, call->num_args, EX_VAR(opline->result.var) TSRMLS_CC);
+ EG(current_execute_data) = call->prev_execute_data;
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
vm_frame_kind frame_kind = EX(frame_kind);
zend_execute_data *prev_nested_call;
- EG(current_execute_data) = EX(prev_execute_data);
-
if (frame_kind == VM_FRAME_NESTED_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
if (UNEXPECTED(EX(symbol_table) != NULL)) {
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
+ EG(current_execute_data) = EX(prev_execute_data);
prev_nested_call = EX(prev_nested_call);
zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
zend_detach_symbol_table(execute_data);
destroy_op_array(&EX(func)->op_array TSRMLS_CC);
efree(EX(func));
+ EG(current_execute_data) = EX(prev_execute_data);
prev_nested_call = EX(prev_nested_call);
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
if ((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) && EX(func)->op_array.prototype) {
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
+ EG(current_execute_data) = EX(prev_execute_data);
prev_nested_call = EX(prev_nested_call);
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
EG(called_scope) = call->called_scope;
}
+ call->opline = NULL;
+ call->call = NULL;
+ call->prev_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = call;
+
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_uint i;
zval *p = ZEND_CALL_ARG(call, 1);
p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
+ EG(current_execute_data) = call->prev_execute_data;
+ zend_vm_stack_free_args(call TSRMLS_CC);
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
}
} else {
zend_execute_internal(execute_data, NULL TSRMLS_CC);
}
-
+ EG(current_execute_data) = call->prev_execute_data;
zend_vm_stack_free_args(call TSRMLS_CC);
-
EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
/* Not sure what should be done here if it's a static method */
if (EXPECTED(call->object != NULL)) {
+ call->opline = NULL;
+ call->call = NULL;
+ call->prev_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = call;
call->object->handlers->call_method(fbc->common.function_name, call->object, call->num_args, EX_VAR(opline->result.var) TSRMLS_CC);
+ EG(current_execute_data) = call->prev_execute_data;
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}