summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_execute.h2
-rw-r--r--Zend/zend_vm_def.h7
-rw-r--r--Zend/zend_vm_execute.h9
-rw-r--r--Zend/zend_vm_gen.php6
4 files changed, 16 insertions, 8 deletions
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 509d624b4f..f196fa7c9d 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -180,6 +180,8 @@ ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data
#define ZEND_USER_OPCODE_RETURN 1 /* exit from executor (return from function) */
#define ZEND_USER_OPCODE_DISPATCH 2 /* call original opcode handler */
+#define ZEND_USER_OPCODE_DISPATCH_TO 0x100 /* call original handler of returned opcode */
+
ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, opcode_handler_t handler);
ZEND_API opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 7e6e825a00..9a0f1d8870 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -3578,14 +3578,17 @@ ZEND_VM_HANDLER(146, ZEND_VERIFY_ABSTRACT_CLASS, ANY, ANY)
ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
{
- switch (zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL)) {
+ int ret = zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL);
+
+ switch (ret) {
case ZEND_USER_OPCODE_CONTINUE:
ZEND_VM_CONTINUE();
case ZEND_USER_OPCODE_RETURN:
ZEND_VM_RETURN();
case ZEND_USER_OPCODE_DISPATCH:
+ ZEND_VM_DISPATCH(EX(opline)->opcode, EX(opline));
default:
- ZEND_VM_DISPATCH(EX(opline));
+ ZEND_VM_DISPATCH(ret & 0xff, EX(opline));
}
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 4fa471003a..9f49f90263 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -27,7 +27,7 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o
#define ZEND_VM_CONTINUE() return 0
#define ZEND_VM_RETURN() return 1
-#define ZEND_VM_DISPATCH(op) return zend_vm_get_opcode_handler(op->opcode, op)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC
@@ -555,14 +555,17 @@ static int ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- switch (zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL)) {
+ int ret = zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL);
+
+ switch (ret) {
case ZEND_USER_OPCODE_CONTINUE:
ZEND_VM_CONTINUE();
case ZEND_USER_OPCODE_RETURN:
ZEND_VM_RETURN();
case ZEND_USER_OPCODE_DISPATCH:
+ ZEND_VM_DISPATCH(EX(opline)->opcode, EX(opline));
default:
- ZEND_VM_DISPATCH(EX(opline));
+ ZEND_VM_DISPATCH(ret & 0xff, EX(opline));
}
}
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index c930709a93..a395ee05d6 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -747,21 +747,21 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
out($f,"\n");
out($f,"#define ZEND_VM_CONTINUE() return 0\n");
out($f,"#define ZEND_VM_RETURN() return 1\n");
- out($f,"#define ZEND_VM_DISPATCH(op) return zend_vm_get_opcode_handler(op->opcode, op)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n");
+ out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n");
out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
break;
case ZEND_VM_KIND_SWITCH:
out($f,"\n");
out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n");
out($f,"#define ZEND_VM_RETURN() return\n");
- out($f,"#define ZEND_VM_DISPATCH(op) dispatch_handler = zend_vm_get_opcode_handler(op->opcode, op); goto zend_vm_dispatch;\n\n");
+ out($f,"#define ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n\n");
out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL &execute_data TSRMLS_CC\n");
break;
case ZEND_VM_KIND_GOTO:
out($f,"\n");
out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(EX(opline)->handler)\n");
out($f,"#define ZEND_VM_RETURN() return\n");
- out($f,"#define ZEND_VM_DISPATCH(op) goto *(void**)(zend_vm_get_opcode_handler(op->opcode, op));\n\n");
+ out($f,"#define ZEND_VM_DISPATCH(opcode, opline) goto *(void**)(zend_vm_get_opcode_handler(opcode, opline));\n\n");
out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL &execute_data TSRMLS_CC\n");
break;
}