diff options
-rw-r--r-- | Zend/zend.c | 5 | ||||
-rw-r--r-- | Zend/zend.h | 2 | ||||
-rw-r--r-- | Zend/zend_alloc.c | 2 | ||||
-rw-r--r-- | Zend/zend_builtin_functions.c | 97 | ||||
-rw-r--r-- | Zend/zend_compile.h | 1 | ||||
-rw-r--r-- | Zend/zend_dtrace.c | 4 | ||||
-rw-r--r-- | Zend/zend_dtrace.h | 4 | ||||
-rw-r--r-- | Zend/zend_exceptions.c | 3 | ||||
-rw-r--r-- | Zend/zend_execute.c | 32 | ||||
-rw-r--r-- | Zend/zend_execute.h | 12 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 30 | ||||
-rw-r--r-- | Zend/zend_generators.c | 15 | ||||
-rw-r--r-- | Zend/zend_generators.h | 2 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 40 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 95 | ||||
-rw-r--r-- | Zend/zend_vm_execute.skl | 10 | ||||
-rw-r--r-- | ext/opcache/ZendAccelerator.c | 16 | ||||
-rw-r--r-- | ext/phar/phar_object.c | 5 | ||||
-rw-r--r-- | ext/spl/php_spl.c | 7 | ||||
-rw-r--r-- | main/main.c | 2 |
20 files changed, 165 insertions, 219 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index 85578b5aac..52d574e047 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -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; diff --git a/Zend/zend.h b/Zend/zend.h index 1ddcdb5aeb..3827f15b54 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -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__) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 35a201b21c..bb3e66c989 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -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; diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index dbe02ded5c..96b339cd67 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -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; } } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index b053ee9820..e6575eecfc 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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))) diff --git a/Zend/zend_dtrace.c b/Zend/zend_dtrace.c index 8d854f1ef8..2c1deadec0 100644 --- a/Zend/zend_dtrace.c +++ b/Zend/zend_dtrace.c @@ -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); diff --git a/Zend/zend_dtrace.h b/Zend/zend_dtrace.h index 26008afb6b..6b1c8413e0 100644 --- a/Zend/zend_dtrace.h +++ b/Zend/zend_dtrace.h @@ -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 */ diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 0f59e254d7..90487bf762 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -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; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 44519adcec..fcc932095d 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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; } /* }}} */ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index f807874a1e..4fc56d9864 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -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--; diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 6730bacf40..69f7cfad5b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -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); diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 427c8bdb11..698b2d8cf3 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -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; } diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h index 999ead4b6e..5d1264cc4f 100644 --- a/Zend/zend_generators.h +++ b/Zend/zend_generators.h @@ -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); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 370bebe1f1..e65483468e 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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 { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 83cfc75949..b069ead63f 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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); diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl index 51cede9834..4825e02b53 100644 --- a/Zend/zend_vm_execute.skl +++ b/Zend/zend_vm_execute.skl @@ -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); } diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index e84de1a34c..c1775b8538 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -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 || diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 684f56ea4c..e2acb53724 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -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)); diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index e5f968e26b..cd0a050b98 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -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); diff --git a/main/main.c b/main/main.c index e66ec77532..f4f88d5360 100644 --- a/main/main.c +++ b/main/main.c @@ -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 ) { |