diff options
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r-- | Zend/zend_execute.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index d2aae1a45f..2391fc08cc 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -169,14 +169,6 @@ ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data return execute_data_ptr->CVs[var]; } -static inline void zend_get_cv_address(zend_compiled_variable *cv, zval ***ptr, temp_variable *Ts TSRMLS_DC) -{ - zval *new_zval = &EG(uninitialized_zval); - - Z_ADDREF_P(new_zval); - zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &new_zval, sizeof(zval *), (void **)ptr); -} - static inline zval *_get_zval_ptr_tmp(znode *node, temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) { return should_free->var = &T(node->u.var).tmp_var; @@ -220,7 +212,8 @@ static inline zval *_get_zval_ptr_cv(znode *node, temp_variable *Ts, int type TS if (!*ptr) { zend_compiled_variable *cv = &CV_DEF_OF(node->u.var); - if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { + if (!EG(active_symbol_table) || + zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -233,7 +226,13 @@ static inline zval *_get_zval_ptr_cv(znode *node, temp_variable *Ts, int type TS zend_error(E_NOTICE, "Undefined variable: %s", cv->name); /* break missing intentionally */ case BP_VAR_W: - zend_get_cv_address(cv, ptr, Ts TSRMLS_CC); + Z_ADDREF(EG(uninitialized_zval)); + if (!EG(active_symbol_table)) { + *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + node->u.var); + **ptr = &EG(uninitialized_zval); + } else { + zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr); + } break; } } @@ -288,7 +287,9 @@ static inline zval **_get_zval_ptr_ptr_cv(znode *node, temp_variable *Ts, int ty if (!*ptr) { zend_compiled_variable *cv = &CV_DEF_OF(node->u.var); - if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { + + if (!EG(active_symbol_table) || + zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -301,7 +302,13 @@ static inline zval **_get_zval_ptr_ptr_cv(znode *node, temp_variable *Ts, int ty zend_error(E_NOTICE, "Undefined variable: %s", cv->name); /* break missing intentionally */ case BP_VAR_W: - zend_get_cv_address(cv, ptr, Ts TSRMLS_CC); + Z_ADDREF(EG(uninitialized_zval)); + if (!EG(active_symbol_table)) { + *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + node->u.var); + **ptr = &EG(uninitialized_zval); + } else { + zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr); + } break; } } @@ -762,6 +769,9 @@ static inline HashTable *zend_get_target_symbol_table(zend_op *opline, temp_vari { switch (opline->op2.u.EA.type) { case ZEND_FETCH_LOCAL: + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + } return EG(active_symbol_table); break; case ZEND_FETCH_GLOBAL: @@ -1298,11 +1308,21 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_v #define ZEND_VM_INC_OPCODE() \ EX(opline)++ -#define ZEND_VM_EXIT_FROM_EXECUTE_LOOP() \ - EG(in_execution) = EX(original_in_execution); \ - EG(current_execute_data) = EX(prev_execute_data); \ - EG(opline_ptr) = NULL; \ - zend_vm_stack_free(execute_data TSRMLS_CC); +#define ZEND_VM_EXIT_FROM_EXECUTE_LOOP() do { \ + EG(in_execution) = EX(original_in_execution); \ + EG(current_execute_data) = EX(prev_execute_data); \ + EG(opline_ptr) = NULL; \ + if (!EG(active_symbol_table)) { \ + int n = EX(op_array)->last_var; \ + while (n > 0) { \ + --n; \ + if (EX(CVs)[n]) { \ + zval_ptr_dtor(EX(CVs)[n]); \ + } \ + } \ + } \ + zend_vm_stack_free(execute_data TSRMLS_CC); \ + } while (0); #define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \ ZEND_VM_EXIT_FROM_EXECUTE_LOOP() \ |