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)
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;
}
$label++;
return;
}
-
+
// Emit pointer to specialized handler
$spec_name = $dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec);
switch ($kind) {
"# 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" .
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);
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);
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";
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) {
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");
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");