]> granicus.if.org Git - php/commitdiff
Support the same handler for multiple opcodes
authorTyson Andre <tysonandre775@hotmail.com>
Wed, 13 Nov 2019 14:10:22 +0000 (09:10 -0500)
committerDmitry Stogov <dmitry@zend.com>
Fri, 15 Nov 2019 14:37:01 +0000 (17:37 +0300)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_gen.php

index a8ab1ff375c42ff80204c1121490853a8725cedc..0dfa91e3845fd532da49a25da3c32d3cdc40dbc2 100644 (file)
@@ -1496,7 +1496,7 @@ ZEND_VM_HELPER(zend_pre_dec_helper, VAR|CV, ANY)
 
        SAVE_OPLINE();
        if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
-               ZVAL_NULL(var_ptr);             
+               ZVAL_NULL(var_ptr);
                ZVAL_UNDEFINED_OP1();
        }
 
@@ -2234,7 +2234,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_fast_copy):
                }
 
                retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
                if (OP2_TYPE != IS_CONST) {
                        zend_tmp_string_release(tmp_name);
                }
@@ -5528,10 +5528,10 @@ ZEND_VM_HANDLER(147, ZEND_ADD_ARRAY_UNPACK, ANY, ANY)
 {
        USE_OPLINE
        zval *op1;
-       
+
        SAVE_OPLINE();
        op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
-       
+
 ZEND_VM_C_LABEL(add_unpack_again):
        if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) {
                HashTable *ht = Z_ARRVAL_P(op1);
@@ -5572,11 +5572,11 @@ ZEND_VM_C_LABEL(add_unpack_again):
                                }
                                HANDLE_EXCEPTION();
                        }
-                       
+
                        if (iter->funcs->rewind) {
                                iter->funcs->rewind(iter);
                        }
-                       
+
                        for (; iter->funcs->valid(iter) == SUCCESS; ) {
                                zval *val;
 
@@ -5625,7 +5625,7 @@ ZEND_VM_C_LABEL(add_unpack_again):
        } else {
                zend_throw_error(NULL, "Only arrays and Traversables can be unpacked");
        }
-       
+
        FREE_OP1();
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
@@ -8677,7 +8677,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_DOUBLE && op2_info =
        ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL|ZEND_IS_IDENTICAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
 {
        USE_OPLINE
        zval *op1, *op2;
@@ -8689,7 +8689,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_LONG && op2_inf
        ZEND_VM_SMART_BRANCH(result, 0);
 }
 
-ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL|ZEND_IS_IDENTICAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
 {
        USE_OPLINE
        zval *op1, *op2;
@@ -8701,7 +8701,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_i
        ZEND_VM_SMART_BRANCH(result, 0);
 }
 
-ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_NOT_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL|ZEND_IS_NOT_IDENTICAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_NOT_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
 {
        USE_OPLINE
        zval *op1, *op2;
@@ -8713,7 +8713,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_LONG && op2
        ZEND_VM_SMART_BRANCH(result, 0);
 }
 
-ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_NOT_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL|ZEND_IS_NOT_IDENTICAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_NOT_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
 {
        USE_OPLINE
        zval *op1, *op2;
index fec62d8dc06adfbb53e7e94e965bd07fb2b145c1..812a7e5bd292d638195e92548cc58fe6f1457e8e 100644 (file)
@@ -59193,7 +59193,6 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
                                spec = 2512 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
                        }
                        break;
-               case ZEND_IS_EQUAL:
                case ZEND_IS_IDENTICAL:
                        if (op->op1_type < op->op2_type) {
                                zend_swap_operands(op);
@@ -59210,7 +59209,6 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
                                spec = 2612 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
                        }
                        break;
-               case ZEND_IS_NOT_EQUAL:
                case ZEND_IS_NOT_IDENTICAL:
                        if (op->op1_type < op->op2_type) {
                                zend_swap_operands(op);
@@ -59227,6 +59225,38 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
                                spec = 2762 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
                        }
                        break;
+               case ZEND_IS_EQUAL:
+                       if (op->op1_type < op->op2_type) {
+                               zend_swap_operands(op);
+                       }
+                       if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
+                               if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
+                                       break;
+                               }
+                               spec = 2537 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+                       } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
+                               if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
+                                       break;
+                               }
+                               spec = 2612 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+                       }
+                       break;
+               case ZEND_IS_NOT_EQUAL:
+                       if (op->op1_type < op->op2_type) {
+                               zend_swap_operands(op);
+                       }
+                       if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
+                               if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
+                                       break;
+                               }
+                               spec = 2687 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+                       } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
+                               if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
+                                       break;
+                               }
+                               spec = 2762 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+                       }
+                       break;
                case ZEND_IS_SMALLER:
                        if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
                                if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
