summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-07-04 18:03:45 +0400
committerDmitry Stogov <dmitry@zend.com>2014-07-04 18:03:45 +0400
commit6bf24f4dd01331122a0f10db392c08605f159826 (patch)
tree7fe575ead375355aab6c9b2c8a1593642d658406 /Zend
parentd2890963e4540a20954afae0e059810312c9dc4e (diff)
downloadphp-git-6bf24f4dd01331122a0f10db392c08605f159826.tar.gz
Removed EG(active_symbol_table) and use corresponding value from EG(current_execute_data)
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend.c10
-rw-r--r--Zend/zend_API.h2
-rw-r--r--Zend/zend_builtin_functions.c6
-rw-r--r--Zend/zend_execute.c92
-rw-r--r--Zend/zend_execute_API.c161
-rw-r--r--Zend/zend_generators.c13
-rw-r--r--Zend/zend_globals.h4
-rw-r--r--Zend/zend_variables.c9
-rw-r--r--Zend/zend_vm_def.h21
-rw-r--r--Zend/zend_vm_execute.h48
-rw-r--r--Zend/zend_vm_execute.skl3
11 files changed, 214 insertions, 155 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index 14045914b6..85578b5aac 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -938,7 +938,6 @@ ZEND_API void zend_deactivate(TSRMLS_D) /* {{{ */
{
/* we're no longer executing anything */
EG(current_execute_data) = NULL;
- EG(active_symbol_table) = NULL;
zend_try {
shutdown_scanner(TSRMLS_C);
@@ -1037,6 +1036,7 @@ 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 */
@@ -1175,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));
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_builtin_functions.c b/Zend/zend_builtin_functions.c
index a9b7a6c12b..dbe02ded5c 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -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);
}
/* }}} */
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 37facb3412..44519adcec 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1444,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)
@@ -1543,6 +1543,93 @@ 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);
@@ -1556,7 +1643,6 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
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);
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index d5bc4c5cf0..6730bacf40 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -159,7 +159,7 @@ 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);
@@ -266,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;
@@ -659,7 +660,6 @@ 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_class_entry *calling_scope = NULL;
zend_execute_data *call, dummy_execute_data;
zend_fcall_info_cache fci_cache_local;
@@ -847,24 +847,13 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
EG(current_execute_data)->call = call;
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;
- } else {
- EG(active_symbol_table) = NULL;
- }
-
+ call->symbol_table = fci->symbol_table;
if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) {
zend_execute(&func->op_array, fci->retval TSRMLS_CC);
} else {
zend_generator_create_zval(&func->op_array, fci->retval TSRMLS_CC);
}
-
- if (!fci->symbol_table && EG(active_symbol_table)) {
- zend_clean_and_cache_symbol_table(EG(active_symbol_table) 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);
@@ -1104,10 +1093,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s
zval local_retval;
int orig_interactive = CG(interactive);
- EG(no_extensions)=1;
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
+ EG(no_extensions)=1;
CG(interactive) = 0;
zend_try {
@@ -1115,6 +1101,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s
if (EG(current_execute_data)) {
EG(current_execute_data)->call = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EG(current_execute_data)->called_scope, Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC);
+ EG(current_execute_data)->call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
zend_execute(new_op_array, &local_retval TSRMLS_CC);
} zend_catch {
@@ -1607,45 +1594,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;
}
/* }}} */
@@ -1700,18 +1684,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;
- zend_ulong h = STR_HASH_VAL(name);
-
- while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
- execute_data = execute_data->prev_execute_data;
- }
+ 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 (execute_data && execute_data->func) {
- op_array = &execute_data->func->op_array;
for (i = 0; i < op_array->last_var; i++) {
if (op_array->vars[i]->h == h &&
op_array->vars[i]->len == name->len &&
@@ -1720,36 +1704,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;
- zend_ulong h = zend_hash_func(name, len);
-
- while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
- execute_data = execute_data->prev_execute_data;
- }
+ 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 (execute_data && execute_data->func) {
- op_array = &execute_data->func->op_array;
for (i = 0; i < op_array->last_var; i++) {
if (op_array->vars[i]->h == h &&
op_array->vars[i]->len == len &&
@@ -1758,19 +1740,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 c529646730..427c8bdb11 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -224,13 +224,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). */
+/* Requires globals EG(scope), EG(This) and EG(current_execute_data). */
ZEND_API void zend_generator_create_zval(zend_op_array *op_array, zval *return_value TSRMLS_DC) /* {{{ */
{
zend_generator *generator;
zend_execute_data *current_execute_data;
- zend_array *current_symbol_table;
zend_execute_data *execute_data;
zend_vm_stack current_stack = EG(argument_stack);
@@ -259,13 +257,9 @@ 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) 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);
- 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;
EG(current_execute_data) = current_execute_data;
object_init_ex(return_value, zend_ce_generator);
@@ -311,7 +305,6 @@ 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_array *original_active_symbol_table = EG(active_symbol_table);
zend_object *original_This;
zend_class_entry *original_scope = EG(scope);
zend_vm_stack original_stack = EG(argument_stack);
@@ -320,7 +313,6 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
/* Set executor globals */
EG(current_execute_data) = generator->execute_data;
- EG(active_symbol_table) = generator->execute_data->symbol_table;
Z_OBJ(EG(This)) = generator->execute_data->object;
EG(scope) = generator->execute_data->scope;
EG(argument_stack) = generator->stack;
@@ -348,7 +340,6 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
/* Restore executor globals */
EG(current_execute_data) = original_execute_data;
- EG(active_symbol_table) = original_active_symbol_table;
Z_OBJ(EG(This)) = original_This;
EG(scope) = original_scope;
EG(argument_stack) = original_stack;
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 2bfd933944..082e733844 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -170,7 +170,6 @@ struct _zend_executor_globals {
zend_array **symtable_cache_limit;
zend_array **symtable_cache_ptr;
- zend_array *active_symbol_table;
zend_array symbol_table; /* main symbol table */
HashTable included_files; /* files already included */
@@ -240,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_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 b865c5aa4d..370bebe1f1 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1789,7 +1789,6 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
execute_data = EG(current_execute_data);
EX(call) = prev_nested_call;
- EG(active_symbol_table) = EX(symbol_table);
if (Z_OBJ(EG(This))) {
if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
@@ -1843,6 +1842,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);
@@ -2681,7 +2683,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
Z_OBJ(EG(This)) = call->object;
EG(scope) = fbc->common.scope;
- EG(active_symbol_table) = NULL;
+ call->symbol_table = NULL;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
@@ -2698,7 +2700,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
call->prev_execute_data = execute_data;
- i_init_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
+ 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,11 +2708,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
execute_ex(call TSRMLS_CC);
}
}
-
- 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;
@@ -3985,12 +3982,14 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
- if (!EX(symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ EX(call)->symbol_table = EX(symbol_table);
+ } else {
+ EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
- i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
+ i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 9c178933a6..83cfc75949 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -381,9 +381,10 @@ ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value TSRMLS_DC
} else {
execute_data = zend_vm_stack_push_call_frame(
(zend_function*)op_array, 0, 0, EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL, Z_OBJ(EG(This)), NULL TSRMLS_CC);
+ execute_data->symbol_table = &EG(symbol_table);
}
EX(prev_execute_data) = EG(current_execute_data);
- i_init_execute_data(execute_data, op_array, return_value, EG(active_symbol_table) ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
+ i_init_execute_data(execute_data, op_array, return_value, (execute_data->symbol_table) ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
zend_execute_ex(execute_data TSRMLS_CC);
}
@@ -407,7 +408,6 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
execute_data = EG(current_execute_data);
EX(call) = prev_nested_call;
- EG(active_symbol_table) = EX(symbol_table);
if (Z_OBJ(EG(This))) {
if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
@@ -461,6 +461,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);
@@ -628,7 +631,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(active_symbol_table) = NULL;
+ call->symbol_table = NULL;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
@@ -645,7 +648,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
call->prev_execute_data = execute_data;
- i_init_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
+ 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();
@@ -653,11 +656,6 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
execute_ex(call TSRMLS_CC);
}
}
-
- 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;
@@ -2920,12 +2918,14 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
- if (!EX(symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ EX(call)->symbol_table = EX(symbol_table);
+ } else {
+ EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
- i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
+ i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
@@ -8111,12 +8111,14 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
- if (!EX(symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ EX(call)->symbol_table = EX(symbol_table);
+ } else {
+ EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
- i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
+ i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
@@ -13369,12 +13371,14 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
- if (!EX(symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ EX(call)->symbol_table = EX(symbol_table);
+ } else {
+ EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
- i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
+ i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
@@ -30499,12 +30503,14 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
EX(call) = zend_vm_stack_push_call_frame(
(zend_function*)new_op_array, 0, 0, EX(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
- if (!EX(symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ if (EX(symbol_table)) {
+ EX(call)->symbol_table = EX(symbol_table);
+ } else {
+ EX(call)->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
}
EX(call)->prev_execute_data = execute_data;
- i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
+ i_init_code_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl
index ae5bac4db3..51cede9834 100644
--- a/Zend/zend_vm_execute.skl
+++ b/Zend/zend_vm_execute.skl
@@ -40,9 +40,10 @@ ZEND_API void zend_{%EXECUTOR_NAME%}(zend_op_array *op_array, zval *return_value
} else {
execute_data = zend_vm_stack_push_call_frame(
(zend_function*)op_array, 0, 0, EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL, Z_OBJ(EG(This)), NULL TSRMLS_CC);
+ execute_data->symbol_table = &EG(symbol_table);
}
EX(prev_execute_data) = EG(current_execute_data);
- i_init_execute_data(execute_data, op_array, return_value, EG(active_symbol_table) ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
+ i_init_execute_data(execute_data, op_array, return_value, (execute_data->symbol_table) ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
zend_{%EXECUTOR_NAME%}_ex(execute_data TSRMLS_CC);
}