]> granicus.if.org Git - php/commitdiff
Changed EG(argument_stack) implementation.
authorDmitry Stogov <dmitry@php.net>
Thu, 24 Jan 2008 09:41:48 +0000 (09:41 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 24 Jan 2008 09:41:48 +0000 (09:41 +0000)
12 files changed:
Zend/tests/bug41209.phpt
Zend/zend_API.c
Zend/zend_builtin_functions.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_execute.h
Zend/zend_execute_API.c
Zend/zend_globals.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_execute.skl
Zend/zend_vm_gen.php

index 0834b376b221867899d59d3435b6c8f221f3315b..5498ede02005231255bd3a5559b00f89a7debfe1 100644 (file)
@@ -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
index a5f24cf6d1c4fc5e9e26ea18d0256b89575b65b2..0e86be5d7e9f92ec3b5c23f789163a9e9af7d1a1 100644 (file)
@@ -43,7 +43,7 @@ ZEND_API int zend_get_parameters(int ht, int param_count, ...) /* {{{ */
        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 ht, int param_count, zval **argument
        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 param_count, ...) /* {{{ */
        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_ex(int param_count, zval ***argument_arr
        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) {
@@ -165,7 +165,7 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TS
        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) {
@@ -963,7 +963,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl
                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, "%v(): could not obtain parameters for parsing",
@@ -976,7 +976,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl
                for (spec_walk = type_spec, i = 0; *spec_walk && i < num_args; spec_walk++) {
                        switch (*spec_walk) {
                                case 'T':
-                                       arg = (zval **) (EG(argument_stack).top_element - 2 - (arg_count-i));
+                                       arg = (zval**)zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count-i);
                                        if (Z_TYPE_PP(arg) == IS_UNICODE && (T_arg_type == -1 || T_arg_type == IS_STRING)) {
                                                /* we can upgrade from strings to Unicode */
                                                T_arg_type = IS_UNICODE;
@@ -1023,7 +1023,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl
 
                        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;
 
@@ -1043,7 +1043,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl
                        }
                }
 
-               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, T_arg_type TSRMLS_CC) == FAILURE) {
                        /* clean up varargs array if it was used */
index a770961b6e09b81f7da0efbf6bdcfeeaf29a1f5e..1f8d547e760df9dd7d4c12b2d2565bec5a477c2b 100644 (file)
@@ -178,18 +178,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);
@@ -206,6 +198,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;
@@ -218,20 +211,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;
        }
@@ -250,21 +238,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++) {
@@ -1786,14 +1768,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;
@@ -1811,11 +1791,6 @@ static zval *debug_backtrace_get_args(void ***curpos TSRMLS_DC) /* {{{ */
                }
        }
 
-       /* skip args from incomplete frames */
-       while ((((*curpos)-1) > EG(argument_stack).elements) && *((*curpos)-1)) {
-               (*curpos)--;
-       }
-
        return arg_array;
 }
 /* }}} */
