]> granicus.if.org Git - php/commitdiff
Fixed support for commutative "user opcodes"
authorDmitry Stogov <dmitry@zend.com>
Wed, 5 Sep 2018 19:11:10 +0000 (22:11 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 5 Sep 2018 19:11:10 +0000 (22:11 +0300)
Zend/zend_vm_execute.h
Zend/zend_vm_gen.php

index 35ab7dda5c48cf90310a3a0d9258e85f284fee93..c5e3cdd2e67b9f8f9ad370ce2c65d4baaf296498 100644 (file)
@@ -65142,14 +65142,13 @@ static const void *zend_vm_get_opcode_handler_func(zend_uchar opcode, const zend
 ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler(zend_op* op)
 {
        zend_uchar opcode = zend_user_opcodes[op->opcode];
-       uint32_t spec = zend_spec_handlers[opcode];
 
-       if (spec & SPEC_RULE_COMMUTATIVE) {
+       if (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {
                if (op->op1_type < op->op2_type) {
                        zend_swap_operands(op);
                }
        }
-       op->handler = zend_vm_get_opcode_handler_ex(spec, op);
+       op->handler = zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);
 }
 
 ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info)
@@ -65372,6 +65371,13 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
                                zend_swap_operands(op);
                        }
                        break;
+               case ZEND_USER_OPCODE:
+                       if (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {
+                               if (op->op1_type < op->op2_type) {
+                                       zend_swap_operands(op);
+                               }
+                       }
+                       break;
                default:
                        break;
        }
index a0b1fa4e9ea9ac73fd39421d2029e1d18a74f955..383b0cb00f8fa1ce0e56c735cd0c45084467c88a 100644 (file)
@@ -1393,7 +1393,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
                                                $label++;
                                                return;
                                        }
-                                       
+
                                        // Emit pointer to specialized handler
                                        $spec_name = $dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec);
                                        switch ($kind) {
@@ -2148,7 +2148,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                                                                "# endif\n" .
                                                                $m[1]."return;\n" .
                                                                "#else\n" .
-                                                               $m[1]."if (EXPECTED(ret > 0)) {\n" . 
+                                                               $m[1]."if (EXPECTED(ret > 0)) {\n" .
                                                        $m[1]."\texecute_data = EG(current_execute_data);\n".
                                                                $m[1]."\tZEND_VM_LOOP_INTERRUPT_CHECK();\n".
                                                        $m[1]."} else {\n" .
@@ -2572,7 +2572,7 @@ function gen_vm($def, $skel) {
        fputs($f, "ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(zend_uchar opcode);\n");
        fputs($f, "ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(zend_uchar opcode);\n\n");
        fputs($f, "END_EXTERN_C()\n\n");
-       
+
        foreach ($opcodes as $code => $dsc) {
                $code = str_pad((string)$code,$code_len," ",STR_PAD_LEFT);
                $op = str_pad($dsc["op"],$max_opcode_len);
@@ -2597,13 +2597,13 @@ function gen_vm($def, $skel) {
        fputs($f,"#include <stdio.h>\n");
        fputs($f,"#include <zend.h>\n");
        fputs($f,"#include <zend_vm_opcodes.h>\n\n");
-       
+
        fputs($f,"static const char *zend_vm_opcodes_names[".($max_opcode + 1)."] = {\n");
        for ($i = 0; $i <= $max_opcode; $i++) {
                fputs($f,"\t".(isset($opcodes[$i]["op"])?'"'.$opcodes[$i]["op"].'"':"NULL").",\n");
        }
        fputs($f, "};\n\n");
-       
+
        fputs($f,"static uint32_t zend_vm_opcodes_flags[".($max_opcode + 1)."] = {\n");
        for ($i = 0; $i <= $max_opcode; $i++) {
                fprintf($f, "\t0x%08x,\n", isset($opcodes[$i]["flags"]) ? $opcodes[$i]["flags"] : 0);
@@ -2623,7 +2623,7 @@ function gen_vm($def, $skel) {
        fputs($f, "\t}\n");
        fputs($f, "\treturn zend_vm_opcodes_flags[opcode];\n");
        fputs($f, "}\n");
-    
+
        fclose($f);
        echo "zend_vm_opcodes.c generated successfully.\n";
 
@@ -2654,7 +2654,7 @@ function gen_vm($def, $skel) {
                out($f, "# pragma warning(once : 6326)\n");
        }
        out($f, "#endif\n");
-       
+
        // Support for ZEND_USER_OPCODE
        out($f, "static user_opcode_handler_t zend_user_opcode_handlers[256] = {\n");
        for ($i = 0; $i < 255; ++$i) {
@@ -2845,13 +2845,13 @@ function gen_vm($def, $skel) {
        if (!ZEND_VM_SPEC) {
                out($f, "\top->handler = zend_vm_get_opcode_handler(opcode, op);\n");
        } else {
-               out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n\n");
-               out($f, "\tif (spec & SPEC_RULE_COMMUTATIVE) {\n");
+               out($f, "\n");
+               out($f, "\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {\n");
                out($f, "\t\tif (op->op1_type < op->op2_type) {\n");
                out($f, "\t\t\tzend_swap_operands(op);\n");
                out($f, "\t\t}\n");
                out($f, "\t}\n");
-               out($f, "\top->handler = zend_vm_get_opcode_handler_ex(spec, op);\n");
+               out($f, "\top->handler = zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);\n");
        }
        out($f, "}\n\n");
 
@@ -2917,6 +2917,13 @@ function gen_vm($def, $skel) {
                                out($f, "\t\t\t\tzend_swap_operands(op);\n");
                                out($f, "\t\t\t}\n");
                                out($f, "\t\t\tbreak;\n");
+                               out($f, "\t\tcase ZEND_USER_OPCODE:\n");
+                               out($f, "\t\t\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {\n");
+                               out($f, "\t\t\t\tif (op->op1_type < op->op2_type) {\n");
+                               out($f, "\t\t\t\t\tzend_swap_operands(op);\n");
+                               out($f, "\t\t\t\t}\n");
+                               out($f, "\t\t\t}\n");
+                               out($f, "\t\t\tbreak;\n");
                        }
                        out($f, "\t\tdefault:\n");
                        out($f, "\t\t\tbreak;\n");