summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend.c5
-rw-r--r--Zend/zend.h2
-rw-r--r--Zend/zend_alloc.c2
-rw-r--r--Zend/zend_builtin_functions.c97
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_dtrace.c4
-rw-r--r--Zend/zend_dtrace.h4
-rw-r--r--Zend/zend_exceptions.c3
-rw-r--r--Zend/zend_execute.c32
-rw-r--r--Zend/zend_execute.h12
-rw-r--r--Zend/zend_execute_API.c30
-rw-r--r--Zend/zend_generators.c15
-rw-r--r--Zend/zend_generators.h2
-rw-r--r--Zend/zend_vm_def.h40
-rw-r--r--Zend/zend_vm_execute.h95
-rw-r--r--Zend/zend_vm_execute.skl10
-rw-r--r--ext/opcache/ZendAccelerator.c16
-rw-r--r--ext/phar/phar_object.c5
-rw-r--r--ext/spl/php_spl.c7
-rw-r--r--main/main.c2
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
) {