Added API function to call VM opcode handler in a portable way

This commit is contained in:
Dmitry Stogov 2015-03-13 11:29:43 +03:00
parent d695a44a7e
commit ae26a51f0f
4 changed files with 56 additions and 1 deletions

View File

@ -25,6 +25,7 @@ BEGIN_EXTERN_C()
ZEND_API void zend_vm_use_old_executor(void);
ZEND_API void zend_vm_set_opcode_handler(zend_op* opcode);
ZEND_API int zend_vm_call_opcode_handler(zend_execute_data *ex);
END_EXTERN_C()

View File

@ -42835,3 +42835,28 @@ ZEND_API void zend_vm_set_opcode_handler(zend_op* op)
op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);
}
ZEND_API int zend_vm_call_opcode_handler(zend_execute_data* ex)
{
int ret;
#ifdef ZEND_VM_IP_GLOBAL_REG
const zend_op *orig_opline = opline;
#endif
#ifdef ZEND_VM_FP_GLOBAL_REG
zend_execute_data *orig_execute_data = execute_data;
execute_data = ex;
#else
zend_execute_data *execute_data = ex;
#endif
LOAD_OPLINE();
ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
SAVE_OPLINE();
#ifdef ZEND_VM_FP_GLOBAL_REG
execute_data = orig_execute_data;
#endif
#ifdef ZEND_VM_IP_GLOBAL_REG
opline = orig_opline;
#endif
return ret;
}

View File

@ -1468,6 +1468,34 @@ function gen_vm($def, $skel) {
out($f, "\top->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);\n");
out($f, "}\n\n");
// Generate zend_vm_call_opcode_handler() function
if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) {
out($f, "ZEND_API int zend_vm_call_opcode_handler(zend_execute_data* ex)\n");
out($f, "{\n");
out($f, "\tint ret;\n");
out($f, "#ifdef ZEND_VM_IP_GLOBAL_REG\n");
out($f, "\tconst zend_op *orig_opline = opline;\n");
out($f, "#endif\n");
out($f, "#ifdef ZEND_VM_FP_GLOBAL_REG\n");
out($f, "\tzend_execute_data *orig_execute_data = execute_data;\n");
out($f, "\texecute_data = ex;\n");
out($f, "#else\n");
out($f, "\tzend_execute_data *execute_data = ex;\n");
out($f, "#endif\n");
out($f, "\n");
out($f, "\tLOAD_OPLINE();\n");
out($f, "\tret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
out($f, "\tSAVE_OPLINE();\n");
out($f, "#ifdef ZEND_VM_FP_GLOBAL_REG\n");
out($f, "\texecute_data = orig_execute_data;\n");
out($f, "#endif\n");
out($f, "#ifdef ZEND_VM_IP_GLOBAL_REG\n");
out($f, "\topline = orig_opline;\n");
out($f, "#endif\n");
out($f, "\treturn ret;\n");
out($f, "}\n\n");
}
// Export handlers and helpers
if (count($export) > 0 &&
ZEND_VM_KIND != ZEND_VM_KIND_CALL) {

View File

@ -23,6 +23,7 @@
#include "zend.h"
#include "zend_compile.h"
#include "zend_exceptions.h"
#include "zend_vm.h"
#include "phpdbg.h"
#include "phpdbg_help.h"
@ -1460,7 +1461,7 @@ next:
execute_data->func->type == ZEND_USER_FUNCTION) {
zend_execute_ex = execute_ex;
}
PHPDBG_G(vmret) = execute_data->opline->handler(execute_data);
PHPDBG_G(vmret) = zend_vm_call_opcode_handler(execute_data);
zend_execute_ex = phpdbg_execute_ex;
if (PHPDBG_G(vmret) != 0) {