Merge branch 'PHP-7.4'

* PHP-7.4:
  Replace ZEND_ASSIGN_ADD (and others) by ZEND_ASSIGN_OP, ZEND_ASSIGN_DIM_OP, ZEND_ASSGIN_OBJ_OP and ZEND_ASSIGN_STATIC_PROP_OP
This commit is contained in:
Dmitry Stogov 2019-07-05 12:16:30 +03:00
commit 1b5b8175af
29 changed files with 3374 additions and 9315 deletions

View File

@ -1714,18 +1714,18 @@ simple_list:
case ZEND_AST_ASSIGN_REF: BINARY_OP(" =& ", 90, 91, 90);
case ZEND_AST_ASSIGN_OP:
switch (ast->attr) {
case ZEND_ASSIGN_ADD: BINARY_OP(" += ", 90, 91, 90);
case ZEND_ASSIGN_SUB: BINARY_OP(" -= ", 90, 91, 90);
case ZEND_ASSIGN_MUL: BINARY_OP(" *= ", 90, 91, 90);
case ZEND_ASSIGN_DIV: BINARY_OP(" /= ", 90, 91, 90);
case ZEND_ASSIGN_MOD: BINARY_OP(" %= ", 90, 91, 90);
case ZEND_ASSIGN_SL: BINARY_OP(" <<= ", 90, 91, 90);
case ZEND_ASSIGN_SR: BINARY_OP(" >>= ", 90, 91, 90);
case ZEND_ASSIGN_CONCAT: BINARY_OP(" .= ", 90, 91, 90);
case ZEND_ASSIGN_BW_OR: BINARY_OP(" |= ", 90, 91, 90);
case ZEND_ASSIGN_BW_AND: BINARY_OP(" &= ", 90, 91, 90);
case ZEND_ASSIGN_BW_XOR: BINARY_OP(" ^= ", 90, 91, 90);
case ZEND_ASSIGN_POW: BINARY_OP(" **= ", 90, 91, 90);
case ZEND_ADD: BINARY_OP(" += ", 90, 91, 90);
case ZEND_SUB: BINARY_OP(" -= ", 90, 91, 90);
case ZEND_MUL: BINARY_OP(" *= ", 90, 91, 90);
case ZEND_DIV: BINARY_OP(" /= ", 90, 91, 90);
case ZEND_MOD: BINARY_OP(" %= ", 90, 91, 90);
case ZEND_SL: BINARY_OP(" <<= ", 90, 91, 90);
case ZEND_SR: BINARY_OP(" >>= ", 90, 91, 90);
case ZEND_CONCAT: BINARY_OP(" .= ", 90, 91, 90);
case ZEND_BW_OR: BINARY_OP(" |= ", 90, 91, 90);
case ZEND_BW_AND: BINARY_OP(" &= ", 90, 91, 90);
case ZEND_BW_XOR: BINARY_OP(" ^= ", 90, 91, 90);
case ZEND_POW: BINARY_OP(" **= ", 90, 91, 90);
EMPTY_SWITCH_DEFAULT_CASE();
}
break;

View File

@ -2826,7 +2826,8 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
zend_delayed_compile_var(&var_node, var_ast, BP_VAR_RW, 0);
zend_compile_expr(&expr_node, expr_ast);
zend_delayed_compile_end(offset);
zend_emit_op(result, opcode, &var_node, &expr_node);
opline = zend_emit_op(result, ZEND_ASSIGN_OP, &var_node, &expr_node);
opline->extended_value = opcode;
return;
case ZEND_AST_STATIC_PROP:
offset = zend_delayed_compile_begin();
@ -2835,8 +2836,8 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
opline = zend_delayed_compile_end(offset);
cache_slot = opline->extended_value;
opline->opcode = opcode;
opline->extended_value = ZEND_ASSIGN_STATIC_PROP;
opline->opcode = ZEND_ASSIGN_STATIC_PROP_OP;
opline->extended_value = opcode;
opline = zend_emit_op_data(&expr_node);
opline->extended_value = cache_slot;
@ -2847,8 +2848,8 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
zend_compile_expr(&expr_node, expr_ast);
opline = zend_delayed_compile_end(offset);
opline->opcode = opcode;
opline->extended_value = ZEND_ASSIGN_DIM;
opline->opcode = ZEND_ASSIGN_DIM_OP;
opline->extended_value = opcode;
zend_emit_op_data(&expr_node);
return;
@ -2859,8 +2860,8 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
opline = zend_delayed_compile_end(offset);
cache_slot = opline->extended_value;
opline->opcode = opcode;
opline->extended_value = ZEND_ASSIGN_OBJ;
opline->opcode = ZEND_ASSIGN_OBJ_OP;
opline->extended_value = opcode;
opline = zend_emit_op_data(&expr_node);
opline->extended_value = cache_slot;

View File

@ -995,6 +995,9 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf,
/* All increment opcodes are even (decrement are odd) */
#define ZEND_IS_INCREMENT(opcode) (((opcode) & 1) == 0)
#define ZEND_IS_BINARY_ASSIGN_OP_OPCODE(opcode) \
(((opcode) >= ZEND_ADD) && ((opcode) <= ZEND_POW))
/* Pseudo-opcodes that are used only temporarily during compilation */
#define ZEND_GOTO 253
#define ZEND_BRK 254

View File

@ -1342,9 +1342,9 @@ static zend_always_inline int zend_binary_op(zval *ret, zval *op1, zval *op2 OPL
pow_function
};
/* size_t cast makes GCC to better optimize 64-bit PIC code */
size_t opcode = (size_t)opline->opcode;
size_t opcode = (size_t)opline->extended_value;
return zend_binary_ops[opcode - ZEND_ASSIGN_ADD](ret, op1, op2);
return zend_binary_ops[opcode - ZEND_ADD](ret, op1, op2);
}
static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval *property, zval *value OPLINE_DC EXECUTE_DATA_DC)
@ -1449,18 +1449,10 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D)
}
switch (opline->opcode) {
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
msg = "Cannot use assign-op operators with string offsets";
break;
case ZEND_FETCH_DIM_W:
@ -1476,25 +1468,15 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D)
while (opline < end) {
if (opline->op1_type == IS_VAR && opline->op1.var == var) {
switch (opline->opcode) {
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
msg = "Cannot use string offset as an object";
} else if (opline->extended_value == ZEND_ASSIGN_DIM) {
msg = "Cannot use string offset as an array";
} else {
msg = "Cannot use assign-op operators with string offsets";
}
case ZEND_ASSIGN_OBJ_OP:
msg = "Cannot use string offset as an object";
break;
case ZEND_ASSIGN_DIM_OP:
msg = "Cannot use string offset as an array";
break;
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_ASSIGN_OP:
msg = "Cannot use assign-op operators with string offsets";
break;
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:

View File

@ -887,29 +887,29 @@ expr:
{ $$ = zend_ast_create(ZEND_AST_ASSIGN_REF, $1, $4); }
| T_CLONE expr { $$ = zend_ast_create(ZEND_AST_CLONE, $2); }
| variable T_PLUS_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_ADD, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_ADD, $1, $3); }
| variable T_MINUS_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_SUB, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_SUB, $1, $3); }
| variable T_MUL_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_MUL, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_MUL, $1, $3); }
| variable T_POW_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_POW, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_POW, $1, $3); }
| variable T_DIV_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_DIV, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_DIV, $1, $3); }
| variable T_CONCAT_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_CONCAT, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_CONCAT, $1, $3); }
| variable T_MOD_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_MOD, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_MOD, $1, $3); }
| variable T_AND_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_BW_AND, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_BW_AND, $1, $3); }
| variable T_OR_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_BW_OR, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_BW_OR, $1, $3); }
| variable T_XOR_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_BW_XOR, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_BW_XOR, $1, $3); }
| variable T_SL_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_SL, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_SL, $1, $3); }
| variable T_SR_EQUAL expr
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_SR, $1, $3); }
{ $$ = zend_ast_create_assign_op(ZEND_SR, $1, $3); }
| variable T_COALESCE_EQUAL expr
{ $$ = zend_ast_create(ZEND_AST_ASSIGN_COALESCE, $1, $3); }
| variable T_INC { $$ = zend_ast_create(ZEND_AST_POST_INC, $1); }

View File

@ -1028,32 +1028,23 @@ ZEND_API binary_op_type get_binary_op(int opcode)
{
switch (opcode) {
case ZEND_ADD:
case ZEND_ASSIGN_ADD:
return (binary_op_type) add_function;
case ZEND_SUB:
case ZEND_ASSIGN_SUB:
return (binary_op_type) sub_function;
case ZEND_MUL:
case ZEND_ASSIGN_MUL:
return (binary_op_type) mul_function;
case ZEND_POW:
case ZEND_ASSIGN_POW:
return (binary_op_type) pow_function;
case ZEND_DIV:
case ZEND_ASSIGN_DIV:
return (binary_op_type) div_function;
case ZEND_MOD:
case ZEND_ASSIGN_MOD:
return (binary_op_type) mod_function;
case ZEND_SL:
case ZEND_ASSIGN_SL:
return (binary_op_type) shift_left_function;
case ZEND_SR:
case ZEND_ASSIGN_SR:
return (binary_op_type) shift_right_function;
case ZEND_FAST_CONCAT:
case ZEND_CONCAT:
case ZEND_ASSIGN_CONCAT:
return (binary_op_type) concat_function;
case ZEND_IS_IDENTICAL:
return (binary_op_type) is_identical_function;
@ -1071,17 +1062,15 @@ ZEND_API binary_op_type get_binary_op(int opcode)
case ZEND_SPACESHIP:
return (binary_op_type) compare_function;
case ZEND_BW_OR:
case ZEND_ASSIGN_BW_OR:
return (binary_op_type) bitwise_or_function;
case ZEND_BW_AND:
case ZEND_ASSIGN_BW_AND:
return (binary_op_type) bitwise_and_function;
case ZEND_BW_XOR:
case ZEND_ASSIGN_BW_XOR:
return (binary_op_type) bitwise_xor_function;
case ZEND_BOOL_XOR:
return (binary_op_type) boolean_xor_function;
default:
ZEND_ASSERT(0);
return (binary_op_type) NULL;
}
}

View File