@@ -1848,47 +1823,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) {
                zstr free_class_name = NULL_ZSTR;
@@ -1906,7 +1850,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) {
@@ -1943,9 +1887,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 {
@@ -2048,28 +1991,6 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
        zstr 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);
 
@@ -2080,17 +2001,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
 
        /* 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);
@@ -2164,9 +2075,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
                        }
 
                        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_ascii_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 0e7ddbcf72962ddcc7cf2d656eeb9c7fa5bf4686..9c722b35c72e517c6415eeadec1f2df66a1d978f 100644 (file)
@@ -276,6 +276,7 @@ typedef union _zend_function {
 
 typedef struct _zend_function_state {
        zend_function *function;
+       void **arguments;
 } zend_function_state;
 
 
@@ -304,7 +305,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 7a355d8f2e6e45f43826028f70470c4e33491646..c2bf057e419725573f80c9e35461ac8bc5a0d89a 100644 (file)
@@ -1418,10 +1418,10 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_v
        EX(opline)++
 
 #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 db9bce8481e51ac49bfbbb1e72f46f62cb4b230e..c31ced7fd62fa97de2a73ede6d2b61112480b94e 100644 (file)
@@ -153,30 +153,158 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC);
 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)
+{
+       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_element-2;
+       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 aa83e59feaf511d27c85154c41c38c6a7240731d..412875165df09bf052cdd8347bd9dfa637fb8682 100644 (file)
@@ -159,8 +159,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_u_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
        {
@@ -308,7 +308,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)) {
@@ -1040,6 +1040,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                }
        }
 
+       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;
 
@@ -1051,8 +1057,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                                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 (old_func_name) {
                                                efree(Z_STRVAL_P(fci->function_name));
@@ -1092,17 +1098,18 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                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;
@@ -1191,7 +1198,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                        *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 dc3d1e87fd6c92cfa6f38d8c1a5d3a2ad3ce8c23..559277064bc32e59727117eb30bace4b14cfa4ba 100644 (file)
@@ -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;
@@ -207,7 +208,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 222c17e85b813a6a8eaaf2629ee31c0eeeabf9b6..7c91bdcd49f44159e9db59f5808ae9060b432f30 100644 (file)
@@ -2153,7 +2153,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
        }
 
        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;
 
@@ -2163,11 +2163,8 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
 
                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);
@@ -2255,6 +2252,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
        }
 
        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))) {
@@ -2279,7 +2277,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                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);
@@ -2455,7 +2453,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP|VAR|CV, ANY)
                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();
@@ -2482,7 +2480,7 @@ ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY)
                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();
@@ -2518,7 +2516,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
             (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;
 
@@ -2528,7 +2526,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
                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();
@@ -2549,7 +2547,7 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
        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();
@@ -2569,10 +2567,10 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY)
 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;
                zstr class_name = get_active_class_name(&space TSRMLS_CC);
                zend_execute_data *ptr = EX(prev_execute_data);
@@ -2606,11 +2604,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;
 
@@ -4173,15 +4172,16 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
        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++) {
index 58ba907b594d1558ea2bd1ef7472982e6948b0cb..50c76ef1c33b075b458d0b9302bd53bdbcb59986 100644 (file)
@@ -30,10 +30,13 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o
 #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_array TSRMLS_DC)
        }
 
        /* 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_array TSRMLS_DC)
        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_array TSRMLS_DC)
                }
 #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_array TSRMLS_DC)
        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
@@ -173,7 +174,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        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;
 
@@ -183,11 +184,8 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 
                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);
@@ -275,6 +273,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        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))) {
@@ -299,7 +298,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                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);
@@ -348,10 +347,10 @@ static int ZEND_CATCH_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 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;
                zstr class_name = get_active_class_name(&space TSRMLS_CC);
                zend_execute_data *ptr = EX(prev_execute_data);
@@ -527,15 +526,16 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        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++) {
@@ -723,11 +723,12 @@ static int ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
 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;
 
@@ -1502,7 +1503,7 @@ static int ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                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();
@@ -4756,7 +4757,7 @@ static int ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                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();
@@ -7993,7 +7994,7 @@ static int ZEND_SEND_VAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                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();
@@ -8020,7 +8021,7 @@ static int zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
                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();
@@ -8056,7 +8057,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
             (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;
 
@@ -8066,7 +8067,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                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();
@@ -8087,7 +8088,7 @@ static int ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        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();
@@ -22129,7 +22130,7 @@ static int ZEND_SEND_VAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                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();
@@ -22156,7 +22157,7 @@ static int zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
                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();
@@ -22192,7 +22193,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
             (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;
 
@@ -22202,7 +22203,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                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();
@@ -22223,7 +22224,7 @@ static int ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        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 05ca0ca2251cf2d86e4b6f5a8fabffeef78fb40c..dce15d9f4f00dae254092fda91baee1992427425 100644 (file)
@@ -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_array *op_array TSRMLS_DC)
        }
 
        /* 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,9 +47,10 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
        EG(opline_ptr) = &EX(opline);
 
        EX(function_state).function = (zend_function *) op_array;
+       EX(function_state).arguments = NULL;
 
        while (1) {
-    {%ZEND_VM_CONTINUE_LABEL%}
+       {%ZEND_VM_CONTINUE_LABEL%}
 #ifdef ZEND_WIN32
                if (EG(timed_out)) {
                        zend_timeout(0);
index 14a0c4624adbfcdd1bcbd78f16f8a791458a34fb..427d1e907be98a476b2a3d9decbdb02d4ad3b9e6 100644 (file)
@@ -404,7 +404,7 @@ function gen_code($f, $spec, $kind, $code, $op1, $op2) {
                                        "/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, $code, $op1, $op2) {
                                        "/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, $kind, $executor_name, $initializer_name,
                                                        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, $kind, $executor_name, $initializer_name,
                                  // 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, $kind, $executor_name, $initializer_name,
                                          // 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]);
                                                }
                                        }