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)
This commit is contained in:
Stanislav Malyshev 2003-01-27 15:13:01 +00:00
parent c375b0b05c
commit 3a4ace13b4
3 changed files with 90 additions and 69 deletions

View File

@ -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)
static void zend_do_op_data(zend_op *data_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);
}
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

View File

@ -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

View File

@ -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;