@ -869,7 +869,7 @@ ZEND_VM_COLD_HELPER(zend_undefined_function_helper, ANY, ANY)
HANDLE_EXCEPTION();
}
ZEND_VM_HELPER(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(28, ZEND_ASSIGN_OBJ_OP, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, OP)
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data;
@ -970,7 +970,7 @@ ZEND_VM_C_LABEL(assign_op_object):
}
/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
ZEND_VM_HELPER(zend_binary_assign_op_static_prop_helper, ANY, ANY)
ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP)
{
/* This helper actually never will receive IS_VAR as second op, and has the same handling for VAR and TMP in the first op, but for interoperability with the other binary_assign_op helpers, it is necessary to "include" it */
@ -1018,7 +1018,7 @@ ZEND_VM_HELPER(zend_binary_assign_op_static_prop_helper, ANY, ANY)
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HELPER(zend_binary_assign_op_dim_helper, VAR|CV, CONST|TMPVAR|UNUSED|CV)
ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMPVAR|UNUSED|THIS|CV, OP)
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data1;
@ -1118,7 +1118,7 @@ ZEND_VM_C_LABEL(assign_dim_op_ret_null):
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HELPER(zend_binary_assign_op_simple_helper, VAR|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMPVAR|CV, OP)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@ -1156,83 +1156,6 @@ ZEND_VM_HELPER(zend_binary_assign_op_simple_helper, VAR|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_INLINE_HELPER(zend_binary_assign_op_helper, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, SPEC(DIM_OBJ))
{
USE_OPLINE
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_simple_helper);
}
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper);
}
if (UNEXPECTED(opline->extended_value == ZEND_ASSIGN_STATIC_PROP)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_static_prop_helper);
}
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper);
}
ZEND_VM_HANDLER(22, ZEND_ASSIGN_ADD, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(23, ZEND_ASSIGN_SUB, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(24, ZEND_ASSIGN_MUL, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(25, ZEND_ASSIGN_DIV, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(26, ZEND_ASSIGN_MOD, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(27, ZEND_ASSIGN_SL, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(28, ZEND_ASSIGN_SR, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(29, ZEND_ASSIGN_CONCAT, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(30, ZEND_ASSIGN_BW_OR, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_AND, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_XOR, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HANDLER(33, ZEND_ASSIGN_POW, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ))
{
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper);
}
ZEND_VM_HELPER(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
@ -1416,13 +1339,13 @@ ZEND_VM_HELPER(zend_pre_incdec_static_property_helper, ANY, ANY)
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
ZEND_VM_HANDLER(200, ZEND_PRE_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
ZEND_VM_HANDLER(38, ZEND_PRE_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_static_property_helper);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
ZEND_VM_HANDLER(201, ZEND_PRE_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
ZEND_VM_HANDLER(39, ZEND_PRE_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_static_property_helper);
}
@ -1447,13 +1370,13 @@ ZEND_VM_HELPER(zend_post_incdec_static_property_helper, ANY, ANY)
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
ZEND_VM_HANDLER(202, ZEND_POST_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
ZEND_VM_HANDLER(40, ZEND_POST_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_static_property_helper);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
ZEND_VM_HANDLER(203, ZEND_POST_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
ZEND_VM_HANDLER(41, ZEND_POST_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_static_property_helper);
}
@ -1645,7 +1568,7 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
ZEND_VM_HANDLER(136, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
{
USE_OPLINE
zend_free_op free_op1;
@ -2340,7 +2263,7 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVARCV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(198, ZEND_FETCH_LIST_W, VAR, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(155, ZEND_FETCH_LIST_W, VAR, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@ -2364,7 +2287,7 @@ ZEND_VM_HANDLER(198, ZEND_FETCH_LIST_W, VAR, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
ZEND_VM_HANDLER(24, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data;
@ -2516,7 +2439,7 @@ ZEND_VM_C_LABEL(exit_assign_obj):
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
ZEND_VM_HANDLER(205, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
{
USE_OPLINE
zend_free_op free_op_data;
@ -2548,7 +2471,7 @@ ZEND_VM_HANDLER(205, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV))
ZEND_VM_HANDLER(23, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV))
{
USE_OPLINE
zend_free_op free_op1;
@ -2665,7 +2588,7 @@ ZEND_VM_C_LABEL(assign_dim_error):
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL))
ZEND_VM_HANDLER(22, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL))
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@ -2693,7 +2616,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL))
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
ZEND_VM_HANDLER(30, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@ -2733,7 +2656,7 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(204, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT|SRC, SPEC(OP_DATA=VAR|CV))
ZEND_VM_HANDLER(32, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT|SRC, SPEC(OP_DATA=VAR|CV))
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data;
@ -2776,7 +2699,7 @@ ZEND_VM_HANDLER(204, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, C
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
ZEND_VM_HANDLER(206, ZEND_ASSIGN_STATIC_PROP_REF, ANY, ANY, CACHE_SLOT|SRC)
ZEND_VM_HANDLER(33, ZEND_ASSIGN_STATIC_PROP_REF, ANY, ANY, CACHE_SLOT|SRC)
{
USE_OPLINE
zend_free_op free_op_data;
@ -5636,7 +5559,7 @@ ZEND_VM_C_LABEL(num_index):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(208, ZEND_ADD_ARRAY_UNPACK, ANY, ANY)
ZEND_VM_HANDLER(147, ZEND_ADD_ARRAY_UNPACK, ANY, ANY)
{
USE_OPLINE
zend_free_op free_op1;
@ -5925,7 +5848,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(196, ZEND_UNSET_CV, CV, UNUSED)
ZEND_VM_HANDLER(153, ZEND_UNSET_CV, CV, UNUSED)
{
USE_OPLINE
zval *var = EX_VAR(opline->op1.var);
@ -6668,7 +6591,7 @@ ZEND_VM_C_LABEL(fe_fetch_w_exit):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HOT_HANDLER(197, ZEND_ISSET_ISEMPTY_CV, CV, UNUSED, ISSET, SPEC(ISSET))
ZEND_VM_HOT_HANDLER(154, ZEND_ISSET_ISEMPTY_CV, CV, UNUSED, ISSET, SPEC(ISSET))
{
USE_OPLINE
zval *value;
@ -6908,7 +6831,7 @@ ZEND_VM_C_LABEL(isset_object_finish):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(199, ZEND_ARRAY_KEY_EXISTS, CV|TMPVAR|CONST, CV|TMPVAR|CONST)
ZEND_VM_HANDLER(194, ZEND_ARRAY_KEY_EXISTS, CV|TMPVAR|CONST, CV|TMPVAR|CONST)
{
USE_OPLINE
@ -7109,7 +7032,7 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMPVAR|CV, JMP_ADDR)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HOT_HANDLER(41, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
ZEND_VM_HOT_HANDLER(31, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
{
USE_OPLINE
zend_free_op free_op1;
@ -7214,7 +7137,7 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_CLASS_DELAYED, CONST, CONST)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY, JMP_ADDR)
ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY, JMP_ADDR)
{
zval *zv;
zend_class_entry *ce;
@ -7500,7 +7423,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
ZEND_VM_HANDLER(142, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
{
USE_OPLINE
zval *zfunc;
@ -7693,7 +7616,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
ZEND_VM_RETURN();
}
ZEND_VM_HANDLER(142, ZEND_YIELD_FROM, CONST|TMP|VAR|CV, ANY)
ZEND_VM_HANDLER(166, ZEND_YIELD_FROM, CONST|TMP|VAR|CV, ANY)
{
USE_OPLINE
@ -8621,7 +8544,7 @@ ZEND_VM_COLD_CONST_HANDLER(193, ZEND_GET_TYPE, CONST|TMP|VAR|CV, UNUSED)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(194, ZEND_FUNC_NUM_ARGS, UNUSED, UNUSED)
ZEND_VM_HANDLER(171, ZEND_FUNC_NUM_ARGS, UNUSED, UNUSED)
{
USE_OPLINE
@ -8629,7 +8552,7 @@ ZEND_VM_HANDLER(194, ZEND_FUNC_NUM_ARGS, UNUSED, UNUSED)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
ZEND_VM_HANDLER(172, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
{
USE_OPLINE
zend_array *ht;
@ -8704,7 +8627,7 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(207, ZEND_COPY_TMP, TMPVAR, UNUSED)
ZEND_VM_HANDLER(167, ZEND_COPY_TMP, TMPVAR, UNUSED)
{
USE_OPLINE
zend_free_op free_op1;

File diff suppressed because it is too large Load Diff

View File

@ -82,7 +82,7 @@ $vm_op_flags = array(
"ZEND_VM_EXT_NUM" => 0x01000000,
"ZEND_VM_EXT_LAST_CATCH" => 0x02000000,
"ZEND_VM_EXT_JMP_ADDR" => 0x03000000,
"ZEND_VM_EXT_DIM_OBJ" => 0x04000000,
"ZEND_VM_EXT_OP" => 0x04000000,
// unused 0x5000000
// unused 0x6000000
"ZEND_VM_EXT_TYPE" => 0x07000000,
@ -123,7 +123,7 @@ $vm_ext_decode = array(
"NUM" => ZEND_VM_EXT_NUM,
"LAST_CATCH" => ZEND_VM_EXT_LAST_CATCH,
"JMP_ADDR" => ZEND_VM_EXT_JMP_ADDR,
"DIM_OBJ" => ZEND_VM_EXT_DIM_OBJ,
"OP" => ZEND_VM_EXT_OP,
"VAR_FETCH" => ZEND_VM_EXT_VAR_FETCH,
"ARRAY_INIT" => ZEND_VM_EXT_ARRAY_INIT,
"TYPE" => ZEND_VM_EXT_TYPE,
@ -839,44 +839,12 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name, $extra_sp
: ($extra_spec['SMART_BRANCH'] == 2 ?
"ZEND_VM_SMART_BRANCH_JMPNZ(\\1, \\2)" : ""))
: "ZEND_VM_SMART_BRANCH(\\1, \\2)",
"/opline->extended_value\s*==\s*0/" => isset($extra_spec['DIM_OBJ']) ?
($extra_spec['DIM_OBJ'] == 0 ? "1" : "0")
: "\\0",
"/opline->extended_value\s*==\s*ZEND_ASSIGN_DIM/" => isset($extra_spec['DIM_OBJ']) ?
($extra_spec['DIM_OBJ'] == 1 ? "1" : "0")
: "\\0",
"/opline->extended_value\s*==\s*ZEND_ASSIGN_OBJ/" => isset($extra_spec['DIM_OBJ']) ?
($extra_spec['DIM_OBJ'] == 2 ? "1" : "0")
: "\\0",
"/opline->extended_value\s*==\s*ZEND_ASSIGN_STATIC_PROP/" => isset($extra_spec['DIM_OBJ']) ?
($extra_spec['DIM_OBJ'] == 3 ? "1" : "0")
: "\\0",
"/opline->extended_value\s*&\s*ZEND_ISEMPTY/" => isset($extra_spec['ISSET']) ?
($extra_spec['ISSET'] == 0 ? "0" : "1")
: "\\0",
"/opline->extended_value\s*&\s*~\s*ZEND_ISEMPTY/" => isset($extra_spec['ISSET']) ?
($extra_spec['ISSET'] == 0 ? "\\0" : "opline->extended_value")
: "\\0",
"/zend_binary_assign_op_helper/" =>
isset($extra_spec['DIM_OBJ']) ?
(
$extra_spec['DIM_OBJ'] < 2 ?
(
$extra_spec['DIM_OBJ'] == 0 ?
"zend_binary_assign_op_simple_helper"
:
"zend_binary_assign_op_dim_helper"
)
:
(
$extra_spec['DIM_OBJ'] == 2 ?
"zend_binary_assign_op_obj_helper"
:
"zend_binary_assign_op_static_prop_helper"
)
)
:
"zend_binary_assign_op_helper",
);
$code = preg_replace(array_keys($specialized_replacements), array_values($specialized_replacements), $code);
@ -1056,15 +1024,6 @@ function skip_extra_spec_function($op1, $op2, $extra_spec) {
return true;
}
if (isset($extra_spec["DIM_OBJ"]) &&
((($op1 == "CONST" || $op1 == "TMP") && $extra_spec["DIM_OBJ"] != 3) ||
($op2 == "UNUSED" && $extra_spec["DIM_OBJ"] != 1 && $extra_spec["DIM_OBJ"] != 3) ||
($op2 == "CV" && $extra_spec["DIM_OBJ"] == 3) ||
($op1 == "UNUSED" && $extra_spec["DIM_OBJ"] != 2))) {
// Skip useless handlers
return true;
}
return false;
}
@ -1110,18 +1069,6 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno,
return;
}
// Prevent generation of specialized ZEND_ASSIGN_OP_..._STATIC_PROP
// handlers, that call unspecialized helper, anyway.
if ($spec &&
isset($extra_spec["DIM_OBJ"]) &&
$extra_spec["DIM_OBJ"] == 3) {
if ($op1 == 'CONST' && $op2 == 'CONST') {
$op1 = $op2 = 'ANY';
} else {
return;
}
}
if (ZEND_VM_LINES) {
out($f, "#line $lineno \"$definition_file\"\n");
}
@ -1201,18 +1148,6 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno,
return;
}
// Prevent generation of specialized ZEND_ASSIGN_OP_..._STATIC_PROP
// handlers, that call unspecialized helper, anyway.
if ($spec &&
isset($extra_spec["DIM_OBJ"]) &&
$extra_spec["DIM_OBJ"] == 3) {
if ($op1 == 'CONST' && $op2 == 'CONST') {
$op1 = $op2 = 'ANY';
} else {
return;
}
}
if (ZEND_VM_LINES) {
out($f, "#line $lineno \"$definition_file\"\n");
}
@ -1426,13 +1361,6 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
return;
}
// Prevent generation of specialized ZEND_ASSIGN_OP_..._STATIC_PROP
// handlers, that call unspecialized helper, anyway.
if (isset($extra_spec["DIM_OBJ"]) &&
$extra_spec["DIM_OBJ"] == 3) {
$op1 = $op2 = 'ANY';
}
// Emit pointer to specialized handler
$spec_name = $dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec);
switch ($kind) {
@ -1612,15 +1540,6 @@ function extra_spec_name($extra_spec) {
$s .= "_JMPNZ";
}
}
if (isset($extra_spec["DIM_OBJ"])) {
if ($extra_spec["DIM_OBJ"] == 1) {
$s .= "_DIM";
} else if ($extra_spec["DIM_OBJ"] == 2) {
$s .= "_OBJ";
} else if ($extra_spec["DIM_OBJ"] == 3) {
$s .= "_STATIC_PROP";
}
}
if (isset($extra_spec["ISSET"])) {
if ($extra_spec["ISSET"] == 0) {
$s .= "_SET";
@ -1645,9 +1564,6 @@ function extra_spec_flags($extra_spec) {
if (isset($extra_spec["SMART_BRANCH"])) {
$s[] = "SPEC_RULE_SMART_BRANCH";
}
if (isset($extra_spec["DIM_OBJ"])) {
$s[] = "SPEC_RULE_DIM_OBJ";
}
if (isset($extra_spec["COMMUTATIVE"])) {
$s[] = "SPEC_RULE_COMMUTATIVE";
}
@ -1850,7 +1766,6 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
out($f,"#define SPEC_RULE_RETVAL 0x00080000\n");
out($f,"#define SPEC_RULE_QUICK_ARG 0x00100000\n");
out($f,"#define SPEC_RULE_SMART_BRANCH 0x00200000\n");
out($f,"#define SPEC_RULE_DIM_OBJ 0x00400000\n");
out($f,"#define SPEC_RULE_COMMUTATIVE 0x00800000\n");
out($f,"#define SPEC_RULE_ISSET 0x01000000\n");
out($f,"\n");
@ -2337,9 +2252,6 @@ function parse_spec_rules($def, $lineno, $str) {
case "SMART_BRANCH":
$ret["SMART_BRANCH"] = array(0, 1, 2);
break;
case "DIM_OBJ":
$ret["DIM_OBJ"] = array(0, 1, 2, 3);
break;
case "NO_CONST_CONST":
$ret["NO_CONST_CONST"] = array(1);
break;
@ -2760,7 +2672,6 @@ function gen_vm($def, $skel) {
isset($used_extra_spec["RETVAL"]) ||
isset($used_extra_spec["QUICK_ARG"]) ||
isset($used_extra_spec["SMART_BRANCH"]) ||
isset($used_extra_spec["DIM_OBJ"]) ||
isset($used_extra_spec["ISSET"])) {
$else = "";
@ -2781,18 +2692,6 @@ function gen_vm($def, $skel) {
out($f, "\t\t\toffset = offset * 5 + zend_vm_decode[(op + 1)->op1_type];\n");
$else = "} else ";
}
if (isset($used_extra_spec["DIM_OBJ"])) {
out($f, "\t\t{$else}if (spec & SPEC_RULE_DIM_OBJ) {\n");
out($f, "\t\t\toffset = offset * 4;\n");
out($f, "\t\t\tif (op->extended_value == ZEND_ASSIGN_DIM) {\n");
out($f, "\t\t\t\toffset += 1;\n");
out($f, "\t\t\t} else if (op->extended_value == ZEND_ASSIGN_OBJ) {\n");
out($f, "\t\t\t\toffset += 2;\n");
out($f, "\t\t\t} else if (op->extended_value == ZEND_ASSIGN_STATIC_PROP) {\n");
out($f, "\t\t\t\toffset += 3;\n");
out($f, "\t\t\t}\n");
$else = "} else ";
}
if (isset($used_extra_spec["ISSET"])) {
out($f, "\t\t{$else}if (spec & SPEC_RULE_ISSET) {\n");
out($f, "\t\t\toffset = offset * 2 + (op->extended_value & ZEND_ISEMPTY);\n");
@ -2855,7 +2754,6 @@ function gen_vm($def, $skel) {
isset($used_extra_spec["RETVAL"]) ||
isset($used_extra_spec["QUICK_ARG"]) ||
isset($used_extra_spec["SMART_BRANCH"]) ||
isset($used_extra_spec["DIM_OBJ"]) ||
isset($used_extra_spec["ISSET"])) {
$else = "";
@ -2884,19 +2782,6 @@ function gen_vm($def, $skel) {
out($f, "\t\t}\n");
$else = "else ";
}
if (isset($used_extra_spec["DIM_OBJ"])) {
out($f, "\t\t{$else}if (spec & SPEC_RULE_DIM_OBJ) {\n");
out($f, "\t\t\toffset = offset * 4;\n");
out($f, "\t\t\tif (op->extended_value == ZEND_ASSIGN_DIM) {\n");
out($f, "\t\t\t\toffset += 1;\n");
out($f, "\t\t\t} else if (op->extended_value == ZEND_ASSIGN_OBJ) {\n");
out($f, "\t\t\t\toffset += 2;\n");
out($f, "\t\t\t} else if (op->extended_value == ZEND_ASSIGN_STATIC_PROP) {\n");
out($f, "\t\t\t\toffset += 3;\n");
out($f, "\t\t\t}\n");
out($f, "\t\t}\n");
$else = "else ";
}
if (isset($used_extra_spec["ISSET"])) {
out($f, "\t\t{$else}if (spec & SPEC_RULE_ISSET) offset = offset * 2 + (op->extended_value & ZEND_ISEMPTY);\n");
$else = "else ";

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@
#include <zend.h>
#include <zend_vm_opcodes.h>
static const char *zend_vm_opcodes_names[209] = {
static const char *zend_vm_opcodes_names[195] = {
"ZEND_NOP",
"ZEND_ADD",
"ZEND_SUB",
@ -45,26 +45,26 @@ static const char *zend_vm_opcodes_names[209] = {
"ZEND_IS_NOT_EQUAL",
"ZEND_IS_SMALLER",
"ZEND_IS_SMALLER_OR_EQUAL",
"ZEND_ASSIGN_ADD",
"ZEND_ASSIGN_SUB",
"ZEND_ASSIGN_MUL",
"ZEND_ASSIGN_DIV",
"ZEND_ASSIGN_MOD",
"ZEND_ASSIGN_SL",
"ZEND_ASSIGN_SR",
"ZEND_ASSIGN_CONCAT",
"ZEND_ASSIGN_BW_OR",
"ZEND_ASSIGN_BW_AND",
"ZEND_ASSIGN_BW_XOR",
"ZEND_ASSIGN_POW",
"ZEND_ASSIGN",
"ZEND_ASSIGN_DIM",
"ZEND_ASSIGN_OBJ",
"ZEND_ASSIGN_STATIC_PROP",
"ZEND_ASSIGN_OP",
"ZEND_ASSIGN_DIM_OP",
"ZEND_ASSIGN_OBJ_OP",
"ZEND_ASSIGN_STATIC_PROP_OP",
"ZEND_ASSIGN_REF",
"ZEND_QM_ASSIGN",
"ZEND_ASSIGN_OBJ_REF",
"ZEND_ASSIGN_STATIC_PROP_REF",
"ZEND_PRE_INC",
"ZEND_PRE_DEC",
"ZEND_POST_INC",
"ZEND_POST_DEC",
"ZEND_ASSIGN",
"ZEND_ASSIGN_REF",
"ZEND_ECHO",
"ZEND_QM_ASSIGN",
"ZEND_PRE_INC_STATIC_PROP",
"ZEND_PRE_DEC_STATIC_PROP",
"ZEND_POST_INC_STATIC_PROP",
"ZEND_POST_DEC_STATIC_PROP",
"ZEND_JMP",
"ZEND_JMPZ",
"ZEND_JMPNZ",
@ -159,26 +159,26 @@ static const char *zend_vm_opcodes_names[209] = {
"ZEND_PRE_DEC_OBJ",
"ZEND_POST_INC_OBJ",
"ZEND_POST_DEC_OBJ",
"ZEND_ASSIGN_OBJ",
"ZEND_ECHO",
"ZEND_OP_DATA",
"ZEND_INSTANCEOF",
"ZEND_GENERATOR_CREATE",
"ZEND_MAKE_REF",
"ZEND_DECLARE_FUNCTION",
"ZEND_YIELD_FROM",
"ZEND_DECLARE_LAMBDA_FUNCTION",
"ZEND_DECLARE_CONST",
"ZEND_DECLARE_CLASS",
"ZEND_DECLARE_CLASS_DELAYED",
NULL,
"ZEND_ASSIGN_DIM",
"ZEND_DECLARE_ANON_CLASS",
"ZEND_ADD_ARRAY_UNPACK",
"ZEND_ISSET_ISEMPTY_PROP_OBJ",
"ZEND_HANDLE_EXCEPTION",
"ZEND_USER_OPCODE",
"ZEND_ASSERT_CHECK",
"ZEND_JMP_SET",
"ZEND_DECLARE_LAMBDA_FUNCTION",
NULL,
NULL,
"ZEND_UNSET_CV",
"ZEND_ISSET_ISEMPTY_CV",
"ZEND_FETCH_LIST_W",
"ZEND_SEPARATE",
"ZEND_FETCH_CLASS_NAME",
"ZEND_CALL_TRAMPOLINE",
@ -189,13 +189,13 @@ static const char *zend_vm_opcodes_names[209] = {
"ZEND_FAST_RET",
"ZEND_RECV_VARIADIC",
"ZEND_SEND_UNPACK",
NULL,
NULL,
"ZEND_YIELD_FROM",
"ZEND_COPY_TMP",
"ZEND_BIND_GLOBAL",
"ZEND_COALESCE",
"ZEND_SPACESHIP",
"ZEND_DECLARE_ANON_CLASS",
NULL,
"ZEND_FUNC_NUM_ARGS",
"ZEND_FUNC_GET_ARGS",
"ZEND_FETCH_STATIC_PROP_R",
"ZEND_FETCH_STATIC_PROP_W",
"ZEND_FETCH_STATIC_PROP_RW",
@ -217,24 +217,10 @@ static const char *zend_vm_opcodes_names[209] = {
"ZEND_GET_CLASS",
"ZEND_GET_CALLED_CLASS",
"ZEND_GET_TYPE",
"ZEND_FUNC_NUM_ARGS",
"ZEND_FUNC_GET_ARGS",
"ZEND_UNSET_CV",
"ZEND_ISSET_ISEMPTY_CV",
"ZEND_FETCH_LIST_W",
"ZEND_ARRAY_KEY_EXISTS",
"ZEND_PRE_INC_STATIC_PROP",
"ZEND_PRE_DEC_STATIC_PROP",
"ZEND_POST_INC_STATIC_PROP",
"ZEND_POST_DEC_STATIC_PROP",
"ZEND_ASSIGN_OBJ_REF",
"ZEND_ASSIGN_STATIC_PROP",
"ZEND_ASSIGN_STATIC_PROP_REF",
"ZEND_COPY_TMP",
"ZEND_ADD_ARRAY_UNPACK",
};
static uint32_t zend_vm_opcodes_flags[209] = {
static uint32_t zend_vm_opcodes_flags[195] = {
0x00000000,
0x00000707,
0x00000707,
@ -257,26 +243,26 @@ static uint32_t zend_vm_opcodes_flags[209] = {
0x80000707,
0x00000707,
0x00000707,
0x04046753,
0x04046753,
0x04046753,
0x04046753,
0x04046753,
0x04046753,
0x04046753,
0x04046753,
0x04046753,
0x04046753,
0x04046753,
0x04046753,
0x00000001,
0x00000001,
0x00000001,
0x00000001,
0x00000301,
0x00006701,
0x00040751,
0x00040000,
0x04000701,
0x04005701,
0x04000751,
0x04000000,
0x0b000101,
0x00000007,
0x00000003,
0x0b040751,
0x0b040000,
0x00000001,
0x00000001,
0x00000001,
0x00000001,
0x00040000,
0x00040000,
0x00040000,
0x00040000,
0x00000020,
0x00002007,
0x00002007,
@ -371,26 +357,26 @@ static uint32_t zend_vm_opcodes_flags[209] = {
0x00040751,
0x00040751,
0x00040751,
0x00040751,
0x00000007,
0x00000000,
0x00047305,
0x00000000,
0x00000101,
0x00000000,
0x00000003,
0x00000103,
0x00000303,
0x00000003,
0x00000303,
0x03000000,
0x00000000,
0x00006701,
0x00060757,
0x00000000,
0x00000000,
0x00002000,
0x00002003,
0x00000103,
0x00000000,
0x00000000,
0x00000101,
0x00020101,
0x00000701,
0x00000101,
0x00000071,
0x00000000,
@ -401,13 +387,13 @@ static uint32_t zend_vm_opcodes_flags[209] = {
0x00003000,
0x0000a110,
0x00000000,
0x00000000,
0x00000000,
0x00000003,
0x00000105,
0x00040301,
0x00002007,
0x00000707,
0x03000000,
0x00000000,
0x00000101,
0x00000103,
0x00047000,
0x00647000,
0x00047000,
@ -429,21 +415,7 @@ static uint32_t zend_vm_opcodes_flags[209] = {
0x00000103,
0x00000101,
0x00000103,
0x00000101,
0x00000103,
0x00000101,
0x00020101,
0x00000701,
0x00000707,
0x00040000,
0x00040000,
0x00040000,
0x00040000,
0x0b040751,
0x00040000,
0x0b040000,
0x00000105,
0x00000000,
};
ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(zend_uchar opcode) {

View File

@ -59,7 +59,7 @@
#define ZEND_VM_EXT_NUM 0x01000000
#define ZEND_VM_EXT_LAST_CATCH 0x02000000
#define ZEND_VM_EXT_JMP_ADDR 0x03000000
#define ZEND_VM_EXT_DIM_OBJ 0x04000000
#define ZEND_VM_EXT_OP 0x04000000
#define ZEND_VM_EXT_TYPE 0x07000000
#define ZEND_VM_EXT_EVAL 0x08000000
#define ZEND_VM_EXT_TYPE_MASK 0x09000000
@ -98,26 +98,26 @@ END_EXTERN_C()
#define ZEND_IS_NOT_EQUAL 19
#define ZEND_IS_SMALLER 20
#define ZEND_IS_SMALLER_OR_EQUAL 21
#define ZEND_ASSIGN_ADD 22
#define ZEND_ASSIGN_SUB 23
#define ZEND_ASSIGN_MUL 24
#define ZEND_ASSIGN_DIV 25
#define ZEND_ASSIGN_MOD 26
#define ZEND_ASSIGN_SL 27
#define ZEND_ASSIGN_SR 28
#define ZEND_ASSIGN_CONCAT 29
#define ZEND_ASSIGN_BW_OR 30
#define ZEND_ASSIGN_BW_AND 31
#define ZEND_ASSIGN_BW_XOR 32
#define ZEND_ASSIGN_POW 33
#define ZEND_ASSIGN 22
#define ZEND_ASSIGN_DIM 23
#define ZEND_ASSIGN_OBJ 24
#define ZEND_ASSIGN_STATIC_PROP 25
#define ZEND_ASSIGN_OP 26
#define ZEND_ASSIGN_DIM_OP 27
#define ZEND_ASSIGN_OBJ_OP 28
#define ZEND_ASSIGN_STATIC_PROP_OP 29
#define ZEND_ASSIGN_REF 30
#define ZEND_QM_ASSIGN 31
#define ZEND_ASSIGN_OBJ_REF 32
#define ZEND_ASSIGN_STATIC_PROP_REF 33
#define ZEND_PRE_INC 34
#define ZEND_PRE_DEC 35
#define ZEND_POST_INC 36
#define ZEND_POST_DEC 37
#define ZEND_ASSIGN 38
#define ZEND_ASSIGN_REF 39
#define ZEND_ECHO 40
#define ZEND_QM_ASSIGN 41
#define ZEND_PRE_INC_STATIC_PROP 38
#define ZEND_PRE_DEC_STATIC_PROP 39
#define ZEND_POST_INC_STATIC_PROP 40
#define ZEND_POST_DEC_STATIC_PROP 41
#define ZEND_JMP 42
#define ZEND_JMPZ 43
#define ZEND_JMPNZ 44
@ -212,23 +212,26 @@ END_EXTERN_C()
#define ZEND_PRE_DEC_OBJ 133
#define ZEND_POST_INC_OBJ 134
#define ZEND_POST_DEC_OBJ 135
#define ZEND_ASSIGN_OBJ 136
#define ZEND_ECHO 136
#define ZEND_OP_DATA 137
#define ZEND_INSTANCEOF 138
#define ZEND_GENERATOR_CREATE 139
#define ZEND_MAKE_REF 140
#define ZEND_DECLARE_FUNCTION 141
#define ZEND_YIELD_FROM 142
#define ZEND_DECLARE_LAMBDA_FUNCTION 142
#define ZEND_DECLARE_CONST 143
#define ZEND_DECLARE_CLASS 144
#define ZEND_DECLARE_CLASS_DELAYED 145
#define ZEND_ASSIGN_DIM 147
#define ZEND_DECLARE_ANON_CLASS 146
#define ZEND_ADD_ARRAY_UNPACK 147
#define ZEND_ISSET_ISEMPTY_PROP_OBJ 148
#define ZEND_HANDLE_EXCEPTION 149
#define ZEND_USER_OPCODE 150
#define ZEND_ASSERT_CHECK 151
#define ZEND_JMP_SET 152
#define ZEND_DECLARE_LAMBDA_FUNCTION 153
#define ZEND_UNSET_CV 153
#define ZEND_ISSET_ISEMPTY_CV 154
#define ZEND_FETCH_LIST_W 155
#define ZEND_SEPARATE 156
#define ZEND_FETCH_CLASS_NAME 157
#define ZEND_CALL_TRAMPOLINE 158
@ -239,10 +242,13 @@ END_EXTERN_C()
#define ZEND_FAST_RET 163
#define ZEND_RECV_VARIADIC 164
#define ZEND_SEND_UNPACK 165
#define ZEND_YIELD_FROM 166
#define ZEND_COPY_TMP 167
#define ZEND_BIND_GLOBAL 168
#define ZEND_COALESCE 169
#define ZEND_SPACESHIP 170
#define ZEND_DECLARE_ANON_CLASS 171
#define ZEND_FUNC_NUM_ARGS 171
#define ZEND_FUNC_GET_ARGS 172
#define ZEND_FETCH_STATIC_PROP_R 173
#define ZEND_FETCH_STATIC_PROP_W 174
#define ZEND_FETCH_STATIC_PROP_RW 175
@ -264,22 +270,8 @@ END_EXTERN_C()
#define ZEND_GET_CLASS 191
#define ZEND_GET_CALLED_CLASS 192
#define ZEND_GET_TYPE 193
#define ZEND_FUNC_NUM_ARGS 194
#define ZEND_FUNC_GET_ARGS 195
#define ZEND_UNSET_CV 196
#define ZEND_ISSET_ISEMPTY_CV 197
#define ZEND_FETCH_LIST_W 198
#define ZEND_ARRAY_KEY_EXISTS 199
#define ZEND_PRE_INC_STATIC_PROP 200
#define ZEND_PRE_DEC_STATIC_PROP 201
#define ZEND_POST_INC_STATIC_PROP 202
#define ZEND_POST_DEC_STATIC_PROP 203
#define ZEND_ASSIGN_OBJ_REF 204
#define ZEND_ASSIGN_STATIC_PROP 205
#define ZEND_ASSIGN_STATIC_PROP_REF 206
#define ZEND_COPY_TMP 207
#define ZEND_ADD_ARRAY_UNPACK 208
#define ZEND_ARRAY_KEY_EXISTS 194
#define ZEND_VM_LAST_OPCODE 208
#define ZEND_VM_LAST_OPCODE 194
#endif

View File

@ -1712,18 +1712,10 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
if (opline->result_type == IS_VAR) {
if (!zend_bitset_in(usage, VAR_NUM(opline->result.var))) {
switch (opline->opcode) {
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_ASSIGN:

View File

@ -197,7 +197,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
case ZEND_PRE_DEC_STATIC_PROP:
case ZEND_POST_INC_STATIC_PROP:
case ZEND_POST_DEC_STATIC_PROP:
literals_handle_static_prop:
case ZEND_ASSIGN_STATIC_PROP_OP:
if (opline->op2_type == IS_CONST) {
LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 2);
}
@ -230,39 +230,11 @@ literals_handle_static_prop:
case ZEND_POST_INC_OBJ:
case ZEND_POST_DEC_OBJ:
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
case ZEND_ASSIGN_OBJ_OP:
if (opline->op2_type == IS_CONST) {
LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1);
}
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
goto literals_handle_static_prop;
}
if (opline->op2_type == IS_CONST) {
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1);
} else if (opline->extended_value == ZEND_ASSIGN_DIM) {
if (Z_EXTRA(op_array->literals[opline->op2.constant]) == ZEND_EXTRA_VALUE) {
LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 2);
} else {
LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1);
}
} else {
LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1);
}
}
break;
case ZEND_BIND_GLOBAL:
LITERAL_INFO(opline->op2.constant, LITERAL_GLOBAL, 1);
break;
@ -290,6 +262,7 @@ literals_handle_static_prop:
case ZEND_FETCH_DIM_UNSET:
case ZEND_FETCH_LIST_R:
case ZEND_FETCH_LIST_W:
case ZEND_ASSIGN_DIM_OP:
if (opline->op1_type == IS_CONST) {
LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1);
}
@ -548,54 +521,41 @@ literals_handle_static_prop:
cache_size += sizeof(void *);
}
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
if (opline->op1_type == IS_CONST) {
// op1 static property
if (opline->op2_type == IS_CONST) {
(opline+1)->extended_value = add_static_slot(&hash, op_array,
opline->op2.constant,
opline->op1.constant,
LITERAL_STATIC_PROPERTY,
&cache_size);
} else {
(opline+1)->extended_value = cache_size;
cache_size += 3 * sizeof(void *);
}
} else if (opline->op2_type == IS_CONST) {
// op2 class
if (class_slot[opline->op2.constant] >= 0) {
(opline+1)->extended_value = class_slot[opline->op2.constant];
} else {
(opline+1)->extended_value = cache_size;
class_slot[opline->op2.constant] = cache_size;
cache_size += sizeof(void *);
}
case ZEND_ASSIGN_STATIC_PROP_OP:
if (opline->op1_type == IS_CONST) {
// op1 static property
if (opline->op2_type == IS_CONST) {
(opline+1)->extended_value = add_static_slot(&hash, op_array,
opline->op2.constant,
opline->op1.constant,
LITERAL_STATIC_PROPERTY,
&cache_size);
} else {
(opline+1)->extended_value = cache_size;
cache_size += 3 * sizeof(void *);
}
} else if (opline->op2_type == IS_CONST) {
// op2 class
if (class_slot[opline->op2.constant] >= 0) {
(opline+1)->extended_value = class_slot[opline->op2.constant];
} else {
(opline+1)->extended_value = cache_size;
class_slot[opline->op2.constant] = cache_size;
cache_size += sizeof(void *);
}
}
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
if (opline->op2_type == IS_CONST) {
// op2 property
if (opline->op1_type == IS_UNUSED &&
property_slot[opline->op2.constant] >= 0) {
(opline+1)->extended_value = property_slot[opline->op2.constant];
} else {
(opline+1)->extended_value = cache_size;
cache_size += 3 * sizeof(void *);
if (opline->op1_type == IS_UNUSED) {
property_slot[opline->op2.constant] = (opline+1)->extended_value;
}
break;
case ZEND_ASSIGN_OBJ_OP:
if (opline->op2_type == IS_CONST) {
// op2 property
if (opline->op1_type == IS_UNUSED &&
property_slot[opline->op2.constant] >= 0) {
(opline+1)->extended_value = property_slot[opline->op2.constant];
} else {
(opline+1)->extended_value = cache_size;
cache_size += 3 * sizeof(void *);
if (opline->op1_type == IS_UNUSED) {
property_slot[opline->op2.constant] = (opline+1)->extended_value;
}
}
}

View File

@ -201,21 +201,9 @@ static inline zend_bool may_have_side_effects(
case ZEND_PRE_DEC:
case ZEND_POST_DEC:
return is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def);
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
return is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def)
|| (opline->extended_value
&& ssa->vars[ssa_op->op1_def].escape_state != ESCAPE_STATE_NO_ESCAPE);
|| ssa->vars[ssa_op->op1_def].escape_state != ESCAPE_STATE_NO_ESCAPE;
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
if (is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def)
@ -349,18 +337,10 @@ static zend_bool try_remove_var_def(context *ctx, int free_var, int use_chain, z
case ZEND_ASSIGN_OBJ_REF:
case ZEND_ASSIGN_STATIC_PROP:
case ZEND_ASSIGN_STATIC_PROP_REF:
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_PRE_INC_OBJ:

View File

@ -1180,8 +1180,8 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
}
}
} else if (opline->opcode == ZEND_ASSIGN_ADD
&& opline->extended_value == 0
} else if (opline->opcode == ZEND_ASSIGN_OP
&& opline->extended_value == ZEND_ADD
&& ssa->ops[op_1].op1_def == v
&& opline->op2_type == IS_CONST
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) == IS_LONG
@ -1192,10 +1192,11 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
// op_1: ASSIGN_ADD #?.CV [undef,null,int,foat] ->#v.CV, int(1) => PRE_INC #?.CV ->#v.CV
opline->opcode = ZEND_PRE_INC;
opline->extended_value = 0;
SET_UNUSED(opline->op2);
} else if (opline->opcode == ZEND_ASSIGN_SUB
&& opline->extended_value == 0
} else if (opline->opcode == ZEND_ASSIGN_OP
&& opline->extended_value == ZEND_SUB
&& ssa->ops[op_1].op1_def == v
&& opline->op2_type == IS_CONST
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) == IS_LONG
@ -1206,6 +1207,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
// op_1: ASSIGN_SUB #?.CV [undef,null,int,foat] -> #v.CV, int(1) => PRE_DEC #?.CV ->#v.CV
opline->opcode = ZEND_PRE_DEC;
opline->extended_value = 0;
SET_UNUSED(opline->op2);
} else if (opline->opcode == ZEND_VERIFY_RETURN_TYPE
@ -1240,26 +1242,18 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
&& !RETURN_VALUE_USED(opline)
&& ssa->ops[op_1].op1_use >= 0
&& !(ssa->var_info[ssa->ops[op_1].op1_use].type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))
&& (opline->opcode == ZEND_ASSIGN_ADD
|| opline->opcode == ZEND_ASSIGN_SUB
|| opline->opcode == ZEND_ASSIGN_MUL
|| opline->opcode == ZEND_ASSIGN_DIV
|| opline->opcode == ZEND_ASSIGN_MOD
|| opline->opcode == ZEND_ASSIGN_SL
|| opline->opcode == ZEND_ASSIGN_SR
|| opline->opcode == ZEND_ASSIGN_BW_OR
|| opline->opcode == ZEND_ASSIGN_BW_AND
|| opline->opcode == ZEND_ASSIGN_BW_XOR)
&& opline->extended_value == 0) {
&& opline->opcode == ZEND_ASSIGN_OP
&& opline->extended_value != ZEND_CONCAT) {
// op_1: ASSIGN_ADD #orig_var.CV [undef,null,bool,int,double] -> #v.CV, ? => #v.CV = ADD #orig_var.CV, ?
// op_1: ASSIGN_OP #orig_var.CV [undef,null,bool,int,double] -> #v.CV, ? => #v.CV = ADD #orig_var.CV, ?
/* Reconstruct SSA */
ssa->ops[op_1].result_def = ssa->ops[op_1].op1_def;
ssa->ops[op_1].op1_def = -1;
/* Update opcode */
opline->opcode -= (ZEND_ASSIGN_ADD - ZEND_ADD);
opline->opcode = opline->extended_value;
opline->extended_value = 0;
opline->result_type = opline->op1_type;
opline->result.var = opline->op1.var;

View File

@ -257,24 +257,11 @@ static int is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var
} else if (op->op1_def == var) {
switch (opline->opcode) {
case ZEND_ASSIGN:
return 1;
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_OBJ_REF:
return 1;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
return (opline->extended_value != 0);
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_POST_INC_OBJ:
@ -312,22 +299,11 @@ static int is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int va
case ZEND_FETCH_DIM_IS:
case ZEND_FETCH_OBJ_IS:
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
if (!opline->extended_value) {
return 1;
}
/* break missing intentionally */
case ZEND_ASSIGN_OP:
return 1;
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_OBJ_REF:

View File

@ -53,16 +53,6 @@ void zend_optimizer_pass2(zend_op_array *op_array)
}
}
}
/* break missing *intentionally* - the assign_op's may only optimize op2 */
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_POW:
if (opline->extended_value != 0) {
/* object tristate op - don't attempt to optimize it! */
break;
}
if (opline->op2_type == IS_CONST) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
/* don't optimise if it should produce a runtime numeric string error */
@ -85,14 +75,6 @@ void zend_optimizer_pass2(zend_op_array *op_array)
}
}
}
/* break missing *intentionally - the assign_op's may only optimize op2 */
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
if (opline->extended_value != 0) {
/* object tristate op - don't attempt to optimize it! */
break;
}
if (opline->op2_type == IS_CONST) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) {
/* don't optimise if it should produce a runtime numeric string error */
@ -111,12 +93,6 @@ void zend_optimizer_pass2(zend_op_array *op_array)
convert_to_string(&ZEND_OP1_LITERAL(opline));
}
}
/* break missing *intentionally - the assign_op's may only optimize op2 */
case ZEND_ASSIGN_CONCAT:
if (opline->extended_value != 0) {
/* object tristate op - don't attempt to optimize it! */
break;
}
if (opline->op2_type == IS_CONST) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
convert_to_string(&ZEND_OP2_LITERAL(opline));
@ -124,6 +100,37 @@ void zend_optimizer_pass2(zend_op_array *op_array)
}
break;
case ZEND_ASSIGN_OP:
if (opline->op2_type == IS_CONST) {
if (opline->extended_value == ZEND_ADD
|| opline->extended_value == ZEND_SUB
|| opline->extended_value == ZEND_MUL
|| opline->extended_value == ZEND_DIV
|| opline->extended_value == ZEND_POW) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
/* don't optimise if it should produce a runtime numeric string error */
if (is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0)) {
convert_scalar_to_number(&ZEND_OP2_LITERAL(opline));
}
}
} else if (opline->extended_value == ZEND_MOD
|| opline->extended_value == ZEND_SL
|| opline->extended_value == ZEND_SR) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) {
/* don't optimise if it should produce a runtime numeric string error */
if (!(Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING
&& !is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0))) {
convert_to_long(&ZEND_OP2_LITERAL(opline));
}
}
} else if (opline->extended_value == ZEND_CONCAT) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
convert_to_string(&ZEND_OP2_LITERAL(opline));
}
}
}
break;
case ZEND_JMPZ_EX:
case ZEND_JMPNZ_EX:
/* convert Ti = JMPZ_EX(Ti, L) to JMPZ(Ti, L) */

View File

@ -113,47 +113,12 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
}
}
if ((opline->op1_type & (IS_VAR | IS_CV))
if (ZEND_IS_BINARY_ASSIGN_OP_OPCODE(opline->opcode)
&& (opline->op1_type & (IS_VAR | IS_CV))
&& opline->op1.var == next_opline->op1.var
&& opline->op1_type == next_opline->op1_type) {
switch (opline->opcode) {
case ZEND_ADD:
opline->opcode = ZEND_ASSIGN_ADD;
break;
case ZEND_SUB:
opline->opcode = ZEND_ASSIGN_SUB;
break;
case ZEND_MUL:
opline->opcode = ZEND_ASSIGN_MUL;
break;
case ZEND_DIV:
opline->opcode = ZEND_ASSIGN_DIV;
break;
case ZEND_MOD:
opline->opcode = ZEND_ASSIGN_MOD;
break;
case ZEND_POW:
opline->opcode = ZEND_ASSIGN_POW;
break;
case ZEND_CONCAT:
opline->opcode = ZEND_ASSIGN_CONCAT;
break;
case ZEND_SL:
opline->opcode = ZEND_ASSIGN_SL;
break;
case ZEND_SR:
opline->opcode = ZEND_ASSIGN_SR;
break;
case ZEND_BW_OR:
opline->opcode = ZEND_ASSIGN_BW_OR;
break;
case ZEND_BW_AND:
opline->opcode = ZEND_ASSIGN_BW_AND;
break;
case ZEND_BW_XOR:
opline->opcode = ZEND_ASSIGN_BW_XOR;
break;
}
opline->extended_value = opline->opcode;
opline->opcode = ZEND_ASSIGN_OP;
COPY_NODE(opline->result, next_opline->result);
MAKE_NOP(next_opline);
opline++;

View File

@ -222,18 +222,10 @@ static zend_bool can_replace_op1(
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_OBJ_REF:
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_FETCH_DIM_W:
case ZEND_FETCH_DIM_RW:
case ZEND_FETCH_DIM_UNSET:
@ -1489,32 +1481,24 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
}
SET_RESULT_BOT(result);
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
if (op1) {
SKIP_IF_TOP(op1);
}
if (op2) {
SKIP_IF_TOP(op2);
}
if (opline->extended_value == 0) {
if (ct_eval_binary_op(&zv, zend_compound_assign_to_binary_op(opline->opcode), op1, op2) == SUCCESS) {
if (opline->opcode == ZEND_ASSIGN_OP) {
if (ct_eval_binary_op(&zv, opline->extended_value, op1, op2) == SUCCESS) {
SET_RESULT(op1, &zv);
SET_RESULT(result, &zv);
zval_ptr_dtor_nogc(&zv);
break;
}
} else if (opline->extended_value == ZEND_ASSIGN_DIM) {
} else if (opline->opcode == ZEND_ASSIGN_DIM_OP) {
if ((IS_PARTIAL_ARRAY(op1) || Z_TYPE_P(op1) == IS_ARRAY)
&& ssa_op->op1_def >= 0 && op2) {
zval tmp;
@ -1533,7 +1517,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
break;
}
if (ct_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) {
if (ct_eval_binary_op(&tmp, opline->extended_value, &tmp, data) != SUCCESS) {
SET_RESULT_BOT(result);
SET_RESULT_BOT(op1);
zval_ptr_dtor_nogc(&tmp);
@ -1558,7 +1542,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
zval_ptr_dtor_nogc(&zv);
}
}
} else if (opline->extended_value == ZEND_ASSIGN_OBJ) {
} else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) {
if (op1 && IS_PARTIAL_OBJECT(op1)
&& ssa_op->op1_def >= 0
&& ctx->scdf.ssa->vars[ssa_op->op1_def].escape_state == ESCAPE_STATE_NO_ESCAPE) {
@ -1578,7 +1562,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
break;
}
if (ct_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) {
if (ct_eval_binary_op(&tmp, opline->extended_value, &tmp, data) != SUCCESS) {
SET_RESULT_BOT(result);
SET_RESULT_BOT(op1);
zval_ptr_dtor_nogc(&tmp);
@ -1599,11 +1583,6 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
zval_ptr_dtor_nogc(&zv);
}
}
} else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
SET_RESULT_BOT(result);
break;
} else {
ZEND_ASSERT(0 && "Invalid compound assignment kind");
}
SET_RESULT_BOT(result);
SET_RESULT_BOT(op1);
@ -2347,18 +2326,10 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
switch (opline->opcode) {
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
if ((ssa_op->op2_use >= 0 && !value_known(&ctx->values[ssa_op->op2_use]))
|| ((ssa_op+1)->op1_use >= 0 &&!value_known(&ctx->values[(ssa_op+1)->op1_use]))) {
return 0;
@ -2411,22 +2382,11 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
removed_ops++;
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
if (opline->extended_value) {
removed_ops++;
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
}
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
removed_ops++;
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
break;
default:
break;

View File

@ -107,18 +107,10 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
case ZEND_FE_RESET_RW:
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_POST_INC:

View File

@ -443,14 +443,8 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
if (ZEND_VM_EXT_NUM == (flags & ZEND_VM_EXT_MASK)) {
fprintf(stderr, " %u", opline->extended_value);
} else if (ZEND_VM_EXT_DIM_OBJ == (flags & ZEND_VM_EXT_MASK)) {
if (opline->extended_value == ZEND_ASSIGN_DIM) {
fprintf(stderr, " (dim)");
} else if (opline->extended_value == ZEND_ASSIGN_OBJ) {
fprintf(stderr, " (obj)");
} else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
fprintf(stderr, " (static prop)");
}
} else if (ZEND_VM_EXT_OP == (flags & ZEND_VM_EXT_MASK)) {
fprintf(stderr, " (%s)", zend_get_opcode_name(opline->extended_value) + 5);
} else if (ZEND_VM_EXT_TYPE == (flags & ZEND_VM_EXT_MASK)) {
switch (opline->extended_value) {
case IS_NULL:

View File

@ -548,25 +548,6 @@ static inline zend_bool shift_left_overflows(zend_long n, zend_long s) {
}
}
/* Get the normal op corresponding to a compound assignment op */
static inline zend_uchar get_compound_assign_op(zend_uchar opcode) {
switch (opcode) {
case ZEND_ASSIGN_ADD: return ZEND_ADD;
case ZEND_ASSIGN_SUB: return ZEND_SUB;
case ZEND_ASSIGN_MUL: return ZEND_MUL;
case ZEND_ASSIGN_DIV: return ZEND_DIV;
case ZEND_ASSIGN_MOD: return ZEND_MOD;
case ZEND_ASSIGN_SL: return ZEND_SL;
case ZEND_ASSIGN_SR: return ZEND_SR;
case ZEND_ASSIGN_CONCAT: return ZEND_CONCAT;
case ZEND_ASSIGN_BW_OR: return ZEND_BW_OR;
case ZEND_ASSIGN_BW_AND: return ZEND_BW_AND;
case ZEND_ASSIGN_BW_XOR: return ZEND_BW_XOR;
case ZEND_ASSIGN_POW: return ZEND_POW;
EMPTY_SWITCH_DEFAULT_CASE()
}
}
static int zend_inference_calc_binary_op_range(
const zend_op_array *op_array, zend_ssa *ssa,
zend_op *opline, zend_ssa_op *ssa_op, zend_uchar opcode, zend_ssa_range *tmp) {
@ -1381,23 +1362,20 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
}
}
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
if (opline->extended_value == 0) {
case ZEND_ASSIGN_OP:
if (opline->extended_value != ZEND_CONCAT
&& opline->extended_value != ZEND_POW) {
if (ssa->ops[line].op1_def == var || ssa->ops[line].result_def == var) {
return zend_inference_calc_binary_op_range(
op_array, ssa, opline, &ssa->ops[line],
get_compound_assign_op(opline->opcode), tmp);
opline->extended_value, tmp);
}
} else if ((opline+1)->opcode == ZEND_OP_DATA) {
}
break;
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
if ((opline+1)->opcode == ZEND_OP_DATA) {
if (ssa->ops[line+1].op1_def == var) {
opline++;
if (OP1_HAS_RANGE()) {
@ -1410,13 +1388,13 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
}
}
break;
// case ZEND_ASSIGN_CONCAT:
case ZEND_OP_DATA:
if ((opline-1)->opcode == ZEND_ASSIGN_DIM ||
(opline-1)->opcode == ZEND_ASSIGN_OBJ ||
(opline-1)->opcode == ZEND_ASSIGN_ADD ||
(opline-1)->opcode == ZEND_ASSIGN_SUB ||
(opline-1)->opcode == ZEND_ASSIGN_MUL) {
((opline-1)->opcode == ZEND_ASSIGN_OP &&
((opline-1)->extended_value == ZEND_ADD ||
(opline-1)->extended_value == ZEND_SUB ||
(opline-1)->extended_value == ZEND_MUL))) {
if (ssa->ops[line].op1_def == var) {
if (OP1_HAS_RANGE()) {
tmp->min = OP1_MIN_RANGE();
@ -2599,34 +2577,27 @@ static int zend_update_type_info(const zend_op_array *op_array,
UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].result_def);
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_CONCAT: {
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
{
zend_property_info *prop_info = NULL;
orig = 0;
tmp = 0;
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
if (opline->opcode == ZEND_ASSIGN_OBJ_OP) {
prop_info = zend_fetch_prop_info(op_array, ssa, opline, i);
orig = t1;
t1 = zend_fetch_prop_type(script, prop_info, &ce);
t2 = OP1_DATA_INFO();
} else if (opline->extended_value == ZEND_ASSIGN_DIM) {
} else if (opline->opcode == ZEND_ASSIGN_DIM_OP) {
if (t1 & MAY_BE_ARRAY_OF_REF) {
tmp |= MAY_BE_REF;
}
orig = t1;
t1 = zend_array_element_type(t1, 1, 0);
t2 = OP1_DATA_INFO();
} else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
} else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) {
prop_info = zend_fetch_static_prop_info(script, op_array, ssa, opline);
t1 = zend_fetch_prop_type(script, prop_info, &ce);
t2 = OP1_DATA_INFO();
@ -2637,7 +2608,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
}
tmp |= binary_op_result_type(
ssa, get_compound_assign_op(opline->opcode), t1, t2, ssa_ops[i].op1_def, optimization_level);
ssa, opline->extended_value, t1, t2, ssa_ops[i].op1_def, optimization_level);
if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY)) {
tmp |= MAY_BE_RC1;
}
@ -2645,13 +2616,13 @@ static int zend_update_type_info(const zend_op_array *op_array,
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
}
if (opline->extended_value == ZEND_ASSIGN_DIM) {
if (opline->opcode == ZEND_ASSIGN_DIM_OP) {
if (opline->op1_type == IS_CV) {
orig = assign_dim_result_type(orig, OP2_INFO(), tmp, opline->op2_type);
UPDATE_SSA_TYPE(orig, ssa_ops[i].op1_def);
COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def);
}
} else if (opline->extended_value == ZEND_ASSIGN_OBJ) {
} else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) {
if (opline->op1_type == IS_CV) {
if (!(orig & MAY_BE_REF)) {
if (orig & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
@ -2665,14 +2636,14 @@ static int zend_update_type_info(const zend_op_array *op_array,
UPDATE_SSA_TYPE(orig, ssa_ops[i].op1_def);
COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def);
}
} else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
} else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP) {
/* Nothing to do */
} else {
UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
}
if (ssa_ops[i].result_def >= 0) {
ce = NULL;
if (opline->extended_value == ZEND_ASSIGN_DIM) {
if (opline->opcode == ZEND_ASSIGN_DIM_OP) {
if (opline->op2_type == IS_UNUSED) {
/* When appending to an array and the LONG_MAX key is already used
* null will be returned. */
@ -2687,7 +2658,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
* results in a null return value. */
tmp |= MAY_BE_NULL;
}
} else if (opline->extended_value == ZEND_ASSIGN_OBJ) {
} else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) {
if (orig & (MAY_BE_ANY - (MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_OBJECT))) {
/* null and false (and empty string) are implicitly converted to object,
* anything else results in a null return value. */
@ -2698,7 +2669,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
if (prop_info) {
tmp &= zend_fetch_prop_type(script, prop_info, NULL);
}
} else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
} else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) {
/* The return value must also satisfy the property type */
if (prop_info) {
tmp &= zend_fetch_prop_type(script, prop_info, NULL);
@ -3441,18 +3412,10 @@ static int zend_update_type_info(const zend_op_array *op_array,
case ZEND_FETCH_DIM_RW:
case ZEND_FETCH_DIM_FUNC_ARG:
case ZEND_FETCH_LIST_W:
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_ASSIGN_DIM:
tmp |= MAY_BE_ARRAY | MAY_BE_ARRAY_OF_ARRAY;
break;
@ -3957,13 +3920,19 @@ static zend_bool can_convert_to_double(
return 0;
}
} else {
zend_uchar opcode = opline->opcode;
if (opcode == ZEND_ASSIGN_OP) {
opcode = opline->extended_value;
}
/* Avoid division by zero */
if (opline->opcode == ZEND_DIV && zval_get_double(&orig_op2) == 0.0) {
if (opcode == ZEND_DIV && zval_get_double(&orig_op2) == 0.0) {
return 0;
}
get_binary_op(opline->opcode)(&orig_result, &orig_op1, &orig_op2);
get_binary_op(opline->opcode)(&dval_result, &dval_op1, &dval_op2);
get_binary_op(opcode)(&orig_result, &orig_op1, &orig_op2);
get_binary_op(opcode)(&dval_result, &dval_op1, &dval_op2);
ZEND_ASSERT(Z_TYPE(dval_result) == IS_DOUBLE);
if (zval_get_double(&orig_result) != Z_DVAL(dval_result)) {
return 0;
@ -4571,62 +4540,48 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa
return 0;
}
return (t1 & (MAY_BE_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT)) || (t2 & (MAY_BE_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT));
case ZEND_ASSIGN_ADD:
if (opline->extended_value != 0) {
return 1;
case ZEND_ASSIGN_OP:
if (opline->extended_value == ZEND_ADD) {
if ((t1 & MAY_BE_ANY) == MAY_BE_ARRAY
&& (t2 & MAY_BE_ANY) == MAY_BE_ARRAY) {
return 0;
}
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
} else if (opline->extended_value == ZEND_DIV ||
opline->extended_value == ZEND_MOD) {
if (!OP2_HAS_RANGE() ||
(OP2_MIN_RANGE() <= 0 && OP2_MAX_RANGE() >= 0)) {
/* Division by zero */
return 1;
}
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
} else if (opline->extended_value == ZEND_SUB ||
opline->extended_value == ZEND_MUL ||
opline->extended_value == ZEND_POW) {
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
} else if (opline->extended_value == ZEND_SL ||
opline->extended_value == ZEND_SR) {
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
!OP2_HAS_RANGE() ||
OP2_MIN_RANGE() < 0;
} else if (opline->extended_value == ZEND_CONCAT) {
return (t1 & (MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT));
} else if (opline->extended_value == ZEND_BW_OR ||
opline->extended_value == ZEND_BW_AND ||
opline->extended_value == ZEND_BW_XOR) {
if ((t1 & MAY_BE_ANY) == MAY_BE_STRING
&& (t2 & MAY_BE_ANY) == MAY_BE_STRING) {
return 0;
}
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
}
if ((t1 & MAY_BE_ANY) == MAY_BE_ARRAY
&& (t2 & MAY_BE_ANY) == MAY_BE_ARRAY) {
return 0;
}
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
if (opline->extended_value != 0) {
return 1;
}
if (!OP2_HAS_RANGE() ||
(OP2_MIN_RANGE() <= 0 && OP2_MAX_RANGE() >= 0)) {
/* Division by zero */
return 1;
}
/* break missing intentionally */
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_POW:
if (opline->extended_value != 0) {
return 1;
}
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
if (opline->extended_value != 0) {
return 1;
}
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
!OP2_HAS_RANGE() ||
OP2_MIN_RANGE() < 0;
case ZEND_ASSIGN_CONCAT:
if (opline->extended_value != 0) {
return 1;
}
return (t1 & (MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT));
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
if (opline->extended_value != 0) {
return 1;
}
if ((t1 & MAY_BE_ANY) == MAY_BE_STRING
&& (t2 & MAY_BE_ANY) == MAY_BE_STRING) {
return 0;
}
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
return 1;
case ZEND_ASSIGN:
if (t1 & MAY_BE_REF) {
return 1;

View File

@ -53,25 +53,6 @@ void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval*
zend_hash_add(ctx->constants, Z_STR_P(name), &val);
}
zend_uchar zend_compound_assign_to_binary_op(zend_uchar opcode)
{
switch (opcode) {
case ZEND_ASSIGN_ADD: return ZEND_ADD;
case ZEND_ASSIGN_SUB: return ZEND_SUB;
case ZEND_ASSIGN_MUL: return ZEND_MUL;
case ZEND_ASSIGN_DIV: return ZEND_DIV;
case ZEND_ASSIGN_MOD: return ZEND_MOD;
case ZEND_ASSIGN_SL: return ZEND_SL;
case ZEND_ASSIGN_SR: return ZEND_SR;
case ZEND_ASSIGN_CONCAT: return ZEND_CONCAT;
case ZEND_ASSIGN_BW_OR: return ZEND_BW_OR;
case ZEND_ASSIGN_BW_AND: return ZEND_BW_AND;
case ZEND_ASSIGN_BW_XOR: return ZEND_BW_XOR;
case ZEND_ASSIGN_POW: return ZEND_POW;
EMPTY_SWITCH_DEFAULT_CASE()
}
}
int zend_optimizer_eval_binary_op(zval *result, zend_uchar opcode, zval *op1, zval *op2) /* {{{ */
{
binary_op_type binary_op = get_binary_op(opcode);
@ -320,21 +301,11 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
}
zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
if (opline->extended_value != ZEND_ASSIGN_STATIC_PROP) {
break;
}
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
break;
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_ASSIGN_STATIC_PROP:
case ZEND_ASSIGN_STATIC_PROP_REF:
case ZEND_FETCH_STATIC_PROP_R:
@ -440,7 +411,7 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_PRE_DEC_STATIC_PROP:
case ZEND_POST_INC_STATIC_PROP:
case ZEND_POST_DEC_STATIC_PROP:
handle_static_prop:
case ZEND_ASSIGN_STATIC_PROP_OP:
REQUIRES_STRING(val);
drop_leading_backslash(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
@ -509,6 +480,7 @@ handle_static_prop:
case ZEND_PRE_DEC_OBJ:
case ZEND_POST_INC_OBJ:
case ZEND_POST_DEC_OBJ:
case ZEND_ASSIGN_OBJ_OP:
TO_STRING_NOWARN(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
opline->extended_value = alloc_cache_slots(op_array, 3);
@ -518,42 +490,7 @@ handle_static_prop:
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
opline->extended_value = alloc_cache_slots(op_array, 3) | (opline->extended_value & ZEND_ISEMPTY);
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
TO_STRING_NOWARN(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
(opline+1)->extended_value = alloc_cache_slots(op_array, 3);
} else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
goto handle_static_prop;
} else if (opline->extended_value == ZEND_ASSIGN_DIM) {
if (Z_TYPE_P(val) == IS_STRING) {
zend_ulong index;
if (ZEND_HANDLE_NUMERIC(Z_STR_P(val), index)) {
ZVAL_LONG(&tmp, index);
opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp);
zend_string_hash_val(Z_STR_P(val));
zend_optimizer_add_literal(op_array, val);
Z_EXTRA(op_array->literals[opline->op2.constant]) = ZEND_EXTRA_VALUE;
break;
}
}
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
} else {
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
}
break;
case ZEND_ASSIGN_DIM_OP:
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
case ZEND_ASSIGN_DIM:
case ZEND_UNSET_DIM:

View File

@ -110,7 +110,6 @@ zend_function *zend_optimizer_get_called_func(
uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args);
void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline);
void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist);
zend_uchar zend_compound_assign_to_binary_op(zend_uchar opcode);
int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_arrya, zend_ssa *ssa, zend_call_info **call_map);
int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_bool reorder_dtor_effects);
int zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa);

View File

@ -716,18 +716,10 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
//NEW_SSA_VAR(opline->op1.var)
}
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_POST_INC:

View File

@ -123,12 +123,7 @@ static zend_bool zend_is_commutative(zend_uchar opcode)
opcode == ZEND_MUL ||
opcode == ZEND_BW_OR ||
opcode == ZEND_BW_AND ||
opcode == ZEND_BW_XOR ||
opcode == ZEND_ASSIGN_ADD ||
opcode == ZEND_ASSIGN_MUL||
opcode == ZEND_ASSIGN_BW_OR ||
opcode == ZEND_ASSIGN_BW_AND ||
opcode == ZEND_ASSIGN_BW_XOR;
opcode == ZEND_BW_XOR;
}
static zend_bool zend_long_is_power_of_two(zend_long x)
@ -496,86 +491,79 @@ static int zend_may_overflow(const zend_op *opline, zend_op_array *op_array, zen
!ssa->var_info[res].has_range ||
ssa->var_info[res].range.underflow ||
ssa->var_info[res].range.overflow);
case ZEND_ASSIGN_ADD:
if (opline->extended_value != 0) {
return 1;
}
num = opline - op_array->opcodes;
res = ssa->ops[num].op1_def;
if (res < 0 ||
!ssa->var_info[res].has_range) {
return 1;
}
if (ssa->var_info[res].range.underflow) {
zend_long op1_min, op2_min;
case ZEND_ASSIGN_OP:
if (opline->extended_value == ZEND_ADD) {
num = opline - op_array->opcodes;
res = ssa->ops[num].op1_def;
if (res < 0 ||
!ssa->var_info[res].has_range) {
return 1;
}
if (ssa->var_info[res].range.underflow) {
zend_long op1_min, op2_min;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_min = OP1_MIN_RANGE();
op2_min = OP2_MIN_RANGE();
if (zend_add_will_overflow(op1_min, op2_min)) {
return 1;
}
}
op1_min = OP1_MIN_RANGE();
op2_min = OP2_MIN_RANGE();
if (zend_add_will_overflow(op1_min, op2_min)) {
return 1;
}
}
if (ssa->var_info[res].range.overflow) {
zend_long op1_max, op2_max;
if (ssa->var_info[res].range.overflow) {
zend_long op1_max, op2_max;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_max = OP1_MAX_RANGE();
op2_max = OP2_MAX_RANGE();
if (zend_add_will_overflow(op1_max, op2_max)) {
return 1;
}
}
return 0;
} else if (opline->extended_value == ZEND_SUB) {
num = opline - op_array->opcodes;
res = ssa->ops[num].op1_def;
if (res < 0 ||
!ssa->var_info[res].has_range) {
return 1;
}
op1_max = OP1_MAX_RANGE();
op2_max = OP2_MAX_RANGE();
if (zend_add_will_overflow(op1_max, op2_max)) {
return 1;
}
}
return 0;
case ZEND_ASSIGN_SUB:
if (opline->extended_value != 0) {
return 1;
}
num = opline - op_array->opcodes;
res = ssa->ops[num].op1_def;
if (res < 0 ||
!ssa->var_info[res].has_range) {
return 1;
}
if (ssa->var_info[res].range.underflow) {
zend_long op1_min, op2_max;
if (ssa->var_info[res].range.underflow) {
zend_long op1_min, op2_max;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_min = OP1_MIN_RANGE();
op2_max = OP2_MAX_RANGE();
if (zend_sub_will_overflow(op1_min, op2_max)) {
return 1;
}
}
op1_min = OP1_MIN_RANGE();
op2_max = OP2_MAX_RANGE();
if (zend_sub_will_overflow(op1_min, op2_max)) {
return 1;
}
}
if (ssa->var_info[res].range.overflow) {
zend_long op1_max, op2_min;
if (ssa->var_info[res].range.overflow) {
zend_long op1_max, op2_min;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_max = OP1_MAX_RANGE();
op2_min = OP2_MIN_RANGE();
if (zend_sub_will_overflow(op1_max, op2_min)) {
return 1;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_max = OP1_MAX_RANGE();
op2_min = OP2_MIN_RANGE();
if (zend_sub_will_overflow(op1_max, op2_min)) {
return 1;
}
}
return 0;
} else if (opline->extended_value == ZEND_MUL) {
num = opline - op_array->opcodes;
res = ssa->ops[num].op1_def;
return (res < 0 ||
!ssa->var_info[res].has_range ||
ssa->var_info[res].range.underflow ||
ssa->var_info[res].range.overflow);
}
return 0;
case ZEND_ASSIGN_MUL:
if (opline->extended_value != 0) {
return 1;
}
num = opline - op_array->opcodes;
res = ssa->ops[num].op1_def;
return (res < 0 ||
!ssa->var_info[res].has_range ||
ssa->var_info[res].range.underflow ||
ssa->var_info[res].range.overflow);
default:
return 1;
}
@ -1471,10 +1459,10 @@ static int zend_jit_try_allocate_free_reg(zend_op_array *op_array, zend_ssa *ssa
case ZEND_MUL:
hint = ssa->ops[current->start].op1_use;
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
if (opline->extended_value) {
case ZEND_ASSIGN_OP:
if (opline->extended_value == ZEND_ADD
|| opline->extended_value == ZEND_SUB
|| opline->extended_value == ZEND_MUL) {
hint = ssa->ops[current->start].op1_use;
}
break;
@ -1920,21 +1908,7 @@ static void zend_calc_checked_this_r(zend_bitset checked_this, zend_op_array *op
for (; opline < end; opline++) {
switch (opline->opcode) {
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
if (opline->extended_value != ZEND_ASSIGN_OBJ) {
break;
}
case ZEND_ASSIGN_OBJ_OP:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_POST_INC_OBJ:
@ -2232,21 +2206,17 @@ static int zend_jit(zend_op_array *op_array, zend_ssa *ssa, const zend_op *rt_op
goto jit_failure;
}
goto done;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
// case ZEND_ASSIGN_DIV: // TODO: check for division by zero ???
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_MOD:
if (!zend_jit_assign_op(&dasm_state, opline, op_array, ssa)) {
goto jit_failure;
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
if (opline->extended_value != ZEND_POW
&& opline->extended_value != ZEND_DIV) {
// TODO: check for division by zero ???
if (!zend_jit_assign_op(&dasm_state, opline, op_array, ssa)) {
goto jit_failure;
}
goto done;
}
goto done;
break;
case ZEND_ASSIGN_DIM:
if (!zend_jit_assign_dim(&dasm_state, opline, op_array, ssa)) {
goto jit_failure;

View File

@ -757,18 +757,10 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
uint32_t var;
switch (opline->opcode) {
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
msg = "Cannot use assign-op operators with string offsets";
break;
case ZEND_FETCH_DIM_W:
@ -783,25 +775,15 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
while (opline < end) {
if (opline->op1_type == IS_VAR && opline->op1.var == var) {
switch (opline->opcode) {
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
msg = "Cannot use string offset as an object";
} else if (opline->extended_value == ZEND_ASSIGN_DIM) {
msg = "Cannot use string offset as an array";
} else {
msg = "Cannot use assign-op operators with string offsets";
}
case ZEND_ASSIGN_OBJ_OP:
msg = "Cannot use string offset as an object";
break;
case ZEND_ASSIGN_DIM_OP:
msg = "Cannot use string offset as an array";
break;
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
msg = "Cannot use assign-op operators with string offsets";
break;
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:

View File

@ -533,19 +533,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro FPU_MATH, opcode, addr
|| switch (opcode) {
|| case ZEND_ADD:
|| case ZEND_ASSIGN_ADD:
| FPU_OP fadd, addr
|| break;
|| case ZEND_SUB:
|| case ZEND_ASSIGN_SUB:
| FPU_OP fsub, addr
|| break;
|| case ZEND_MUL:
|| case ZEND_ASSIGN_MUL:
| FPU_OP fmul, addr
|| break;
|| case ZEND_DIV:
|| case ZEND_ASSIGN_DIV:
| FPU_OP fdiv, addr
|| break;
|| }
@ -664,19 +660,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro SSE_MATH, opcode, reg, addr
|| switch (opcode) {
|| case ZEND_ADD:
|| case ZEND_ASSIGN_ADD:
| SSE_OP addsd, reg, addr
|| break;
|| case ZEND_SUB:
|| case ZEND_ASSIGN_SUB:
| SSE_OP subsd, reg, addr
|| break;
|| case ZEND_MUL:
|| case ZEND_ASSIGN_MUL:
| SSE_OP mulsd, reg, addr
|| break;
|| case ZEND_DIV:
|| case ZEND_ASSIGN_DIV:
| SSE_OP divsd, reg, addr
|| break;
|| }
@ -685,19 +677,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro SSE_MATH_REG, opcode, dst_reg, src_reg
|| switch (opcode) {
|| case ZEND_ADD:
|| case ZEND_ASSIGN_ADD:
| addsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_SUB:
|| case ZEND_ASSIGN_SUB:
| subsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_MUL:
|| case ZEND_ASSIGN_MUL:
| mulsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_DIV:
|| case ZEND_ASSIGN_DIV:
| divsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| }
@ -729,19 +717,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro AVX_MATH, opcode, reg, op1_reg, addr
|| switch (opcode) {
|| case ZEND_ADD:
|| case ZEND_ASSIGN_ADD:
| AVX_OP vaddsd, reg, op1_reg, addr
|| break;
|| case ZEND_SUB:
|| case ZEND_ASSIGN_SUB:
| AVX_OP vsubsd, reg, op1_reg, addr
|| break;
|| case ZEND_MUL:
|| case ZEND_ASSIGN_MUL:
| AVX_OP vmulsd, reg, op1_reg, addr
|| break;
|| case ZEND_DIV:
|| case ZEND_ASSIGN_DIV:
| AVX_OP vdivsd, reg, op1_reg, addr
|| break;
|| }
@ -750,19 +734,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro AVX_MATH_REG, opcode, dst_reg, op1_reg, src_reg
|| switch (opcode) {
|| case ZEND_ADD:
|| case ZEND_ASSIGN_ADD:
| vaddsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_SUB:
|| case ZEND_ASSIGN_SUB:
| vsubsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_MUL:
|| case ZEND_ASSIGN_MUL:
| vmulsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_DIV:
|| case ZEND_ASSIGN_DIV:
| vdivsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| }
@ -851,27 +831,21 @@ static void* dasm_labels[zend_lb_MAX];
|.macro LONG_MATH, opcode, reg, addr
|| switch (opcode) {
|| case ZEND_ADD:
|| case ZEND_ASSIGN_ADD:
| LONG_OP add, reg, addr
|| break;
|| case ZEND_SUB:
|| case ZEND_ASSIGN_SUB:
| LONG_OP sub, reg, addr
|| break;
|| case ZEND_MUL:
|| case ZEND_ASSIGN_MUL:
| LONG_OP imul, reg, addr
|| break;
|| case ZEND_BW_OR:
|| case ZEND_ASSIGN_BW_OR:
| LONG_OP or, reg, addr
|| break;
|| case ZEND_BW_AND:
|| case ZEND_ASSIGN_BW_AND:
| LONG_OP and, reg, addr
|| break;
|| case ZEND_BW_XOR:
|| case ZEND_ASSIGN_BW_XOR:
| LONG_OP xor, reg, addr
|| break;
|| default:
@ -882,27 +856,21 @@ static void* dasm_labels[zend_lb_MAX];
|.macro LONG_MATH_REG, opcode, dst_reg, src_reg
|| switch (opcode) {
|| case ZEND_ADD:
|| case ZEND_ASSIGN_ADD:
| add dst_reg, src_reg
|| break;
|| case ZEND_SUB:
|| case ZEND_ASSIGN_SUB:
| sub dst_reg, src_reg
|| break;
|| case ZEND_MUL:
|| case ZEND_ASSIGN_MUL:
| imul dst_reg, src_reg
|| break;
|| case ZEND_BW_OR:
|| case ZEND_ASSIGN_BW_OR:
| or dst_reg, src_reg
|| break;
|| case ZEND_BW_AND:
|| case ZEND_ASSIGN_BW_AND:
| and dst_reg, src_reg
|| break;
|| case ZEND_BW_XOR:
|| case ZEND_ASSIGN_BW_XOR:
| xor dst_reg, src_reg
|| break;
|| default:
@ -938,19 +906,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro FPU_MATH_REG, opcode, reg
|| switch (opcode) {
|| case ZEND_ADD:
|| case ZEND_ASSIGN_ADD:
| fadd reg
|| break;
|| case ZEND_SUB:
|| case ZEND_ASSIGN_SUB:
| fsub reg
|| break;
|| case ZEND_MUL:
|| case ZEND_ASSIGN_MUL:
| fmul reg
|| break;
|| case ZEND_DIV:
|| case ZEND_ASSIGN_DIV:
| fdiv reg
|| break;
|| }
@ -2786,26 +2750,13 @@ static int zend_jit_handler(dasm_State **Dst, const zend_op *opline, int may_thr
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_STATIC_PROP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_ASSIGN_STATIC_PROP_REF:
case ZEND_ASSIGN_OBJ_REF:
last_valid_opline++;
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
if (opline->extended_value) {
last_valid_opline++;
}
break;
default:
break;
}
@ -3261,6 +3212,7 @@ static int zend_jit_math_long_long(dasm_State **Dst,
zend_op_array *op_array,
zend_ssa *ssa,
const zend_op *opline,
zend_uchar opcode,
zend_jit_addr op1_addr,
zend_jit_addr op2_addr,
zend_jit_addr res_addr,
@ -3278,7 +3230,7 @@ static int zend_jit_math_long_long(dasm_State **Dst,
result_reg = ZREG_R0;
}
if (opline->opcode == ZEND_MUL &&
if (opcode == ZEND_MUL &&
((Z_MODE(op2_addr) == IS_CONST_ZVAL &&
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr))) &&
is_power_of_two(Z_LVAL_P(Z_ZV(op2_addr)))) ||
@ -3292,17 +3244,17 @@ static int zend_jit_math_long_long(dasm_State **Dst,
| GET_ZVAL_LVAL result_reg, op2_addr
| shl Ra(result_reg), floor_log2(Z_LVAL_P(Z_ZV(op1_addr)))
}
} else if (opline->opcode == ZEND_DIV &&
} else if (opcode == ZEND_DIV &&
(Z_MODE(op2_addr) == IS_CONST_ZVAL &&
is_power_of_two(Z_LVAL_P(Z_ZV(op2_addr))))) {
| GET_ZVAL_LVAL result_reg, op1_addr
| shr Ra(result_reg), floor_log2(Z_LVAL_P(Z_ZV(op2_addr)))
} else {
| GET_ZVAL_LVAL result_reg, op1_addr
if (same_ops && opline->opcode != ZEND_DIV) {
| LONG_MATH_REG opline->opcode, Ra(result_reg), Ra(result_reg)
if (same_ops && opcode != ZEND_DIV) {
| LONG_MATH_REG opcode, Ra(result_reg), Ra(result_reg)
} else {
| LONG_MATH opline->opcode, result_reg, op2_addr
| LONG_MATH opcode, result_reg, op2_addr
}
}
if ((res_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, op_array, ssa)) {
@ -3316,15 +3268,15 @@ static int zend_jit_math_long_long(dasm_State **Dst,
| SSE_GET_ZVAL_LVAL tmp_reg1, op1_addr
| SSE_GET_ZVAL_LVAL tmp_reg2, op2_addr
if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) {
| AVX_MATH_REG opline->opcode, tmp_reg1, tmp_reg1, tmp_reg2
| AVX_MATH_REG opcode, tmp_reg1, tmp_reg1, tmp_reg2
} else {
| SSE_MATH_REG opline->opcode, tmp_reg1, tmp_reg2
| SSE_MATH_REG opcode, tmp_reg1, tmp_reg2
}
| SSE_SET_ZVAL_DVAL res_addr, tmp_reg1
|.else
| FPU_GET_ZVAL_LVAL op2_addr
| FPU_GET_ZVAL_LVAL op1_addr
| FPU_MATH_REG opline->opcode, st1
| FPU_MATH_REG opcode, st1
| FPU_SET_ZVAL_DVAL res_addr
|.endif
if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) != MAY_BE_DOUBLE) {
@ -3355,6 +3307,7 @@ static int zend_jit_math_long_double(dasm_State **Dst,
zend_op_array *op_array,
zend_ssa *ssa,
const zend_op *opline,
zend_uchar opcode,
zend_jit_addr op1_addr,
zend_jit_addr op2_addr,
zend_jit_addr res_addr,
@ -3366,14 +3319,14 @@ static int zend_jit_math_long_double(dasm_State **Dst,
| SSE_GET_ZVAL_LVAL result_reg, op1_addr
if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) {
| AVX_MATH opline->opcode, result_reg, result_reg, op2_addr
| AVX_MATH opcode, result_reg, result_reg, op2_addr
} else {
| SSE_MATH opline->opcode, result_reg, op2_addr
| SSE_MATH opcode, result_reg, op2_addr
}
| SSE_SET_ZVAL_DVAL res_addr, result_reg
|.else
| FPU_GET_ZVAL_LVAL op1_addr
| FPU_MATH opline->opcode, op2_addr
| FPU_MATH opcode, op2_addr
| FPU_SET_ZVAL_DVAL res_addr
|.endif
@ -3390,6 +3343,7 @@ static int zend_jit_math_double_long(dasm_State **Dst,
zend_op_array *op_array,
zend_ssa *ssa,
const zend_op *opline,
zend_uchar opcode,
zend_jit_addr op1_addr,
zend_jit_addr op2_addr,
zend_jit_addr res_addr,
@ -3398,7 +3352,7 @@ static int zend_jit_math_double_long(dasm_State **Dst,
|.if SSE
zend_reg result_reg;
if (zend_is_commutative(opline->opcode)) {
if (zend_is_commutative(opcode)) {
if (Z_MODE(res_addr) == IS_REG) {
result_reg = Z_REG(res_addr);
} else {
@ -3406,9 +3360,9 @@ static int zend_jit_math_double_long(dasm_State **Dst,
}
| SSE_GET_ZVAL_LVAL result_reg, op2_addr
if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) {
| AVX_MATH opline->opcode, result_reg, result_reg, op1_addr
| AVX_MATH opcode, result_reg, result_reg, op1_addr
} else {
| SSE_MATH opline->opcode, result_reg, op1_addr
| SSE_MATH opcode, result_reg, op1_addr
}
} else {
zend_reg tmp_reg;
@ -3433,21 +3387,21 @@ static int zend_jit_math_double_long(dasm_State **Dst,
op1_reg = result_reg;
}
| SSE_GET_ZVAL_LVAL tmp_reg, op2_addr
| AVX_MATH_REG opline->opcode, result_reg, op1_reg, tmp_reg
| AVX_MATH_REG opcode, result_reg, op1_reg, tmp_reg
} else {
| SSE_GET_ZVAL_DVAL result_reg, op1_addr
| SSE_GET_ZVAL_LVAL tmp_reg, op2_addr
| SSE_MATH_REG opline->opcode, result_reg, tmp_reg
| SSE_MATH_REG opcode, result_reg, tmp_reg
}
}
| SSE_SET_ZVAL_DVAL res_addr, result_reg
|.else
| FPU_GET_ZVAL_LVAL op2_addr
if (zend_is_commutative(opline->opcode)) {
| FPU_MATH opline->opcode, op1_addr
if (zend_is_commutative(opcode)) {
| FPU_MATH opcode, op1_addr
} else {
| FPU_GET_ZVAL_DVAL op1_addr
| FPU_MATH_REG opline->opcode, st1
| FPU_MATH_REG opcode, st1
}
| FPU_SET_ZVAL_DVAL res_addr
|.endif
@ -3467,6 +3421,7 @@ static int zend_jit_math_double_double(dasm_State **Dst,
zend_op_array *op_array,
zend_ssa *ssa,
const zend_op *opline,
zend_uchar opcode,
zend_jit_addr op1_addr,
zend_jit_addr op2_addr,
zend_jit_addr res_addr,
@ -3492,7 +3447,7 @@ static int zend_jit_math_double_double(dasm_State **Dst,
if (Z_MODE(op1_addr) == IS_REG) {
op1_reg = Z_REG(op1_addr);
val_addr = op2_addr;
} else if (Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opline->opcode)) {
} else if (Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opcode)) {
op1_reg = Z_REG(op2_addr);
val_addr = op1_addr;
} else {
@ -3500,16 +3455,16 @@ static int zend_jit_math_double_double(dasm_State **Dst,
op1_reg = result_reg;
val_addr = op2_addr;
}
if ((opline->opcode == ZEND_MUL || opline->opcode == ZEND_ASSIGN_MUL) &&
if ((opcode == ZEND_MUL) &&
Z_MODE(val_addr) == IS_CONST_ZVAL && Z_DVAL_P(Z_ZV(val_addr)) == 2.0) {
| AVX_MATH_REG ZEND_ADD, result_reg, op1_reg, op1_reg
} else {
| AVX_MATH opline->opcode, result_reg, op1_reg, val_addr
| AVX_MATH opcode, result_reg, op1_reg, val_addr
}
} else {
zend_jit_addr val_addr;
if (Z_MODE(op1_addr) != IS_REG && Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opline->opcode)) {
if (Z_MODE(op1_addr) != IS_REG && Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opcode)) {
| SSE_GET_ZVAL_DVAL result_reg, op2_addr
val_addr = op1_addr;
} else {
@ -3517,18 +3472,18 @@ static int zend_jit_math_double_double(dasm_State **Dst,
val_addr = op2_addr;
}
if (same_ops) {
| SSE_MATH_REG opline->opcode, result_reg, result_reg
} else if ((opline->opcode == ZEND_MUL || opline->opcode == ZEND_ASSIGN_MUL) &&
| SSE_MATH_REG opcode, result_reg, result_reg
} else if ((opcode == ZEND_MUL) &&
Z_MODE(val_addr) == IS_CONST_ZVAL && Z_DVAL_P(Z_ZV(val_addr)) == 2.0) {
| SSE_MATH_REG ZEND_ADD, result_reg, result_reg
} else {
| SSE_MATH opline->opcode, result_reg, val_addr
| SSE_MATH opcode, result_reg, val_addr
}
}
| SSE_SET_ZVAL_DVAL res_addr, result_reg
|.else
| FPU_GET_ZVAL_DVAL op1_addr
| FPU_MATH opline->opcode, op2_addr
| FPU_MATH opcode, op2_addr
| FPU_SET_ZVAL_DVAL res_addr
|.endif
@ -3545,6 +3500,7 @@ static int zend_jit_math_double_double(dasm_State **Dst,
static int zend_jit_math_helper(dasm_State **Dst,
const zend_op *opline,
zend_uchar opcode,
zend_op_array *op_array,
zend_ssa *ssa,
zend_uchar op1_type,
@ -3579,7 +3535,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
if (op2_info & (MAY_BE_ANY-(MAY_BE_LONG|MAY_BE_DOUBLE))) {
| IF_NOT_ZVAL_TYPE op2_addr, IS_DOUBLE, >6
}
if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
| jmp >5
@ -3588,7 +3544,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6
}
}
if (!zend_jit_math_long_long(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_info, res_use_info)) {
if (!zend_jit_math_long_long(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_info, res_use_info)) {
return 0;
}
if (op1_info & MAY_BE_DOUBLE) {
@ -3605,7 +3561,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE, op2_addr, IS_DOUBLE, >6
}
}
if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
| jmp >5
@ -3615,7 +3571,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
if (op2_info & (MAY_BE_ANY-(MAY_BE_LONG|MAY_BE_DOUBLE))) {
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6
}
if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
| jmp >5
@ -3636,7 +3592,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE op2_addr, IS_DOUBLE, >6
}
}
if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
}
@ -3648,7 +3604,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
if (op2_info & (MAY_BE_ANY-(MAY_BE_DOUBLE|MAY_BE_LONG))) {
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6
}
if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
if (op2_info & MAY_BE_DOUBLE) {
@ -3670,7 +3626,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE op1_addr, IS_DOUBLE, >6
}
}
if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
}
@ -3682,7 +3638,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
if (op1_info & (MAY_BE_ANY-(MAY_BE_DOUBLE|MAY_BE_LONG))) {
| IF_NOT_ZVAL_TYPE op1_addr, IS_LONG, >6
}
if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
if (op1_info & MAY_BE_DOUBLE) {
@ -3729,13 +3685,13 @@ static int zend_jit_math_helper(dasm_State **Dst,
| sub r4, 12
| PUSH_ZVAL_ADDR op2_addr, r0
|.endif
if (opline->opcode == ZEND_ADD || opline->opcode == ZEND_ASSIGN_ADD) {
if (opcode == ZEND_ADD) {
| EXT_CALL add_function, r0
} else if (opline->opcode == ZEND_SUB || opline->opcode == ZEND_ASSIGN_SUB) {
} else if (opcode == ZEND_SUB) {
| EXT_CALL sub_function, r0
} else if (opline->opcode == ZEND_MUL || opline->opcode == ZEND_ASSIGN_MUL) {
} else if (opcode == ZEND_MUL) {
| EXT_CALL mul_function, r0
} else if (opline->opcode == ZEND_DIV || opline->opcode == ZEND_ASSIGN_DIV) {
} else if (opcode == ZEND_DIV) {
| EXT_CALL div_function, r0
} else {
ZEND_ASSERT(0);
@ -3806,7 +3762,7 @@ static int zend_jit_math(dasm_State **Dst, const zend_op *opline, int *opnum, ze
res_addr = zend_jit_decode_op(op_array, opline->result_type, opline->result, opline, ra, ssa->ops[opline - op_array->opcodes].result_def);
}
if (!zend_jit_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->result.var, res_addr, RES_INFO(), res_use_info)) {
if (!zend_jit_math_helper(Dst, opline, opline->opcode, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->result.var, res_addr, RES_INFO(), res_use_info)) {
return 0;
}
if (ra && !zend_jit_store_ssa_var_if_necessary(Dst, ssa, ra, res_addr, ssa->ops[opline - op_array->opcodes].result_def, ssa->ops[opline - op_array->opcodes].result_use)) {
@ -3821,6 +3777,7 @@ fallback:
static int zend_jit_long_math_helper(dasm_State **Dst,
const zend_op *opline,
zend_uchar opcode,
zend_op_array *op_array,
zend_ssa *ssa,
zend_uchar op1_type,
@ -3841,7 +3798,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
{
zend_bool same_ops = zend_jit_same_addr(op1_addr, op2_addr);
zend_reg result_reg;
zend_uchar opcode = opline->opcode;
zval tmp;
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)) {
@ -3875,7 +3831,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
result_reg = ZREG_R0;
}
if (opcode == ZEND_SL || opcode == ZEND_ASSIGN_SL) {
if (opcode == ZEND_SL) {
if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr));
@ -3913,7 +3869,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
| shl Ra(result_reg), cl
|1:
}
} else if (opcode == ZEND_SR || opcode == ZEND_ASSIGN_SR) {
} else if (opcode == ZEND_SR) {
| GET_ZVAL_LVAL result_reg, op1_addr
if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr));
@ -3950,7 +3906,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
|1:
| sar Ra(result_reg), cl
}
} else if (opcode == ZEND_MOD || opcode == ZEND_ASSIGN_MOD) {
} else if (opcode == ZEND_MOD) {
if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr));
@ -4056,17 +4012,17 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
| sub r4, 12
| PUSH_ZVAL_ADDR op2_addr, r0
|.endif
if (opline->opcode == ZEND_BW_OR || opline->opcode == ZEND_ASSIGN_BW_OR) {
if (opcode == ZEND_BW_OR) {
| EXT_CALL bitwise_or_function, r0
} else if (opline->opcode == ZEND_BW_AND || opline->opcode == ZEND_ASSIGN_BW_AND) {
} else if (opcode == ZEND_BW_AND) {
| EXT_CALL bitwise_and_function, r0
} else if (opline->opcode == ZEND_BW_XOR || opline->opcode == ZEND_ASSIGN_BW_XOR) {
} else if (opcode == ZEND_BW_XOR) {
| EXT_CALL bitwise_xor_function, r0
} else if (opline->opcode == ZEND_SL || opline->opcode == ZEND_ASSIGN_SL) {
} else if (opcode == ZEND_SL) {
| EXT_CALL shift_left_function, r0
} else if (opline->opcode == ZEND_SR || opline->opcode == ZEND_ASSIGN_SR) {
} else if (opcode == ZEND_SR) {
| EXT_CALL shift_right_function, r0
} else if (opline->opcode == ZEND_MOD || opline->opcode == ZEND_ASSIGN_MOD) {
} else if (opcode == ZEND_MOD) {
| EXT_CALL mod_function, r0
} else {
ZEND_ASSERT(0);
@ -4140,7 +4096,7 @@ static int zend_jit_long_math(dasm_State **Dst, const zend_op *opline, int *opnu
res_addr = zend_jit_decode_op(op_array, opline->result_type, opline->result, opline, ra, ssa->ops[opline - op_array->opcodes].result_def);
}
if (!zend_jit_long_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->result.var, res_addr, RES_INFO(), res_use_info)) {
if (!zend_jit_long_math_helper(Dst, opline, opline->opcode, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->result.var, res_addr, RES_INFO(), res_use_info)) {
return 0;
}
if (ra && !zend_jit_store_ssa_var_if_necessary(Dst, ssa, ra, res_addr, ssa->ops[opline - op_array->opcodes].result_def, ssa->ops[opline - op_array->opcodes].result_use)) {
@ -5186,26 +5142,26 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, zend_
}
var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
switch (opline->opcode) {
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
if (!zend_jit_math_helper(Dst, opline, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), 0, var_addr, var_def_info, var_info)) {
switch (opline->extended_value) {
case ZEND_ADD:
case ZEND_SUB:
case ZEND_MUL:
case ZEND_DIV:
if (!zend_jit_math_helper(Dst, opline, opline->extended_value, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), 0, var_addr, var_def_info, var_info)) {
return 0;
}
break;
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_MOD:
if (!zend_jit_long_math_helper(Dst, opline, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), op3_ssa_var, 0, var_addr, OP1_DEF_INFO(), var_info)) {
case ZEND_BW_OR:
case ZEND_BW_AND:
case ZEND_BW_XOR:
case ZEND_SL:
case ZEND_SR:
case ZEND_MOD:
if (!zend_jit_long_math_helper(Dst, opline, opline->extended_value, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), op3_ssa_var, 0, var_addr, OP1_DEF_INFO(), var_info)) {
return 0;
}
break;
case ZEND_ASSIGN_CONCAT:
case ZEND_CONCAT:
if (!zend_jit_concat_helper(Dst, opline, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), var_addr, OP1_DEF_INFO())) {
return 0;
}
@ -5235,7 +5191,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, zend_
} else {
| LOAD_ZVAL_ADDR FCARG2a, op2_addr
}
binary_op = get_binary_op(opline->opcode);
binary_op = get_binary_op(opline->extended_value);
|.if X64
| LOAD_ZVAL_ADDR CARG3, op3_addr
| LOAD_ADDR CARG4, binary_op
@ -5269,9 +5225,9 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, zend_op_a
zend_jit_addr op1_addr, op2_addr;
int op1_ssa_var, op2_ssa_var;
if (opline->extended_value == ZEND_ASSIGN_DIM) {
if (opline->opcode == ZEND_ASSIGN_DIM_OP) {
return zend_jit_assign_dim_op(Dst, opline, op_array, ssa);
} else if (opline->extended_value == ZEND_ASSIGN_OBJ || opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
} else if (opline->opcode == ZEND_ASSIGN_OBJ_OP || opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) {
goto fallback;
}
@ -5295,28 +5251,28 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, zend_op_a
goto fallback;
}
switch (opline->opcode) {
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
switch (opline->extended_value) {
case ZEND_ADD:
case ZEND_SUB:
case ZEND_MUL:
case ZEND_DIV:
if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) ||
!(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) {
goto fallback;
}
break;
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_MOD:
case ZEND_BW_OR:
case ZEND_BW_AND:
case ZEND_BW_XOR:
case ZEND_SL:
case ZEND_SR:
case ZEND_MOD:
if (!(op1_info & MAY_BE_LONG) ||
!(op2_info & MAY_BE_LONG)) {
goto fallback;
}
break;
case ZEND_ASSIGN_CONCAT:
case ZEND_CONCAT:
if (!(op1_info & MAY_BE_STRING) ||
!(op2_info & MAY_BE_STRING)) {
goto fallback;
@ -5332,20 +5288,20 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, zend_op_a
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
}
switch (opline->opcode) {
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
return zend_jit_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info);
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_MOD:
return zend_jit_long_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info);
case ZEND_ASSIGN_CONCAT:
switch (opline->extended_value) {
case ZEND_ADD:
case ZEND_SUB:
case ZEND_MUL:
case ZEND_DIV:
return zend_jit_math_helper(Dst, opline, opline->extended_value, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info);
case ZEND_BW_OR:
case ZEND_BW_AND:
case ZEND_BW_XOR:
case ZEND_SL:
case ZEND_SR:
case ZEND_MOD:
return zend_jit_long_math_helper(Dst, opline, opline->extended_value, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info);
case ZEND_CONCAT:
return zend_jit_concat_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, op1_addr, OP1_DEF_INFO());
default:
ZEND_ASSERT(0);