summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend.c9
-rw-r--r--Zend/zend.h4
-rw-r--r--Zend/zend_compile.c3
-rw-r--r--Zend/zend_execute.c40
-rw-r--r--Zend/zend_execute_API.c22
-rw-r--r--Zend/zend_globals.h2
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];