#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)
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;
}
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;
}
} 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
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;
}
/* 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);
}
}
}
-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;
}
/* 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 */
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();
}
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();
}
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;