mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
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:
parent
c375b0b05c
commit
3a4ace13b4
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user