Permalink
Browse files

Changed EG(argument_stack) implementation.

  • Loading branch information...
1 parent 07000cc commit 0b6825102d19c74974cc05468e19502c4caecdcd Dmitry Stogov committed Jan 24, 2008
View
1 NEWS
@@ -78,6 +78,7 @@ PHP NEWS
(Dmitry, Pierre)
- Added lcfirst() function. (David C)
+- Changed EG(argument_stack) implementation. (Dmitry)
- Changed exception handling. Now each op_array doesn't contain
ZEND_HANDLE_EXCEPTION opcode in the end. (Dmitry)
View
@@ -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
View
@@ -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) {
@@ -187,7 +187,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) {
@@ -746,7 +746,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, "%s(): could not obtain parameters for parsing",
@@ -770,7 +770,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;
@@ -790,7 +790,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 TSRMLS_CC) == FAILURE) {
/* clean up varargs array if it was used */
@@ -211,18 +211,10 @@ ZEND_FUNCTION(gc_disable)
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);
@@ -240,6 +232,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;
@@ -252,20 +245,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;
}
@@ -285,21 +273,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++) {
@@ -1724,14 +1706,12 @@ ZEND_FUNCTION(get_defined_constants)
/* }}} */
-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;
@@ -1749,11 +1729,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;
}
@@ -1784,47 +1759,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;
@@ -1840,7 +1784,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) {
@@ -1876,9 +1820,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 {
@@ -1973,28 +1916,6 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
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);
@@ -2005,17 +1926,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);
@@ -2090,9 +2001,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_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 {
View
@@ -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;
View
@@ -1399,10 +1399,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() \
Oops, something went wrong.

0 comments on commit 0b68251

Please sign in to comment.