diff options
-rw-r--r-- | Zend/zend.c | 9 | ||||
-rw-r--r-- | Zend/zend.h | 4 | ||||
-rw-r--r-- | Zend/zend_compile.c | 3 | ||||
-rw-r--r-- | Zend/zend_execute.c | 40 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 22 | ||||
-rw-r--r-- | Zend/zend_globals.h | 2 |
6 files changed, 56 insertions, 24 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index 83800b54e4..4733e22c9c 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -60,6 +60,8 @@ HashTable *global_constants_table; zend_utility_values zend_uv; +zval zval_used_for_init; /* True global variable */ + /* version information */ static char *zend_version_info; static uint zend_version_info_length; @@ -329,6 +331,13 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) zend_hash_init(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1); zend_hash_init(&list_destructors, 50, NULL, NULL, 1); + /* This zval can be used to initialize allocate zval's to an uninit'ed value */ + zval_used_for_init.is_ref = 0; + zval_used_for_init.refcount = 1; + zval_used_for_init.type = IS_STRING; + zval_used_for_init.value.str.val = undefined_variable_string; + zval_used_for_init.value.str.len = 0; + #ifdef ZTS global_constants_table = NULL; compiler_globals_id = ts_allocate_id(sizeof(zend_compiler_globals), (void (*)(void *)) compiler_globals_ctor, (void (*)(void *)) compiler_globals_dtor); diff --git a/Zend/zend.h b/Zend/zend.h index 0ef98ee46a..8533a2d5c1 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -250,6 +250,8 @@ void zenderror(char *error); extern ZEND_API zend_class_entry zend_standard_class_def; extern zend_utility_values zend_uv; +extern zval zval_used_for_init; + END_EXTERN_C() #define ZEND_UV(name) (zend_uv.name) @@ -272,6 +274,8 @@ END_EXTERN_C() (z)->refcount = 1; \ (z)->is_ref = 0; +#define INIT_ZVAL(z) z = zval_used_for_init; + #define MAKE_STD_ZVAL(zv) \ zv = (zval *) emalloc(sizeof(zval)); \ INIT_PZVAL(zv); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 52d2cc10dd..5f16d23580 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -991,9 +991,8 @@ void do_return(znode *expr, int do_end_vparse CLS_DC) if (expr) { opline->op1 = *expr; } else { - var_uninit(&opline->op1.u.constant); opline->op1.op_type = IS_CONST; - INIT_PZVAL(&opline->op1.u.constant); + INIT_ZVAL(opline->op1.u.constant); } SET_UNUSED(opline->op2); } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 78982c85c4..c20d9fe98b 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1475,14 +1475,15 @@ do_fcall_common: zval **original_return_value; int return_value_not_used = (opline->result.u.EA.type & EXT_TYPE_UNUSED); + zend_ptr_stack_push(&EG(argument_stack), (void *) opline->extended_value); - Ts[opline->result.u.var].var.ptr = (zval *)emalloc(sizeof(zval)); Ts[opline->result.u.var].var.ptr_ptr = &Ts[opline->result.u.var].var.ptr; - var_uninit(Ts[opline->result.u.var].var.ptr); - Ts[opline->result.u.var].var.ptr->is_ref = 0; - Ts[opline->result.u.var].var.ptr->refcount = 1; + /* The emalloc() could be optimized out for call user function but it + creates a problem with include() */ + Ts[opline->result.u.var].var.ptr = (zval *)emalloc(sizeof(zval)); + INIT_ZVAL(*(Ts[opline->result.u.var].var.ptr)); - if (function_state.function->type==ZEND_INTERNAL_FUNCTION) { + if (function_state.function->type==ZEND_INTERNAL_FUNCTION) { ((zend_internal_function *) function_state.function)->handler(opline->extended_value, Ts[opline->result.u.var].var.ptr, &EG(regular_list), &EG(persistent_list), object.ptr, !return_value_not_used); if (object.ptr) { object.ptr->refcount--; @@ -1567,6 +1568,7 @@ do_fcall_common: if (!EG(free_op1)) { /* Not a temp var */ if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) { + /**(EG(return_value_ptr_ptr)) = (zval *)emalloc(sizeof(zval));*/ **EG(return_value_ptr_ptr) = *retval_ptr; (*EG(return_value_ptr_ptr))->is_ref = 0; (*EG(return_value_ptr_ptr))->refcount = 1; @@ -1577,6 +1579,7 @@ do_fcall_common: retval_ptr->refcount++; } } else { + /**(EG(return_value_ptr_ptr))= (zval *)emalloc(sizeof(zval));*/ **EG(return_value_ptr_ptr) = *retval_ptr; (*EG(return_value_ptr_ptr))->refcount = 1; (*EG(return_value_ptr_ptr))->is_ref = 0; @@ -1615,9 +1618,8 @@ do_fcall_common: if (varptr == &EG(uninitialized_zval)) { varptr = (zval *) emalloc(sizeof(zval)); - var_uninit(varptr); - varptr->refcount=0; - varptr->is_ref=0; + INIT_ZVAL(*varptr); + varptr->refcount = 0; } else if (PZVAL_IS_REF(varptr)) { zval *original_var = varptr; @@ -1923,7 +1925,7 @@ send_by_ref: break; case ZEND_INCLUDE_OR_EVAL: { zend_op_array *new_op_array=NULL; - zval *original_return_value = EG(return_value); + zval **original_return_value = EG(return_value_ptr_ptr); CLS_FETCH(); switch (opline->op2.u.constant.value.lval) { @@ -1938,22 +1940,36 @@ send_by_ref: break; } FREE_OP(&opline->op1, EG(free_op1)); + if (new_op_array) { - Ts[opline->result.u.var].tmp_var.value.lval = 1; + zval *return_value_ptr; + /*Ts[opline->result.u.var].tmp_var.value.lval = 1; Ts[opline->result.u.var].tmp_var.type = IS_LONG; EG(return_value) = &Ts[opline->result.u.var].tmp_var; + */ + return_value_ptr = emalloc(sizeof(zval)); + + INIT_PZVAL(return_value_ptr); + return_value_ptr->value.lval = 1; + return_value_ptr->type = IS_LONG; + EG(return_value_ptr_ptr) = &return_value_ptr; EG(active_op_array) = new_op_array; + zend_execute(new_op_array ELS_CC); + Ts[opline->result.u.var].tmp_var = *return_value_ptr; + zval_copy_ctor(&Ts[opline->result.u.var].tmp_var); + zval_ptr_dtor(&return_value_ptr); + EG(opline_ptr) = &opline; EG(active_op_array) = op_array; EG(function_state_ptr) = &function_state; destroy_op_array(new_op_array); efree(new_op_array); } else { - var_uninit(&Ts[opline->result.u.var].tmp_var); + INIT_ZVAL(Ts[opline->result.u.var].tmp_var); } - EG(return_value) = original_return_value; + EG(return_value_ptr_ptr) = original_return_value; } break; case ZEND_UNSET_VAR: { diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 536e63f9c0..938b11e235 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -81,13 +81,9 @@ static void zend_extension_deactivator(zend_extension *extension) void init_executor(CLS_D ELS_DC) { - var_uninit(&EG(uninitialized_zval)); - var_uninit(&EG(error_zval)); - EG(uninitialized_zval).refcount = 1; - EG(uninitialized_zval).is_ref=0; + INIT_ZVAL(EG(uninitialized_zval)); + INIT_ZVAL(EG(error_zval)); EG(uninitialized_zval_ptr)=&EG(uninitialized_zval); - EG(error_zval).refcount = 1; - EG(error_zval).is_ref=0; EG(error_zval_ptr)=&EG(error_zval); zend_ptr_stack_init(&EG(arg_types_stack)); zend_stack_init(&EG(overloaded_objects_stack)); @@ -97,8 +93,15 @@ void init_executor(CLS_D ELS_DC) original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv); #endif #endif + /* EG(return_value) = &EG(global_return_value); var_reset(EG(return_value)); + */ + EG(return_value_ptr_ptr) = &EG(global_return_value); + EG(global_return_value) = emalloc(sizeof(zval)); + INIT_PZVAL(EG(global_return_value)); + var_reset(EG(global_return_value)); + EG(symtable_cache_ptr) = EG(symtable_cache)-1; EG(symtable_cache_limit)=EG(symtable_cache)+SYMTABLE_CACHE_SIZE-1; EG(no_extensions)=0; @@ -123,7 +126,8 @@ void init_executor(CLS_D ELS_DC) void shutdown_executor(ELS_D) { - zval_dtor(&EG(global_return_value)); + zval_ptr_dtor(&EG(global_return_value)); + /*zval_dtor(&EG(global_return_value));*/ zend_ptr_stack_destroy(&EG(arg_types_stack)); zend_stack_destroy(&EG(overloaded_objects_stack)); @@ -373,8 +377,8 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio if (object) { zval *dummy = (zval *) emalloc(sizeof(zval)), **this_ptr; - var_uninit(dummy); - INIT_PZVAL(dummy); + INIT_ZVAL(*dummy); + zend_hash_update_ptr(EG(active_symbol_table), "this", sizeof("this"), dummy, sizeof(zval *), (void **) &this_ptr); zend_assign_to_variable_reference(NULL, this_ptr, &object, NULL ELS_CC); } diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index f4b20ee875..2cd1009603 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -122,7 +122,7 @@ struct _zend_executor_globals { zend_function_state *function_state_ptr; zend_ptr_stack arg_types_stack; zend_stack overloaded_objects_stack; - zval global_return_value; + zval *global_return_value; /* symbol table cache */ HashTable *symtable_cache[SYMTABLE_CACHE_SIZE]; |