summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend.c56
-rw-r--r--Zend/zend.h5
-rw-r--r--Zend/zend_API.c53
-rw-r--r--Zend/zend_API.h2
-rw-r--r--Zend/zend_alloc.c16
-rw-r--r--Zend/zend_builtin_functions.c148
-rw-r--r--Zend/zend_closures.c2
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_constants.c8
-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.c143
-rw-r--r--Zend/zend_execute.h43
-rw-r--r--Zend/zend_execute_API.c311
-rw-r--r--Zend/zend_generators.c50
-rw-r--r--Zend/zend_generators.h2
-rw-r--r--Zend/zend_globals.h10
-rw-r--r--Zend/zend_interfaces.c7
-rw-r--r--Zend/zend_object_handlers.c20
-rw-r--r--Zend/zend_objects.c8
-rw-r--r--Zend/zend_variables.c9
-rw-r--r--Zend/zend_vm_def.h109
-rw-r--r--Zend/zend_vm_execute.h301
-rw-r--r--Zend/zend_vm_execute.skl15
-rw-r--r--Zend/zend_vm_gen.php5
-rw-r--r--ext/mbstring/mbstring.c7
-rw-r--r--ext/opcache/Optimizer/pass1_5.c12
-rw-r--r--ext/opcache/ZendAccelerator.c76
-rw-r--r--ext/opcache/zend_persist.c12
-rw-r--r--ext/phar/phar_object.c5
-rw-r--r--ext/readline/readline_cli.c3
-rw-r--r--ext/soap/php_encoding.c2
-rw-r--r--ext/soap/soap.c7
-rw-r--r--ext/spl/php_spl.c23
-rw-r--r--ext/standard/array.c18
-rw-r--r--ext/standard/assert.c2
-rw-r--r--ext/standard/basic_functions.c14
-rw-r--r--ext/standard/http_fopen_wrapper.c7
-rw-r--r--ext/standard/string.c6
-rw-r--r--ext/wddx/wddx.c6
-rw-r--r--main/SAPI.c10
-rw-r--r--main/main.c32
-rw-r--r--main/php_variables.c3
44 files changed, 782 insertions, 798 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index a1ffb5f0c9..52d574e047 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -559,7 +559,6 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals TSRMLS
EG(lambda_count) = 0;
ZVAL_UNDEF(&EG(user_error_handler));
ZVAL_UNDEF(&EG(user_exception_handler));
- EG(in_execution) = 0;
EG(in_autoload) = NULL;
EG(current_execute_data) = NULL;
EG(current_module) = NULL;
@@ -880,7 +879,7 @@ ZEND_API void _zend_bailout(char *filename, uint lineno) /* {{{ */
}
CG(unclean_shutdown) = 1;
CG(active_class_entry) = NULL;
- CG(in_compilation) = EG(in_execution) = 0;
+ CG(in_compilation) = 0;
EG(current_execute_data) = NULL;
LONGJMP(*EG(bailout), FAILURE);
}
@@ -938,8 +937,7 @@ void zend_call_destructors(TSRMLS_D) /* {{{ */
ZEND_API void zend_deactivate(TSRMLS_D) /* {{{ */
{
/* we're no longer executing anything */
- EG(opline_ptr) = NULL;
- EG(active_symbol_table) = NULL;
+ EG(current_execute_data) = NULL;
zend_try {
shutdown_scanner(TSRMLS_C);
@@ -1038,10 +1036,14 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
zend_stack declare_stack;
zend_stack list_stack;
zend_stack context_stack;
+ zend_array *symbol_table;
TSRMLS_FETCH();
/* Report about uncaught exception in case of fatal errors */
if (EG(exception)) {
+ zend_execute_data *ex;
+ zend_op *opline;
+
switch (type) {
case E_CORE_ERROR:
case E_ERROR:
@@ -1049,13 +1051,19 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
case E_PARSE:
case E_COMPILE_ERROR:
case E_USER_ERROR:
- if (zend_is_executing(TSRMLS_C)) {
- error_lineno = zend_get_executed_lineno(TSRMLS_C);
+ ex = EG(current_execute_data);
+ opline = NULL;
+ while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
+ ex = ex->prev_execute_data;
+ }
+ if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
+ EG(opline_before_exception)) {
+ opline = EG(opline_before_exception);
}
zend_exception_error(EG(exception), E_WARNING TSRMLS_CC);
EG(exception) = NULL;
- if (zend_is_executing(TSRMLS_C) && EG(opline_ptr)) {
- active_opline->lineno = error_lineno;
+ if (opline) {
+ ex->opline = opline;
}
break;
default:
@@ -1088,7 +1096,12 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
error_lineno = zend_get_compiled_lineno(TSRMLS_C);
} else if (zend_is_executing(TSRMLS_C)) {
error_filename = zend_get_executed_filename(TSRMLS_C);
- error_lineno = zend_get_executed_lineno(TSRMLS_C);
+ if (error_filename[0] == '[') { /* [no active file] */
+ error_filename = NULL;
+ error_lineno = 0;
+ } else {
+ error_lineno = zend_get_executed_lineno(TSRMLS_C);
+ }
} else {
error_filename = NULL;
error_lineno = 0;
@@ -1162,16 +1175,14 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
ZVAL_LONG(&params[3], error_lineno);
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
+ symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
/* during shutdown the symbol table table can be still null */
- if (!EG(active_symbol_table)) {
+ if (!symbol_table) {
ZVAL_NULL(&params[4]);
} else {
ZVAL_NEW_ARR(&params[4]);
- zend_array_dup(Z_ARRVAL(params[4]), &EG(active_symbol_table)->ht);
+ zend_array_dup(Z_ARRVAL(params[4]), &symbol_table->ht);
}
ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
@@ -1242,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;
@@ -1287,7 +1299,7 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_cou
va_list files;
int i;
zend_file_handle *file_handle;
- zend_op_array *orig_op_array = EG(active_op_array);
+ zend_op_array *op_array;
long orig_interactive = CG(interactive);
va_start(files, file_count);
@@ -1305,13 +1317,13 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_cou
}
}
- EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);
+ op_array = zend_compile_file(file_handle, type TSRMLS_CC);
if (file_handle->opened_path) {
zend_hash_str_add_empty_element(&EG(included_files), file_handle->opened_path, strlen(file_handle->opened_path));
}
zend_destroy_file_handle(file_handle TSRMLS_CC);
- if (EG(active_op_array)) {
- zend_execute(EG(active_op_array), retval TSRMLS_CC);
+ if (op_array) {
+ zend_execute(op_array, retval TSRMLS_CC);
zend_exception_restore(TSRMLS_C);
if (EG(exception)) {
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
@@ -1338,17 +1350,15 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_cou
zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
}
}
- destroy_op_array(EG(active_op_array) TSRMLS_CC);
- efree(EG(active_op_array));
+ destroy_op_array(op_array TSRMLS_CC);
+ efree(op_array);
} else if (type==ZEND_REQUIRE) {
va_end(files);
- EG(active_op_array) = orig_op_array;
CG(interactive) = orig_interactive;
return FAILURE;
}
}
va_end(files);
- EG(active_op_array) = orig_op_array;
CG(interactive) = orig_interactive;
return SUCCESS;
diff --git a/Zend/zend.h b/Zend/zend.h
index f21ba92d61..3827f15b54 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -290,8 +290,9 @@ typedef enum {
#define USED_RET() \
(!EG(current_execute_data) || \
- !EG(current_execute_data)->opline || \
- !(EG(current_execute_data)->opline->result_type & EXT_TYPE_UNUSED))
+ !EG(current_execute_data)->prev_execute_data || \
+ !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__)
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((noreturn));
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 6b469c2b0a..faf18252e4 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -49,8 +49,8 @@ ZEND_API int zend_get_parameters(int ht, int param_count, ...) /* {{{ */
zval **param, *param_ptr;
TSRMLS_FETCH();
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
- arg_count = EG(current_execute_data)->call->num_args;
+ param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
+ arg_count = EG(current_execute_data)->num_args;
if (param_count>arg_count) {
return FAILURE;
@@ -85,8 +85,8 @@ ZEND_API int zend_get_parameters_ex(int param_count, ...) /* {{{ */
zval **param, *param_ptr;
TSRMLS_FETCH();
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
- arg_count = EG(current_execute_data)->call->num_args;
+ param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
+ arg_count = EG(current_execute_data)->num_args;
if (param_count>arg_count) {
return FAILURE;
@@ -109,8 +109,8 @@ ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array
zval *param_ptr;
int arg_count;
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
- arg_count = EG(current_execute_data)->call->num_args;
+ param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
+ arg_count = EG(current_execute_data)->num_args;
if (param_count>arg_count) {
return FAILURE;
@@ -131,8 +131,8 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TS
zval *param_ptr;
int arg_count;
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
- arg_count = EG(current_execute_data)->call->num_args;
+ param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
+ arg_count = EG(current_execute_data)->num_args;
if (param_count>arg_count) {
return FAILURE;
@@ -803,7 +803,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
case '+':
if (have_varargs) {
if (!quiet) {
- zend_function *active_function = EG(current_execute_data)->call->func;
+ zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
zend_error(E_WARNING, "%s%s%s(): only one varargs specifier (* or +) is permitted",
class_name,
@@ -823,7 +823,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
default:
if (!quiet) {
- zend_function *active_function = EG(current_execute_data)->call->func;
+ zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
zend_error(E_WARNING, "%s%s%s(): bad type specifier while parsing parameters",
class_name,
@@ -846,7 +846,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
if (num_args < min_num_args || (num_args > max_num_args && max_num_args > 0)) {
if (!quiet) {
- zend_function *active_function = EG(current_execute_data)->call->func;
+ zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : "";
zend_error(E_WARNING, "%s%s%s() expects %s %d parameter%s, %d given",
class_name,
@@ -860,7 +860,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
return FAILURE;
}
- arg_count = EG(current_execute_data)->call->num_args;
+ arg_count = EG(current_execute_data)->num_args;
if (num_args > arg_count) {
zend_error(E_WARNING, "%s(): could not obtain parameters for parsing",
@@ -884,7 +884,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
if (num_varargs > 0) {
*n_varargs = num_varargs;
- *varargs = ZEND_CALL_ARG(EG(current_execute_data)->call, i + 1);
+ *varargs = ZEND_CALL_ARG(EG(current_execute_data), i + 1);
/* adjust how many args we have left and restart loop */
num_args += 1 - num_varargs;
i += num_varargs;
@@ -895,7 +895,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
}
}
- arg = ZEND_CALL_ARG(EG(current_execute_data)->call, i + 1);
+ arg = ZEND_CALL_ARG(EG(current_execute_data), i + 1);
if (zend_parse_arg(i+1, arg, va, &type_spec, quiet TSRMLS_CC) == FAILURE) {
/* clean up varargs array if it was used */
@@ -966,7 +966,7 @@ ZEND_API int zend_parse_method_parameters(int num_args TSRMLS_DC, zval *this_ptr
* Z_OBJ(EG(This)) to NULL when calling an internal function with common.scope == NULL.
* In that case EG(This) would still be the $this from the calling code and we'd take the
* wrong branch here. */
- zend_bool is_method = EG(current_execute_data)->call->func->common.scope != NULL;
+ zend_bool is_method = EG(current_execute_data)->func->common.scope != NULL;
if (!is_method || !this_ptr || Z_TYPE_P(this_ptr) != IS_OBJECT) {
RETURN_IF_ZERO_ARGS(num_args, p, 0);
@@ -1072,7 +1072,7 @@ static int zval_update_class_constant(zval *pp, int is_static, int offset TSRMLS
{
ZVAL_DEREF(pp);
if (Z_CONSTANT_P(pp)) {
- zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry);
+ zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry);
if ((*scope)->parent) {
zend_class_entry *ce = *scope;
@@ -1136,7 +1136,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC
}
if ((class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) == 0) {
- zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry);
+ zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry);
zend_class_entry *old_scope = *scope;
zval *val;
@@ -2494,7 +2494,7 @@ static int module_registry_cleanup(zval *zv TSRMLS_DC) /* {{{ */
ZEND_API void zend_deactivate_modules(TSRMLS_D) /* {{{ */
{
- EG(opline_ptr) = NULL; /* we're no longer executing anything */
+ EG(current_execute_data) = NULL; /* we're no longer executing anything */
zend_try {
if (EG(full_tables_cleanup)) {
@@ -2770,7 +2770,7 @@ static int zend_is_callable_check_class(zend_string *name, zend_fcall_info_cache
if (!EG(scope)) {
if (error) *error = estrdup("cannot access self:: when no class scope is active");
} else {
- fcc->called_scope = EG(called_scope);
+ fcc->called_scope = EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL;
fcc->calling_scope = EG(scope);
if (!fcc->object && Z_OBJ(EG(This))) {
fcc->object = Z_OBJ(EG(This));
@@ -2784,7 +2784,7 @@ static int zend_is_callable_check_class(zend_string *name, zend_fcall_info_cache
} else if (!EG(scope)->parent) {
if (error) *error = estrdup("cannot access parent:: when current class scope has no parent");
} else {
- fcc->called_scope = EG(called_scope);
+ fcc->called_scope = EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL;
fcc->calling_scope = EG(scope)->parent;
if (!fcc->object && Z_OBJ(EG(This))) {
fcc->object = Z_OBJ(EG(This));
@@ -2794,11 +2794,11 @@ static int zend_is_callable_check_class(zend_string *name, zend_fcall_info_cache
}
} else if (name_len == sizeof("static") - 1 &&
!memcmp(lcname->val, "static", sizeof("static") - 1)) {
- if (!EG(called_scope)) {
+ if (!EG(current_execute_data) || !EG(current_execute_data)->called_scope) {
if (error) *error = estrdup("cannot access static:: when no class scope is active");
} else {
- fcc->called_scope = EG(called_scope);
- fcc->calling_scope = EG(called_scope);
+ fcc->called_scope = EG(current_execute_data)->called_scope;
+ fcc->calling_scope = EG(current_execute_data)->called_scope;
if (!fcc->object && Z_OBJ(EG(This))) {
fcc->object = Z_OBJ(EG(This));
}
@@ -2806,8 +2806,13 @@ static int zend_is_callable_check_class(zend_string *name, zend_fcall_info_cache
ret = 1;
}
} else if ((ce = zend_lookup_class_ex(name, NULL, 1 TSRMLS_CC)) != NULL) {
- zend_class_entry *scope = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
+ zend_class_entry *scope;
+ zend_execute_data *ex = EG(current_execute_data);
+ while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
+ ex = ex->prev_execute_data;
+ }
+ scope = ex ? ex->func->common.scope : NULL;
fcc->calling_scope = ce;
if (scope && !fcc->object && Z_OBJ(EG(This)) &&
instanceof_function(Z_OBJCE(EG(This)), scope TSRMLS_CC) &&
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index eafdf64b4b..b702bd4138 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -521,7 +521,7 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_lengt
ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC);
-ZEND_API void zend_rebuild_symbol_table(TSRMLS_D);
+ZEND_API zend_array *zend_rebuild_symbol_table(TSRMLS_D);
ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data);
ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data);
ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS_DC);
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index 3e94ae0bd6..bb3e66c989 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -1761,9 +1761,19 @@ static void zend_mm_safe_error(zend_mm_heap *heap,
zend_string *str = zend_get_compiled_filename(TSRMLS_C);
error_filename = str ? str->val : NULL;
error_lineno = zend_get_compiled_lineno(TSRMLS_C);
- } else if (EG(in_execution)) {
- error_filename = EG(active_op_array)?EG(active_op_array)->filename->val:NULL;
- error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
+ } else if (EG(current_execute_data)) {
+ zend_execute_data *ex = EG(current_execute_data);
+
+ while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
+ ex = ex->prev_execute_data;
+ }
+ if (ex) {
+ error_filename = ex->func->op_array.filename->val;
+ error_lineno = ex->opline->lineno;
+ } else {
+ error_filename = NULL;
+ error_lineno = 0;
+ }
} else {
error_filename = NULL;
error_lineno = 0;
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index df81c5d666..96b339cd67 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -394,7 +394,7 @@ ZEND_FUNCTION(gc_disable)
Get the number of arguments that were passed to the function */
ZEND_FUNCTION(func_num_args)
{
- zend_execute_data *ex = EG(current_execute_data);
+ zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
if (ex->frame_kind == VM_FRAME_NESTED_FUNCTION || ex->frame_kind == VM_FRAME_TOP_FUNCTION) {
RETURN_LONG(ex->num_args);
@@ -423,7 +423,7 @@ ZEND_FUNCTION(func_get_arg)
RETURN_FALSE;
}
- ex = EG(current_execute_data);
+ ex = EG(current_execute_data)->prev_execute_data;
if (ex->frame_kind != VM_FRAME_NESTED_FUNCTION && ex->frame_kind != VM_FRAME_TOP_FUNCTION) {
zend_error(E_WARNING, "func_get_arg(): Called from the global scope - no function context");
RETURN_FALSE;
@@ -456,7 +456,7 @@ ZEND_FUNCTION(func_get_args)
zval *p;
int arg_count, first_extra_arg;
int i;
- zend_execute_data *ex = EG(current_execute_data);
+ zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
if (ex->frame_kind != VM_FRAME_NESTED_FUNCTION && ex->frame_kind != VM_FRAME_TOP_FUNCTION) {
zend_error(E_WARNING, "func_get_args(): Called from the global scope - no function context");
@@ -809,8 +809,8 @@ ZEND_FUNCTION(get_called_class)
return;
}
- if (EG(called_scope)) {
- RETURN_STR(STR_COPY(EG(called_scope)->name));
+ if (EG(current_execute_data)->called_scope) {
+ RETURN_STR(STR_COPY(EG(current_execute_data)->called_scope->name));
} else if (!EG(scope)) {
zend_error(E_WARNING, "get_called_class() called from outside a class");
}
@@ -1749,12 +1749,10 @@ ZEND_FUNCTION(get_defined_functions)
Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
ZEND_FUNCTION(get_defined_vars)
{
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
+ zend_array *symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
ZVAL_NEW_ARR(return_value);
- zend_array_dup(Z_ARRVAL_P(return_value), &EG(active_symbol_table)->ht);
+ zend_array_dup(Z_ARRVAL_P(return_value), &symbol_table->ht);
}
/* }}} */
@@ -2035,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;
@@ -2054,10 +2052,10 @@ ZEND_FUNCTION(debug_print_backtrace)
}
ZVAL_UNDEF(&arg_array);
- ptr = EG(current_execute_data);
+ 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)) {
@@ -2070,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;
@@ -2078,22 +2077,31 @@ ZEND_FUNCTION(debug_print_backtrace)
if (skip->func && ZEND_USER_CODE(skip->func->common.type)) {
filename = skip->func->op_array.filename->val;
- lineno = skip->opline->lineno;
+ if (skip->opline->opcode == ZEND_HANDLE_EXCEPTION) {
+ if (EG(opline_before_exception)) {
+ lineno = EG(opline_before_exception)->lineno;
+ } else {
+ lineno = skip->func->op_array.line_end;
+ }
+ } else {
+ lineno = skip->opline->lineno;
+ }
} else {
filename = NULL;
lineno = 0;
}
/* $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(
@@ -2103,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) {
@@ -2126,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;
@@ -2182,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;
}
@@ -2195,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) {
@@ -2202,7 +2211,7 @@ ZEND_FUNCTION(debug_print_backtrace)
}
}
include_filename = filename;
- object = skip->object;
+ call = skip;
ptr = skip->prev_execute_data;
++indent;
}
@@ -2212,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;
@@ -2222,18 +2231,28 @@ 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);
-
- /* skip "new Exception()" */
- if (ptr && (skip_last == 0) && ptr->opline && (ptr->opline->opcode == ZEND_NEW)) {
- object = ptr->object;
+ if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type)) {
+ call = ptr;
ptr = ptr->prev_execute_data;
}
- /* skip debug_backtrace() */
- if (skip_last-- && ptr) {
- object = ptr->object;
- ptr = ptr->prev_execute_data;
+ if (ptr) {
+ if (skip_last) {
+ /* skip debug_backtrace() */
+ call = ptr;
+ ptr = ptr->prev_execute_data;
+ } else {
+ /* skip "new Exception()" */
+ 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);
@@ -2246,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;
@@ -2254,7 +2274,15 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
if (skip->func && ZEND_USER_CODE(skip->func->common.type)) {
filename = skip->func->op_array.filename->val;
- lineno = skip->opline->lineno;
+ if (skip->opline->opcode == ZEND_HANDLE_EXCEPTION) {
+ if (EG(opline_before_exception)) {
+ lineno = EG(opline_before_exception)->lineno;
+ } else {
+ lineno = skip->func->op_array.line_end;
+ }
+ } else {
+ lineno = skip->opline->lineno;
+ }
add_assoc_string_ex(&stack_frame, "file", sizeof("file")-1, (char*)filename);
add_assoc_long_ex(&stack_frame, "line", sizeof("line")-1, lineno);
@@ -2262,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)) {
@@ -2278,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(
@@ -2302,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) {
@@ -2333,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;
@@ -2393,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_closures.c b/Zend/zend_closures.c
index 053a5eb199..29c1328f2c 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -47,7 +47,7 @@ static zend_object_handlers closure_handlers;
ZEND_METHOD(Closure, __invoke) /* {{{ */
{
- zend_function *func = EG(current_execute_data)->call->func;
+ zend_function *func = EG(current_execute_data)->func;
zval *arguments;
arguments = emalloc(sizeof(zval) * ZEND_NUM_ARGS());
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 1c5d5dd4f6..0f077517f5 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_constants.c b/Zend/zend_constants.c
index 4930d1fdd4..650a566159 100644
--- a/Zend/zend_constants.c
+++ b/Zend/zend_constants.c
@@ -231,7 +231,7 @@ static zend_constant *zend_get_special_constant(const char *name, uint name_len
zend_constant *c;
static char haltoff[] = "__COMPILER_HALT_OFFSET__";
- if (!EG(in_execution)) {
+ if (!EG(current_execute_data)) {
return NULL;
} else if (name_len == sizeof("__CLASS__")-1 &&
!memcmp(name, "__CLASS__", sizeof("__CLASS__")-1)) {
@@ -354,7 +354,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
lcname = do_alloca(class_name_len + 1, use_heap);
zend_str_tolower_copy(lcname, name, class_name_len);
if (!scope) {
- if (EG(in_execution)) {
+ if (EG(current_execute_data)) {
scope = EG(scope);
} else {
scope = CG(active_class_entry);
@@ -379,8 +379,8 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
}
} else if (class_name_len == sizeof("static")-1 &&
!memcmp(lcname, "static", sizeof("static")-1)) {
- if (EG(called_scope)) {
- ce = EG(called_scope);
+ if (EG(current_execute_data) && EG(current_execute_data)->called_scope) {
+ ce = EG(current_execute_data)->called_scope;
} else {
zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
}
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 5318bbe2d3..fcc932095d 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -116,7 +116,8 @@ static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *sho
/* End of zend_execute_locks.h */
-#define CV_DEF_OF(i) (EG(active_op_array)->vars[i])
+// TODO: avoid global variable usage ???
+#define CV_DEF_OF(i) (EG(current_execute_data)->func->op_array.vars[i])
#define CTOR_CALL_BIT 0x1
#define CTOR_USED_BIT 0x2
@@ -546,7 +547,7 @@ ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, zen
ZVAL_UNDEF(arg);
}
- if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
+ if (zf->common.type == ZEND_USER_FUNCTION && ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->func->op_array.filename->val, ptr->opline->lineno);
} else {
zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
@@ -982,7 +983,7 @@ static void zend_extension_fcall_end_handler(const zend_extension *extension, ze
}
-static zend_always_inline HashTable *zend_get_target_symbol_table(int fetch_type TSRMLS_DC)
+static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_data *execute_data, int fetch_type TSRMLS_DC)
{
HashTable *ht;
@@ -990,14 +991,14 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(int fetch_type
EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
ht = &EG(symbol_table).ht;
} else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
- ZEND_ASSERT(EG(active_op_array)->static_variables != NULL);
- ht = EG(active_op_array)->static_variables;
+ ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
+ ht = EX(func)->op_array.static_variables;
} else {
ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL);
- if (!EG(active_symbol_table)) {
+ if (!EX(symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
- ht = &EG(active_symbol_table)->ht;
+ ht = &EX(symbol_table)->ht;
}
return ht;
}
@@ -1443,8 +1444,8 @@ static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_of
#define CHECK_SYMBOL_TABLES() \
zend_hash_apply(&EG(symbol_table), zend_check_symbol TSRMLS_CC); \
- if (&EG(symbol_table)!=EG(active_symbol_table)) { \
- zend_hash_apply(EG(active_symbol_table), zend_check_symbol TSRMLS_CC); \
+ if (&EG(symbol_table)!=EX(symbol_table)) { \
+ zend_hash_apply(EX(symbol_table), zend_check_symbol TSRMLS_CC); \
}
static int zend_check_symbol(zval *pz TSRMLS_DC)
@@ -1475,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) /* {{{ */
@@ -1542,11 +1534,97 @@ void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /*
* +----------------------------------------+
*/
+static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
+{
+ zend_uint first_extra_arg;
+ ZEND_ASSERT(EX(func) == (zend_function*)op_array);
+ ZEND_ASSERT(EX(object) == Z_OBJ(EG(This)));
+
+ EX(return_value) = return_value;
+ EX(frame_kind) = frame_kind;
+ ZVAL_UNDEF(&EX(old_error_reporting));
+ EX(delayed_exception) = NULL;
+ EX(call) = NULL;
+
+ EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
+ EX(scope) = EG(scope);
+
+ first_extra_arg = op_array->num_args;
+
+ if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_VARIADIC) != 0)) {
+ first_extra_arg--;
+ }
+ if (UNEXPECTED(EX(num_args) > first_extra_arg)) {
+ /* move extra args into separate array after all CV and TMP vars */
+ zval *extra_args = EX_VAR_NUM(op_array->last_var + op_array->T);
+
+ memmove(extra_args, EX_VAR_NUM(first_extra_arg), sizeof(zval) * (EX(num_args) - first_extra_arg));
+ }
+
+ do {
+ /* Initialize CV variables (skip arguments) */
+ int num_args = MIN(op_array->num_args, EX(num_args));
+
+ if (EXPECTED(num_args < op_array->last_var)) {
+ zval *var = EX_VAR_NUM(num_args);
+ zval *end = EX_VAR_NUM(op_array->last_var);
+
+ do {
+ ZVAL_UNDEF(var);
+ var++;
+ } while (var != end);
+ }
+ } while (0);
+
+ if (op_array->this_var != -1 && Z_OBJ(EG(This))) {
+ ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EG(This)));
+ Z_ADDREF(EG(This));
+ }
+
+ if (!op_array->run_time_cache && op_array->last_cache_slot) {
+ if (op_array->function_name) {
+ op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
+ } else {
+ op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
+ }
+ }
+ EX(run_time_cache) = op_array->run_time_cache;
+
+ EG(current_execute_data) = execute_data;
+}
+
+static zend_always_inline void i_init_code_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
+{
+ ZEND_ASSERT(EX(func) == (zend_function*)op_array);
+ ZEND_ASSERT(EX(object) == Z_OBJ(EG(This)));
+
+ EX(return_value) = return_value;
+ EX(frame_kind) = frame_kind;
+ ZVAL_UNDEF(&EX(old_error_reporting));
+ EX(delayed_exception) = NULL;
+ EX(call) = NULL;
+
+ EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
+ EX(scope) = EG(scope);
+
+ zend_attach_symbol_table(execute_data);
+
+ if (!op_array->run_time_cache && op_array->last_cache_slot) {
+ if (op_array->function_name) {
+ op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
+ } else {
+ op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
+ }
+ }
+ EX(run_time_cache) = op_array->run_time_cache;
+
+ EG(current_execute_data) = execute_data;
+}
+
static zend_always_inline void i_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
{
ZEND_ASSERT(EX(func) == (zend_function*)op_array);
ZEND_ASSERT(EX(object) == Z_OBJ(EG(This)));
- ZEND_ASSERT(EX(called_scope) == EG(called_scope));
EX(return_value) = return_value;
EX(frame_kind) = frame_kind;
@@ -1554,10 +1632,8 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
EX(delayed_exception) = NULL;
EX(call) = NULL;
- EG(opline_ptr) = &EX(opline);
EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
EX(scope) = EG(scope);
- EX(symbol_table) = EG(active_symbol_table);
if (UNEXPECTED(EX(symbol_table) != NULL)) {
zend_attach_symbol_table(execute_data);
@@ -1608,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
@@ -1620,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,
@@ -1630,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);
- execute_data->num_args = num_args;
+ 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;
@@ -1653,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 40f42ae2dd..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--;
@@ -272,35 +272,6 @@ static zend_always_inline void zend_vm_stack_free_call_frame(zend_execute_data *
}
}
-static zend_always_inline int zend_vm_stack_get_args_count_ex(zend_execute_data *ex)
-{
- return ex->call->num_args;
-}
-
-static zend_always_inline zval* zend_vm_stack_get_arg_ex(zend_execute_data *ex, int requested_arg)
-{
- int arg_count = ex->call->num_args;
-
- if (UNEXPECTED(requested_arg > arg_count)) {
- return NULL;
- }
- return ZEND_CALL_ARG(ex->call, requested_arg);
-}
-
-static zend_always_inline int zend_vm_stack_get_args_count(TSRMLS_D)
-{
- if (EG(current_execute_data)->prev_execute_data) {
- return zend_vm_stack_get_args_count_ex(EG(current_execute_data)->prev_execute_data);
- } else {
- return 0;
- }
-}
-
-static zend_always_inline zval* zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
-{
- return zend_vm_stack_get_arg_ex(EG(current_execute_data)->prev_execute_data, requested_arg);
-}
-
void execute_new_code(TSRMLS_D);
@@ -325,8 +296,6 @@ void zend_shutdown_timeout_thread(void);
#define WM_UNREGISTER_ZEND_TIMEOUT (WM_USER+2)
#endif
-#define active_opline (*EG(opline_ptr))
-
/* The following tries to resolve the classname of a zval of type object.
* Since it is slow it should be only used in error messages.
*/
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 2ba582942a..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 };
@@ -150,7 +150,6 @@ void init_executor(TSRMLS_D) /* {{{ */
EG(function_table) = CG(function_table);
EG(class_table) = CG(class_table);
- EG(in_execution) = 0;
EG(in_autoload) = NULL;
EG(autoload_func) = NULL;
EG(error_handling) = EH_NORMAL;
@@ -160,10 +159,9 @@ void init_executor(TSRMLS_D) /* {{{ */
zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0);
GC_REFCOUNT(&EG(symbol_table)) = 1;
GC_TYPE_INFO(&EG(symbol_table)) = IS_ARRAY;
- EG(active_symbol_table) = &EG(symbol_table);
+ EG(valid_symbol_table) = 1;
zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC);
- EG(opline_ptr) = NULL;
zend_hash_init(&EG(included_files), 8, NULL, NULL, 0);
@@ -188,12 +186,9 @@ void init_executor(TSRMLS_D) /* {{{ */
EG(prev_exception) = NULL;
EG(scope) = NULL;
- EG(called_scope) = NULL;
ZVAL_OBJ(&EG(This), NULL);
- EG(active_op_array) = NULL;
-
EG(active) = 1;
EG(start_op) = NULL;
}
@@ -271,6 +266,7 @@ void shutdown_executor(TSRMLS_D) /* {{{ */
}
zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht);
} zend_end_try();
+ EG(valid_symbol_table) = 0;
zend_try {
zval *zeh;
@@ -401,11 +397,7 @@ ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC) /* {{{
return "";
}
- if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) {
- func = EG(current_execute_data)->call->func;
- } else {
- func = EG(current_execute_data)->func;
- }
+ func = EG(current_execute_data)->func;
switch (func->type) {
case ZEND_USER_FUNCTION:
case ZEND_INTERNAL_FUNCTION:
@@ -433,11 +425,7 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */
if (!zend_is_executing(TSRMLS_C)) {
return NULL;
}
- if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) {
- func = EG(current_execute_data)->call->func;
- } else {
- func = EG(current_execute_data)->func;
- }
+ func = EG(current_execute_data)->func;
switch (func->type) {
case ZEND_USER_FUNCTION: {
zend_string *function_name = func->common.function_name;
@@ -460,8 +448,13 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */
ZEND_API const char *zend_get_executed_filename(TSRMLS_D) /* {{{ */
{
- if (EG(active_op_array)) {
- return EG(active_op_array)->filename->val;
+ zend_execute_data *ex = EG(current_execute_data);
+
+ while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
+ ex = ex->prev_execute_data;
+ }
+ if (ex) {
+ return ex->func->op_array.filename->val;
} else {
return "[no active file]";
}
@@ -470,12 +463,17 @@ ZEND_API const char *zend_get_executed_filename(TSRMLS_D) /* {{{ */
ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */
{
- if(EG(exception) && EG(opline_ptr) && active_opline->opcode == ZEND_HANDLE_EXCEPTION &&
- active_opline->lineno == 0 && EG(opline_before_exception)) {
- return EG(opline_before_exception)->lineno;
+ zend_execute_data *ex = EG(current_execute_data);
+
+ while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
+ ex = ex->prev_execute_data;
}
- if (EG(opline_ptr)) {
- return active_opline->lineno;
+ 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;
+ }
+ return ex->opline->lineno;
} else {
return 0;
}
@@ -484,7 +482,7 @@ ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */
ZEND_API zend_bool zend_is_executing(TSRMLS_D) /* {{{ */
{
- return EG(in_execution);
+ return EG(current_execute_data) != 0;
}
/* }}} */
@@ -662,14 +660,12 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio
int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC) /* {{{ */
{
zend_uint i;
- zend_array *calling_symbol_table;
- zend_op_array *original_op_array;
- zend_op **original_opline_ptr;
zend_class_entry *calling_scope = NULL;
- zend_class_entry *called_scope = NULL;
- zend_execute_data execute_data;
+ zend_execute_data *call, dummy_execute_data;
zend_fcall_info_cache fci_cache_local;
zend_function *func;
+ zend_object *orig_object;
+ zend_class_entry *orig_scope;
zval tmp;
ZVAL_UNDEF(fci->retval);
@@ -690,20 +686,28 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
break;
}
+ orig_object = Z_OBJ(EG(This));
+ orig_scope = EG(scope);
+
/* Initialize execute_data */
- if (EG(current_execute_data)) {
- execute_data = *EG(current_execute_data);
- EX(object) = Z_OBJ(EG(This));
- EX(scope) = EG(scope);
- EX(called_scope) = EG(called_scope);
- EX(func) = NULL;
- EX(opline) = NULL;
- } else {
+ if (!EG(current_execute_data)) {
/* This only happens when we're called outside any execute()'s
* It shouldn't be strictly necessary to NULL execute_data out,
* but it may make bugs easier to spot
*/
- memset(&execute_data, 0, sizeof(zend_execute_data));
+ memset(&dummy_execute_data, 0, sizeof(zend_execute_data));
+ EG(current_execute_data) = &dummy_execute_data;
+ } else if (EG(current_execute_data)->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);
+ dummy_execute_data.prev_execute_data = EG(current_execute_data);
+ dummy_execute_data.call = NULL;
+ dummy_execute_data.prev_nested_call = NULL;
+ dummy_execute_data.opline = NULL;
+ dummy_execute_data.func = NULL;
+ EG(current_execute_data) = &dummy_execute_data;
}
if (!fci_cache || !fci_cache->initialized) {
@@ -722,6 +726,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
if (callable_name) {
STR_RELEASE(callable_name);
}
+ if (EG(current_execute_data) == &dummy_execute_data) {
+ EG(current_execute_data) = dummy_execute_data.prev_execute_data;
+ }
return FAILURE;
} else if (error) {
/* Capitalize the first latter of the error message */
@@ -735,13 +742,15 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
}
func = fci_cache->function_handler;
- EX(call) = zend_vm_stack_push_call_frame(func, fci->param_count, ZEND_CALL_DONE, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC);
+ call = zend_vm_stack_push_call_frame(func, fci->param_count, 0, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC);
calling_scope = fci_cache->calling_scope;
- called_scope = fci_cache->called_scope;
fci->object = fci_cache->object;
if (fci->object &&
(!EG(objects_store).object_buckets ||
!IS_OBJ_VALID(EG(objects_store).object_buckets[fci->object->handle]))) {
+ if (EG(current_execute_data) == &dummy_execute_data) {
+ EG(current_execute_data) = dummy_execute_data.prev_execute_data;
+ }
return FAILURE;
}
@@ -783,16 +792,19 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
if (i) {
/* hack to clean up the stack */
- EX(call)->num_args = i;
- zend_vm_stack_free_args(EX(call) TSRMLS_CC);
+ call->num_args = i;
+ zend_vm_stack_free_args(call TSRMLS_CC);
}
- zend_vm_stack_free_call_frame(EX(call) TSRMLS_CC);
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
i+1,
func->common.scope ? func->common.scope->name->val : "",
func->common.scope ? "::" : "",
func->common.function_name->val);
+ if (EG(current_execute_data) == &dummy_execute_data) {
+ EG(current_execute_data) = dummy_execute_data.prev_execute_data;
+ }
return FAILURE;
}
@@ -808,73 +820,56 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
} else if (Z_REFCOUNTED(fci->params[i])) {
Z_ADDREF(fci->params[i]);
}
- param = ZEND_CALL_ARG(EX(call), i+1);
+ param = ZEND_CALL_ARG(call, i+1);
ZVAL_COPY_VALUE(param, &fci->params[i]);
} else if (Z_ISREF(fci->params[i]) &&
/* don't separate references for __call */
(func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) {
param = &tmp;
- param = ZEND_CALL_ARG(EX(call), i+1);
+ param = ZEND_CALL_ARG(call, i+1);
ZVAL_DUP(param, Z_REFVAL(fci->params[i]));
} else {
- param = ZEND_CALL_ARG(EX(call), i+1);
+ param = ZEND_CALL_ARG(call, i+1);
ZVAL_COPY(param, &fci->params[i]);
}
}
- EX(call)->num_args = fci->param_count;
+ call->num_args = fci->param_count;
EG(scope) = calling_scope;
- EG(called_scope) = called_scope;
if (!fci->object ||
(func->common.fn_flags & ZEND_ACC_STATIC)) {
- Z_OBJ(EG(This)) = EX(call)->object = NULL;
+ Z_OBJ(EG(This)) = call->object = NULL;
} else {
Z_OBJ(EG(This)) = fci->object;
Z_ADDREF(EG(This));
}
- EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = &execute_data;
-
if (func->type == ZEND_USER_FUNCTION) {
- calling_symbol_table = EG(active_symbol_table);
EG(scope) = func->common.scope;
- if (fci->symbol_table) {
- EG(active_symbol_table) = fci->symbol_table;
+ call->symbol_table = fci->symbol_table;
+ if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) {
+ 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 {
- EG(active_symbol_table) = NULL;
- }
-
- original_op_array = EG(active_op_array);
- EG(active_op_array) = (zend_op_array *) func;
- original_opline_ptr = EG(opline_ptr);
-
- if (EXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) == 0)) {
- zend_execute(EG(active_op_array), fci->retval TSRMLS_CC);
- } else {
- zend_generator_create_zval(EG(active_op_array), fci->retval TSRMLS_CC);
- }
-
- EG(active_op_array) = original_op_array;
- EG(opline_ptr) = original_opline_ptr;
- if (!fci->symbol_table && EG(active_symbol_table)) {
- zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
+ zend_generator_create_zval(call, &func->op_array, fci->retval TSRMLS_CC);
}
- EG(active_symbol_table) = calling_symbol_table;
} else if (func->type == ZEND_INTERNAL_FUNCTION) {
int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
ZVAL_NULL(fci->retval);
if (func->common.scope) {
EG(scope) = func->common.scope;
}
+ call->prev_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = call;
if (EXPECTED(zend_execute_internal == NULL)) {
/* saves one function call if zend_execute_internal is not used */
func->internal_function.handler(fci->param_count, fci->retval TSRMLS_CC);
} else {
- zend_execute_internal(&execute_data, fci TSRMLS_CC);
+ zend_execute_internal(call, fci->retval TSRMLS_CC);
}
- zend_vm_stack_free_args(EX(call) TSRMLS_CC);
- zend_vm_stack_free_call_frame(EX(call) TSRMLS_CC);
+ EG(current_execute_data) = call->prev_execute_data;
+ zend_vm_stack_free_args(call TSRMLS_CC);
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
/* We shouldn't fix bad extensions here,
because it can break proper ones (Bug #34045)
@@ -896,11 +891,17 @@ 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->prev_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = call;
fci->object->handlers->call_method(func->common.function_name, fci->object, fci->param_count, fci->retval TSRMLS_CC);
+ EG(current_execute_data) = call->prev_execute_data;
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
+ zend_vm_stack_free_args(call TSRMLS_CC);
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+
if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
STR_RELEASE(func->common.function_name);
}
@@ -916,10 +917,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
zval_ptr_dtor(&EG(This));
}
- Z_OBJ(EG(This)) = EX(object);
- EG(scope) = EX(scope);
- EG(called_scope) = EX(called_scope);
- EG(current_execute_data) = EX(prev_execute_data);
+ Z_OBJ(EG(This)) = orig_object;
+ EG(scope) = orig_scope;
+ if (EG(current_execute_data) == &dummy_execute_data) {
+ EG(current_execute_data) = dummy_execute_data.prev_execute_data;
+ }
if (EG(exception)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
@@ -1060,7 +1062,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s
{
zval pv;
zend_op_array *new_op_array;
- zend_op_array *original_active_op_array = EG(active_op_array);
zend_uint original_compiler_options;
int retval;
@@ -1083,22 +1084,13 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s
if (new_op_array) {
zval local_retval;
- zend_op **original_opline_ptr = EG(opline_ptr);
int orig_interactive = CG(interactive);
- EG(active_op_array) = new_op_array;
- EG(no_extensions)=1;
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
+ EG(no_extensions)=1;
CG(interactive) = 0;
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(called_scope), Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC);
- }
zend_execute(new_op_array, &local_retval TSRMLS_CC);
} zend_catch {
destroy_op_array(new_op_array TSRMLS_CC);
@@ -1120,8 +1112,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s
}
EG(no_extensions)=0;
- EG(opline_ptr) = original_opline_ptr;
- EG(active_op_array) = original_active_op_array;
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
retval = SUCCESS;
@@ -1222,7 +1212,6 @@ void execute_new_code(TSRMLS_D) /* {{{ */
zend_release_labels(1 TSRMLS_CC);
- EG(active_op_array) = CG(active_op_array);
orig_interactive = CG(interactive);
CG(interactive) = 0;
zend_execute(CG(active_op_array), NULL TSRMLS_CC);
@@ -1474,10 +1463,10 @@ check_fetch_type:
}
return EG(scope)->parent;
case ZEND_FETCH_CLASS_STATIC:
- if (!EG(called_scope)) {
+ if (!EG(current_execute_data) || !EG(current_execute_data)->called_scope) {
zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
}
- return EG(called_scope);
+ return EG(current_execute_data)->called_scope;
case ZEND_FETCH_CLASS_AUTO: {
fetch_type = zend_get_class_fetch_type(class_name->val, class_name->len);
if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) {
@@ -1593,45 +1582,42 @@ ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC) /* {{{ */
}
/* }}} */
-ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
+ZEND_API zend_array *zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
{
zend_uint i;
zend_execute_data *ex;
+ zend_array *symbol_table;
- if (!EG(active_symbol_table)) {
-
- /* Search for last called user function */
- ex = EG(current_execute_data);
- while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) {
- ex = ex->prev_execute_data;
- }
- if (!ex) {
- return;
- }
- if (ex->symbol_table) {
- EG(active_symbol_table) = ex->symbol_table;
- return;
- }
+ /* Search for last called user function */
+ ex = EG(current_execute_data);
+ while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) {
+ ex = ex->prev_execute_data;
+ }
+ if (!ex) {
+ return NULL;
+ }
+ if (ex->symbol_table) {
+ return ex->symbol_table;
+ }
- if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
- /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
- EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
- } else {
- EG(active_symbol_table) = emalloc(sizeof(zend_array));
- GC_REFCOUNT(EG(active_symbol_table)) = 0;
- GC_TYPE_INFO(EG(active_symbol_table)) = IS_ARRAY;
- zend_hash_init(&EG(active_symbol_table)->ht, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0);
- /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/
- }
- ex->symbol_table = EG(active_symbol_table);
- for (i = 0; i < ex->func->op_array.last_var; i++) {
- zval zv;
+ if (EG(symtable_cache_ptr) >= EG(symtable_cache)) {
+ /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
+ symbol_table = ex->symbol_table = *(EG(symtable_cache_ptr)--);
+ } else {
+ symbol_table = ex->symbol_table = emalloc(sizeof(zend_array));
+ GC_REFCOUNT(symbol_table) = 0;
+ GC_TYPE_INFO(symbol_table) = IS_ARRAY;
+ zend_hash_init(&symbol_table->ht, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0);
+ /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/
+ }
+ for (i = 0; i < ex->func->op_array.last_var; i++) {
+ zval zv;
- ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i));
- zend_hash_add_new(&EG(active_symbol_table)->ht,
- ex->func->op_array.vars[i], &zv);
- }
+ ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i));
+ zend_hash_add_new(&symbol_table->ht,
+ ex->func->op_array.vars[i], &zv);
}
+ return symbol_table;
}
/* }}} */
@@ -1686,13 +1672,18 @@ ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ *
ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS_DC) /* {{{ */
{
- if (!EG(active_symbol_table)) {
- int i;
- zend_execute_data *execute_data = EG(current_execute_data);
- zend_op_array *op_array = &execute_data->func->op_array;
- zend_ulong h = STR_HASH_VAL(name);
+ zend_execute_data *execute_data = EG(current_execute_data);
+
+ while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
+ execute_data = execute_data->prev_execute_data;
+ }
+
+ if (execute_data) {
+ if (!execute_data->symbol_table) {
+ zend_ulong h = STR_HASH_VAL(name);
+ zend_op_array *op_array = &execute_data->func->op_array;
+ int i;
- if (op_array) {
for (i = 0; i < op_array->last_var; i++) {
if (op_array->vars[i]->h == h &&
op_array->vars[i]->len == name->len &&
@@ -1701,31 +1692,34 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS
return SUCCESS;
}
}
- }
- if (force) {
- zend_rebuild_symbol_table(TSRMLS_C);
- if (EG(active_symbol_table)) {
- zend_hash_update(&EG(active_symbol_table)->ht, name, value);
+ if (force) {
+ zend_array *symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
+ if (symbol_table) {
+ return zend_hash_update(&symbol_table->ht, name, value) ? SUCCESS : FAILURE;;
+ }
}
} else {
- return FAILURE;
+ return (zend_hash_update_ind(&execute_data->symbol_table->ht, name, value) != NULL) ? SUCCESS : FAILURE;
}
- } else {
- return (zend_hash_update_ind(&EG(active_symbol_table)->ht, name, value) != NULL) ? SUCCESS : FAILURE;
}
- return SUCCESS;
+ return FAILURE;
}
/* }}} */
ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int force TSRMLS_DC) /* {{{ */
{
- if (!EG(active_symbol_table)) {
- int i;
- zend_execute_data *execute_data = EG(current_execute_data);
- zend_op_array *op_array = &execute_data->func->op_array;
- zend_ulong h = zend_hash_func(name, len);
+ zend_execute_data *execute_data = EG(current_execute_data);
+
+ while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
+ execute_data = execute_data->prev_execute_data;
+ }
+
+ if (execute_data) {
+ if (!execute_data->symbol_table) {
+ zend_ulong h = zend_hash_func(name, len);
+ zend_op_array *op_array = &execute_data->func->op_array;
+ int i;
- if (op_array) {
for (i = 0; i < op_array->last_var; i++) {
if (op_array->vars[i]->h == h &&
op_array->vars[i]->len == len &&
@@ -1734,19 +1728,18 @@ ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int
return SUCCESS;
}
}
- }
- if (force) {
- zend_rebuild_symbol_table(TSRMLS_C);
- if (EG(active_symbol_table)) {
- zend_hash_str_update(&EG(active_symbol_table)->ht, name, len, value);
+
+ if (force) {
+ zend_array *symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
+ if (symbol_table) {
+ return zend_hash_str_update(&symbol_table->ht, name, len, value) ? SUCCESS : FAILURE;;
+ }
}
} else {
- return FAILURE;
+ return (zend_hash_str_update_ind(&execute_data->symbol_table->ht, name, len, value) != NULL) ? SUCCESS : FAILURE;
}
- } else {
- return (zend_hash_str_update_ind(&EG(active_symbol_table)->ht, name, len, value) != NULL) ? SUCCESS : FAILURE;
}
- return SUCCESS;
+ return FAILURE;
}
/* }}} */
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index f4847b0839..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;
}
@@ -224,14 +220,11 @@ static int copy_closure_static_var(zval *var TSRMLS_DC, int num_args, va_list ar
}
/* }}} */
-/* Requires globals EG(scope), EG(current_scope), EG(This),
- * EG(active_symbol_table) and EG(current_execute_data). */
-ZEND_API void zend_generator_create_zval(zend_op_array *op_array, zval *return_value TSRMLS_DC) /* {{{ */
+/* Requires globals EG(scope), EG(This) and EG(current_execute_data). */
+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;
- zend_op **opline_ptr;
- zend_array *current_symbol_table;
zend_execute_data *execute_data;
zend_vm_stack current_stack = EG(argument_stack);
@@ -260,16 +253,10 @@ 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), EG(opline_ptr) and EG(active_symbol_table)
- * here because the function modifies or uses them */
+ * EG(current_execute_data) here. */
current_execute_data = EG(current_execute_data);
- opline_ptr = EG(opline_ptr);
- current_symbol_table = EG(active_symbol_table);
- EG(active_symbol_table) = NULL;
- execute_data = zend_create_generator_execute_data(op_array, return_value TSRMLS_CC);
- EG(active_symbol_table) = current_symbol_table;
+ execute_data = zend_create_generator_execute_data(call, op_array, return_value TSRMLS_CC);
EG(current_execute_data) = current_execute_data;
- EG(opline_ptr) = opline_ptr;
object_init_ex(return_value, zend_ce_generator);
@@ -314,43 +301,23 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
{
/* Backup executor globals */
zend_execute_data *original_execute_data = EG(current_execute_data);
- zend_op **original_opline_ptr = EG(opline_ptr);
- zend_op_array *original_active_op_array = EG(active_op_array);
- zend_array *original_active_symbol_table = EG(active_symbol_table);
zend_object *original_This;
zend_class_entry *original_scope = EG(scope);
- zend_class_entry *original_called_scope = EG(called_scope);
zend_vm_stack original_stack = EG(argument_stack);
- zend_execute_data *prev_execute_data;
original_This = Z_OBJ(EG(This));
/* Set executor globals */
EG(current_execute_data) = generator->execute_data;
- EG(opline_ptr) = &generator->execute_data->opline;
- EG(active_op_array) = &generator->execute_data->func->op_array;
- EG(active_symbol_table) = generator->execute_data->symbol_table;
Z_OBJ(EG(This)) = generator->execute_data->object;
EG(scope) = generator->execute_data->scope;
- EG(called_scope) = generator->execute_data->called_scope;
EG(argument_stack) = generator->stack;
/* We want the backtrace to look as if the generator function was
* called from whatever method we are current running (e.g. next()).
* So we have to link generator call frame with caller call frames */
- prev_execute_data = original_execute_data;
- if (prev_execute_data &&
- prev_execute_data->call &&
- (prev_execute_data->call->flags & ZEND_CALL_DONE)) {
- prev_execute_data->call->prev_execute_data = prev_execute_data;
- prev_execute_data = prev_execute_data->call;
- }
- generator->execute_data->prev_execute_data = prev_execute_data;
- if (prev_execute_data) {
- generator->execute_data->prev_nested_call = prev_execute_data->call;
- prev_execute_data->call = generator->execute_data;
- }
+ generator->execute_data->prev_execute_data = original_execute_data;
/* Resume execution */
generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;
@@ -358,19 +325,14 @@ 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;
}
/* Restore executor globals */
EG(current_execute_data) = original_execute_data;
- EG(opline_ptr) = original_opline_ptr;
- EG(active_op_array) = original_active_op_array;
- EG(active_symbol_table) = original_active_symbol_table;
Z_OBJ(EG(This)) = original_This;
EG(scope) = original_scope;
- EG(called_scope) = original_called_scope;
EG(argument_stack) = original_stack;
/* If an exception was thrown in the generator we have to internally
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_globals.h b/Zend/zend_globals.h
index 7a43e6e02f..082e733844 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -170,9 +170,6 @@ struct _zend_executor_globals {
zend_array **symtable_cache_limit;
zend_array **symtable_cache_ptr;
- zend_op **opline_ptr;
-
- zend_array *active_symbol_table;
zend_array symbol_table; /* main symbol table */
HashTable included_files; /* files already included */
@@ -183,14 +180,11 @@ struct _zend_executor_globals {
int orig_error_reporting;
int exit_status;
- zend_op_array *active_op_array;
-
HashTable *function_table; /* function symbol table */
HashTable *class_table; /* class table */
HashTable *zend_constants; /* constants table */
zend_class_entry *scope;
- zend_class_entry *called_scope; /* Scope of the calling class */
zval This;
@@ -198,7 +192,6 @@ struct _zend_executor_globals {
int ticks_count;
- zend_bool in_execution;
HashTable *in_autoload;
zend_function *autoload_func;
zend_bool full_tables_cleanup;
@@ -246,7 +239,8 @@ struct _zend_executor_globals {
zend_property_info std_property_info;
- zend_bool active;
+ zend_bool active;
+ zend_bool valid_symbol_table;
zend_op *start_op;
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c
index ded81e2918..d5420dae76 100644
--- a/Zend/zend_interfaces.c
+++ b/Zend/zend_interfaces.c
@@ -90,11 +90,12 @@ ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_fun
if (object) {
fcic.called_scope = Z_OBJCE_P(object);
} else if (obj_ce &&
- !(EG(called_scope) &&
- instanceof_function(EG(called_scope), obj_ce TSRMLS_CC))) {
+ !(EG(current_execute_data) &&
+ EG(current_execute_data)->called_scope &&
+ instanceof_function(EG(current_execute_data)->called_scope, obj_ce TSRMLS_CC))) {
fcic.called_scope = obj_ce;
} else {
- fcic.called_scope = EG(called_scope);
+ fcic.called_scope = EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL;
}
fcic.object = object ? Z_OBJ_P(object) : NULL;
result = zend_call_function(&fci, &fcic TSRMLS_CC);
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index e38fbfc640..cd6b0b4ad0 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -299,8 +299,8 @@ static zend_always_inline struct _zend_property_info *zend_get_property_info_qui
zend_property_info *scope_property_info;
zend_bool denied_access = 0;
- if (cache_slot != -1 && EXPECTED(ce == CACHED_PTR_EX(EG(active_op_array), cache_slot))) {
- property_info = CACHED_PTR_EX(EG(active_op_array), cache_slot + 1);
+ if (cache_slot != -1 && EXPECTED(ce == CACHED_PTR_EX(&EG(current_execute_data)->func->op_array, cache_slot))) {
+ property_info = CACHED_PTR_EX(&EG(current_execute_data)->func->op_array, cache_slot + 1);
if (UNEXPECTED(!property_info)) {
EG(std_property_info).flags = ZEND_ACC_PUBLIC;
EG(std_property_info).name = member;
@@ -339,7 +339,7 @@ static zend_always_inline struct _zend_property_info *zend_get_property_info_qui
zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name->val, member->val);
}
if (cache_slot != -1) {
- CACHE_POLYMORPHIC_PTR_EX(EG(active_op_array), cache_slot, ce, property_info);
+ CACHE_POLYMORPHIC_PTR_EX(&EG(current_execute_data)->func->op_array, cache_slot, ce, property_info);
}
return property_info;
}
@@ -355,7 +355,7 @@ static zend_always_inline struct _zend_property_info *zend_get_property_info_qui
&& (scope_property_info = zend_hash_find_ptr(&EG(scope)->properties_info, member)) != NULL
&& scope_property_info->flags & ZEND_ACC_PRIVATE) {
if (cache_slot != -1) {
- CACHE_POLYMORPHIC_PTR_EX(EG(active_op_array), cache_slot, ce, scope_property_info);
+ CACHE_POLYMORPHIC_PTR_EX(&EG(current_execute_data)->func->op_array, cache_slot, ce, scope_property_info);
}
return scope_property_info;
} else if (property_info) {
@@ -368,12 +368,12 @@ static zend_always_inline struct _zend_property_info *zend_get_property_info_qui
} else {
/* fall through, return property_info... */
if (cache_slot != -1) {
- CACHE_POLYMORPHIC_PTR_EX(EG(active_op_array), cache_slot, ce, property_info);
+ CACHE_POLYMORPHIC_PTR_EX(&EG(current_execute_data)->func->op_array, cache_slot, ce, property_info);
}
}
} else {
if (cache_slot != -1) {
- CACHE_POLYMORPHIC_PTR_EX(EG(active_op_array), cache_slot, ce, NULL);
+ CACHE_POLYMORPHIC_PTR_EX(&EG(current_execute_data)->func->op_array, cache_slot, ce, NULL);
}
EG(std_property_info).flags = ZEND_ACC_PUBLIC;
EG(std_property_info).name = member;
@@ -905,7 +905,7 @@ static void zend_std_unset_dimension(zval *object, zval *offset TSRMLS_DC) /* {{
ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
{
- zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->call->func;
+ zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->func;
zval method_name, method_args;
zval method_result;
zend_class_entry *ce = Z_OBJCE_P(getThis());
@@ -1123,7 +1123,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
{
- zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->call->func;
+ zend_internal_function *func = (zend_internal_function *)EG(current_execute_data)->func;
zval method_name, method_args;
zval method_result;
zend_class_entry *ce = EG(scope);
@@ -1276,7 +1276,7 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p
zend_property_info *property_info;
if (UNEXPECTED(cache_slot == -1) ||
- (property_info = CACHED_POLYMORPHIC_PTR_EX(EG(active_op_array), cache_slot, ce)) == NULL) {
+ (property_info = CACHED_POLYMORPHIC_PTR_EX(&EG(current_execute_data)->func->op_array, cache_slot, ce)) == NULL) {
if (UNEXPECTED((property_info = zend_hash_find_ptr(&ce->properties_info, property_name)) == NULL)) {
if (!silent) {
@@ -1302,7 +1302,7 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p
zend_update_class_constants(ce TSRMLS_CC);
if (EXPECTED(cache_slot != -1)) {
- CACHE_POLYMORPHIC_PTR_EX(EG(active_op_array), cache_slot, ce, property_info);
+ CACHE_POLYMORPHIC_PTR_EX(&EG(current_execute_data)->func->op_array, cache_slot, ce, property_info);
}
}
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index 1ef0e1d7e7..af0070c5fb 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -77,11 +77,11 @@ ZEND_API void zend_objects_destroy_object(zend_object *object TSRMLS_DC)
if (object->ce != EG(scope)) {
zend_class_entry *ce = object->ce;
- zend_error(EG(in_execution) ? E_ERROR : E_WARNING,
+ zend_error(EG(current_execute_data) ? E_ERROR : E_WARNING,
"Call to private %s::__destruct() from context '%s'%s",
ce->name->val,
EG(scope) ? EG(scope)->name->val : "",
- EG(in_execution) ? "" : " during shutdown ignored");
+ EG(current_execute_data) ? "" : " during shutdown ignored");
return;
}
} else {
@@ -90,11 +90,11 @@ ZEND_API void zend_objects_destroy_object(zend_object *object TSRMLS_DC)
if (!zend_check_protected(zend_get_function_root_class(destructor), EG(scope))) {
zend_class_entry *ce = object->ce;
- zend_error(EG(in_execution) ? E_ERROR : E_WARNING,
+ zend_error(EG(current_execute_data) ? E_ERROR : E_WARNING,
"Call to protected %s::__destruct() from context '%s'%s",
ce->name->val,
EG(scope) ? EG(scope)->name->val : "",
- EG(in_execution) ? "" : " during shutdown ignored");
+ EG(current_execute_data) ? "" : " during shutdown ignored");
return;
}
}
diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c
index 2031b017eb..b512c45672 100644
--- a/Zend/zend_variables.c
+++ b/Zend/zend_variables.c
@@ -305,6 +305,7 @@ ZEND_API void _zval_internal_ptr_dtor_wrapper(zval *zval_ptr)
ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
{
+ zend_array *symbol_table;
HashTable *target = va_arg(args, HashTable*);
zend_bool is_ref;
zval tmp;
@@ -312,16 +313,14 @@ ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args,
if (Z_CONST_FLAGS_P(p) & (IS_LEXICAL_VAR|IS_LEXICAL_REF)) {
is_ref = Z_CONST_FLAGS_P(p) & IS_LEXICAL_REF;
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
- p = zend_hash_find(&EG(active_symbol_table)->ht, key->key);
+ symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
+ p = zend_hash_find(&symbol_table->ht, key->key);
if (!p) {
p = &tmp;
ZVAL_NULL(&tmp);
if (is_ref) {
ZVAL_NEW_REF(&tmp, &tmp);
- zend_hash_add_new(&EG(active_symbol_table)->ht, key->key, &tmp);
+ zend_hash_add_new(&symbol_table->ht, key->key, &tmp);
Z_ADDREF_P(p);
} else {
zend_error(E_NOTICE,"Undefined variable: %s", key->key->val);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 50f0e53e14..89668bd3b5 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1145,7 +1145,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
retval = zend_std_get_static_property(ce, name, 0, ((OP1_TYPE == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
FREE_OP1();
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -1772,9 +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;
-
- EG(current_execute_data) = EX(prev_execute_data);
if (frame_kind == VM_FRAME_NESTED_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
@@ -1784,15 +1781,11 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
- prev_nested_call = EX(prev_nested_call);
+ EG(current_execute_data) = EX(prev_execute_data);
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;
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
- EG(active_symbol_table) = EX(symbol_table);
if (Z_OBJ(EG(This))) {
if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
@@ -1811,7 +1804,6 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
}
Z_OBJ(EG(This)) = EX(object);
EG(scope) = EX(scope);
- EG(called_scope) = EX(called_scope);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_op *opline = EX(opline);
@@ -1829,14 +1821,11 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
zend_detach_symbol_table(execute_data);
destroy_op_array(&EX(func)->op_array TSRMLS_CC);
efree(EX(func));
- prev_nested_call = EX(prev_nested_call);
+ EG(current_execute_data) = EX(prev_execute_data);
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);
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION_LEAVE();
@@ -1848,6 +1837,9 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
} else {
if (frame_kind == VM_FRAME_TOP_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
+ if (UNEXPECTED(EX(symbol_table) != NULL)) {
+ zend_clean_and_cache_symbol_table(EX(symbol_table) TSRMLS_CC);
+ }
zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
} else /* if (frame_kind == VM_FRAME_TOP_CODE) */ {
zend_array *symbol_table = EX(symbol_table);
@@ -1868,13 +1860,9 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
if ((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) && EX(func)->op_array.prototype) {
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
- prev_nested_call = EX(prev_nested_call);
+ EG(current_execute_data) = EX(prev_execute_data);
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
- if (EG(current_execute_data)) {
- EG(current_execute_data)->call = prev_nested_call;
- }
- EG(opline_ptr) = NULL;
ZEND_VM_RETURN();
}
}
@@ -2369,7 +2357,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
if (OP1_TYPE != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -2576,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);
@@ -2624,9 +2612,13 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
#else
EG(scope) = fbc->common.scope;
#endif
- EG(called_scope) = call->called_scope;
+ } else {
+ call->called_scope = EX(called_scope);
}
+ call->prev_execute_data = execute_data;
+ EG(current_execute_data) = call;
+
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_uint i;
zval *p = ZEND_CALL_ARG(call, 1);
@@ -2636,6 +2628,9 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
+ EG(current_execute_data) = call->prev_execute_data;
+ zend_vm_stack_free_args(call TSRMLS_CC);
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
}
@@ -2655,12 +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)) {
@@ -2677,9 +2670,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
Z_OBJ(EG(This)) = call->object;
EG(scope) = fbc->common.scope;
- EG(called_scope) = call->called_scope;
- EG(active_symbol_table) = NULL;
- EG(active_op_array) = &fbc->op_array;
+ call->symbol_table = NULL;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
@@ -2689,16 +2680,15 @@ 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);
} else {
zend_vm_stack_free_args(call TSRMLS_CC);
}
- EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
- call->prev_execute_data = EG(current_execute_data);
- i_init_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
+ call->prev_execute_data = execute_data;
+ i_init_func_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
@@ -2706,31 +2696,25 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
execute_ex(call TSRMLS_CC);
}
}
-
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
- if (UNEXPECTED(EG(active_symbol_table) != NULL)) {
- zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
- }
- EG(active_symbol_table) = EX(symbol_table);
} else { /* ZEND_OVERLOADED_FUNCTION */
Z_OBJ(EG(This)) = call->object;
//??? EG(scope) = NULL;
EG(scope) = fbc->common.scope;
- EG(called_scope) = call->called_scope;
ZVAL_NULL(EX_VAR(opline->result.var));
/* Not sure what should be done here if it's a static method */
if (EXPECTED(call->object != 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);
+ EG(current_execute_data) = call->prev_execute_data;
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
zend_vm_stack_free_args(call TSRMLS_CC);
- EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
@@ -2765,7 +2749,6 @@ ZEND_VM_C_LABEL(fcall_end_change_scope):
}
Z_OBJ(EG(This)) = EX(object);
EG(scope) = EX(scope);
- EG(called_scope) = EX(called_scope);
ZEND_VM_C_LABEL(fcall_end):
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -3538,14 +3521,14 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
- if (UNEXPECTED(ce != EG(scope))) {
- zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(ce != EX(scope))) {
+ zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
- zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EX(scope)))) {
+ zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
}
}
@@ -3976,29 +3959,29 @@ 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;
- EG(active_op_array) = new_op_array;
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, EG(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 (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ call->symbol_table = EX(symbol_table);
+ } else {
+ call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
- EX(call)->prev_execute_data = EG(current_execute_data);
- i_init_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);
}
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -4070,7 +4053,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((OP1_TYPE == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -4588,7 +4571,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -4829,7 +4812,7 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY)
{
SAVE_OPLINE();
- zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name->val, EX(func)->op_array.function_name->val);
+ zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(scope)->name->val, EX(func)->op_array.function_name->val);
ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
@@ -5343,11 +5326,11 @@ 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), EG(called_scope), NULL TSRMLS_CC);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(called_scope), NULL TSRMLS_CC);
} else {
- zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EG(scope), Z_OBJ(EG(This)) ? &EG(This) : NULL TSRMLS_CC);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(scope), Z_OBJ(EG(This)) ? &EG(This) : NULL TSRMLS_CC);
}
CHECK_EXCEPTION();
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 31f1b9d4ae..dcaa1657c6 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -337,13 +337,9 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o
ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC)
{
DCL_OPLINE
- zend_bool original_in_execution;
- original_in_execution = EG(in_execution);
- EG(in_execution) = 1;
-
LOAD_REGS();
LOAD_OPLINE();
@@ -358,7 +354,6 @@ ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC)
if ((ret = OPLINE->handler(execute_data TSRMLS_CC)) > 0) {
switch (ret) {
case 1:
- EG(in_execution) = original_in_execution;
return;
case 2:
case 3:
@@ -381,23 +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(called_scope), 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, EG(active_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;
-
- EG(current_execute_data) = EX(prev_execute_data);
if (frame_kind == VM_FRAME_NESTED_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
@@ -407,15 +400,11 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
- prev_nested_call = EX(prev_nested_call);
+ EG(current_execute_data) = EX(prev_execute_data);
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;
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
- EG(active_symbol_table) = EX(symbol_table);
if (Z_OBJ(EG(This))) {
if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
@@ -434,7 +423,6 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
}
Z_OBJ(EG(This)) = EX(object);
EG(scope) = EX(scope);
- EG(called_scope) = EX(called_scope);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_op *opline = EX(opline);
@@ -452,14 +440,11 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
zend_detach_symbol_table(execute_data);
destroy_op_array(&EX(func)->op_array TSRMLS_CC);
efree(EX(func));
- prev_nested_call = EX(prev_nested_call);
+ EG(current_execute_data) = EX(prev_execute_data);
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);
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION_LEAVE();
@@ -471,6 +456,9 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
} else {
if (frame_kind == VM_FRAME_TOP_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
+ if (UNEXPECTED(EX(symbol_table) != NULL)) {
+ zend_clean_and_cache_symbol_table(EX(symbol_table) TSRMLS_CC);
+ }
zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
} else /* if (frame_kind == VM_FRAME_TOP_CODE) */ {
zend_array *symbol_table = EX(symbol_table);
@@ -491,13 +479,9 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
if ((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) && EX(func)->op_array.prototype) {
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
- prev_nested_call = EX(prev_nested_call);
+ EG(current_execute_data) = EX(prev_execute_data);
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
- if (EG(current_execute_data)) {
- EG(current_execute_data)->call = prev_nested_call;
- }
- EG(opline_ptr) = NULL;
ZEND_VM_RETURN();
}
}
@@ -528,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);
@@ -576,9 +560,13 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
#else
EG(scope) = fbc->common.scope;
#endif
- EG(called_scope) = call->called_scope;
+ } else {
+ call->called_scope = EX(called_scope);
}
+ call->prev_execute_data = execute_data;
+ EG(current_execute_data) = call;
+
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_uint i;
zval *p = ZEND_CALL_ARG(call, 1);
@@ -588,6 +576,9 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
+ EG(current_execute_data) = call->prev_execute_data;
+ zend_vm_stack_free_args(call TSRMLS_CC);
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
}
@@ -607,12 +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)) {
@@ -629,9 +618,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
Z_OBJ(EG(This)) = call->object;
EG(scope) = fbc->common.scope;
- EG(called_scope) = call->called_scope;
- EG(active_symbol_table) = NULL;
- EG(active_op_array) = &fbc->op_array;
+ call->symbol_table = NULL;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
@@ -641,16 +628,15 @@ 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);
} else {
zend_vm_stack_free_args(call TSRMLS_CC);
}
- EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
- call->prev_execute_data = EG(current_execute_data);
- i_init_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
+ call->prev_execute_data = execute_data;
+ i_init_func_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
@@ -658,31 +644,25 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
execute_ex(call TSRMLS_CC);
}
}
-
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
- if (UNEXPECTED(EG(active_symbol_table) != NULL)) {
- zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
- }
- EG(active_symbol_table) = EX(symbol_table);
} else { /* ZEND_OVERLOADED_FUNCTION */
Z_OBJ(EG(This)) = call->object;
//??? EG(scope) = NULL;
EG(scope) = fbc->common.scope;
- EG(called_scope) = call->called_scope;
ZVAL_NULL(EX_VAR(opline->result.var));
/* Not sure what should be done here if it's a static method */
if (EXPECTED(call->object != 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);
+ EG(current_execute_data) = call->prev_execute_data;
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
zend_vm_stack_free_args(call TSRMLS_CC);
- EX(call) = call->prev_nested_call;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
@@ -717,7 +697,6 @@ fcall_end_change_scope:
}
Z_OBJ(EG(This)) = EX(object);
EG(scope) = EX(scope);
- EG(called_scope) = EX(called_scope);
fcall_end:
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -1058,7 +1037,7 @@ static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
static int ZEND_FASTCALL ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
SAVE_OPLINE();
- zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name->val, EX(func)->op_array.function_name->val);
+ zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(scope)->name->val, EX(func)->op_array.function_name->val);
ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
@@ -2698,14 +2677,14 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
- if (UNEXPECTED(ce != EG(scope))) {
- zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(ce != EX(scope))) {
+ zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
- zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EX(scope)))) {
+ zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
}
}
@@ -2916,29 +2895,29 @@ 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;
- EG(active_op_array) = new_op_array;
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, EG(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 (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ call->symbol_table = EX(symbol_table);
+ } else {
+ call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
- EX(call)->prev_execute_data = EG(current_execute_data);
- i_init_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);
}
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -3563,7 +3542,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type
retval = zend_std_get_static_property(ce, name, 0, ((IS_CONST == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -3808,7 +3787,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
if (IS_CONST != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -4110,7 +4089,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CONST == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -4173,7 +4152,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -4774,7 +4753,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
if (IS_CONST != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -5385,7 +5364,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type,
retval = zend_std_get_static_property(ce, name, 0, ((IS_CONST == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -5608,7 +5587,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
if (IS_CONST != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -5812,7 +5791,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CONST == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -5875,7 +5854,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -6095,7 +6074,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ
retval = zend_std_get_static_property(ce, name, 0, ((IS_CONST == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -6301,7 +6280,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
if (IS_CONST != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -6489,7 +6468,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CONST == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -6552,7 +6531,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -6596,11 +6575,11 @@ 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), EG(called_scope), NULL TSRMLS_CC);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(called_scope), NULL TSRMLS_CC);
} else {
- zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EG(scope), Z_OBJ(EG(This)) ? &EG(This) : NULL TSRMLS_CC);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(scope), Z_OBJ(EG(This)) ? &EG(This) : NULL TSRMLS_CC);
}
CHECK_EXCEPTION();
@@ -7130,7 +7109,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
if (IS_CONST != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -7891,14 +7870,14 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
- if (UNEXPECTED(ce != EG(scope))) {
- zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(ce != EX(scope))) {
+ zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
- zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EX(scope)))) {
+ zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
}
}
@@ -8110,29 +8089,29 @@ 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;
- EG(active_op_array) = new_op_array;
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, EG(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 (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ call->symbol_table = EX(symbol_table);
+ } else {
+ call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
- EX(call)->prev_execute_data = EG(current_execute_data);
- i_init_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);
}
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -8806,7 +8785,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
retval = zend_std_get_static_property(ce, name, 0, ((IS_TMP_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
zval_dtor(free_op1.var);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -9250,7 +9229,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_TMP_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -9313,7 +9292,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -10495,7 +10474,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
retval = zend_std_get_static_property(ce, name, 0, ((IS_TMP_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
zval_dtor(free_op1.var);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -10925,7 +10904,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_TMP_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -10988,7 +10967,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -11208,7 +11187,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
retval = zend_std_get_static_property(ce, name, 0, ((IS_TMP_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
zval_dtor(free_op1.var);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -11490,7 +11469,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_TMP_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -11553,7 +11532,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -13151,14 +13130,14 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
- if (UNEXPECTED(ce != EG(scope))) {
- zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(ce != EX(scope))) {
+ zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
- zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EX(scope)))) {
+ zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
}
}
@@ -13371,29 +13350,29 @@ 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;
- EG(active_op_array) = new_op_array;
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, EG(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 (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ call->symbol_table = EX(symbol_table);
+ } else {
+ call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
- EX(call)->prev_execute_data = EG(current_execute_data);
- i_init_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);
}
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -14718,7 +14697,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
retval = zend_std_get_static_property(ce, name, 0, ((IS_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op1.var);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -15425,7 +15404,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
if (IS_VAR != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -15727,7 +15706,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -15918,7 +15897,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -17653,7 +17632,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
if (IS_VAR != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -19073,7 +19052,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
retval = zend_std_get_static_property(ce, name, 0, ((IS_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op1.var);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -19848,7 +19827,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
if (IS_VAR != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -20052,7 +20031,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -20243,7 +20222,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -20963,7 +20942,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
retval = zend_std_get_static_property(ce, name, 0, ((IS_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op1.var);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -21312,7 +21291,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
if (IS_VAR != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -21500,7 +21479,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_VAR == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -21563,7 +21542,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -23215,7 +23194,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
if (IS_VAR != IS_CONST) {
/* previous opcode is ZEND_FETCH_CLASS */
if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
- ce = EG(called_scope);
+ ce = EX(called_scope);
}
}
@@ -23815,14 +23794,14 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
- if (UNEXPECTED(ce != EG(scope))) {
- zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(ce != EX(scope))) {
+ zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
- zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EX(scope)))) {
+ zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
}
}
@@ -30286,14 +30265,14 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
- if (UNEXPECTED(ce != EG(scope))) {
- zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(ce != EX(scope))) {
+ zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
- zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
+ if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EX(scope)))) {
+ zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
}
}
}
@@ -30504,29 +30483,29 @@ 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;
- EG(active_op_array) = new_op_array;
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, EG(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 (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ call->symbol_table = EX(symbol_table);
+ } else {
+ call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
- EX(call)->prev_execute_data = EG(current_execute_data);
- i_init_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);
}
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = &EX(func)->op_array;
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -31700,7 +31679,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
retval = zend_std_get_static_property(ce, name, 0, ((IS_CV == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -32497,7 +32476,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CV == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -32688,7 +32667,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCO
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -35756,7 +35735,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
retval = zend_std_get_static_property(ce, name, 0, ((IS_CV == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -36621,7 +36600,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CV == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -36812,7 +36791,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -37530,7 +37509,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
retval = zend_std_get_static_property(ce, name, 0, ((IS_CV == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
switch (type) {
@@ -37955,7 +37934,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
}
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CV == IS_CONST) ? Z_CACHE_SLOT_P(varname) : -1) TSRMLS_CC);
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
@@ -38018,7 +37997,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
isset = 0;
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
+ target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl
index 41a834de95..4825e02b53 100644
--- a/Zend/zend_vm_execute.skl
+++ b/Zend/zend_vm_execute.skl
@@ -3,15 +3,11 @@
ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *execute_data TSRMLS_DC)
{
DCL_OPLINE
- zend_bool original_in_execution;
{%HELPER_VARS%}
{%INTERNAL_LABELS%}
- original_in_execution = EG(in_execution);
- EG(in_execution) = 1;
-
LOAD_REGS();
LOAD_OPLINE();
@@ -39,14 +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(called_scope), 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, EG(active_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/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index bdc6cc79b8..b0a642084d 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -941,7 +941,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
out($f,"#define LOAD_REGS()\n");
out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n");
- out($f,"#define ZEND_VM_RETURN() EG(in_execution) = original_in_execution; return\n");
+ out($f,"#define ZEND_VM_RETURN() return\n");
out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
out($f,"#define ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n\n");
@@ -973,7 +973,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
}
out($f,"#define LOAD_REGS()\n");
out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
- out($f,"#define ZEND_VM_RETURN() EG(in_execution) = original_in_execution; return\n");
+ out($f,"#define ZEND_VM_RETURN() return\n");
out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
out($f,"#define ZEND_VM_DISPATCH(opcode, opline) goto *(void**)(zend_vm_get_opcode_handler(opcode, opline));\n\n");
@@ -1043,7 +1043,6 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
// Executor is defined as a set of functions
out($f, $m[1]."switch (ret) {\n" .
$m[1]."\tcase 1:\n" .
- $m[1]."\t\tEG(in_execution) = original_in_execution;\n".
$m[1]."\t\treturn;\n".
$m[1]."\tcase 2:\n" .
$m[1]."\tcase 3:\n" .
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c
index ebea66323c..df264e02af 100644
--- a/ext/mbstring/mbstring.c
+++ b/ext/mbstring/mbstring.c
@@ -2084,10 +2084,9 @@ PHP_FUNCTION(mb_parse_str)
detected = _php_mb_encoding_handler_ex(&info, track_vars_array, encstr TSRMLS_CC);
} else {
zval tmp;
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
- ZVAL_ARR(&tmp, EG(active_symbol_table));
+ zend_array *symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
+
+ ZVAL_ARR(&tmp, symbol_table);
detected = _php_mb_encoding_handler_ex(&info, &tmp, encstr TSRMLS_CC);
}
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c
index de97f64db8..91b78ec6f0 100644
--- a/ext/opcache/Optimizer/pass1_5.c
+++ b/ext/opcache/Optimizer/pass1_5.c
@@ -219,12 +219,13 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("__COMPILER_HALT_OFFSET__") - 1 &&
memcmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1) == 0) {
/* substitute __COMPILER_HALT_OFFSET__ constant */
- zend_bool orig_in_execution = EG(in_execution);
- zend_op_array *orig_op_array = EG(active_op_array);
+ zend_execute_data *orig_execute_data = EG(current_execute_data);
+ zend_execute_data fake_execute_data;
zval *offset;
- EG(in_execution) = 1;
- EG(active_op_array) = op_array;
+ memset(&fake_execute_data, 0, sizeof(zend_execute_data));
+ fake_execute_data.func = (zend_function*)op_array;
+ EG(current_execute_data) = &fake_execute_data;
if ((offset = zend_get_constant_str("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1 TSRMLS_CC)) != NULL) {
zend_uint tv = ZEND_RESULT(opline).var;
@@ -232,8 +233,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
MAKE_NOP(opline);
replace_tmp_by_const(op_array, opline, tv, offset TSRMLS_CC);
}
- EG(active_op_array) = orig_op_array;
- EG(in_execution) = orig_in_execution;
+ EG(current_execute_data) = orig_execute_data;
break;
}
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 426156fa5b..c1775b8538 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -733,7 +733,7 @@ static accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle
#endif
if (sapi_module.get_stat &&
- !EG(opline_ptr) &&
+ !EG(current_execute_data) &&
file_handle->filename == SG(request_info).path_translated) {
struct stat *tmpbuf = sapi_module.get_stat(TSRMLS_C);
@@ -995,7 +995,7 @@ char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_lengt
since fopen_wrappers from version 4.0.7 use current script's path
in include path too.
*/
- if (EG(in_execution) &&
+ if (EG(current_execute_data) &&
(parent_script = zend_get_executed_filename(TSRMLS_C)) != NULL &&
parent_script[0] != '[') {
@@ -1518,16 +1518,18 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type T
/* In case this callback is called from include_once, require_once or it's
* a main FastCGI request, the key must be already calculated, and cached
* persistent script already found */
- if ((EG(opline_ptr) == NULL &&
+ if ((EG(current_execute_data) == NULL &&
ZCG(cache_opline) == NULL &&
file_handle->filename == SG(request_info).path_translated &&
ZCG(cache_persistent_script)) ||
- (EG(opline_ptr) && *EG(opline_ptr) &&
- *EG(opline_ptr) == ZCG(cache_opline) &&
- (*EG(opline_ptr))->opcode == ZEND_INCLUDE_OR_EVAL &&
+ (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
- ((*EG(opline_ptr))->extended_value == ZEND_INCLUDE_ONCE ||
- (*EG(opline_ptr))->extended_value == ZEND_REQUIRE_ONCE))) {
+ (EG(current_execute_data)->opline->extended_value == ZEND_INCLUDE_ONCE ||
+ EG(current_execute_data)->opline->extended_value == ZEND_REQUIRE_ONCE))) {
#else
((*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_INCLUDE_ONCE ||
(*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_REQUIRE_ONCE))) {
@@ -1682,11 +1684,13 @@ 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(opline_ptr) || !*EG(opline_ptr) ||
- (*EG(opline_ptr))->opcode != ZEND_INCLUDE_OR_EVAL ||
+ 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(opline_ptr))->extended_value != ZEND_INCLUDE_ONCE &&
- (*EG(opline_ptr))->extended_value != ZEND_REQUIRE_ONCE)) {
+ (EG(current_execute_data)->opline->extended_value != ZEND_INCLUDE_ONCE &&
+ EG(current_execute_data)->opline->extended_value != ZEND_REQUIRE_ONCE)) {
#else
((*EG(opline_ptr))->op2.u.constant.value.lval != ZEND_INCLUDE_ONCE &&
(*EG(opline_ptr))->op2.u.constant.value.lval != ZEND_REQUIRE_ONCE)) {
@@ -1843,8 +1847,10 @@ static int persistent_stream_open_function(const char *filename, zend_file_handl
!CG(interactive) &&
!ZCSG(restart_in_progress)) {
- if (EG(opline_ptr) && *EG(opline_ptr)) {
- zend_op *opline = *EG(opline_ptr);
+ 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 &&
(opline->op2.u.constant.value.lval == ZEND_INCLUDE_ONCE ||
@@ -1940,14 +1946,15 @@ static int persistent_stream_open_function(const char *filename, zend_file_handl
!ZCSG(restart_in_progress)) {
/* check if callback is called from include_once or it's a main request */
- if ((!EG(opline_ptr) &&
+ if ((!EG(current_execute_data) &&
filename == SG(request_info).path_translated) ||
- (EG(opline_ptr) &&
- *EG(opline_ptr) &&
- (*EG(opline_ptr))->opcode == ZEND_INCLUDE_OR_EVAL &&
+ (EG(current_execute_data) &&
+ 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(opline_ptr))->extended_value == ZEND_INCLUDE_ONCE ||
- (*EG(opline_ptr))->extended_value == ZEND_REQUIRE_ONCE))) {
+ (EG(current_execute_data)->opline->extended_value == ZEND_INCLUDE_ONCE ||
+ EG(current_execute_data)->opline->extended_value == ZEND_REQUIRE_ONCE))) {
#else
((*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_INCLUDE_ONCE ||
(*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_REQUIRE_ONCE))) {
@@ -1960,11 +1967,11 @@ static int persistent_stream_open_function(const char *filename, zend_file_handl
handle->free_filename = 0;
/* check if cached script was already found by resolve_path() */
- if ((EG(opline_ptr) == NULL &&
+ if ((EG(current_execute_data) == NULL &&
ZCG(cache_opline) == NULL &&
ZCG(cache_persistent_script) != NULL) ||
- (EG(opline_ptr) &&
- (ZCG(cache_opline) == *EG(opline_ptr)))) {
+ (EG(current_execute_data) &&
+ (ZCG(cache_opline) == EG(current_execute_data)->opline))) {
persistent_script = ZCG(cache_persistent_script);
handle->opened_path = estrndup(persistent_script->full_path->val, persistent_script->full_path->len);
handle->type = ZEND_HANDLE_FILENAME;
@@ -1983,8 +1990,8 @@ static int persistent_stream_open_function(const char *filename, zend_file_handl
handle->type = ZEND_HANDLE_FILENAME;
memcpy(ZCG(key), persistent_script->full_path, persistent_script->full_path_len + 1);
ZCG(key_len) = persistent_script->full_path_len;
- ZCG(cache_opline) = EG(opline_ptr) ? *EG(opline_ptr) : NULL;
- ZCG(cache_persistent_script) = EG(opline_ptr) ? persistent_script : NULL;
+ ZCG(cache_opline) = EG(current_execute_data) ? EG(current_execute_data)->opline : NULL;
+ ZCG(cache_persistent_script) = EG(current_execute_data) ? persistent_script : NULL;
return SUCCESS;
}
#endif
@@ -2005,14 +2012,15 @@ static char* persistent_zend_resolve_path(const char *filename, int filename_len
!ZCSG(restart_in_progress)) {
/* check if callback is called from include_once or it's a main request */
- if ((!EG(opline_ptr) &&
+ if ((!EG(current_execute_data) &&
filename == SG(request_info).path_translated) ||
- (EG(opline_ptr) &&
- *EG(opline_ptr) &&
- (*EG(opline_ptr))->opcode == ZEND_INCLUDE_OR_EVAL &&
+ (EG(current_execute_data) &&
+ 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(opline_ptr))->extended_value == ZEND_INCLUDE_ONCE ||
- (*EG(opline_ptr))->extended_value == ZEND_REQUIRE_ONCE))) {
+ (EG(current_execute_data)->opline->extended_value == ZEND_INCLUDE_ONCE ||
+ EG(current_execute_data)->opline->extended_value == ZEND_REQUIRE_ONCE))) {
#else
((*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_INCLUDE_ONCE ||
(*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_REQUIRE_ONCE))) {
@@ -2034,7 +2042,7 @@ static char* persistent_zend_resolve_path(const char *filename, int filename_len
if (persistent_script && !persistent_script->corrupted) {
memcpy(ZCG(key), persistent_script->full_path->val, persistent_script->full_path->len + 1);
ZCG(key_len) = persistent_script->full_path->len;
- ZCG(cache_opline) = EG(opline_ptr) ? *EG(opline_ptr) : NULL;
+ ZCG(cache_opline) = EG(current_execute_data) ? EG(current_execute_data)->opline : NULL;
ZCG(cache_persistent_script) = persistent_script;
return estrndup(persistent_script->full_path->val, persistent_script->full_path->len);
}
@@ -2051,7 +2059,7 @@ static char* persistent_zend_resolve_path(const char *filename, int filename_len
!persistent_script->corrupted) {
/* we have persistent script */
- ZCG(cache_opline) = EG(opline_ptr) ? *EG(opline_ptr) : NULL;
+ ZCG(cache_opline) = EG(current_execute_data) ? EG(current_execute_data)->opline : NULL;
ZCG(cache_persistent_script) = persistent_script;
return estrndup(persistent_script->full_path->val, persistent_script->full_path->len);
}
@@ -2073,7 +2081,7 @@ static char* persistent_zend_resolve_path(const char *filename, int filename_len
zend_shared_alloc_unlock(TSRMLS_C);
SHM_PROTECT();
}
- ZCG(cache_opline) = (EG(opline_ptr) && key) ? *EG(opline_ptr): NULL;
+ ZCG(cache_opline) = (EG(current_execute_data) && key) ? EG(current_execute_data)->opline : NULL;
ZCG(cache_persistent_script) = key ? persistent_script : NULL;
return resolved_path;
}
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c
index 1f76f7ca03..e47cfda894 100644
--- a/ext/opcache/zend_persist.c
+++ b/ext/opcache/zend_persist.c
@@ -297,20 +297,20 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
op_array->refcount = NULL;
if (main_persistent_script) {
- zend_bool orig_in_execution = EG(in_execution);
- zend_op_array *orig_op_array = EG(active_op_array);
+ zend_execute_data *orig_execute_data = EG(current_execute_data);
+ zend_execute_data fake_execute_data;
zval *offset;
#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
main_persistent_script->early_binding = -1;
#endif
- EG(in_execution) = 1;
- EG(active_op_array) = op_array;
+ memset(&fake_execute_data, 0, sizeof(fake_execute_data));
+ fake_execute_data.func = (zend_function*)op_array;
+ EG(current_execute_data) = &fake_execute_data;
if ((offset = zend_get_constant_str("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1 TSRMLS_CC)) != NULL) {
main_persistent_script->compiler_halt_offset = Z_LVAL_P(offset);
}
- EG(active_op_array) = orig_op_array;
- EG(in_execution) = orig_in_execution;
+ EG(current_execute_data) = orig_execute_data;
}
if (op_array->static_variables) {
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 048362d3ec..e2acb53724 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -283,13 +283,8 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char
#endif
if (new_op_array) {
ZVAL_UNDEF(&result);
- EG(active_op_array) = new_op_array;
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(called_scope), Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC);
- }
zend_execute(new_op_array, &result TSRMLS_CC);
if (PHAR_G(cwd)) {
efree(PHAR_G(cwd));
diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c
index c94c245071..84d27ca046 100644
--- a/ext/readline/readline_cli.c
+++ b/ext/readline/readline_cli.c
@@ -432,8 +432,9 @@ static char *cli_completion_generator_ht(const char *text, int textlen, int *sta
static char *cli_completion_generator_var(const char *text, int textlen, int *state TSRMLS_DC) /* {{{ */
{
char *retval, *tmp;
+ zend_array *symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
- tmp = retval = cli_completion_generator_ht(text + 1, textlen - 1, state, EG(active_symbol_table) ? &EG(active_symbol_table)->ht : NULL, NULL TSRMLS_CC);
+ tmp = retval = cli_completion_generator_ht(text + 1, textlen - 1, state, symbol_table ? &symbol_table->ht : NULL, NULL TSRMLS_CC);
if (retval) {
retval = malloc(strlen(tmp) + 2);
retval[0] = '$';
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c
index 0ec71d7625..a2596be3c6 100644
--- a/ext/soap/php_encoding.c
+++ b/ext/soap/php_encoding.c
@@ -1232,7 +1232,7 @@ static void unset_zval_property(zval* object, char* name TSRMLS_DC)
ZVAL_STRING(&member, name);
old_scope = EG(scope);
EG(scope) = Z_OBJCE_P(object);
- Z_OBJ_HT_P(object)->unset_property(object, &member, 0 TSRMLS_CC);
+ Z_OBJ_HT_P(object)->unset_property(object, &member, -1 TSRMLS_CC);
EG(scope) = old_scope;
zval_ptr_dtor(&member);
} else if (Z_TYPE_P(object) == IS_ARRAY) {
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index fe97793afe..d98d1fc494 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -92,7 +92,6 @@ static void soap_error_handler(int error_num, const char *error_filename, const
zend_object* _old_error_object = Z_OBJ(SOAP_GLOBAL(error_object));\
int _old_soap_version = SOAP_GLOBAL(soap_version);\
zend_bool _old_in_compilation = CG(in_compilation); \
- zend_bool _old_in_execution = EG(in_execution); \
zend_execute_data *_old_current_execute_data = EG(current_execute_data); \
zval *_old_stack_top = EG(argument_stack)->top; \
int _bailout = 0;\
@@ -104,7 +103,6 @@ static void soap_error_handler(int error_num, const char *error_filename, const
#define SOAP_CLIENT_END_CODE() \
} zend_catch {\
CG(in_compilation) = _old_in_compilation; \
- EG(in_execution) = _old_in_execution; \
EG(current_execute_data) = _old_current_execute_data; \
if (EG(exception) == NULL || \
!instanceof_function(zend_get_class_entry(EG(exception) TSRMLS_CC), soap_fault_class_entry TSRMLS_CC)) {\
@@ -2131,14 +2129,13 @@ static void soap_server_fault(char* code, char* string, char *actor, zval* detai
static void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args)
{
- zend_bool _old_in_compilation, _old_in_execution;
+ zend_bool _old_in_compilation;
zend_execute_data *_old_current_execute_data;
int _old_http_response_code;
char *_old_http_status_line;
TSRMLS_FETCH();
_old_in_compilation = CG(in_compilation);
- _old_in_execution = EG(in_execution);
_old_current_execute_data = EG(current_execute_data);
_old_http_response_code = SG(sapi_headers).http_response_code;
_old_http_status_line = SG(sapi_headers).http_status_line;
@@ -2204,7 +2201,6 @@ static void soap_error_handler(int error_num, const char *error_filename, const
call_old_error_handler(error_num, error_filename, error_lineno, format, args);
} zend_catch {
CG(in_compilation) = _old_in_compilation;
- EG(in_execution) = _old_in_execution;
EG(current_execute_data) = _old_current_execute_data;
if (SG(sapi_headers).http_status_line) {
efree(SG(sapi_headers).http_status_line);
@@ -2287,7 +2283,6 @@ static void soap_error_handler(int error_num, const char *error_filename, const
call_old_error_handler(error_num, error_filename, error_lineno, format, args);
} zend_catch {
CG(in_compilation) = _old_in_compilation;
- EG(in_execution) = _old_in_execution;
EG(current_execute_data) = _old_current_execute_data;
if (SG(sapi_headers).http_status_line) {
efree(SG(sapi_headers).http_status_line);
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c
index 5ec20cd563..cd0a050b98 100644
--- a/ext/spl/php_spl.c
+++ b/ext/spl/php_spl.c
@@ -286,16 +286,7 @@ static int spl_autoload(zend_string *class_name, zend_string *lc_name, const cha
}
STR_RELEASE(opened_path);
if (new_op_array) {
- EG(active_op_array) = new_op_array;
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
-
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(called_scope), Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC);
- }
zend_execute(new_op_array, &result TSRMLS_CC);
destroy_op_array(new_op_array TSRMLS_CC);
@@ -319,8 +310,6 @@ PHP_FUNCTION(spl_autoload)
int found = 0, pos_len, pos1_len;
char *pos, *pos1;
zend_string *class_name, *lc_name, *file_exts = SPL_G(autoload_extensions);
- zend_op **original_opline_ptr = EG(opline_ptr);
- zend_op_array *original_active_op_array = EG(active_op_array);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|S", &class_name, &file_exts) == FAILURE) {
RETURN_FALSE;
@@ -337,8 +326,6 @@ PHP_FUNCTION(spl_autoload)
lc_name = STR_ALLOC(class_name->len, 0);
zend_str_tolower_copy(lc_name->val, class_name->val, class_name->len);
while (pos && *pos && !EG(exception)) {
- EG(opline_ptr) = original_opline_ptr;
- EG(active_op_array) = original_active_op_array;
pos1 = strchr(pos, ',');
if (pos1) {
pos1_len = pos1 - pos;
@@ -354,15 +341,17 @@ PHP_FUNCTION(spl_autoload)
}
STR_FREE(lc_name);
- EG(opline_ptr) = original_opline_ptr;
- EG(active_op_array) = original_active_op_array;
-
if (!found && !SPL_G(autoload_running)) {
/* For internal errors, we generate E_ERROR, for direct calls an exception is thrown.
* The "scope" is determined by an opcode, if it is ZEND_FETCH_CLASS we know function was called indirectly by
* the Zend engine.
*/
- if (active_opline->opcode != ZEND_FETCH_CLASS) {
+ zend_execute_data *ex = EG(current_execute_data);
+
+ while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
+ ex = ex->prev_execute_data;
+ }
+ 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/ext/standard/array.c b/ext/standard/array.c
index e1113a8ed5..06f04aed2c 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1294,6 +1294,7 @@ PHP_FUNCTION(extract)
ulong num_key;
int var_exists, count = 0;
int extract_refs = 0;
+ zend_array *symbol_table;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|lz/", &var_array, &extract_type, &prefix) == FAILURE) {
return;
@@ -1320,9 +1321,7 @@ PHP_FUNCTION(extract)
}
}
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
+ symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(var_array), num_key, var_name, entry) {
zval final_name;
@@ -1331,7 +1330,7 @@ PHP_FUNCTION(extract)
var_exists = 0;
if (var_name) {
- var_exists = zend_hash_exists_ind(&EG(active_symbol_table)->ht, var_name);
+ var_exists = zend_hash_exists_ind(&symbol_table->ht, var_name);
} else if (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID) {
zval num;
@@ -1401,14 +1400,14 @@ PHP_FUNCTION(extract)
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
- if ((orig_var = zend_hash_find(&EG(active_symbol_table)->ht, Z_STR(final_name))) != NULL) {
+ if ((orig_var = zend_hash_find(&symbol_table->ht, Z_STR(final_name))) != NULL) {
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
orig_var = Z_INDIRECT_P(orig_var);
}
zval_ptr_dtor(orig_var);
ZVAL_COPY_VALUE(orig_var, entry);
} else {
- zend_hash_update(&EG(active_symbol_table)->ht, Z_STR(final_name), entry);
+ zend_hash_update(&symbol_table->ht, Z_STR(final_name), entry);
}
} else {
if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry);
@@ -1458,14 +1457,13 @@ PHP_FUNCTION(compact)
{
zval *args = NULL; /* function arguments array */
int num_args, i;
+ zend_array *symbol_table;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &num_args) == FAILURE) {
return;
}
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
+ symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
/* compact() is probably most used with a single array of var_names
or multiple string names, rather than a combination of both.
@@ -1477,7 +1475,7 @@ PHP_FUNCTION(compact)
}
for (i=0; i<ZEND_NUM_ARGS(); i++) {
- php_compact_var(&EG(active_symbol_table)->ht, return_value, &args[i] TSRMLS_CC);
+ php_compact_var(&symbol_table->ht, return_value, &args[i] TSRMLS_CC);
}
}
/* }}} */
diff --git a/ext/standard/assert.c b/ext/standard/assert.c
index 3ec7361197..e64e2e1ecb 100644
--- a/ext/standard/assert.c
+++ b/ext/standard/assert.c
@@ -53,7 +53,7 @@ enum {
static PHP_INI_MH(OnChangeCallback) /* {{{ */
{
- if (EG(in_execution)) {
+ if (EG(current_execute_data)) {
if (Z_TYPE(ASSERTG(callback)) != IS_UNDEF) {
zval_ptr_dtor(&ASSERTG(callback));
ZVAL_UNDEF(&ASSERTG(callback));
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index c8b3f96bc5..644e364f21 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -4759,15 +4759,15 @@ PHP_FUNCTION(forward_static_call)
return;
}
- if (!EG(active_op_array)->scope) {
+ if (!EG(current_execute_data)->prev_execute_data->func->common.scope) {
zend_error(E_ERROR, "Cannot call forward_static_call() when no class scope is active");
}
fci.retval = &retval;
- if (EG(called_scope) &&
- instanceof_function(EG(called_scope), fci_cache.calling_scope TSRMLS_CC)) {
- fci_cache.called_scope = EG(called_scope);
+ if (EG(current_execute_data)->called_scope &&
+ instanceof_function(EG(current_execute_data)->called_scope, fci_cache.calling_scope TSRMLS_CC)) {
+ fci_cache.called_scope = EG(current_execute_data)->called_scope;
}
if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
@@ -4791,9 +4791,9 @@ PHP_FUNCTION(forward_static_call_array)
zend_fcall_info_args(&fci, params TSRMLS_CC);
fci.retval = &retval;
- if (EG(called_scope) &&
- instanceof_function(EG(called_scope), fci_cache.calling_scope TSRMLS_CC)) {
- fci_cache.called_scope = EG(called_scope);
+ if (EG(current_execute_data)->called_scope &&
+ instanceof_function(EG(current_execute_data)->called_scope, fci_cache.calling_scope TSRMLS_CC)) {
+ fci_cache.called_scope = EG(current_execute_data)->called_scope;
}
if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index 2b10370710..f7d6fc4500 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -141,6 +141,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
int follow_location = 1;
php_stream_filter *transfer_encoding = NULL;
int response_code;
+ zend_array *symbol_table;
tmp_line[0] = '\0';
@@ -634,9 +635,7 @@ finish:
location[0] = '\0';
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
+ symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
if (header_init) {
zval ztmp;
@@ -644,7 +643,7 @@ finish:
zend_set_local_var_str("http_response_header", sizeof("http_response_header")-1, &ztmp, 0 TSRMLS_CC);
}
- response_header = zend_hash_str_find_ind(&EG(active_symbol_table)->ht, "http_response_header", sizeof("http_response_header")-1);
+ response_header = zend_hash_str_find_ind(&symbol_table->ht, "http_response_header", sizeof("http_response_header")-1);
if (!php_stream_eof(stream)) {
size_t tmp_line_len;
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 3250241bc6..ceebf77a70 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -4221,11 +4221,9 @@ PHP_FUNCTION(parse_str)
if (arrayArg == NULL) {
zval tmp;
+ zend_array *symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
- ZVAL_ARR(&tmp, EG(active_symbol_table));
+ ZVAL_ARR(&tmp, symbol_table);
sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC);
} else {
zval ret;
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index a87f97fdcf..0b853f34f2 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -668,10 +668,8 @@ static void php_wddx_add_var(wddx_packet *packet, zval *name_var)
TSRMLS_FETCH();
if (Z_TYPE_P(name_var) == IS_STRING) {
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
- if ((val = zend_hash_find(&EG(active_symbol_table)->ht, Z_STR_P(name_var))) != NULL) {
+ zend_array *symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
+ if ((val = zend_hash_find(&symbol_table->ht, Z_STR_P(name_var))) != NULL) {
if (Z_TYPE_P(val) == IS_INDIRECT) {
val = Z_INDIRECT_P(val);
}
diff --git a/main/SAPI.c b/main/SAPI.c
index e587f7aaf7..229396dd79 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -947,7 +947,7 @@ SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entries TSRMLS_DC)
SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry TSRMLS_DC)
{
- if (SG(sapi_started) && EG(in_execution)) {
+ if (SG(sapi_started) && EG(current_execute_data)) {
return FAILURE;
}
return zend_hash_str_add_mem(&SG(known_post_content_types),
@@ -957,7 +957,7 @@ SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry TSRMLS_DC)
SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry TSRMLS_DC)
{
- if (SG(sapi_started) && EG(in_execution)) {
+ if (SG(sapi_started) && EG(current_execute_data)) {
return;
}
zend_hash_str_del(&SG(known_post_content_types), post_entry->content_type,
@@ -967,7 +967,7 @@ SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry TSRMLS_DC)
SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D) TSRMLS_DC)
{
- if (SG(sapi_started) && EG(in_execution)) {
+ if (SG(sapi_started) && EG(current_execute_data)) {
return FAILURE;
}
sapi_module.default_post_reader = default_post_reader;
@@ -977,7 +977,7 @@ SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRML
SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC) TSRMLS_DC)
{
- if (SG(sapi_started) && EG(in_execution)) {
+ if (SG(sapi_started) && EG(current_execute_data)) {
return FAILURE;
}
sapi_module.treat_data = treat_data;
@@ -986,7 +986,7 @@ SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zva
SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC), unsigned int (*input_filter_init)(TSRMLS_D) TSRMLS_DC)
{
- if (SG(sapi_started) && EG(in_execution)) {
+ if (SG(sapi_started) && EG(current_execute_data)) {
return FAILURE;
}
sapi_module.input_filter = input_filter;
diff --git a/main/main.c b/main/main.c
index 0e17be81f9..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
) {
@@ -897,12 +899,16 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c
efree(docref_buf);
}
- if (PG(track_errors) && module_initialized &&
+ if (PG(track_errors) && module_initialized && EG(valid_symbol_table) &&
(Z_TYPE(EG(user_error_handler)) == IS_UNDEF || !(EG(user_error_handler_error_reporting) & type))) {
zval tmp;
ZVAL_STRINGL(&tmp, buffer, buffer_len);
- if (zend_set_local_var_str("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0 TSRMLS_CC) == FAILURE) {
- zval_ptr_dtor(&tmp);
+ if (EG(current_execute_data)) {
+ if (zend_set_local_var_str("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0 TSRMLS_CC) == FAILURE) {
+ zval_ptr_dtor(&tmp);
+ }
+ } else {
+ zend_hash_str_update_ind(&EG(symbol_table).ht, "php_errormsg", sizeof("php_errormsg")-1, &tmp);
}
}
if (replace_buffer) {
@@ -1227,16 +1233,16 @@ static void php_error_cb(int type, const char *error_filename, const uint error_
return;
}
- if (PG(track_errors) && module_initialized) {
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
- if (EG(active_symbol_table)) {
- zval tmp;
- ZVAL_STRINGL(&tmp, buffer, buffer_len);
+ if (PG(track_errors) && module_initialized && EG(valid_symbol_table)) {
+ zval tmp;
+
+ ZVAL_STRINGL(&tmp, buffer, buffer_len);
+ if (EG(current_execute_data)) {
if (zend_set_local_var_str("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0 TSRMLS_CC) == FAILURE) {
zval_ptr_dtor(&tmp);
}
+ } else {
+ zend_hash_str_update_ind(&EG(symbol_table).ht, "php_errormsg", sizeof("php_errormsg")-1, &tmp);
}
}
@@ -1776,11 +1782,10 @@ void php_request_shutdown(void *dummy)
report_memleaks = PG(report_memleaks);
- /* EG(opline_ptr) points into nirvana and therefore cannot be safely accessed
+ /* EG(current_execute_data) points into nirvana and therefore cannot be safely accessed
* inside zend_executor callback functions.
*/
- EG(opline_ptr) = NULL;
- EG(active_op_array) = NULL;
+ EG(current_execute_data) = NULL;
php_deactivate_ticks(TSRMLS_C);
@@ -2126,7 +2131,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
#endif
EG(bailout) = NULL;
EG(error_reporting) = E_ALL & ~E_NOTICE;
- EG(active_symbol_table) = NULL;
PG(header_is_being_sent) = 0;
SG(request_info).headers_only = 0;
SG(request_info).argv0 = NULL;
diff --git a/main/php_variables.c b/main/php_variables.c
index fbd91dc286..3bb6d65aa5 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -110,8 +110,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
}
/* GLOBALS hijack attempt, reject parameter */
- if (symtable1 && EG(active_symbol_table) &&
- symtable1 == &EG(active_symbol_table)->ht &&
+ if (symtable1 == &EG(symbol_table).ht &&
var_len == sizeof("GLOBALS")-1 &&
!memcmp(var, "GLOBALS", sizeof("GLOBALS")-1)) {
zval_dtor(val);