Simplify call-frame handling

This commit is contained in:
Dmitry Stogov 2014-07-07 15:50:44 +04:00
parent 6bf24f4dd0
commit 5aa91be509
20 changed files with 165 additions and 219 deletions

View File

@ -1056,7 +1056,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
ex = ex->prev_execute_data;
}
if (ex && ex->opline && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
EG(opline_before_exception)) {
opline = EG(opline_before_exception);
}
@ -1253,7 +1253,8 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
if (type == E_PARSE) {
/* eval() errors do not affect exit_status */
if (!(EG(current_execute_data) &&
EG(current_execute_data)->opline &&
EG(current_execute_data)->func &&
ZEND_USER_CODE(EG(current_execute_data)->func->type) &&
EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
EG(current_execute_data)->opline->extended_value == ZEND_EVAL)) {
EG(exit_status) = 255;

View File

@ -291,7 +291,7 @@ typedef enum {
#define USED_RET() \
(!EG(current_execute_data) || \
!EG(current_execute_data)->prev_execute_data || \
!EG(current_execute_data)->prev_execute_data->opline || \
!ZEND_USER_CODE(EG(current_execute_data)->prev_execute_data->func->common.type) || \
!(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__)

View File

@ -1769,7 +1769,7 @@ static void zend_mm_safe_error(zend_mm_heap *heap,
}
if (ex) {
error_filename = ex->func->op_array.filename->val;
error_lineno = ex->opline ? ex->opline->lineno : 0;
error_lineno = ex->opline->lineno;
} else {
error_filename = NULL;
error_lineno = 0;

View File

@ -2033,7 +2033,7 @@ void debug_print_backtrace_args(zval *arg_array TSRMLS_DC)
/* {{{ proto void debug_print_backtrace([int options[, int limit]]) */
ZEND_FUNCTION(debug_print_backtrace)
{
zend_execute_data *ptr, *skip;
zend_execute_data *call, *ptr, *skip;
zend_object *object;
int lineno, frameno = 0;
zend_function *func;
@ -2055,7 +2055,7 @@ ZEND_FUNCTION(debug_print_backtrace)
ptr = EG(current_execute_data)->prev_execute_data;
/* skip debug_backtrace() */
object = ptr->object;
call = ptr;
ptr = ptr->prev_execute_data;
while (ptr && (limit == 0 || frameno < limit)) {
@ -2068,7 +2068,8 @@ ZEND_FUNCTION(debug_print_backtrace)
/* skip internal handler */
if ((!skip->func || !ZEND_USER_CODE(skip->func->common.type)) &&
skip->prev_execute_data &&
skip->prev_execute_data->opline &&
skip->prev_execute_data->func &&
ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
skip = skip->prev_execute_data;
@ -2091,15 +2092,16 @@ ZEND_FUNCTION(debug_print_backtrace)
}
/* $this may be passed into regular internal functions */
object = call->object;
if (object &&
ptr->call &&
ptr->call->func->type == ZEND_INTERNAL_FUNCTION &&
!ptr->call->func->common.scope) {
call &&
call->func->type == ZEND_INTERNAL_FUNCTION &&
!call->func->common.scope) {
object = NULL;
}
if (ptr->call && ptr->call->func && (ptr->call->flags & ZEND_CALL_DONE)) {
func = ptr->call->func;
if (call->func) {
func = call->func;
function_name = (func->common.scope &&
func->common.scope->trait_aliases) ?
zend_resolve_method_name(
@ -2109,9 +2111,8 @@ ZEND_FUNCTION(debug_print_backtrace)
(func->common.function_name ?
func->common.function_name->val : NULL);
} else {
func = ptr->func;
function_name = func && func->common.function_name ?
func->common.function_name->val : NULL;
func = NULL;
function_name = NULL;
}
if (function_name) {
@ -2132,14 +2133,14 @@ ZEND_FUNCTION(debug_print_backtrace)
}
if (func->type != ZEND_EVAL_CODE) {
if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) {
debug_backtrace_get_args(ptr->call, &arg_array TSRMLS_CC);
debug_backtrace_get_args(call, &arg_array TSRMLS_CC);
}
}
} else {
/* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
zend_bool build_filename_arg = 1;
if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type) || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
/* can happen when calling eval from a custom sapi */
function_name = "unknown";
build_filename_arg = 0;
@ -2188,12 +2189,13 @@ ZEND_FUNCTION(debug_print_backtrace)
if (filename) {
zend_printf(") called at [%s:%d]\n", filename, lineno);
} else {
zend_execute_data *prev_call = skip;
zend_execute_data *prev = skip->prev_execute_data;
while (prev) {
if (prev->call &&
prev->call->func &&
!ZEND_USER_CODE(prev->call->func->common.type)) {
if (prev_call &&
prev_call->func &&
!ZEND_USER_CODE(prev_call->func->common.type)) {
prev = NULL;
break;
}
@ -2201,6 +2203,7 @@ ZEND_FUNCTION(debug_print_backtrace)
zend_printf(") called at [%s:%d]\n", prev->func->op_array.filename->val, prev->opline->lineno);
break;
}
prev_call = prev;
prev = prev->prev_execute_data;
}
if (!prev) {
@ -2208,7 +2211,7 @@ ZEND_FUNCTION(debug_print_backtrace)
}
}
include_filename = filename;
object = skip->object;
call = skip;
ptr = skip->prev_execute_data;
++indent;
}
@ -2218,8 +2221,8 @@ ZEND_FUNCTION(debug_print_backtrace)
ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit TSRMLS_DC)
{
zend_execute_data *ptr, *skip;
zend_object *object = Z_OBJ(EG(This));
zend_execute_data *call, *ptr, *skip;
zend_object *object;
int lineno, frameno = 0;
zend_function *func;
const char *function_name;
@ -2228,24 +2231,29 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
const char *include_filename = NULL;
zval stack_frame;
call = NULL;
ptr = EG(current_execute_data);
if (!ptr->opline) {
if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type)) {
call = ptr;
ptr = ptr->prev_execute_data;
}
if (ptr) {
if (skip_last) {
/* skip debug_backtrace() */
object = ptr->object;
call = ptr;
ptr = ptr->prev_execute_data;
} else {
/* skip "new Exception()" */
if (ptr->opline && (ptr->opline->opcode == ZEND_NEW)) {
object = ptr->object;
if (ptr->func && ZEND_USER_CODE(ptr->func->common.type) && (ptr->opline->opcode == ZEND_NEW)) {
call = ptr;
ptr = ptr->prev_execute_data;
}
}
}
if (!call) {
call = ptr;
}
array_init(return_value);
@ -2257,7 +2265,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
/* skip internal handler */
if ((!skip->func || !ZEND_USER_CODE(skip->func->common.type)) &&
skip->prev_execute_data &&
skip->prev_execute_data->opline &&
skip->prev_execute_data->func &&
ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
skip = skip->prev_execute_data;
@ -2281,14 +2290,15 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
* and debug_baktrace() might have been called by the error_handler. in this case we don't
* want to pop anything of the argument-stack */
} else {
zend_execute_data *prev_call = skip;
zend_execute_data *prev = skip->prev_execute_data;
while (prev) {
if (prev->call &&
prev->call->func &&
!ZEND_USER_CODE(prev->call->func->common.type) &&
!(prev->call->func->common.type == ZEND_INTERNAL_FUNCTION &&
(prev->call->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER))) {
if (prev_call &&
prev_call->func &&
!ZEND_USER_CODE(prev_call->func->common.type) &&
!(prev_call->func->common.type == ZEND_INTERNAL_FUNCTION &&
(prev_call->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER))) {
break;
}
if (prev->func && ZEND_USER_CODE(prev->func->common.type)) {
@ -2297,21 +2307,22 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
add_assoc_long_ex(&stack_frame, "line", sizeof("line")-1, prev->opline->lineno);
break;
}
prev_call = prev;
prev = prev->prev_execute_data;
}
filename = NULL;
}
/* $this may be passed into regular internal functions */
object = call ? call->object : NULL;
if (object &&
ptr->call &&
ptr->call->func->type == ZEND_INTERNAL_FUNCTION &&
!ptr->call->func->common.scope) {
call->func->type == ZEND_INTERNAL_FUNCTION &&
!call->func->common.scope) {
object = NULL;
}
if (ptr->call && ptr->call->func && (ptr->call->flags & ZEND_CALL_DONE)) {
func = ptr->call->func;
if (call && call->func) {
func = call->func;
function_name = (func->common.scope &&
func->common.scope->trait_aliases) ?
zend_resolve_method_name(
@ -2321,9 +2332,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
(func->common.function_name ?
func->common.function_name->val : NULL);
} else {
func = ptr->func;
function_name = func && func->common.function_name ?
func->common.function_name->val : NULL;
func = NULL;
function_name = NULL;
}
if (function_name) {
@ -2352,17 +2362,16 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 &&
func->type != ZEND_EVAL_CODE) {
if (ptr->call) {
zval args;
debug_backtrace_get_args(ptr->call, &args TSRMLS_CC);
add_assoc_zval_ex(&stack_frame, "args", sizeof("args")-1, &args);
}
zval args;
debug_backtrace_get_args(call, &args TSRMLS_CC);
add_assoc_zval_ex(&stack_frame, "args", sizeof("args")-1, &args);
}
} else {
/* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
zend_bool build_filename_arg = 1;
if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type) || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
/* can happen when calling eval from a custom sapi */
function_name = "unknown";
build_filename_arg = 0;
@ -2412,7 +2421,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
include_filename = filename;
object = skip->object;
call = skip;
ptr = skip->prev_execute_data;
}
}

View File

@ -380,7 +380,6 @@ struct _zend_execute_data {
#define ZEND_CALL_CTOR (1 << 0)
#define ZEND_CALL_CTOR_RESULT_UNUSED (1 << 1)
#define ZEND_CALL_DONE (1 << 2)
#define ZEND_CALL_FRAME_SLOT \
((ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval)))

View File

@ -81,7 +81,7 @@ ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data TSRMLS_DC)
}
}
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci TSRMLS_DC)
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *return_value TSRMLS_DC)
{
int lineno;
const char *filename;
@ -94,7 +94,7 @@ ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, zend_
DTRACE_EXECUTE_ENTRY((char *)filename, lineno);
}
execute_internal(execute_data_ptr, fci TSRMLS_CC);
execute_internal(execute_data, return_value TSRMLS_CC);
if (DTRACE_EXECUTE_RETURN_ENABLED()) {
DTRACE_EXECUTE_RETURN((char *)filename, lineno);

View File

@ -32,11 +32,11 @@ extern "C" {
#ifdef HAVE_DTRACE
ZEND_API zend_op_array *(*zend_dtrace_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
ZEND_API void (*zend_dtrace_execute)(zend_op_array *op_array TSRMLS_DC);
ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC);
ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data TSRMLS_DC);
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC);
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
#include <zend_dtrace_gen.h>
#endif /* HAVE_DTRACE */

View File

@ -119,7 +119,8 @@ void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
zend_throw_exception_hook(exception TSRMLS_CC);
}
if (EG(current_execute_data)->opline == NULL ||
if (!EG(current_execute_data)->func ||
!ZEND_USER_CODE(EG(current_execute_data)->func->common.type) ||
(EG(current_execute_data)->opline+1)->opcode == ZEND_HANDLE_EXCEPTION) {
/* no need to rethrow the exception */
return;

View File

@ -1476,18 +1476,9 @@ static int zend_check_symbol(zval *pz TSRMLS_DC)
ZEND_API opcode_handler_t *zend_opcode_handlers;
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci TSRMLS_DC)
ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value TSRMLS_DC)
{
if (fci != NULL) {
execute_data_ptr->call->func->internal_function.handler(
fci->param_count, fci->retval TSRMLS_CC
);
} else {
zval *return_value = EX_VAR_2(execute_data_ptr, execute_data_ptr->opline->result.var);
execute_data_ptr->call->func->internal_function.handler(
execute_data_ptr->call->num_args, return_value TSRMLS_CC
);
}
execute_data->func->internal_function.handler(execute_data->num_args, return_value TSRMLS_CC);
}
void zend_clean_and_cache_symbol_table(zend_array *symbol_table TSRMLS_DC) /* {{{ */
@ -1693,7 +1684,7 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
}
/* }}} */
ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_op_array *op_array, zval *return_value TSRMLS_DC) /* {{{ */
ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data *call, zend_op_array *op_array, zval *return_value TSRMLS_DC) /* {{{ */
{
/*
* Normally the execute_data is allocated on the VM stack (because it does
@ -1705,7 +1696,7 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_op_array *op
* restore it simply by replacing a pointer.
*/
zend_execute_data *execute_data;
zend_uint num_args = EG(current_execute_data)->call->num_args;
zend_uint num_args = call->num_args;
EG(argument_stack) = zend_vm_stack_new_page(
MAX(ZEND_VM_STACK_PAGE_SIZE,
@ -1715,15 +1706,15 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_op_array *op
execute_data = zend_vm_stack_push_call_frame(
(zend_function*)op_array,
num_args,
EG(current_execute_data)->call->flags,
EG(current_execute_data)->call->called_scope,
EG(current_execute_data)->call->object,
call->flags,
call->called_scope,
call->object,
NULL TSRMLS_CC);
EX(num_args) = num_args;
/* copy arguments */
if (num_args > 0) {
zval *arg_src = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
zval *arg_src = ZEND_CALL_ARG(call, 1);
zval *arg_dst = ZEND_CALL_ARG(execute_data, 1);
int i;
@ -1738,15 +1729,10 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_op_array *op
}
/* }}} */
ZEND_API zend_execute_data *zend_create_execute_data(zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
ZEND_API void zend_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
{
zend_execute_data *execute_data;
execute_data = EG(current_execute_data)->call;
EX(prev_execute_data) = EG(current_execute_data);
i_init_execute_data(execute_data, op_array, return_value, frame_kind TSRMLS_CC);
return execute_data;
}
/* }}} */

View File

@ -30,16 +30,16 @@
BEGIN_EXTERN_C()
struct _zend_fcall_info;
ZEND_API extern void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC);
ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci TSRMLS_DC);
ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
void init_executor(TSRMLS_D);
void shutdown_executor(TSRMLS_D);
void shutdown_destructors(TSRMLS_D);
ZEND_API zend_execute_data *zend_create_execute_data(zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC);
ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_op_array *op_array, zval *return_value TSRMLS_DC);
ZEND_API void zend_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC);
ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data *call, zend_op_array *op_array, zval *return_value TSRMLS_DC);
ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value TSRMLS_DC);
ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC);
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci TSRMLS_DC);
ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
ZEND_API int zend_is_true(zval *op TSRMLS_DC);
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name TSRMLS_DC);
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *key, int use_autoload TSRMLS_DC);
@ -250,8 +250,8 @@ static zend_always_inline void zend_vm_stack_free_args(zend_execute_data *call T
zend_uint num_args = call->num_args;
if (num_args > 0) {
zval *p = ZEND_CALL_ARG(call, num_args + 1);
zval *end = p - num_args;;
zval *end = ZEND_CALL_ARG(call, 1);
zval *p = end + num_args;
do {
p--;

View File

@ -39,7 +39,7 @@
#endif
ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC);
ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci TSRMLS_DC);
ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
/* true globals */
ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0},0}, NULL, NULL, 0, NULL, NULL, 0 };
@ -468,7 +468,7 @@ ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
ex = ex->prev_execute_data;
}
if (ex && ex->opline) {
if (ex) {
if (EG(exception) && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
ex->opline->lineno == 0 && EG(opline_before_exception)) {
return EG(opline_before_exception)->lineno;
@ -697,7 +697,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
*/
memset(&dummy_execute_data, 0, sizeof(zend_execute_data));
EG(current_execute_data) = &dummy_execute_data;
} else if (EG(current_execute_data)->opline &&
} else if (EG(current_execute_data)->func &&
ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
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);
@ -741,7 +742,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
}
func = fci_cache->function_handler;
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, 0, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC);
calling_scope = fci_cache->calling_scope;
fci->object = fci_cache->object;
if (fci->object &&
@ -843,16 +844,14 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
Z_ADDREF(EG(This));
}
call->prev_nested_call = EG(current_execute_data)->call;
EG(current_execute_data)->call = call;
if (func->type == ZEND_USER_FUNCTION) {
EG(scope) = func->common.scope;
call->symbol_table = fci->symbol_table;
if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) {
zend_execute(&func->op_array, fci->retval TSRMLS_CC);
zend_init_execute_data(call, &func->op_array, fci->retval, call->symbol_table ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
zend_execute_ex(call TSRMLS_CC);
} else {
zend_generator_create_zval(&func->op_array, fci->retval TSRMLS_CC);
zend_generator_create_zval(call, &func->op_array, fci->retval TSRMLS_CC);
}
} else if (func->type == ZEND_INTERNAL_FUNCTION) {
int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
@ -860,19 +859,16 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
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(call->prev_execute_data, fci TSRMLS_CC);
zend_execute_internal(call, fci->retval 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,
@ -895,8 +891,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
/* 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);
@ -906,7 +900,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
}
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) {
@ -1098,11 +1091,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s
zend_try {
ZVAL_UNDEF(&local_retval);
if (EG(current_execute_data)) {
EG(current_execute_data)->call = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EG(current_execute_data)->called_scope, Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC);
EG(current_execute_data)->call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
zend_execute(new_op_array, &local_retval TSRMLS_CC);
} zend_catch {
destroy_op_array(new_op_array TSRMLS_CC);

View File

@ -132,10 +132,6 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
efree(op_array);
}
if (generator->execute_data->prev_execute_data) {
generator->execute_data->prev_execute_data->call = generator->execute_data->prev_nested_call;
}
efree(generator->stack);
generator->execute_data = NULL;
}
@ -225,7 +221,7 @@ static int copy_closure_static_var(zval *var TSRMLS_DC, int num_args, va_list ar
/* }}} */
/* Requires globals EG(scope), EG(This) and EG(current_execute_data). */
ZEND_API void zend_generator_create_zval(zend_op_array *op_array, zval *return_value TSRMLS_DC) /* {{{ */
ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array *op_array, zval *return_value TSRMLS_DC) /* {{{ */
{
zend_generator *generator;
zend_execute_data *current_execute_data;
@ -259,7 +255,7 @@ ZEND_API void zend_generator_create_zval(zend_op_array *op_array, zval *return_v
/* Create new execution context. We have to back up and restore
* EG(current_execute_data) here. */
current_execute_data = EG(current_execute_data);
execute_data = zend_create_generator_execute_data(op_array, return_value TSRMLS_CC);
execute_data = zend_create_generator_execute_data(call, op_array, return_value TSRMLS_CC);
EG(current_execute_data) = current_execute_data;
object_init_ex(return_value, zend_ce_generator);
@ -322,10 +318,6 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
* So we have to link generator call frame with caller call frames */
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 */
generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;
@ -333,8 +325,7 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
generator->flags &= ~ZEND_GENERATOR_CURRENTLY_RUNNING;
/* Unlink generator call_frame from the caller */
if (generator->execute_data && generator->execute_data->prev_execute_data) {
generator->execute_data->prev_execute_data->call = generator->execute_data->prev_nested_call;
if (generator->execute_data) {
generator->execute_data->prev_execute_data = NULL;
}

View File

@ -54,7 +54,7 @@ static const zend_uchar ZEND_GENERATOR_FORCED_CLOSE = 0x2;
static const zend_uchar ZEND_GENERATOR_AT_FIRST_YIELD = 0x4;
void zend_register_generator_ce(TSRMLS_D);
ZEND_API void zend_generator_create_zval(zend_op_array *op_array, zval *return_value TSRMLS_DC);
ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array *op_array, zval *return_value TSRMLS_DC);
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC);
ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC);

View File

@ -1772,7 +1772,6 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
{
vm_frame_kind frame_kind = EX(frame_kind);
zend_execute_data *prev_nested_call;
if (frame_kind == VM_FRAME_NESTED_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
@ -1783,12 +1782,10 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
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);
execute_data = EG(current_execute_data);
EX(call) = prev_nested_call;
if (Z_OBJ(EG(This))) {
if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
@ -1825,11 +1822,9 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
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);
execute_data = EG(current_execute_data);
EX(call) = prev_nested_call;
zend_attach_symbol_table(execute_data);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
@ -1866,12 +1861,8 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
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);
if (EG(current_execute_data)) {
EG(current_execute_data)->call = prev_nested_call;
}
ZEND_VM_RETURN();
}
}
@ -2573,7 +2564,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
zend_function *fbc = call->func;
SAVE_OPLINE();
call->flags = ZEND_CALL_DONE;
EX(call) = call->prev_nested_call;
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);
@ -2625,8 +2616,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
call->called_scope = EX(called_scope);
}
call->opline = NULL;
call->call = NULL;
call->prev_execute_data = execute_data;
EG(current_execute_data) = call;
@ -2641,7 +2630,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
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));
@ -2662,11 +2650,10 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
/* saves one function call if zend_execute_internal is not used */
fbc->internal_function.handler(call->num_args, ret TSRMLS_CC);
} else {
zend_execute_internal(execute_data, NULL TSRMLS_CC);
zend_execute_internal(call, ret 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);
if (!RETURN_VALUE_USED(opline)) {
@ -2693,10 +2680,9 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
if (RETURN_VALUE_USED(opline)) {
zend_generator_create_zval(&fbc->op_array, EX_VAR(opline->result.var) TSRMLS_CC);
zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var) TSRMLS_CC);
}
EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
call->prev_execute_data = execute_data;
@ -2717,8 +2703,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
/* 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 = 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);
@ -2729,7 +2713,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
zend_vm_stack_free_args(call TSRMLS_CC);
EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
@ -3974,26 +3957,27 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
zend_execute_data *call;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
call = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), NULL TSRMLS_CC);
if (EX(symbol_table)) {
EX(call)->symbol_table = EX(symbol_table);
call->symbol_table = EX(symbol_table);
} else {
EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
execute_ex(EG(current_execute_data) TSRMLS_CC);
execute_ex(call TSRMLS_CC);
}
destroy_op_array(new_op_array TSRMLS_CC);
@ -5340,7 +5324,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
}
closure_is_static = Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC;
closure_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->call->func->common.fn_flags & ZEND_ACC_STATIC;
closure_is_being_defined_inside_static_context = EX(func)->common.fn_flags & ZEND_ACC_STATIC;
if (closure_is_static || closure_is_being_defined_inside_static_context) {
zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(called_scope), NULL TSRMLS_CC);
} else {

View File

@ -376,22 +376,21 @@ ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value TSRMLS_DC
return;
}
if (EG(current_execute_data) && EG(current_execute_data)->call) {
execute_data = EG(current_execute_data)->call;
execute_data = zend_vm_stack_push_call_frame(
(zend_function*)op_array, 0, 0, EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL, Z_OBJ(EG(This)), NULL TSRMLS_CC);
if (EG(current_execute_data)) {
execute_data->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
} else {
execute_data = zend_vm_stack_push_call_frame(
(zend_function*)op_array, 0, 0, EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL, Z_OBJ(EG(This)), NULL TSRMLS_CC);
execute_data->symbol_table = &EG(symbol_table);
}
EX(prev_execute_data) = EG(current_execute_data);
i_init_execute_data(execute_data, op_array, return_value, (execute_data->symbol_table) ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
i_init_execute_data(execute_data, op_array, return_value, VM_FRAME_TOP_CODE TSRMLS_CC);
zend_execute_ex(execute_data TSRMLS_CC);
}
static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
{
vm_frame_kind frame_kind = EX(frame_kind);
zend_execute_data *prev_nested_call;
if (frame_kind == VM_FRAME_NESTED_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
@ -402,12 +401,10 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
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);
execute_data = EG(current_execute_data);
EX(call) = prev_nested_call;
if (Z_OBJ(EG(This))) {
if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
@ -444,11 +441,9 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
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);
execute_data = EG(current_execute_data);
EX(call) = prev_nested_call;
zend_attach_symbol_table(execute_data);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
@ -485,12 +480,8 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
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);
if (EG(current_execute_data)) {
EG(current_execute_data)->call = prev_nested_call;
}
ZEND_VM_RETURN();
}
}
@ -521,7 +512,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_function *fbc = call->func;
SAVE_OPLINE();
call->flags = ZEND_CALL_DONE;
EX(call) = call->prev_nested_call;
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);
@ -573,8 +564,6 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
call->called_scope = EX(called_scope);
}
call->opline = NULL;
call->call = NULL;
call->prev_execute_data = execute_data;
EG(current_execute_data) = call;
@ -589,7 +578,6 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
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));
@ -610,11 +598,10 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
/* saves one function call if zend_execute_internal is not used */
fbc->internal_function.handler(call->num_args, ret TSRMLS_CC);
} else {
zend_execute_internal(execute_data, NULL TSRMLS_CC);
zend_execute_internal(call, ret 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);
if (!RETURN_VALUE_USED(opline)) {
@ -641,10 +628,9 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
if (RETURN_VALUE_USED(opline)) {
zend_generator_create_zval(&fbc->op_array, EX_VAR(opline->result.var) TSRMLS_CC);
zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var) TSRMLS_CC);
}
EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
call->prev_execute_data = execute_data;
@ -665,8 +651,6 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
/* 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 = 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);
@ -677,7 +661,6 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_vm_stack_free_args(call TSRMLS_CC);
EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
@ -2910,26 +2893,27 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
zend_execute_data *call;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
call = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), NULL TSRMLS_CC);
if (EX(symbol_table)) {
EX(call)->symbol_table = EX(symbol_table);
call->symbol_table = EX(symbol_table);
} else {
EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
execute_ex(EG(current_execute_data) TSRMLS_CC);
execute_ex(call TSRMLS_CC);
}
destroy_op_array(new_op_array TSRMLS_CC);
@ -6589,7 +6573,7 @@ static int ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER
}
closure_is_static = Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC;
closure_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->call->func->common.fn_flags & ZEND_ACC_STATIC;
closure_is_being_defined_inside_static_context = EX(func)->common.fn_flags & ZEND_ACC_STATIC;
if (closure_is_static || closure_is_being_defined_inside_static_context) {
zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(called_scope), NULL TSRMLS_CC);
} else {
@ -8103,26 +8087,27 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
zend_execute_data *call;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
call = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), NULL TSRMLS_CC);
if (EX(symbol_table)) {
EX(call)->symbol_table = EX(symbol_table);
call->symbol_table = EX(symbol_table);
} else {
EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
execute_ex(EG(current_execute_data) TSRMLS_CC);
execute_ex(call TSRMLS_CC);
}
destroy_op_array(new_op_array TSRMLS_CC);
@ -13363,26 +13348,27 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
zend_execute_data *call;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
call = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), NULL TSRMLS_CC);
if (EX(symbol_table)) {
EX(call)->symbol_table = EX(symbol_table);
call->symbol_table = EX(symbol_table);
} else {
EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
execute_ex(EG(current_execute_data) TSRMLS_CC);
execute_ex(call TSRMLS_CC);
}
destroy_op_array(new_op_array TSRMLS_CC);
@ -30495,26 +30481,27 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
zend_execute_data *call;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
call = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), NULL TSRMLS_CC);
if (EX(symbol_table)) {
EX(call)->symbol_table = EX(symbol_table);
call->symbol_table = EX(symbol_table);
} else {
EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
execute_ex(EG(current_execute_data) TSRMLS_CC);
execute_ex(call TSRMLS_CC);
}
destroy_op_array(new_op_array TSRMLS_CC);

View File

@ -35,15 +35,15 @@ ZEND_API void zend_{%EXECUTOR_NAME%}(zend_op_array *op_array, zval *return_value
return;
}
if (EG(current_execute_data) && EG(current_execute_data)->call) {
execute_data = EG(current_execute_data)->call;
execute_data = zend_vm_stack_push_call_frame(
(zend_function*)op_array, 0, 0, EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL, Z_OBJ(EG(This)), NULL TSRMLS_CC);
if (EG(current_execute_data)) {
execute_data->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
} else {
execute_data = zend_vm_stack_push_call_frame(
(zend_function*)op_array, 0, 0, EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL, Z_OBJ(EG(This)), NULL TSRMLS_CC);
execute_data->symbol_table = &EG(symbol_table);
}
EX(prev_execute_data) = EG(current_execute_data);
i_init_execute_data(execute_data, op_array, return_value, (execute_data->symbol_table) ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
i_init_execute_data(execute_data, op_array, return_value, VM_FRAME_TOP_CODE TSRMLS_CC);
zend_{%EXECUTOR_NAME%}_ex(execute_data TSRMLS_CC);
}

View File

@ -1522,7 +1522,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type T
ZCG(cache_opline) == NULL &&
file_handle->filename == SG(request_info).path_translated &&
ZCG(cache_persistent_script)) ||
(EG(current_execute_data) && EG(current_execute_data)->opline &&
(EG(current_execute_data) &&
EG(current_execute_data)->func &&
ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
EG(current_execute_data)->opline == ZCG(cache_opline) &&
EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
@ -1683,6 +1685,8 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type T
/* see bug #15471 (old BTS) */
if (persistent_script->full_path) {
if (!EG(current_execute_data) || !EG(current_execute_data)->opline ||
!EG(current_execute_data)->func ||
!ZEND_USER_CODE(EG(current_execute_data)->func->common.type) ||
EG(current_execute_data)->opline->opcode != ZEND_INCLUDE_OR_EVAL ||
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
(EG(current_execute_data)->opline->extended_value != ZEND_INCLUDE_ONCE &&
@ -1843,7 +1847,9 @@ static int persistent_stream_open_function(const char *filename, zend_file_handl
!CG(interactive) &&
!ZCSG(restart_in_progress)) {
if (EG(current_execute_data) && EG(current_execute_data)->opline) {
if (EG(current_execute_data) &&
EG(current_execute_data)->func &&
ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
zend_op *opline = EG(current_execute_data)->opline;
if (opline->opcode == ZEND_INCLUDE_OR_EVAL &&
@ -1943,7 +1949,8 @@ static int persistent_stream_open_function(const char *filename, zend_file_handl
if ((!EG(current_execute_data) &&
filename == SG(request_info).path_translated) ||
(EG(current_execute_data) &&
EG(current_execute_data)->opline &&
EG(current_execute_data)->func &&
ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
(EG(current_execute_data)->opline->extended_value == ZEND_INCLUDE_ONCE ||
@ -2008,7 +2015,8 @@ static char* persistent_zend_resolve_path(const char *filename, int filename_len
if ((!EG(current_execute_data) &&
filename == SG(request_info).path_translated) ||
(EG(current_execute_data) &&
EG(current_execute_data)->opline &&
EG(current_execute_data)->func &&
ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
(EG(current_execute_data)->opline->extended_value == ZEND_INCLUDE_ONCE ||

View File

@ -285,11 +285,6 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char
ZVAL_UNDEF(&result);
zend_try {
if (EG(current_execute_data)) {
EG(current_execute_data)->call = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EG(current_execute_data)->called_scope, Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC);
EG(current_execute_data)->call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
zend_execute(new_op_array, &result TSRMLS_CC);
if (PHAR_G(cwd)) {
efree(PHAR_G(cwd));

View File

@ -287,11 +287,6 @@ static int spl_autoload(zend_string *class_name, zend_string *lc_name, const cha
STR_RELEASE(opened_path);
if (new_op_array) {
ZVAL_UNDEF(&result);
if (EG(current_execute_data)) {
EG(current_execute_data)->call = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EG(current_execute_data)->called_scope, Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC);
EG(current_execute_data)->call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
zend_execute(new_op_array, &result TSRMLS_CC);
destroy_op_array(new_op_array TSRMLS_CC);
@ -356,7 +351,7 @@ PHP_FUNCTION(spl_autoload)
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
ex = ex->prev_execute_data;
}
if (ex && ex->opline && ex->opline->opcode != ZEND_FETCH_CLASS) {
if (ex && ex->opline->opcode != ZEND_FETCH_CLASS) {
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Class %s could not be loaded", class_name->val);
} else {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s could not be loaded", class_name->val);

View File

@ -770,6 +770,8 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c
} else if (php_during_module_shutdown()) {
function = "PHP Shutdown";
} else if (EG(current_execute_data) &&
EG(current_execute_data)->func &&
ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
EG(current_execute_data)->opline &&
EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL
) {