summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-09-05 22:11:10 +0300
committerDmitry Stogov <dmitry@zend.com>2018-09-05 22:11:10 +0300
commit1d36c3361fcad50d17d660d13fdcfebfde478dad (patch)
tree37f5850c0979ba9be6cd9d503d94ed23fc5d7425
parent21cd552e1e6685048ed159091274a8311b84d4c8 (diff)
downloadphp-git-1d36c3361fcad50d17d660d13fdcfebfde478dad.tar.gz
Fixed support for commutative "user opcodes"
-rw-r--r--Zend/zend_vm_execute.h12
-rw-r--r--Zend/zend_vm_gen.php27
2 files changed, 26 insertions, 13 deletions
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 <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");