From: Andi Gutmans Date: Sun, 15 Aug 1999 19:29:39 +0000 (+0000) Subject: - Optimize the execute stack a bit. X-Git-Tag: PRE_DELAYED_ARRAY_FETCH_PATCH~381 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b5f5e9a6d1bed2e329c98084e4a91f5302124bf2;p=php - Optimize the execute stack a bit. --- diff --git a/Zend/zend.h b/Zend/zend.h index 30252d022e..d6ed0ed387 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -260,4 +260,6 @@ extern zend_utility_values zend_uv; } \ } +#define ZEND_MAX_RESERVED_RESOURCES 1 + #endif /* _ZEND_H */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 428046dcbb..291390f41b 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -118,7 +118,7 @@ struct _zend_op_array { int backpatch_count; #endif - void *reserved[4]; + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; @@ -147,7 +147,7 @@ typedef union _zend_function { typedef struct _zend_function_state { HashTable *function_symbol_table; zend_function *function; - void *reserved[4]; + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; } zend_function_state; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 0536dbdd89..e42f94e54e 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -865,6 +865,11 @@ static void call_overloaded_function(int arg_count, zval *return_value, HashTabl # define free_alloca(p) efree(p) #endif +#undef do_alloca +#undef free_aloca +# define do_alloca(p) emalloc(p) +# define free_alloca(p) efree(p) + typedef struct _object_info { zval *ptr; zval **ptr_ptr; @@ -873,12 +878,8 @@ typedef struct _object_info { void execute(zend_op_array *op_array ELS_DC) { zend_op *opline = op_array->opcodes; - int free_op1, free_op2; - int (*unary_op)(zval *result, zval *op1); - int (*binary_op)(zval *result, zval *op1, zval *op2); zend_op *end = op_array->opcodes + op_array->last; zend_function_state function_state; - HashTable *calling_symbol_table; zend_function *function_being_called=NULL; object_info object = {NULL, NULL}; #if !defined (__GNUC__) || __GNUC__ < 2 @@ -921,100 +922,100 @@ void execute(zend_op_array *op_array ELS_DC) while (oplineopcode) { case ZEND_ADD: - binary_op = add_function; + EG(binary_op) = add_function; goto binary_op_addr; case ZEND_SUB: - binary_op = sub_function; + EG(binary_op) = sub_function; goto binary_op_addr; case ZEND_MUL: - binary_op = mul_function; + EG(binary_op) = mul_function; goto binary_op_addr; case ZEND_DIV: - binary_op = div_function; + EG(binary_op) = div_function; goto binary_op_addr; case ZEND_MOD: - binary_op = mod_function; + EG(binary_op) = mod_function; goto binary_op_addr; case ZEND_SL: - binary_op = shift_left_function; + EG(binary_op) = shift_left_function; goto binary_op_addr; case ZEND_SR: - binary_op = shift_right_function; + EG(binary_op) = shift_right_function; goto binary_op_addr; case ZEND_CONCAT: - binary_op = concat_function; + EG(binary_op) = concat_function; goto binary_op_addr; case ZEND_IS_EQUAL: - binary_op = is_equal_function; + EG(binary_op) = is_equal_function; goto binary_op_addr; case ZEND_IS_NOT_EQUAL: - binary_op = is_not_equal_function; + EG(binary_op) = is_not_equal_function; goto binary_op_addr; case ZEND_IS_SMALLER: - binary_op = is_smaller_function; + EG(binary_op) = is_smaller_function; goto binary_op_addr; case ZEND_IS_SMALLER_OR_EQUAL: - binary_op = is_smaller_or_equal_function; + EG(binary_op) = is_smaller_or_equal_function; goto binary_op_addr; case ZEND_BW_OR: - binary_op = bitwise_or_function; + EG(binary_op) = bitwise_or_function; goto binary_op_addr; case ZEND_BW_AND: - binary_op = bitwise_and_function; + EG(binary_op) = bitwise_and_function; goto binary_op_addr; case ZEND_BW_XOR: - binary_op = bitwise_xor_function; + EG(binary_op) = bitwise_xor_function; goto binary_op_addr; case ZEND_BOOL_XOR: - binary_op = boolean_xor_function; + EG(binary_op) = boolean_xor_function; /* Fall through */ binary_op_addr: - binary_op(&Ts[opline->result.u.var].tmp_var, - get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R), - get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R) ); - FREE_OP(&opline->op1, free_op1); - FREE_OP(&opline->op2, free_op2); + EG(binary_op)(&Ts[opline->result.u.var].tmp_var, + get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R), + get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R) ); + FREE_OP(&opline->op1, EG(free_op1)); + FREE_OP(&opline->op2, EG(free_op2)); break; case ZEND_BW_NOT: case ZEND_BOOL_NOT: - unary_op = get_unary_op(opline->opcode); - unary_op(&Ts[opline->result.u.var].tmp_var, - get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R) ); - FREE_OP(&opline->op1, free_op1); + EG(unary_op) = get_unary_op(opline->opcode); + EG(unary_op)(&Ts[opline->result.u.var].tmp_var, + get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R) ); + FREE_OP(&opline->op1, EG(free_op1)); break; case ZEND_ASSIGN_ADD: - binary_op = add_function; + EG(binary_op) = add_function; goto binary_assign_op_addr; case ZEND_ASSIGN_SUB: - binary_op = sub_function; + EG(binary_op) = sub_function; goto binary_assign_op_addr; case ZEND_ASSIGN_MUL: - binary_op = mul_function; + EG(binary_op) = mul_function; goto binary_assign_op_addr; case ZEND_ASSIGN_DIV: - binary_op = div_function; + EG(binary_op) = div_function; goto binary_assign_op_addr; case ZEND_ASSIGN_MOD: - binary_op = mod_function; + EG(binary_op) = mod_function; goto binary_assign_op_addr; case ZEND_ASSIGN_SL: - binary_op = shift_left_function; + EG(binary_op) = shift_left_function; goto binary_assign_op_addr; case ZEND_ASSIGN_SR: - binary_op = shift_right_function; + EG(binary_op) = shift_right_function; goto binary_assign_op_addr; case ZEND_ASSIGN_CONCAT: - binary_op = concat_function; + EG(binary_op) = concat_function; goto binary_assign_op_addr; case ZEND_ASSIGN_BW_OR: - binary_op = bitwise_or_function; + EG(binary_op) = bitwise_or_function; goto binary_assign_op_addr; case ZEND_ASSIGN_BW_AND: - binary_op = bitwise_and_function; + EG(binary_op) = bitwise_and_function; goto binary_assign_op_addr; case ZEND_ASSIGN_BW_XOR: - binary_op = bitwise_xor_function; + EG(binary_op) = bitwise_xor_function; /* Fall through */ binary_assign_op_addr: { zval **var_ptr = get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_RW); @@ -1042,11 +1043,11 @@ binary_assign_op_addr: { } } previous_lock_count = (*var_ptr)->EA.locks; - binary_op(*var_ptr, *var_ptr, get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R)); + EG(binary_op)(*var_ptr, *var_ptr, get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R)); (*var_ptr)->EA.locks = previous_lock_count; Ts[opline->result.u.var].var = var_ptr; SELECTIVE_PZVAL_LOCK(*var_ptr, &opline->result); - FREE_OP(&opline->op2, free_op2); + FREE_OP(&opline->op2, EG(free_op2)); } break; case ZEND_PRE_INC: @@ -1098,14 +1099,14 @@ binary_assign_op_addr: { } break; case ZEND_PRINT: - zend_print_variable(get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R)); + zend_print_variable(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R)); Ts[opline->result.u.var].tmp_var.value.lval = 1; Ts[opline->result.u.var].tmp_var.type = IS_LONG; - FREE_OP(&opline->op1, free_op1); + FREE_OP(&opline->op1, EG(free_op1)); break; case ZEND_ECHO: - zend_print_variable(get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R)); - FREE_OP(&opline->op1, free_op1); + zend_print_variable(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R)); + FREE_OP(&opline->op1, EG(free_op1)); break; case ZEND_FETCH_R: zend_fetch_var_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_R ELS_CC); @@ -1150,9 +1151,9 @@ binary_assign_op_addr: { zend_fetch_dimension_address_from_tmp_var(&opline->result, &opline->op1, &opline->op2, Ts ELS_CC); break; case ZEND_ASSIGN: { - zval *value = get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R); + zval *value = get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R); - zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (free_op2?IS_TMP_VAR:opline->op2.op_type), Ts ELS_CC); + zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (EG(free_op2)?IS_TMP_VAR:opline->op2.op_type), Ts ELS_CC); /* zend_assign_to_variable() always takes care of op2, never free it! */ } break; @@ -1169,35 +1170,35 @@ binary_assign_op_addr: { case ZEND_JMPZ: { znode *op1 = &opline->op1; - if (!i_zend_is_true(get_zval_ptr(op1, Ts, &free_op1, BP_VAR_R))) { + if (!i_zend_is_true(get_zval_ptr(op1, Ts, &EG(free_op1), BP_VAR_R))) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif opline = &op_array->opcodes[opline->op2.u.opline_num]; - FREE_OP(op1, free_op1); + FREE_OP(op1, EG(free_op1)); continue; } - FREE_OP(op1, free_op1); + FREE_OP(op1, EG(free_op1)); } break; case ZEND_JMPNZ: { znode *op1 = &opline->op1; - if (zend_is_true(get_zval_ptr(op1, Ts, &free_op1, BP_VAR_R))) { + if (zend_is_true(get_zval_ptr(op1, Ts, &EG(free_op1), BP_VAR_R))) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif opline = &op_array->opcodes[opline->op2.u.opline_num]; - FREE_OP(op1, free_op1); + FREE_OP(op1, EG(free_op1)); continue; } - FREE_OP(op1, free_op1); + FREE_OP(op1, EG(free_op1)); } break; case ZEND_JMPZNZ: { znode *res = &opline->result; - if (!zend_is_true(get_zval_ptr(res, Ts, &free_op1, BP_VAR_R))) { + if (!zend_is_true(get_zval_ptr(res, Ts, &EG(free_op1), BP_VAR_R))) { #if DEBUG_ZEND>=2 printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num); #endif @@ -1208,44 +1209,44 @@ binary_assign_op_addr: { #endif opline = &op_array->opcodes[opline->op1.u.opline_num]; } - FREE_OP(res, free_op1); + FREE_OP(res, EG(free_op1)); } continue; break; case ZEND_JMPZ_EX: { zend_op *original_opline = opline; - int retval = zend_is_true(get_zval_ptr(&original_opline->op1, Ts, &free_op1, BP_VAR_R)); + int retval = zend_is_true(get_zval_ptr(&original_opline->op1, Ts, &EG(free_op1), BP_VAR_R)); if (!retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif opline = &op_array->opcodes[opline->op2.u.opline_num]; - FREE_OP(&original_opline->op1, free_op1); + FREE_OP(&original_opline->op1, EG(free_op1)); Ts[original_opline->result.u.var].tmp_var.value.lval = retval; Ts[original_opline->result.u.var].tmp_var.type = IS_LONG; continue; } - FREE_OP(&original_opline->op1, free_op1); + FREE_OP(&original_opline->op1, EG(free_op1)); Ts[original_opline->result.u.var].tmp_var.value.lval = retval; Ts[original_opline->result.u.var].tmp_var.type = IS_LONG; } break; case ZEND_JMPNZ_EX: { zend_op *original_opline = opline; - int retval = zend_is_true(get_zval_ptr(&original_opline->op1, Ts, &free_op1, BP_VAR_R)); + int retval = zend_is_true(get_zval_ptr(&original_opline->op1, Ts, &EG(free_op1), BP_VAR_R)); if (retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif opline = &op_array->opcodes[opline->op2.u.opline_num]; - FREE_OP(&original_opline->op1, free_op1); + FREE_OP(&original_opline->op1, EG(free_op1)); Ts[original_opline->result.u.var].tmp_var.value.lval = retval; Ts[original_opline->result.u.var].tmp_var.type = IS_LONG; continue; } - FREE_OP(&original_opline->op1, free_op1); + FREE_OP(&original_opline->op1, EG(free_op1)); Ts[original_opline->result.u.var].tmp_var.value.lval = retval; Ts[original_opline->result.u.var].tmp_var.type = IS_LONG; } @@ -1261,18 +1262,18 @@ binary_assign_op_addr: { break; case ZEND_ADD_CHAR: add_char_to_string( &Ts[opline->result.u.var].tmp_var, - get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_NA), + get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_NA), &opline->op2.u.constant); /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */ break; case ZEND_ADD_STRING: add_string_to_string( &Ts[opline->result.u.var].tmp_var, - get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_NA), + get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_NA), &opline->op2.u.constant); /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */ break; case ZEND_ADD_VAR: { - zval *var = get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R); + zval *var = get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R); zval var_copy; int use_copy; @@ -1281,7 +1282,7 @@ binary_assign_op_addr: { var = &var_copy; } add_string_to_string( &Ts[opline->result.u.var].tmp_var, - get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_NA), + get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_NA), var); if (use_copy) { zval_dtor(var); @@ -1292,7 +1293,7 @@ binary_assign_op_addr: { * which aren't affected by FREE_OP()'s anyway, unless they're * string offsets or overloaded objects */ - FREE_OP(&opline->op2, free_op2); + FREE_OP(&opline->op2, EG(free_op2)); } break; case ZEND_INIT_FCALL_BY_NAME: { @@ -1317,7 +1318,7 @@ binary_assign_op_addr: { PZVAL_LOCK(*Ts[opline->op2.u.var].var); } } - function_name = get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R); + function_name = get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R); tmp = *function_name; zval_copy_ctor(&tmp); @@ -1341,7 +1342,7 @@ binary_assign_op_addr: { object.ptr_ptr = object_ptr_ptr; } } else { /* used for member function calls */ - object.ptr = _get_object_zval_ptr(&opline->op1, Ts, &free_op1, &object.ptr_ptr ELS_CC); + object.ptr = _get_object_zval_ptr(&opline->op1, Ts, &EG(free_op1), &object.ptr_ptr ELS_CC); if (!object.ptr || ((object.ptr->type==IS_OBJECT) && (object.ptr->value.obj.ce->handle_function_call))) { /* overloaded function call */ @@ -1382,19 +1383,19 @@ binary_assign_op_addr: { zval_dtor(&tmp); function_being_called = function; overloaded_function_call_cont: - FREE_OP(&opline->op2, free_op2); + FREE_OP(&opline->op2, EG(free_op2)); } break; case ZEND_DO_FCALL_BY_NAME: function_state.function = function_being_called; goto do_fcall_common; case ZEND_DO_FCALL: { - zval *fname = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + zval *fname = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &function_state.function)==FAILURE) { zend_error(E_ERROR, "Unknown function: %s()\n", fname->value.str.val); } - FREE_OP(&opline->op1, free_op1); + FREE_OP(&opline->op1, EG(free_op1)); goto do_fcall_common; } do_fcall_common: @@ -1406,6 +1407,8 @@ do_fcall_common: var_uninit(&Ts[opline->result.u.var].tmp_var); ((zend_internal_function *) function_state.function)->handler(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list), (object.ptr?object.ptr:NULL)); } else if (function_state.function->type==ZEND_USER_FUNCTION) { + HashTable *calling_symbol_table; + if (EG(symtable_cache_ptr)>=EG(symtable_cache)) { /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/ function_state.function_symbol_table = *(EG(symtable_cache_ptr)--); @@ -1477,10 +1480,10 @@ do_fcall_common: } break; case ZEND_RETURN: { - zval *retval = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + zval *retval = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); *EG(return_value) = *retval; - if (!free_op1) { + if (!EG(free_op1)) { zendi_zval_copy_ctor(*EG(return_value)); } #if SUPPORT_INTERACTIVE @@ -1515,7 +1518,7 @@ do_fcall_common: goto send_by_ref; } { - zval *varptr = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + zval *varptr = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); if (varptr == &EG(uninitialized_zval)) { varptr = (zval *) emalloc(sizeof(zval)); @@ -1535,7 +1538,7 @@ do_fcall_common: } varptr->refcount++; zend_ptr_stack_push(&EG(argument_stack), varptr); - FREE_OP(&opline->op1, free_op1); /* for string offsets */ + FREE_OP(&opline->op1, EG(free_op1)); /* for string offsets */ } break; send_by_ref: @@ -1619,13 +1622,13 @@ send_by_ref: break; case ZEND_BOOL: /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ - Ts[opline->result.u.var].tmp_var.value.lval = zend_is_true(get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R)); + Ts[opline->result.u.var].tmp_var.value.lval = zend_is_true(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R)); Ts[opline->result.u.var].tmp_var.type = IS_LONG; - FREE_OP(&opline->op1, free_op1); + FREE_OP(&opline->op1, EG(free_op1)); break; case ZEND_BRK: case ZEND_CONT: { - zval *nest_levels_zval = get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R); + zval *nest_levels_zval = get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R); zval tmp; int array_offset, nest_levels, original_nest_levels; zend_brk_cont_element *jmp_to; @@ -1653,7 +1656,7 @@ send_by_ref: } else { opline = op_array->opcodes+jmp_to->cont; } - FREE_OP(&opline->op2, free_op2); + FREE_OP(&opline->op2, EG(free_op2)); continue; } break; @@ -1671,17 +1674,17 @@ send_by_ref: } } is_equal_function(&Ts[opline->result.u.var].tmp_var, - get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R), - get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R)); + get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R), + get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R)); - FREE_OP(&opline->op2, free_op2); + FREE_OP(&opline->op2, EG(free_op2)); if (switch_expr_is_overloaded) { /* We only free op1 if this is a string offset, * Since if it is a TMP_VAR, it'll be reused by * other CASE opcodes (whereas string offsets * are allocated at each get_zval_ptr()) */ - FREE_OP(&opline->op1, free_op1); + FREE_OP(&opline->op1, EG(free_op1)); Ts[opline->op1.u.var].var = NULL; } } @@ -1690,8 +1693,8 @@ send_by_ref: switch (opline->op1.op_type) { case IS_VAR: if (!Ts[opline->op1.u.var].var) { - get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); - FREE_OP(&opline->op1, free_op1); + get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); + FREE_OP(&opline->op1, EG(free_op1)); } break; case IS_TMP_VAR: @@ -1700,7 +1703,7 @@ send_by_ref: } break; case ZEND_NEW: { - zval *tmp = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + zval *tmp = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); zval class_name; zend_class_entry *ce; @@ -1718,7 +1721,7 @@ send_by_ref: Ts[opline->result.u.var].tmp_var.EA.locks=0; zval_dtor(&class_name); - FREE_OP(&opline->op1, free_op1); + FREE_OP(&opline->op1, EG(free_op1)); } break; case ZEND_FETCH_CONSTANT: @@ -1733,8 +1736,8 @@ send_by_ref: case ZEND_INIT_ARRAY: case ZEND_ADD_ARRAY_ELEMENT: { zval *array_ptr = &Ts[opline->result.u.var].tmp_var; - zval *expr=get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); - zval *offset=get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R); + zval *expr=get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); + zval *offset=get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R); if (opline->opcode==ZEND_INIT_ARRAY) { array_init(array_ptr); @@ -1742,7 +1745,7 @@ send_by_ref: break; } } - if (free_op1) { /* temporary variable */ + if (EG(free_op1)) { /* temporary variable */ zval *new_expr = (zval *) emalloc(sizeof(zval)); *new_expr = *expr; @@ -1775,18 +1778,18 @@ send_by_ref: /* do nothing */ break; } - FREE_OP(&opline->op2, free_op2); + FREE_OP(&opline->op2, EG(free_op2)); } else { zend_hash_next_index_insert(array_ptr->value.ht, &expr, sizeof(zval *), NULL); } } break; case ZEND_CAST: { - zval *expr = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + zval *expr = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); zval *result = &Ts[opline->result.u.var].tmp_var; *result = *expr; - if (!free_op1) { + if (!EG(free_op1)) { zendi_zval_copy_ctor(*result); } switch (opline->op2.u.constant.type) { @@ -1818,10 +1821,10 @@ send_by_ref: switch (opline->op2.u.constant.value.lval) { case ZEND_INCLUDE: - new_op_array = compile_filename(get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R) CLS_CC); + new_op_array = compile_filename(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R) CLS_CC); break; case ZEND_EVAL: - new_op_array = compile_string(get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R) CLS_CC); + new_op_array = compile_string(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R) CLS_CC); break; } if (new_op_array) { @@ -1840,11 +1843,11 @@ send_by_ref: var_uninit(&Ts[opline->result.u.var].tmp_var); } EG(return_value) = original_return_value; - FREE_OP(&opline->op1, free_op1); + FREE_OP(&opline->op1, EG(free_op1)); } break; case ZEND_UNSET_VAR: { - zval tmp, *variable = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + zval tmp, *variable = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); if (variable->type != IS_STRING) { tmp = *variable; @@ -1858,12 +1861,12 @@ send_by_ref: if (variable == &tmp) { zval_dtor(&tmp); } - FREE_OP(&opline->op1, free_op1); + FREE_OP(&opline->op1, EG(free_op1)); } break; case ZEND_UNSET_DIM_OBJ: { zval **container = get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_R); - zval *offset = get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R); + zval *offset = get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R); if (container) { HashTable *ht; @@ -1892,15 +1895,15 @@ send_by_ref: } else { /* overloaded element */ } - FREE_OP(&opline->op2, free_op2); + FREE_OP(&opline->op2, EG(free_op2)); } break; case ZEND_FE_RESET: { - zval *array = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + zval *array = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); Ts[opline->result.u.var].tmp_var = *array; array = &Ts[opline->result.u.var].tmp_var; - if (!free_op1) { + if (!EG(free_op1)) { zval_copy_ctor(array); } if (array->type == IS_ARRAY) { @@ -1912,7 +1915,7 @@ send_by_ref: } break; case ZEND_FE_FETCH: { - zval *array = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + zval *array = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); zval *result = &Ts[opline->result.u.var].tmp_var; zval **value, *key; char *str_key; @@ -1956,7 +1959,7 @@ send_by_ref: PZVAL_LOCK(*Ts[opline->op1.u.var].var); } - object = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + object = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); if (!object->value.obj.ce->handle_function_call && !zend_hash_exists(&object->value.obj.ce->function_table, object->value.obj.ce->name, object->value.obj.ce->name_length+1)) { opline = op_array->opcodes + opline->op2.u.opline_num; @@ -2010,8 +2013,8 @@ send_by_ref: break; case ZEND_EXIT: if (opline->op1.op_type != IS_UNUSED) { - zend_print_variable(get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R)); - FREE_OP(&opline->op1, free_op1); + zend_print_variable(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R)); + FREE_OP(&opline->op1, EG(free_op1)); } zend_bailout(); break; @@ -2024,10 +2027,10 @@ send_by_ref: EG(error_reporting) = Ts[opline->op1.u.var].tmp_var.value.lval; break; case ZEND_QM_ASSIGN: { - zval *value = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R); + zval *value = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); Ts[opline->result.u.var].tmp_var = *value; - if (!free_op1) { + if (!EG(free_op1)) { zval_copy_ctor(&Ts[opline->result.u.var].tmp_var); } } diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index aae7624c7a..c8bd32aa29 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -208,8 +208,11 @@ struct _zend_executor_globals { HashTable persistent_list; zend_ptr_stack argument_stack; + int free_op1, free_op2; + int (*unary_op)(zval *result, zval *op1); + int (*binary_op)(zval *result, zval *op1, zval *op2); - void *reserved[4]; + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; #if SUPPORT_INTERACTIVE int interactive; #endif