From: Dmitry Stogov Date: Wed, 5 Sep 2018 19:11:10 +0000 (+0300) Subject: Fixed support for commutative "user opcodes" X-Git-Tag: php-7.3.0RC1~18 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d36c3361fcad50d17d660d13fdcfebfde478dad;p=php Fixed support for commutative "user opcodes" --- diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 35ab7dda5c..c5e3cdd2e6 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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; } diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index a0b1fa4e9e..383b0cb00f 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -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 \n"); fputs($f,"#include \n"); fputs($f,"#include \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");