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(&params_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 **) &param 
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 **) &param 
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 **) &param 
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 **) &param 
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

Reply via email to