mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Changed EG(argument_stack) implementation.
This commit is contained in:
parent
07000cc2ba
commit
0b6825102d
1
NEWS
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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 @@ 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;
|
||||
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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() \
|
||||
|
@ -143,30 +143,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)
|
||||
{
|
||||
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);
|
||||
|
@ -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)) {
|
||||
@ -944,6 +944,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;
|
||||
|
||||
@ -956,8 +962,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 (call_via_handler) {
|
||||
@ -993,17 +999,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;
|
||||
@ -1092,7 +1099,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(¶ms_array);
|
||||
|
@ -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;
|
||||
|
@ -2091,7 +2091,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;
|
||||
|
||||
@ -2101,11 +2101,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);
|
||||
@ -2193,6 +2190,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))) {
|
||||
@ -2217,7 +2215,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);
|
||||
@ -2409,7 +2407,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();
|
||||
@ -2436,7 +2434,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();
|
||||
@ -2472,7 +2470,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;
|
||||
|
||||
@ -2482,7 +2480,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();
|
||||
@ -2503,7 +2501,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();
|
||||
@ -2523,10 +2521,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 **) ¶m TSRMLS_CC)==FAILURE) {
|
||||
if (param == NULL) {
|
||||
char *space;
|
||||
char *class_name = get_active_class_name(&space TSRMLS_CC);
|
||||
zend_execute_data *ptr = EX(prev_execute_data);
|
||||
@ -2560,11 +2558,12 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
|
||||
ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zval **param, *assignment_value, **var_ptr;
|
||||
zval *assignment_value, **var_ptr;
|
||||
zend_uint arg_num = Z_LVAL(opline->op1.u.constant);
|
||||
zend_free_op free_res;
|
||||
zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
|
||||
|
||||
if (zend_ptr_stack_get_arg(arg_num, (void **) ¶m TSRMLS_CC)==FAILURE) {
|
||||
if (param == NULL) {
|
||||
if ((Z_TYPE(opline->op2.u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || Z_TYPE(opline->op2.u.constant)==IS_CONSTANT_ARRAY) {
|
||||
zval *default_value;
|
||||
|
||||
@ -4006,15 +4005,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;
|
||||
|
||||
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++) {
|
||||
|
@ -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
|
||||
@ -165,7 +166,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;
|
||||
|
||||
@ -175,11 +176,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);
|
||||
@ -267,6 +265,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))) {
|
||||
@ -291,7 +290,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);
|
||||
@ -340,10 +339,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 **) ¶m TSRMLS_CC)==FAILURE) {
|
||||
if (param == NULL) {
|
||||
char *space;
|
||||
char *class_name = get_active_class_name(&space TSRMLS_CC);
|
||||
zend_execute_data *ptr = EX(prev_execute_data);
|
||||
@ -519,15 +518,16 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_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++) {
|
||||
@ -710,11 +710,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 **) ¶m TSRMLS_CC)==FAILURE) {
|
||||
if (param == NULL) {
|
||||
if ((Z_TYPE(opline->op2.u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || Z_TYPE(opline->op2.u.constant)==IS_CONSTANT_ARRAY) {
|
||||
zval *default_value;
|
||||
|
||||
@ -1505,7 +1506,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();
|
||||
@ -4638,7 +4639,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();
|
||||
@ -7751,7 +7752,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();
|
||||
@ -7778,7 +7779,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();
|
||||
@ -7814,7 +7815,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;
|
||||
|
||||
@ -7824,7 +7825,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();
|
||||
@ -7845,7 +7846,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();
|
||||
@ -21312,7 +21313,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();
|
||||
@ -21339,7 +21340,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();
|
||||
@ -21375,7 +21376,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;
|
||||
|
||||
@ -21385,7 +21386,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();
|
||||
@ -21406,7 +21407,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();
|
||||
}
|
||||
|
@ -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,6 +47,7 @@ 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%}
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user