From: Stanislav Malyshev Date: Mon, 27 Jan 2003 15:13:01 +0000 (+0000) Subject: Replace MAKE_VAR opcode with special 'data' opcode X-Git-Tag: PHP_5_0_dev_before_13561_fix~22 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a4ace13b4a2bcd53a01e10f77253e7da3024276;p=php Replace MAKE_VAR opcode with special 'data' opcode This opcode is not executeable but only holds data for opcodes that need more than two arguments (presently only ASSIGN_OBJ and the ilk but in the future also ASSIGN_DIM) --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 86954dd48c..f05ca5af2b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -184,21 +184,12 @@ void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC) #define MAKE_NOP(opline) { opline->opcode = ZEND_NOP; memset(&opline->result,0,sizeof(znode)); memset(&opline->op1,0,sizeof(znode)); memset(&opline->op2,0,sizeof(znode)); opline->result.op_type=opline->op1.op_type=opline->op2.op_type=IS_UNUSED; } -static void zend_replace_object_fetch(zend_op *last_op, znode *value TSRMLS_DC) -{ - if (value->op_type != IS_VAR) { - last_op->opcode = ZEND_MAKE_VAR; - last_op->result.op_type = IS_VAR; - last_op->result.u.EA.type = 0; - last_op->result.u.var = get_temporary_variable(CG(active_op_array)); - last_op->op1 = *value; - SET_UNUSED(last_op->op2); - value->op_type = IS_VAR; - value->u.EA.type = 0; - value->u.var = last_op->result.u.var; - } else { - MAKE_NOP(last_op); - } + +static void zend_do_op_data(zend_op *data_op, znode *value TSRMLS_DC) +{ + data_op->opcode = ZEND_OP_DATA; + data_op->op1 = *value; + SET_UNUSED(data_op->op2); } void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC) @@ -206,61 +197,58 @@ void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *o int last_op_number = get_next_op_number(CG(active_op_array))-1; zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number]; - + if (last_op->opcode == ZEND_FETCH_OBJ_RW) { switch (op) { case ZEND_ASSIGN_ADD: - opline->opcode = ZEND_ASSIGN_ADD_OBJ; + last_op->opcode = ZEND_ASSIGN_ADD_OBJ; break; case ZEND_ASSIGN_SUB: - opline->opcode = ZEND_ASSIGN_SUB_OBJ; + last_op->opcode = ZEND_ASSIGN_SUB_OBJ; break; case ZEND_ASSIGN_MUL: - opline->opcode = ZEND_ASSIGN_MUL_OBJ; + last_op->opcode = ZEND_ASSIGN_MUL_OBJ; break; case ZEND_ASSIGN_DIV: - opline->opcode = ZEND_ASSIGN_DIV_OBJ; + last_op->opcode = ZEND_ASSIGN_DIV_OBJ; break; case ZEND_ASSIGN_MOD: - opline->opcode = ZEND_ASSIGN_MOD_OBJ; + last_op->opcode = ZEND_ASSIGN_MOD_OBJ; break; case ZEND_ASSIGN_SL: - opline->opcode = ZEND_ASSIGN_SL_OBJ; + last_op->opcode = ZEND_ASSIGN_SL_OBJ; break; case ZEND_ASSIGN_SR: - opline->opcode = ZEND_ASSIGN_SR_OBJ; + last_op->opcode = ZEND_ASSIGN_SR_OBJ; break; case ZEND_ASSIGN_CONCAT: - opline->opcode = ZEND_ASSIGN_CONCAT_OBJ; + last_op->opcode = ZEND_ASSIGN_CONCAT_OBJ; break; case ZEND_ASSIGN_BW_OR: - opline->opcode = ZEND_ASSIGN_BW_OR_OBJ; + last_op->opcode = ZEND_ASSIGN_BW_OR_OBJ; break; case ZEND_ASSIGN_BW_AND: - opline->opcode = ZEND_ASSIGN_BW_AND_OBJ; + last_op->opcode = ZEND_ASSIGN_BW_AND_OBJ; break; case ZEND_ASSIGN_BW_XOR: - opline->opcode = ZEND_ASSIGN_BW_XOR_OBJ; + last_op->opcode = ZEND_ASSIGN_BW_XOR_OBJ; break; default: zend_error(E_COMPILE_ERROR, "Unknown binary op opcode %d", op); } - - opline->op2 = last_op->op2; - opline->op1 = last_op->op1; - zend_replace_object_fetch(last_op, op2 TSRMLS_CC); - opline->extended_value = op2->u.var; - + + zend_do_op_data(opline, op2 TSRMLS_CC); + SET_UNUSED(opline->result); + *result = last_op->result; } else { opline->opcode = op; opline->op1 = *op1; opline->op2 = *op2; + opline->result.op_type = IS_VAR; + opline->result.u.EA.type = 0; + opline->result.u.var = get_temporary_variable(CG(active_op_array)); + *result = opline->result; } - - opline->result.op_type = IS_VAR; - opline->result.u.EA.type = 0; - opline->result.u.var = get_temporary_variable(CG(active_op_array)); - *result = opline->result; } @@ -395,22 +383,20 @@ void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC) zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number]; if (last_op->opcode == ZEND_FETCH_OBJ_W) { - opline->opcode = ZEND_ASSIGN_OBJ; - opline->op1 = last_op->op1; - opline->op2 = last_op->op2; - - zend_replace_object_fetch(last_op, value TSRMLS_CC); + last_op->opcode = ZEND_ASSIGN_OBJ; - opline->extended_value = value->u.var; + zend_do_op_data(opline, value TSRMLS_CC); + SET_UNUSED(opline->result); + *result = last_op->result; } else { opline->opcode = ZEND_ASSIGN; opline->op1 = *variable; opline->op2 = *value; + opline->result.op_type = IS_VAR; + opline->result.u.EA.type = 0; + opline->result.u.var = get_temporary_variable(CG(active_op_array)); + *result = opline->result; } - opline->result.op_type = IS_VAR; - opline->result.u.EA.type = 0; - opline->result.u.var = get_temporary_variable(CG(active_op_array)); - *result = opline->result; } @@ -873,7 +859,7 @@ void zend_do_free(znode *op1 TSRMLS_DC) } else if (op1->op_type==IS_VAR) { zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1]; - while (opline->opcode == ZEND_END_SILENCE || opline->opcode == ZEND_EXT_FCALL_END) { + while (opline->opcode == ZEND_END_SILENCE || opline->opcode == ZEND_EXT_FCALL_END || opline->opcode == ZEND_OP_DATA) { opline--; } if (opline->result.op_type == op1->op_type diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 1b965cef76..8b676a6337 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -619,7 +619,7 @@ int zendlex(znode *zendlval TSRMLS_DC); #define ZEND_POST_DEC_OBJ 135 #define ZEND_ASSIGN_OBJ 136 -#define ZEND_MAKE_VAR 137 +#define ZEND_OP_DATA 137 #define ZEND_INSTANCEOF 138 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 4c158ec846..dff57717a0 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -267,11 +267,13 @@ static inline zval *get_obj_zval_ptr(znode *op, temp_variable *Ts, zval **freeop return get_zval_ptr(op, Ts, freeop, type); } -static inline void zend_assign_to_object(znode *result, znode *op1, znode *op2, zval *value, temp_variable *Ts TSRMLS_DC) +static inline void zend_assign_to_object(znode *result, znode *op1, znode *op2, znode *value_op, temp_variable *Ts TSRMLS_DC) { zval **object_ptr = get_obj_zval_ptr_ptr(op1, Ts, BP_VAR_W TSRMLS_CC); zval *object; zval *property = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R); + zval *free_value; + zval *value = get_zval_ptr(value_op, Ts, &free_value, BP_VAR_R); zval tmp; zval **retval = &T(result->u.var).var.ptr; @@ -310,10 +312,7 @@ static inline void zend_assign_to_object(znode *result, znode *op1, znode *op2, } /* here property is a string */ - Z_OBJ_HT_P(object)->write_property(object, property, value TSRMLS_CC); - - PZVAL_UNLOCK(value); if (property == &tmp) { zval_dtor(property); } @@ -326,11 +325,13 @@ static inline void zend_assign_to_object(znode *result, znode *op1, znode *op2, } } -static inline void zend_assign_to_object_op(znode *result, znode *op1, znode *op2, zval *value, temp_variable *Ts, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC) TSRMLS_DC) +static inline void zend_assign_to_object_op(znode *result, znode *op1, znode *op2, znode *value_op, temp_variable *Ts, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC) TSRMLS_DC) { zval **object_ptr = get_obj_zval_ptr_ptr(op1, Ts, BP_VAR_W TSRMLS_CC); zval *object; zval *property = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R); + zval *free_value; + zval *value = get_zval_ptr(value_op, Ts, &free_value, BP_VAR_R); zval tmp; zval **retval = &T(result->u.var).var.ptr; int have_get_ptr = 0; @@ -365,8 +366,6 @@ static inline void zend_assign_to_object_op(znode *result, znode *op1, znode *op } /* here property is a string */ - PZVAL_UNLOCK(value); - if (Z_OBJ_HT_P(object)->get_property_zval_ptr) { zval **zptr = Z_OBJ_HT_P(object)->get_property_zval_ptr(object, property TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ @@ -1506,67 +1505,100 @@ int zend_assign_bw_xor_handler(ZEND_OPCODE_HANDLER_ARGS) int zend_assign_add_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), add_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), add_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_sub_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), sub_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), sub_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_mul_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), mul_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), mul_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_div_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), div_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), div_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_mod_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), mod_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), mod_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_sl_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), shift_left_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), shift_left_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_sr_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), shift_right_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), shift_right_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_concat_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), concat_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), concat_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_bw_or_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), bitwise_or_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), bitwise_or_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_bw_and_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), bitwise_and_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), bitwise_and_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } int zend_assign_bw_xor_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts), bitwise_xor_function TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object_op(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts), bitwise_xor_function TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } @@ -1864,7 +1896,10 @@ int zend_make_var_handler(ZEND_OPCODE_HANDLER_ARGS) int zend_assign_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { - zend_assign_to_object(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX_T(EX(opline)->extended_value).var.ptr, EX(Ts) TSRMLS_CC); + zend_op *op_data = EX(opline)+1; + zend_assign_to_object(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, &op_data->op1, EX(Ts) TSRMLS_CC); + /* assign_obj has two opcodes! */ + EX(opline)++; NEXT_OPCODE(); } @@ -3983,7 +4018,7 @@ void zend_init_opcodes_handlers() zend_opcode_handlers[ZEND_POST_DEC_OBJ] = zend_post_dec_obj_handler; zend_opcode_handlers[ZEND_ASSIGN_OBJ] = zend_assign_obj_handler; - zend_opcode_handlers[ZEND_MAKE_VAR] = zend_make_var_handler; + zend_opcode_handlers[ZEND_OP_DATA] = NULL; zend_opcode_handlers[ZEND_INSTANCEOF] = zend_instanceof_handler;