index 47975b39404ed78d36aa50ef93b81501c16b298a..ccf23613f73d0164e24afda5802a2774ebeb4d7a 100755 (executable)
@@ -2394,19 +2394,22 @@ function gen_vm($def, $skel) {
                           strpos($line,"ZEND_VM_HOT_OBJ_TYPE_SPEC_HANDLER(") === 0) {
                  // Parsing opcode handler's definition
                        if (preg_match(
-                                       "/^ZEND_VM_(HOT_|INLINE_|HOT_OBJ_|HOT_SEND_|HOT_NOCONST_|HOT_NOCONSTCONST_)?TYPE_SPEC_HANDLER\(\s*([A-Z_]+)\s*,\s*((?:[^(,]|\([^()]*|(?R)*\))*),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
+                                       "/^ZEND_VM_(HOT_|INLINE_|HOT_OBJ_|HOT_SEND_|HOT_NOCONST_|HOT_NOCONSTCONST_)?TYPE_SPEC_HANDLER\(\s*([A-Z_|]+)\s*,\s*((?:[^(,]|\([^()]*|(?R)*\))*),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
                                        $line,
                                        $m) == 0) {
                                die("ERROR ($def:$lineno): Invalid ZEND_VM_TYPE_HANDLER_HANDLER definition.\n");
                        }
                        $hot = !empty($m[1]) ? $m[1] : false;
-                       $orig_op = $m[2];
-                       if (!isset($opnames[$orig_op])) {
-                               die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n");
-                       }
-                       $orig_code = $opnames[$orig_op];
-                       $condition = $m[3];
+                       $orig_op_list = $m[2];
                        $code = $extra_num++;
+                       foreach (explode('|', $orig_op_list) as $orig_op) {
+                               if (!isset($opnames[$orig_op])) {
+                                       die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n");
+                               }
+                               $orig_code = $opnames[$orig_op];
+                               $condition = $m[3];
+                               $opcodes[$orig_code]['type_spec'][$code] = $condition;
+                       }
                        $op = $m[4];
                        $op1  = parse_operand_spec($def, $lineno, $m[5], $flags1);
                        $op2  = parse_operand_spec($def, $lineno, $m[6], $flags2);
@@ -2418,7 +2421,6 @@ function gen_vm($def, $skel) {
                        if (isset($opcodes[$code])) {
                                die("ERROR ($def:$lineno): Opcode with name '$code' is already defined.\n");
                        }
-                       $opcodes[$orig_code]['type_spec'][$code] = $condition;
                        $used_extra_spec["TYPE"] = 1;
                        $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags,"hot"=>$hot,"is_type_spec"=>true);
                        if (isset($m[10])) {
@@ -2818,13 +2820,6 @@ function gen_vm($def, $skel) {
                                if (isset($dsc['type_spec'])) {
                                        $orig_op = $dsc['op'];
                                        out($f, "\t\tcase $orig_op:\n");
-                                       // XXX: Copy the specializations for LONG == LONG and DOUBLE != DOUBLE to work for ===/!== as well.
-                                       // (Those are currently the only specializations)
-                                       if ($orig_op === 'ZEND_IS_EQUAL') {
-                                               out($f, "\t\tcase ZEND_IS_IDENTICAL:\n");
-                                       } elseif ($orig_op === 'ZEND_IS_NOT_EQUAL') {
-                                               out($f, "\t\tcase ZEND_IS_NOT_IDENTICAL:\n");
-                                       }
                                        if (isset($dsc["spec"]["COMMUTATIVE"])) {
                                                out($f, "\t\t\tif (op->op1_type < op->op2_type) {\n");
                                                out($f, "\t\t\t\tzend_swap_operands(op);\n");
@@ -2864,10 +2859,8 @@ function gen_vm($def, $skel) {
                                    !isset($dsc['type_spec']) &&
                                    isset($dsc["spec"]["COMMUTATIVE"])) {
                                        $orig_op = $dsc['op'];
-                                       if (!in_array($orig_op, ['ZEND_IS_IDENTICAL', 'ZEND_IS_NOT_IDENTICAL'])) {
-                                               out($f, "\t\tcase $orig_op:\n");
-                                               $has_commutative = true;
-                                       }
+                                       out($f, "\t\tcase $orig_op:\n");
+                                       $has_commutative = true;
                                }
                        }
                        if ($has_commutative) {