Hi,
The attached patch (for PHP_5_3) implements the segmented argument_stack
that has the following advantages:
1) It fixes #43426 and other crashes which occur because of stack
reallocation.
2) The whole stack is never reallocated. So we don't have penalties
because of the while stack copying (it may be 1MB and more).
3) CPU stack usage reduced, because execute_data, Ts and CVs now are
stored in the same argument_stack. As result the probability of CPU
stack overflow is reduced.
4) func_num_args(), func_get_agr(), func_get_args(),
debug_print_backtrace() and exception's backtrace now always able to get
arguments. They didn't work before in case of incomplete "arguments
frame". For example: "foo(1, func_num_args());".
5) bench.php got about 1% speedup
I'm going to commit the patch into HEAD and PHP_5_3 on Thursday.
Any objections?
Thanks. Dmitry.
Index: Zend/zend_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.296.2.27.2.34.2.15
diff -u -p -d -r1.296.2.27.2.34.2.15 zend_API.c
--- Zend/zend_API.c 31 Dec 2007 07:17:04 -0000 1.296.2.27.2.34.2.15
+++ Zend/zend_API.c 18 Jan 2008 14:04:43 -0000
@@ -43,7 +43,7 @@ ZEND_API int zend_get_parameters(int ht,
zval **param, *param_ptr;
TSRMLS_FETCH();
- p = EG(argument_stack).top_element-2;
+ p = zend_vm_stack_top(TSRMLS_C) - 1;
arg_count = (int)(zend_uintptr_t) *p;
if (param_count>arg_count) {
@@ -81,7 +81,7 @@ ZEND_API int _zend_get_parameters_array(
int arg_count;
zval *param_ptr;
- p = EG(argument_stack).top_element-2;
+ p = zend_vm_stack_top(TSRMLS_C) - 1;
arg_count = (int)(zend_uintptr_t) *p;
if (param_count>arg_count) {
@@ -119,7 +119,7 @@ ZEND_API int zend_get_parameters_ex(int
zval ***param;
TSRMLS_FETCH();
- p = EG(argument_stack).top_element-2;
+ p = zend_vm_stack_top(TSRMLS_C) - 1;
arg_count = (int)(zend_uintptr_t) *p;
if (param_count>arg_count) {
@@ -142,7 +142,7 @@ ZEND_API int _zend_get_parameters_array_
void **p;
int arg_count;
- p = EG(argument_stack).top_element-2;
+ p = zend_vm_stack_top(TSRMLS_C) - 1;
arg_count = (int)(zend_uintptr_t) *p;
if (param_count>arg_count) {
@@ -187,7 +187,7 @@ ZEND_API int zend_copy_parameters_array(
void **p;
int arg_count;
- p = EG(argument_stack).top_element-2;
+ p = zend_vm_stack_top(TSRMLS_C) - 1;
arg_count = (int)(zend_uintptr_t) *p;
if (param_count>arg_count) {
@@ -746,7 +746,7 @@ static int zend_parse_va_args(int num_ar
return FAILURE;
}
- arg_count = (int)(zend_uintptr_t) *(EG(argument_stack).top_element-2);
+ arg_count = (int)(zend_uintptr_t) *(zend_vm_stack_top(TSRMLS_C) - 1);
if (num_args > arg_count) {
zend_error(E_WARNING, "%s(): could not obtain parameters for
parsing",
@@ -770,7 +770,7 @@ static int zend_parse_va_args(int num_ar
if (num_varargs > 0) {
int iv = 0;
- zval **p = (zval **)
(EG(argument_stack).top_element - 2 - (arg_count - i));
+ zval **p = (zval **)
(zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - i));
*n_varargs = num_varargs;
@@ -790,7 +790,7 @@ static int zend_parse_va_args(int num_ar
}
}
- arg = (zval **) (EG(argument_stack).top_element - 2 -
(arg_count-i));
+ arg = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 -
(arg_count-i));
if (zend_parse_arg(i+1, arg, va, &type_spec, quiet TSRMLS_CC)
== FAILURE) {
/* clean up varargs array if it was used */
Index: Zend/zend_builtin_functions.c
===================================================================
RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v
retrieving revision 1.277.2.12.2.25.2.7
diff -u -p -d -r1.277.2.12.2.25.2.7 zend_builtin_functions.c
--- Zend/zend_builtin_functions.c 31 Dec 2007 07:17:04 -0000
1.277.2.12.2.25.2.7
+++ Zend/zend_builtin_functions.c 18 Jan 2008 14:04:43 -0000
@@ -171,18 +171,10 @@ ZEND_FUNCTION(zend_version)
Get the number of arguments that were passed to the function */
ZEND_FUNCTION(func_num_args)
{
- void **p;
- int arg_count;
+ zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
- p = EG(argument_stack).top_element-1-1;
- arg_count = (int)(zend_uintptr_t) *p; /* this is the amount
of arguments passed to func_num_args(); */
- p -= 1+arg_count;
- if (*p) {
- zend_error(E_ERROR, "func_num_args(): Can't be used as a
function parameter");
- }
- --p;
- if (p>=EG(argument_stack).elements) {
- RETURN_LONG((long)(zend_uintptr_t) *p);
+ if (ex && ex->function_state.arguments) {
+
RETURN_LONG((long)(zend_uintptr_t)*(ex->function_state.arguments));
} else {
zend_error(E_WARNING, "func_num_args(): Called from the global
scope - no function context");
RETURN_LONG(-1);
@@ -200,6 +192,7 @@ ZEND_FUNCTION(func_get_arg)
zval **z_requested_offset;
zval *arg;
long requested_offset;
+ zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1,
&z_requested_offset)==FAILURE) {
RETURN_FALSE;
@@ -212,20 +205,15 @@ ZEND_FUNCTION(func_get_arg)
RETURN_FALSE;
}
- p = EG(argument_stack).top_element-1-1;
- arg_count = (int)(zend_uintptr_t) *p; /* this is the amount
of arguments passed to func_get_arg(); */
- p -= 1+arg_count;
- if (*p) {
- zend_error(E_ERROR, "func_get_arg(): Can't be used as a
function parameter");
- }
- --p;
- if (p<EG(argument_stack).elements) {
+ if (!ex || !ex->function_state.arguments) {
zend_error(E_WARNING, "func_get_arg(): Called from the global
scope - no function context");
RETURN_FALSE;
}
- arg_count = (int)(zend_uintptr_t) *p;
- if (requested_offset>=arg_count) {
+ p = ex->function_state.arguments;
+ arg_count = (int)(zend_uintptr_t) *p; /* this is the amount
of arguments passed to func_get_arg(); */
+
+ if (requested_offset >= arg_count) {
zend_error(E_WARNING, "func_get_arg(): Argument %ld not passed
to function", requested_offset);
RETURN_FALSE;
}
@@ -245,21 +233,15 @@ ZEND_FUNCTION(func_get_args)
void **p;
int arg_count;
int i;
+ zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
- p = EG(argument_stack).top_element-1-1;
- arg_count = (int)(zend_uintptr_t) *p; /* this is the amount
of arguments passed to func_get_args(); */
- p -= 1+arg_count;
- if (*p) {
- zend_error(E_ERROR, "func_get_args(): Can't be used as a
function parameter");
- }
- --p;
-
- if (p<EG(argument_stack).elements) {
+ if (!ex || !ex->function_state.arguments) {
zend_error(E_WARNING, "func_get_args(): Called from the global
scope - no function context");
RETURN_FALSE;
}
- arg_count = (int)(zend_uintptr_t) *p;
+ p = ex->function_state.arguments;
+ arg_count = (int)(zend_uintptr_t) *p; /* this is the amount
of arguments passed to func_get_args(); */
array_init(return_value);
for (i=0; i<arg_count; i++) {
@@ -1684,14 +1666,12 @@ bad_module_id:
/* }}} */
-static zval *debug_backtrace_get_args(void ***curpos TSRMLS_DC)
+static zval *debug_backtrace_get_args(void **curpos TSRMLS_DC)
{
- void **p = *curpos - 2;
+ void **p = curpos;
zval *arg_array, **arg;
int arg_count = (int)(zend_uintptr_t) *p;
- *curpos -= (arg_count+2);
-
MAKE_STD_ZVAL(arg_array);
array_init(arg_array);
p -= arg_count;
@@ -1709,11 +1689,6 @@ static zval *debug_backtrace_get_args(vo
}
}
- /* skip args from incomplete frames */
- while ((((*curpos)-1) > EG(argument_stack).elements) && *((*curpos)-1))
{
- (*curpos)--;
- }
-
return arg_array;
}
@@ -1744,47 +1719,16 @@ ZEND_FUNCTION(debug_print_backtrace)
char *call_type;
char *include_filename = NULL;
zval *arg_array = NULL;
- void **cur_arg_pos = EG(argument_stack).top_element;
- void **args = cur_arg_pos;
- int arg_stack_consistent = 0;
- int frames_on_stack = 0;
int indent = 0;
if (ZEND_NUM_ARGS()) {
ZEND_WRONG_PARAM_COUNT();
}
- while (--args > EG(argument_stack).elements) {
- if (*args--) {
- break;
- }
- args -= *(ulong*)args;
- frames_on_stack++;
-
- /* skip args from incomplete frames */
- while (((args-1) > EG(argument_stack).elements) && *(args-1)) {
- args--;
- }
-
- if ((args-1) == EG(argument_stack).elements) {
- arg_stack_consistent = 1;
- break;
- }
- }
-
ptr = EG(current_execute_data);
/* skip debug_backtrace() */
ptr = ptr->prev_execute_data;
- cur_arg_pos -= 2;
- frames_on_stack--;
-
- if (arg_stack_consistent) {
- /* skip args from incomplete frames */
- while (((cur_arg_pos-1) > EG(argument_stack).elements) &&
*(cur_arg_pos-1)) {
- cur_arg_pos--;
- }
- }
while (ptr) {
char *free_class_name = NULL;
@@ -1800,7 +1744,7 @@ ZEND_FUNCTION(debug_print_backtrace)
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
skip->prev_execute_data->opline->opcode !=
ZEND_DO_FCALL_BY_NAME &&
skip->prev_execute_data->opline->opcode !=
ZEND_INCLUDE_OR_EVAL) {
- skip = skip->prev_execute_data;
+ skip = skip->prev_execute_data;
}
if (skip->op_array) {
@@ -1836,9 +1780,8 @@ ZEND_FUNCTION(debug_print_backtrace)
call_type = NULL;
}
if ((! ptr->opline) || ((ptr->opline->opcode ==
ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
- if (arg_stack_consistent && (frames_on_stack >
0)) {
- arg_array =
debug_backtrace_get_args(&cur_arg_pos TSRMLS_CC);
- frames_on_stack--;
+ if (ptr->function_state.arguments) {
+ arg_array =
debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC);
}
}
} else {
@@ -1933,28 +1876,6 @@ ZEND_API void zend_fetch_debug_backtrace
char *class_name;
char *include_filename = NULL;
zval *stack_frame;
- void **cur_arg_pos = EG(argument_stack).top_element;
- void **args = cur_arg_pos;
- int arg_stack_consistent = 0;
- int frames_on_stack = 0;
-
- while (--args > EG(argument_stack).elements) {
- if (*args--) {
- break;
- }
- args -= *(ulong*)args;
- frames_on_stack++;
-
- /* skip args from incomplete frames */
- while (((args-1) > EG(argument_stack).elements) && *(args-1)) {
- args--;
- }
-
- if ((args-1) == EG(argument_stack).elements) {
- arg_stack_consistent = 1;
- break;
- }
- }
ptr = EG(current_execute_data);
@@ -1965,17 +1886,7 @@ ZEND_API void zend_fetch_debug_backtrace
/* skip debug_backtrace() */
if (skip_last-- && ptr) {
- int arg_count = *((ulong*)(cur_arg_pos - 2));
- cur_arg_pos -= (arg_count + 2);
- frames_on_stack--;
ptr = ptr->prev_execute_data;
-
- if (arg_stack_consistent) {
- /* skip args from incomplete frames */
- while (((cur_arg_pos-1) > EG(argument_stack).elements)
&& *(cur_arg_pos-1)) {
- cur_arg_pos--;
- }
- }
}
array_init(return_value);
@@ -2050,9 +1961,8 @@ ZEND_API void zend_fetch_debug_backtrace
}
if ((! ptr->opline) || ((ptr->opline->opcode ==
ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
- if (arg_stack_consistent && (frames_on_stack >
0)) {
- add_assoc_zval_ex(stack_frame, "args",
sizeof("args"), debug_backtrace_get_args(&cur_arg_pos TSRMLS_CC));
- frames_on_stack--;
+ if (ptr->function_state.arguments) {
+ add_assoc_zval_ex(stack_frame, "args",
sizeof("args"), debug_backtrace_get_args(ptr->function_state.arguments
TSRMLS_CC));
}
}
} else {
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.316.2.8.2.12.2.12
diff -u -p -d -r1.316.2.8.2.12.2.12 zend_compile.h
--- Zend/zend_compile.h 31 Dec 2007 07:17:04 -0000 1.316.2.8.2.12.2.12
+++ Zend/zend_compile.h 18 Jan 2008 14:04:43 -0000
@@ -271,6 +271,7 @@ typedef union _zend_function {
typedef struct _zend_function_state {
zend_function *function;
+ void **arguments;
} zend_function_state;
@@ -299,7 +300,6 @@ struct _zend_execute_data {
union _temp_variable *Ts;
zval ***CVs;
zend_bool original_in_execution;
- ALLOCA_FLAG(use_heap)
HashTable *symbol_table;
struct _zend_execute_data *prev_execute_data;
zval *old_error_reporting;
Index: Zend/zend_execute.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute.c,v
retrieving revision 1.716.2.12.2.24.2.14
diff -u -p -d -r1.716.2.12.2.24.2.14 zend_execute.c
--- Zend/zend_execute.c 15 Jan 2008 11:52:44 -0000 1.716.2.12.2.24.2.14
+++ Zend/zend_execute.c 18 Jan 2008 14:04:44 -0000
@@ -1457,10 +1457,10 @@ ZEND_API void execute_internal(zend_exec
}
#define ZEND_VM_EXIT_FROM_EXECUTE_LOOP() \
- free_alloca(EX(CVs), EX(use_heap)); \
EG(in_execution) = EX(original_in_execution); \
EG(current_execute_data) = EX(prev_execute_data); \
- EG(opline_ptr) = NULL;
+ EG(opline_ptr) = NULL; \
+ zend_vm_stack_free(execute_data TSRMLS_CC);
#define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
ZEND_VM_EXIT_FROM_EXECUTE_LOOP() \
Index: Zend/zend_execute.h
===================================================================
RCS file: /repository/ZendEngine2/zend_execute.h,v
retrieving revision 1.84.2.4.2.8.2.2
diff -u -p -d -r1.84.2.4.2.8.2.2 zend_execute.h
--- Zend/zend_execute.h 31 Dec 2007 07:17:04 -0000 1.84.2.4.2.8.2.2
+++ Zend/zend_execute.h 18 Jan 2008 14:04:44 -0000
@@ -143,30 +143,158 @@ ZEND_API int zval_update_constant(zval *
ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry
*scope TSRMLS_DC);
/* dedicated Zend executor functions - do not use! */
-static inline void zend_ptr_stack_clear_multiple(TSRMLS_D)
+#define ZEND_VM_STACK_PAGE_SIZE (64 * 1024)
+
+struct _zend_vm_stack {
+ void **top;
+ void **end;
+ zend_vm_stack prev;
+ void *elements[1];
+};
+
+#define ZEND_VM_STACK_GROW_IF_NEEDED(count)
\
+ do {
\
+ if (UNEXPECTED(count > \
+ EG(argument_stack)->end - EG(argument_stack)->top)) {
\
+ zend_vm_stack_extend(count TSRMLS_CC);
\
+ }
\
+ } while (0)
+
+static inline zend_vm_stack zend_vm_stack_new_page(int count) {
+ zend_vm_stack page =
emalloc(sizeof(*page)+sizeof(page->elements[0])*(count-1));
+
+ page->top = page->elements;
+ page->end = page->elements + count;
+ page->prev = NULL;
+ return page;
+}
+
+static inline void zend_vm_stack_init(TSRMLS_D)
{
- void **p = EG(argument_stack).top_element-2;
+ EG(argument_stack) = zend_vm_stack_new_page(ZEND_VM_STACK_PAGE_SIZE);
+}
+
+static inline void zend_vm_stack_destroy(TSRMLS_D)
+{
+ zend_vm_stack stack = EG(argument_stack);
+
+ while (stack != NULL) {
+ zend_vm_stack p = stack->prev;
+ efree(stack);
+ stack = p;
+ }
+}
+
+static inline void zend_vm_stack_extend(int count TSRMLS_DC)
+{
+ zend_vm_stack p = zend_vm_stack_new_page(count >=
ZEND_VM_STACK_PAGE_SIZE ? count : ZEND_VM_STACK_PAGE_SIZE);
+ p->prev = EG(argument_stack);
+ EG(argument_stack) = p;
+}
+
+static inline void **zend_vm_stack_top(TSRMLS_D)
+{
+ return EG(argument_stack)->top;
+}
+
+static inline void zend_vm_stack_push(void *ptr TSRMLS_DC)
+{
+ ZEND_VM_STACK_GROW_IF_NEEDED(1);
+ *(EG(argument_stack)->top++) = ptr;
+}
+
+static inline void zend_vm_stack_push_nocheck(void *ptr TSRMLS_DC)
+{
+ *(EG(argument_stack)->top++) = ptr;
+}
+
+static inline void *zend_vm_stack_pop(TSRMLS_D)
+{
+ void *el = *(--EG(argument_stack)->top);
+
+ if (UNEXPECTED(EG(argument_stack)->top ==
EG(argument_stack)->elements)) {
+ zend_vm_stack p = EG(argument_stack);
+ EG(argument_stack) = p->prev;
+ efree(p);
+ }
+ return el;
+}
+
+static inline void *zend_vm_stack_alloc(size_t size TSRMLS_DC)
+{
+ void *ret;
+
+ size = (size + (sizeof(void*) - 1)) / sizeof(void*);
+
+ ZEND_VM_STACK_GROW_IF_NEEDED(size);
+ ret = EG(argument_stack)->top;
+ EG(argument_stack)->top += size;
+ return ret;
+}
+
+static inline void zend_vm_stack_free(void *ptr TSRMLS_DC)
+{
+ if (UNEXPECTED(EG(argument_stack)->elements == ptr)) {
+ zend_vm_stack p = EG(argument_stack);
+
+ EG(argument_stack) = p->prev;
+ efree(p);
+ } else {
+ EG(argument_stack)->top = ptr;
+ }
+}
+
+static inline void** zend_vm_stack_push_args(int count TSRMLS_DC)
+{
+
+ if (UNEXPECTED(EG(argument_stack)->top - EG(argument_stack)->elements <
count) ||
+ UNEXPECTED(EG(argument_stack)->top == EG(argument_stack)->end))
{
+ zend_vm_stack p = EG(argument_stack);
+
+ zend_vm_stack_extend(count + 1 TSRMLS_CC);
+
+ EG(argument_stack)->top += count;
+ *(EG(argument_stack)->top) = (void*)(zend_uintptr_t)count;
+ while (count-- > 0) {
+ void *data = *(--p->top);
+
+ if (UNEXPECTED(p->top == p->elements)) {
+ zend_vm_stack r = p;
+
+ EG(argument_stack)->prev = p->prev;
+ p = p->prev;
+ efree(r);
+ }
+ *(EG(argument_stack)->elements + count) = data;
+ }
+ return EG(argument_stack)->top++;
+ }
+ *(EG(argument_stack)->top) = (void*)(zend_uintptr_t)count;
+ return EG(argument_stack)->top++;
+}
+
+static inline void zend_vm_stack_clear_multiple(TSRMLS_D)
+{
+ void **p = EG(argument_stack)->top - 1;
int delete_count = (int)(zend_uintptr_t) *p;
- EG(argument_stack).top -= (delete_count+2);
while (--delete_count>=0) {
zval *q = *(zval **)(--p);
*p = NULL;
zval_ptr_dtor(&q);
}
- EG(argument_stack).top_element = p;
+ zend_vm_stack_free(p TSRMLS_CC);
}
-static inline int zend_ptr_stack_get_arg(int requested_arg, void **data
TSRMLS_DC)
+static inline zval** zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
{
- void **p = EG(argument_stack).top_element-2;
+ void **p =
EG(current_execute_data)->prev_execute_data->function_state.arguments;
int arg_count = (int)(zend_uintptr_t) *p;
- if (requested_arg>arg_count) {
- return FAILURE;
+ if (UNEXPECTED(requested_arg > arg_count)) {
+ return NULL;
}
- *data = (p-arg_count+requested_arg-1);
- return SUCCESS;
+ return (zval**)p - arg_count + requested_arg - 1;
}
void execute_new_code(TSRMLS_D);
Index: Zend/zend_execute_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute_API.c,v
retrieving revision 1.331.2.20.2.24.2.19
diff -u -p -d -r1.331.2.20.2.24.2.19 zend_execute_API.c
--- Zend/zend_execute_API.c 15 Jan 2008 11:47:05 -0000
1.331.2.20.2.24.2.19
+++ Zend/zend_execute_API.c 18 Jan 2008 14:04:44 -0000
@@ -146,8 +146,8 @@ void init_executor(TSRMLS_D) /* {{{ */
EG(in_autoload) = NULL;
EG(autoload_func) = NULL;
- zend_ptr_stack_init(&EG(argument_stack));
- zend_ptr_stack_push(&EG(argument_stack), (void *) NULL);
+ zend_vm_stack_init(TSRMLS_C);
+ zend_vm_stack_push((void *) NULL TSRMLS_CC);
zend_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0);
{
@@ -287,7 +287,7 @@ void shutdown_executor(TSRMLS_D) /* {{{
}
zend_hash_apply(EG(class_table), (apply_func_t)
zend_cleanup_class_data TSRMLS_CC);
- zend_ptr_stack_destroy(&EG(argument_stack));
+ zend_vm_stack_destroy(TSRMLS_C);
/* Destroy all op arrays */
if (EG(full_tables_cleanup)) {
@@ -939,6 +939,12 @@ int zend_call_function(zend_fcall_info *
}
}
+ if (call_via_handler) {
+ ZEND_VM_STACK_GROW_IF_NEEDED(2 + 1);
+ } else {
+ ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1);
+ }
+
for (i=0; i<fci->param_count; i++) {
zval *param;
@@ -951,8 +957,8 @@ int zend_call_function(zend_fcall_info *
if (fci->no_separation) {
if(i) {
/* hack to clean up the stack */
-
zend_ptr_stack_n_push(&EG(argument_stack), 2, (void *) (zend_uintptr_t) i,
NULL);
-
zend_ptr_stack_clear_multiple(TSRMLS_C);
+
zend_vm_stack_push_nocheck((void *) (zend_uintptr_t)i TSRMLS_CC);
+
zend_vm_stack_clear_multiple(TSRMLS_C);
}
if (call_via_handler) {
@@ -988,17 +994,18 @@ int zend_call_function(zend_fcall_info *
if (call_via_handler) {
add_next_index_zval(params_array, param);
} else {
- zend_ptr_stack_push(&EG(argument_stack), param);
+ zend_vm_stack_push_nocheck(param TSRMLS_CC);
}
}
if (call_via_handler) {
- zend_ptr_stack_push(&EG(argument_stack), method_name);
- zend_ptr_stack_push(&EG(argument_stack), params_array);
+ zend_vm_stack_push_nocheck(method_name TSRMLS_CC);
+ zend_vm_stack_push_nocheck(params_array TSRMLS_CC);
fci->param_count = 2;
}
- zend_ptr_stack_2_push(&EG(argument_stack), (void *) (zend_uintptr_t)
fci->param_count, NULL);
+ EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
+ zend_vm_stack_push_nocheck((void*)(zend_uintptr_t)fci->param_count
TSRMLS_CC);
current_scope = EG(scope);
EG(scope) = calling_scope;
@@ -1087,7 +1094,7 @@ int zend_call_function(zend_fcall_info *
*fci->retval_ptr_ptr = NULL;
}
}
- zend_ptr_stack_clear_multiple(TSRMLS_C);
+ zend_vm_stack_clear_multiple(TSRMLS_C);
if (call_via_handler) {
zval_ptr_dtor(&method_name);
zval_ptr_dtor(¶ms_array);
Index: Zend/zend_globals.h
===================================================================
RCS file: /repository/ZendEngine2/zend_globals.h,v
retrieving revision 1.141.2.3.2.7.2.5
diff -u -p -d -r1.141.2.3.2.7.2.5 zend_globals.h
--- Zend/zend_globals.h 31 Dec 2007 07:17:04 -0000 1.141.2.3.2.7.2.5
+++ Zend/zend_globals.h 18 Jan 2008 14:04:44 -0000
@@ -64,6 +64,7 @@ typedef struct _zend_declarables {
zval ticks;
} zend_declarables;
+typedef struct _zend_vm_stack *zend_vm_stack;
struct _zend_compiler_globals {
zend_stack bp_stack;
@@ -213,7 +214,7 @@ struct _zend_executor_globals {
HashTable regular_list;
HashTable persistent_list;
- zend_ptr_stack argument_stack;
+ zend_vm_stack argument_stack;
int user_error_handler_error_reporting;
zval *user_error_handler;
Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.59.2.29.2.48.2.27
diff -u -p -d -r1.59.2.29.2.48.2.27 zend_vm_def.h
--- Zend/zend_vm_def.h 11 Jan 2008 10:08:49 -0000 1.59.2.29.2.48.2.27
+++ Zend/zend_vm_def.h 18 Jan 2008 14:04:44 -0000
@@ -2028,7 +2028,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_help
}
zend_ptr_stack_3_pop(&EG(arg_types_stack), (void*)&EX(called_scope),
(void**)&ex_object, (void**)&EX(fbc));
- zend_ptr_stack_2_push(&EG(argument_stack), (void
*)(zend_uintptr_t)opline->extended_value, NULL);
+ EX(function_state).arguments =
zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
EX_T(opline->result.u.var).var.ptr_ptr =
&EX_T(opline->result.u.var).var.ptr;
@@ -2038,11 +2038,8 @@ ZEND_VM_HELPER(zend_do_fcall_common_help
if (EX(function_state).function->common.arg_info) {
zend_uint i=0;
- zval **p;
- ulong arg_count;
-
- p = (zval **) EG(argument_stack).top_element-2;
- arg_count = (ulong)(zend_uintptr_t) *p;
+ zval **p = (zval**)EX(function_state).arguments;
+ ulong arg_count = opline->extended_value;
while (arg_count>0) {
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count), 0
TSRMLS_CC);
@@ -2130,6 +2127,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_help
}
EX(function_state).function = (zend_function *) EX(op_array);
+ EX(function_state).arguments = NULL;
if (EG(This)) {
if (EG(exception) && IS_CTOR_CALL(EX(called_scope))) {
@@ -2154,7 +2152,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_help
EG(called_scope) = current_called_scope;
}
- zend_ptr_stack_clear_multiple(TSRMLS_C);
+ zend_vm_stack_clear_multiple(TSRMLS_C);
if (EG(exception)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
@@ -2346,7 +2344,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST
if (!IS_OP1_TMP_FREE()) {
zval_copy_ctor(valptr);
}
- zend_ptr_stack_push(&EG(argument_stack), valptr);
+ zend_vm_stack_push(valptr TSRMLS_CC);
FREE_OP1_IF_VAR();
}
ZEND_VM_NEXT_OPCODE();
@@ -2373,7 +2371,7 @@ ZEND_VM_HELPER(zend_send_by_var_helper,
zval_copy_ctor(varptr);
}
Z_ADDREF_P(varptr);
- zend_ptr_stack_push(&EG(argument_stack), varptr);
+ zend_vm_stack_push(varptr TSRMLS_CC);
FREE_OP1(); /* for string offsets */
ZEND_VM_NEXT_OPCODE();
@@ -2409,7 +2407,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_RE
(Z_REFCOUNT_P(varptr) == 1 && (OP1_TYPE == IS_CV ||
free_op1.var)))) {
Z_SET_ISREF_P(varptr);
Z_ADDREF_P(varptr);
- zend_ptr_stack_push(&EG(argument_stack), varptr);
+ zend_vm_stack_push(varptr TSRMLS_CC);
} else {
zval *valptr;
@@ -2419,7 +2417,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_RE
if (!IS_OP1_TMP_FREE()) {
zval_copy_ctor(valptr);
}
- zend_ptr_stack_push(&EG(argument_stack), valptr);
+ zend_vm_stack_push(valptr TSRMLS_CC);
}
FREE_OP1_IF_VAR();
ZEND_VM_NEXT_OPCODE();
@@ -2440,7 +2438,7 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|C
SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
varptr = *varptr_ptr;
Z_ADDREF_P(varptr);
- zend_ptr_stack_push(&EG(argument_stack), varptr);
+ zend_vm_stack_push(varptr TSRMLS_CC);
FREE_OP1_VAR_PTR();
ZEND_VM_NEXT_OPCODE();
@@ -2460,10 +2458,10 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|C
ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
{
zend_op *opline = EX(opline);
- zval **param;
zend_uint arg_num = Z_LVAL(opline->op1.u.constant);
+ zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
- if (zend_ptr_stack_get_arg(arg_num, (void **) ¶m
TSRMLS_CC)==FAILURE) {
+ if (param == NULL) {
char *space;
char *class_name = get_active_class_name(&space TSRMLS_CC);
zend_execute_data *ptr = EX(prev_execute_data);
@@ -2497,11 +2495,12 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
{
zend_op *opline = EX(opline);
- zval **param, *assignment_value, **var_ptr;
+ zval *assignment_value, **var_ptr;
zend_uint arg_num = Z_LVAL(opline->op1.u.constant);
zend_free_op free_res;
+ zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
- if (zend_ptr_stack_get_arg(arg_num, (void **) ¶m
TSRMLS_CC)==FAILURE) {
+ if (param == NULL) {
if ((Z_TYPE(opline->op2.u.constant) & IS_CONSTANT_TYPE_MASK) ==
IS_CONSTANT || Z_TYPE(opline->op2.u.constant)==IS_CONSTANT_ARRAY) {
zval *default_value;
@@ -3943,15 +3942,16 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTI
int i;
zend_uint catch_op_num;
int catched = 0;
- zval **stack_zval_pp;
zval restored_error_reporting;
+
+ void **stack_frame = (void**)execute_data +
+ (sizeof(zend_execute_data) +
+ sizeof(zval**) * EX(op_array)->last_var +
+ sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*);
- stack_zval_pp = (zval **) EG(argument_stack).top_element - 1;
- while (*stack_zval_pp != NULL) {
- zval_ptr_dtor(stack_zval_pp);
- EG(argument_stack).top_element--;
- EG(argument_stack).top--;
- stack_zval_pp--;
+ while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
+ zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
+ zval_ptr_dtor(&stack_zval_p);
}
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
Index: Zend/zend_vm_execute.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_execute.h,v
retrieving revision 1.62.2.30.2.49.2.28
diff -u -p -d -r1.62.2.30.2.49.2.28 zend_vm_execute.h
--- Zend/zend_vm_execute.h 11 Jan 2008 10:08:49 -0000
1.62.2.30.2.49.2.28
+++ Zend/zend_vm_execute.h 18 Jan 2008 14:04:44 -0000
@@ -30,10 +30,13 @@ static opcode_handler_t zend_vm_get_opco
#define ZEND_VM_DISPATCH(opcode, opline) return
zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC
+#undef EX
+#define EX(element) execute_data->element
+
ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
{
- zend_execute_data execute_data;
+ zend_execute_data *execute_data;
if (EG(exception)) {
@@ -41,23 +44,23 @@ ZEND_API void execute(zend_op_array *op_
}
/* Initialize execute_data */
+ execute_data = (zend_execute_data *)zend_vm_stack_alloc(
+ sizeof(zend_execute_data) +
+ sizeof(zval**) * op_array->last_var +
+ sizeof(temp_variable) * op_array->T TSRMLS_CC);
+
+ EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data));
+ memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
+ EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var);
EX(fbc) = NULL;
EX(called_scope) = NULL;
EX(object) = NULL;
EX(old_error_reporting) = NULL;
- if (EXPECTED(op_array->T < TEMP_VAR_STACK_LIMIT && op_array->last_var <
TEMP_VAR_STACK_LIMIT)) {
- EX(CVs) = (zval***)do_alloca(sizeof(zval**) *
op_array->last_var + sizeof(temp_variable) * op_array->T, EX(use_heap));
- } else {
- SET_ALLOCA_FLAG(EX(use_heap));
- EX(CVs) = (zval***)safe_emalloc(sizeof(temp_variable),
op_array->T, sizeof(zval**) * op_array->last_var);
- }
- EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var);
- memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
EX(op_array) = op_array;
EX(original_in_execution) = EG(in_execution);
EX(symbol_table) = EG(active_symbol_table);
EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = &execute_data;
+ EG(current_execute_data) = execute_data;
EG(in_execution) = 1;
if (op_array->start_op) {
@@ -76,6 +79,7 @@ ZEND_API void execute(zend_op_array *op_
EG(opline_ptr) = &EX(opline);
EX(function_state).function = (zend_function *) op_array;
+ EX(function_state).arguments = NULL;
while (1) {
#ifdef ZEND_WIN32
@@ -84,7 +88,7 @@ ZEND_API void execute(zend_op_array *op_
}
#endif
- if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0) {
+ if (EX(opline)->handler(execute_data TSRMLS_CC) > 0) {
return;
}
@@ -92,9 +96,6 @@ ZEND_API void execute(zend_op_array *op_
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which
shouldn't happen");
}
-#undef EX
-#define EX(element) execute_data->element
-
static int ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
#if DEBUG_ZEND>=2
@@ -165,7 +166,7 @@ static int zend_do_fcall_common_helper_S
}
zend_ptr_stack_3_pop(&EG(arg_types_stack), (void*)&EX(called_scope),
(void**)&ex_object, (void**)&EX(fbc));
- zend_ptr_stack_2_push(&EG(argument_stack), (void
*)(zend_uintptr_t)opline->extended_value, NULL);
+ EX(function_state).arguments =
zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
EX_T(opline->result.u.var).var.ptr_ptr =
&EX_T(opline->result.u.var).var.ptr;
@@ -175,11 +176,8 @@ static int zend_do_fcall_common_helper_S
if (EX(function_state).function->common.arg_info) {
zend_uint i=0;
- zval **p;
- ulong arg_count;
-
- p = (zval **) EG(argument_stack).top_element-2;
- arg_count = (ulong)(zend_uintptr_t) *p;
+ zval **p = (zval**)EX(function_state).arguments;
+ ulong arg_count = opline->extended_value;
while (arg_count>0) {
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count), 0
TSRMLS_CC);
@@ -267,6 +265,7 @@ static int zend_do_fcall_common_helper_S
}
EX(function_state).function = (zend_function *) EX(op_array);
+ EX(function_state).arguments = NULL;
if (EG(This)) {
if (EG(exception) && IS_CTOR_CALL(EX(called_scope))) {
@@ -291,7 +290,7 @@ static int zend_do_fcall_common_helper_S
EG(called_scope) = current_called_scope;
}
- zend_ptr_stack_clear_multiple(TSRMLS_C);
+ zend_vm_stack_clear_multiple(TSRMLS_C);
if (EG(exception)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
@@ -340,10 +339,10 @@ static int ZEND_CATCH_SPEC_HANDLER(ZEND_
static int ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
- zval **param;
zend_uint arg_num = Z_LVAL(opline->op1.u.constant);
+ zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
- if (zend_ptr_stack_get_arg(arg_num, (void **) ¶m
TSRMLS_CC)==FAILURE) {
+ if (param == NULL) {
char *space;
char *class_name = get_active_class_name(&space TSRMLS_CC);
zend_execute_data *ptr = EX(prev_execute_data);
@@ -519,15 +518,16 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HA
int i;
zend_uint catch_op_num;
int catched = 0;
- zval **stack_zval_pp;
zval restored_error_reporting;
- stack_zval_pp = (zval **) EG(argument_stack).top_element - 1;
- while (*stack_zval_pp != NULL) {
- zval_ptr_dtor(stack_zval_pp);
- EG(argument_stack).top_element--;
- EG(argument_stack).top--;
- stack_zval_pp--;
+ void **stack_frame = (void**)execute_data +
+ (sizeof(zend_execute_data) +
+ sizeof(zval**) * EX(op_array)->last_var +
+ sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*);
+
+ while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
+ zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
+ zval_ptr_dtor(&stack_zval_p);
}
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
@@ -715,11 +715,12 @@ static int ZEND_INIT_NS_FCALL_BY_NAME_SP
static int ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
- zval **param, *assignment_value, **var_ptr;
+ zval *assignment_value, **var_ptr;
zend_uint arg_num = Z_LVAL(opline->op1.u.constant);
zend_free_op free_res;
+ zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
- if (zend_ptr_stack_get_arg(arg_num, (void **) ¶m
TSRMLS_CC)==FAILURE) {
+ if (param == NULL) {
if ((Z_TYPE(opline->op2.u.constant) & IS_CONSTANT_TYPE_MASK) ==
IS_CONSTANT || Z_TYPE(opline->op2.u.constant)==IS_CONSTANT_ARRAY) {
zval *default_value;
@@ -1521,7 +1522,7 @@ static int ZEND_SEND_VAL_SPEC_CONST_HAND
if (!0) {
zval_copy_ctor(valptr);
}
- zend_ptr_stack_push(&EG(argument_stack), valptr);
+ zend_vm_stack_push(valptr TSRMLS_CC);
}
ZEND_VM_NEXT_OPCODE();
@@ -4618,7 +4619,7 @@ static int ZEND_SEND_VAL_SPEC_TMP_HANDLE
if (!1) {
zval_copy_ctor(valptr);
}
- zend_ptr_stack_push(&EG(argument_stack), valptr);
+ zend_vm_stack_push(valptr TSRMLS_CC);
}
ZEND_VM_NEXT_OPCODE();
@@ -7690,7 +7691,7 @@ static int ZEND_SEND_VAL_SPEC_VAR_HANDLE
if (!0) {
zval_copy_ctor(valptr);
}
- zend_ptr_stack_push(&EG(argument_stack), valptr);
+ zend_vm_stack_push(valptr TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
ZEND_VM_NEXT_OPCODE();
@@ -7717,7 +7718,7 @@ static int zend_send_by_var_helper_SPEC_
zval_copy_ctor(varptr);
}
Z_ADDREF_P(varptr);
- zend_ptr_stack_push(&EG(argument_stack), varptr);
+ zend_vm_stack_push(varptr TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; /* for string
offsets */
ZEND_VM_NEXT_OPCODE();
@@ -7753,7 +7754,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_VAR
(Z_REFCOUNT_P(varptr) == 1 && (IS_VAR == IS_CV || free_op1.var))))
{
Z_SET_ISREF_P(varptr);
Z_ADDREF_P(varptr);
- zend_ptr_stack_push(&EG(argument_stack), varptr);
+ zend_vm_stack_push(varptr TSRMLS_CC);
} else {
zval *valptr;
@@ -7763,7 +7764,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_VAR
if (!0) {
zval_copy_ctor(valptr);
}
- zend_ptr_stack_push(&EG(argument_stack), valptr);
+ zend_vm_stack_push(valptr TSRMLS_CC);
}
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
ZEND_VM_NEXT_OPCODE();
@@ -7784,7 +7785,7 @@ static int ZEND_SEND_REF_SPEC_VAR_HANDLE
SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
varptr = *varptr_ptr;
Z_ADDREF_P(varptr);
- zend_ptr_stack_push(&EG(argument_stack), varptr);
+ zend_vm_stack_push(varptr TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
ZEND_VM_NEXT_OPCODE();
@@ -20885,7 +20886,7 @@ static int ZEND_SEND_VAL_SPEC_CV_HANDLER
if (!0) {
zval_copy_ctor(valptr);
}
- zend_ptr_stack_push(&EG(argument_stack), valptr);
+ zend_vm_stack_push(valptr TSRMLS_CC);
}
ZEND_VM_NEXT_OPCODE();
@@ -20912,7 +20913,7 @@ static int zend_send_by_var_helper_SPEC_
zval_copy_ctor(varptr);
}
Z_ADDREF_P(varptr);
- zend_ptr_stack_push(&EG(argument_stack), varptr);
+ zend_vm_stack_push(varptr TSRMLS_CC);
; /* for string offsets */
ZEND_VM_NEXT_OPCODE();
@@ -20948,7 +20949,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_CV_
(Z_REFCOUNT_P(varptr) == 1 && (IS_CV == IS_CV || free_op1.var)))) {
Z_SET_ISREF_P(varptr);
Z_ADDREF_P(varptr);
- zend_ptr_stack_push(&EG(argument_stack), varptr);
+ zend_vm_stack_push(varptr TSRMLS_CC);
} else {
zval *valptr;
@@ -20958,7 +20959,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_CV_
if (!0) {
zval_copy_ctor(valptr);
}
- zend_ptr_stack_push(&EG(argument_stack), valptr);
+ zend_vm_stack_push(valptr TSRMLS_CC);
}
ZEND_VM_NEXT_OPCODE();
@@ -20979,7 +20980,7 @@ static int ZEND_SEND_REF_SPEC_CV_HANDLER
SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
varptr = *varptr_ptr;
Z_ADDREF_P(varptr);
- zend_ptr_stack_push(&EG(argument_stack), varptr);
+ zend_vm_stack_push(varptr TSRMLS_CC);
ZEND_VM_NEXT_OPCODE();
}
Index: Zend/zend_vm_execute.skl
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_execute.skl,v
retrieving revision 1.2.2.2.2.1.2.5
diff -u -p -d -r1.2.2.2.2.1.2.5 zend_vm_execute.skl
--- Zend/zend_vm_execute.skl 23 Nov 2007 15:03:03 -0000 1.2.2.2.2.1.2.5
+++ Zend/zend_vm_execute.skl 18 Jan 2008 14:04:44 -0000
@@ -2,7 +2,7 @@
ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
{
- zend_execute_data execute_data;
+ zend_execute_data *execute_data;
{%HELPER_VARS%}
{%INTERNAL_LABELS%}
@@ -12,23 +12,23 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_
}
/* Initialize execute_data */
+ execute_data = (zend_execute_data *)zend_vm_stack_alloc(
+ sizeof(zend_execute_data) +
+ sizeof(zval**) * op_array->last_var +
+ sizeof(temp_variable) * op_array->T TSRMLS_CC);
+
+ EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data));
+ memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
+ EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var);
EX(fbc) = NULL;
EX(called_scope) = NULL;
EX(object) = NULL;
EX(old_error_reporting) = NULL;
- if (EXPECTED(op_array->T < TEMP_VAR_STACK_LIMIT && op_array->last_var <
TEMP_VAR_STACK_LIMIT)) {
- EX(CVs) = (zval***)do_alloca(sizeof(zval**) *
op_array->last_var + sizeof(temp_variable) * op_array->T, EX(use_heap));
- } else {
- SET_ALLOCA_FLAG(EX(use_heap));
- EX(CVs) = (zval***)safe_emalloc(sizeof(temp_variable),
op_array->T, sizeof(zval**) * op_array->last_var);
- }
- EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var);
- memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
EX(op_array) = op_array;
EX(original_in_execution) = EG(in_execution);
EX(symbol_table) = EG(active_symbol_table);
EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = &execute_data;
+ EG(current_execute_data) = execute_data;
EG(in_execution) = 1;
if (op_array->start_op) {
@@ -47,6 +47,7 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_
EG(opline_ptr) = &EX(opline);
EX(function_state).function = (zend_function *) op_array;
+ EX(function_state).arguments = NULL;
while (1) {
{%ZEND_VM_CONTINUE_LABEL%}
Index: Zend/zend_vm_gen.php
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_gen.php,v
retrieving revision 1.12.2.5.2.4.2.1
diff -u -p -d -r1.12.2.5.2.4.2.1 zend_vm_gen.php
--- Zend/zend_vm_gen.php 31 Dec 2007 07:24:44 -0000 1.12.2.5.2.4.2.1
+++ Zend/zend_vm_gen.php 18 Jan 2008 14:04:44 -0000
@@ -404,7 +404,7 @@ function gen_code($f, $spec, $kind, $cod
"/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/me",
),
array(
- "&execute_data",
+ "execute_data",
"goto
\\1".($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."_LABEL",
"'goto
'.helper_name('\\1',$spec,'$op1','$op2')",
"'\\2 = \\3; goto
'.helper_name('\\1',$spec,'$op1','$op2').';'",
@@ -420,7 +420,7 @@ function gen_code($f, $spec, $kind, $cod
"/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/me",
),
array(
- "&execute_data",
+ "execute_data",
"goto
\\1".($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."_HANDLER",
"'goto
'.helper_name('\\1',$spec,'$op1','$op2')",
"'\\2 = \\3; goto
'.helper_name('\\1',$spec,'$op1','$op2').';'",
@@ -801,20 +801,26 @@ function gen_executor($f, $skl, $spec, $
out($f,"#define
ZEND_VM_RETURN() return 1\n");
out($f,"#define
ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode,
opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n");
out($f,"#define
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
+ out($f,"#undef EX\n");
+ out($f,"#define
EX(element) execute_data->element\n\n");
break;
case ZEND_VM_KIND_SWITCH:
out($f,"\n");
out($f,"#define
ZEND_VM_CONTINUE() goto zend_vm_continue\n");
out($f,"#define
ZEND_VM_RETURN() return\n");
out($f,"#define
ZEND_VM_DISPATCH(opcode, opline) dispatch_handler =
zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n\n");
- out($f,"#define
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL &execute_data TSRMLS_CC\n");
+ out($f,"#define
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
+ out($f,"#undef EX\n");
+ out($f,"#define
EX(element) execute_data->element\n\n");
break;
case ZEND_VM_KIND_GOTO:
out($f,"\n");
out($f,"#define
ZEND_VM_CONTINUE() goto *(void**)(EX(opline)->handler)\n");
out($f,"#define
ZEND_VM_RETURN() return\n");
out($f,"#define
ZEND_VM_DISPATCH(opcode, opline) goto
*(void**)(zend_vm_get_opcode_handler(opcode, opline));\n\n");
- out($f,"#define
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL &execute_data TSRMLS_CC\n");
+ out($f,"#define
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
+ out($f,"#undef EX\n");
+ out($f,"#define
EX(element) execute_data->element\n\n");
break;
}
break;
@@ -862,7 +868,7 @@ function gen_executor($f, $skl, $spec, $
// Emit code that dispatches to opcode handler
switch ($kind) {
case ZEND_VM_KIND_CALL:
- out($f, $m[1]."if
(EX(opline)->handler(&execute_data TSRMLS_CC) > 0)".$m[3]."\n");
+ out($f, $m[1]."if
(EX(opline)->handler(execute_data TSRMLS_CC) > 0)".$m[3]."\n");
break;
case ZEND_VM_KIND_SWITCH:
out($f,
$m[1]."dispatch_handler =
EX(opline)->handler;\nzend_vm_dispatch:\n".$m[1]."switch
((int)dispatch_handler)".$m[3]."\n");
@@ -886,9 +892,7 @@ function gen_executor($f, $skl, $spec, $
// Unspecialized executor with CALL
threading is the same as the
// old one, so we don't need to
produce code twitch
if (!$old || ZEND_VM_SPEC ||
(ZEND_VM_KIND != ZEND_VM_KIND_CALL)) {
- out($f,"#undef EX\n");
- out($f,"#define
EX(element) execute_data->element\n\n");
- // Emit executor code
+ // Emit executor code
gen_executor_code($f,
$spec, $kind, $m[1]);
}
}
Index: Zend/tests/bug41209.phpt
===================================================================
RCS file: /repository/ZendEngine2/tests/bug41209.phpt,v
retrieving revision 1.1.2.2
diff -u -p -d -r1.1.2.2 bug41209.phpt
--- Zend/tests/bug41209.phpt 27 Apr 2007 08:12:24 -0000 1.1.2.2
+++ Zend/tests/bug41209.phpt 18 Jan 2008 14:04:44 -0000
@@ -41,6 +41,6 @@ echo "Done\n";
--EXPECTF--
Fatal error: Uncaught exception 'ErrorException' with message 'Undefined
variable: id' in %s:%d
Stack trace:
-#0 %s(%d): env::errorHandler()
+#0 %s(%d): env::errorHandler(8, '%s', '%s', 34, Array)
#1 {main}
thrown in %s on line %d
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php