summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_vm.h1
-rw-r--r--Zend/zend_vm_execute.h25
-rw-r--r--Zend/zend_vm_gen.php28
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c3
4 files changed, 56 insertions, 1 deletions
diff --git a/Zend/zend_vm.h b/Zend/zend_vm.h
index 15a269e0a7..5a5c9fa96e 100644
--- a/Zend/zend_vm.h
+++ b/Zend/zend_vm.h
@@ -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()
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 189555891d..af085f6b27 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -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;
+}
+
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index a972784283..7fc7902ae6 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -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) {
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index 72cb2e018c..b9228aa922 100644
--- a/sapi/phpdbg/phpdbg_prompt.c
+++ b/sapi/phpdbg/phpdbg_prompt.c
@@ -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) {