summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2005-06-10 09:54:38 +0000
committerDmitry Stogov <dmitry@php.net>2005-06-10 09:54:38 +0000
commit84b96e9b03534400f155c5580f1c2fe399966bb3 (patch)
tree22c3e761370a26af46bd759b73536d1fc04af2be
parent6efa17c2a1dd3448718845b9bbd93ca7769c7068 (diff)
downloadphp-git-84b96e9b03534400f155c5580f1c2fe399966bb3.tar.gz
Fix so that extensions like xdebug, can overload opcodes in all execution modes including goto/switch
-rw-r--r--Zend/zend_execute.c15
-rw-r--r--Zend/zend_execute.h7
-rw-r--r--Zend/zend_extensions.h2
-rw-r--r--Zend/zend_vm_def.h13
-rw-r--r--Zend/zend_vm_execute.h89
-rw-r--r--Zend/zend_vm_gen.php49
-rw-r--r--Zend/zend_vm_opcodes.h1
7 files changed, 159 insertions, 17 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index ffae16f577..d3ae96caf5 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1460,6 +1460,21 @@ static int zend_vm_old_executor = 0;
#include "zend_vm_execute.h"
+ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, opcode_handler_t handler)
+{
+ if (opcode != ZEND_USER_OPCODE) {
+ zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
+ zend_user_opcode_handlers[opcode] = handler;
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+ZEND_API opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
+{
+ return zend_user_opcode_handlers[opcode];
+}
+
/*
* Local variables:
* tab-width: 4
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 7e96ecc39f..509d624b4f 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -176,6 +176,13 @@ void zend_shutdown_timeout_thread();
ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data_ptr, zend_uint var);
+#define ZEND_USER_OPCODE_CONTINUE 0 /* execute next opcode */
+#define ZEND_USER_OPCODE_RETURN 1 /* exit from executor (return from function) */
+#define ZEND_USER_OPCODE_DISPATCH 2 /* call original opcode handler */
+
+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);
+
END_EXTERN_C()
#endif /* ZEND_EXECUTE_H */
diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h
index 19584341ba..a937430d88 100644
--- a/Zend/zend_extensions.h
+++ b/Zend/zend_extensions.h
@@ -27,7 +27,7 @@
/* The first number is the engine version and the rest is the date.
* This way engine 2 API no. is always greater than engine 1 API no..
*/
-#define ZEND_EXTENSION_API_NO 220041031
+#define ZEND_EXTENSION_API_NO 220050610
typedef struct _zend_extension_version_info {
int zend_extension_api_no;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index e8d5e71c59..8d5d81a54c 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -3581,3 +3581,16 @@ ZEND_VM_HANDLER(146, ZEND_VERIFY_ABSTRACT_CLASS, ANY, ANY)
ZEND_VM_NEXT_OPCODE();
}
+ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
+{
+ switch (zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL)) {
+ case ZEND_USER_OPCODE_CONTINUE:
+ ZEND_VM_CONTINUE();
+ case ZEND_USER_OPCODE_RETURN:
+ ZEND_VM_RETURN();
+ case ZEND_USER_OPCODE_DISPATCH:
+ default:
+ ZEND_VM_DISPATCH(EX(opline));
+ }
+}
+
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index cdc4adbd07..74e74430cf 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -18,9 +18,18 @@
/* $Id$ */
+static opcode_handler_t zend_user_opcode_handlers[256] = {(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL};
-#define ZEND_VM_CONTINUE() return 0
-#define ZEND_VM_RETURN() return 1
+static zend_uchar zend_user_opcodes[256] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
+
+static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op);
+
+
+#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_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC
ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
{
@@ -544,6 +553,19 @@ static int ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_NEXT_OPCODE();
}
+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)) {
+ case ZEND_USER_OPCODE_CONTINUE:
+ ZEND_VM_CONTINUE();
+ case ZEND_USER_OPCODE_RETURN:
+ ZEND_VM_RETURN();
+ case ZEND_USER_OPCODE_DISPATCH:
+ default:
+ ZEND_VM_DISPATCH(EX(opline));
+ }
+}
+
static int ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
@@ -29477,6 +29499,31 @@ void zend_init_opcodes_handlers()
ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
+ ZEND_USER_OPCODE_SPEC_HANDLER,
ZEND_NULL_HANDLER
};
zend_opcode_handlers = (opcode_handler_t*)labels;
@@ -29491,9 +29538,18 @@ void zend_init_opcodes_handlers()
#undef ZEND_VM_RETURN
+#undef ZEND_VM_DISPATCH
+
+#undef ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL
+
+static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op);
+
-#define ZEND_VM_CONTINUE() return 0
-#define ZEND_VM_RETURN() return 1
+#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_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC
ZEND_API void old_execute(zend_op_array *op_array TSRMLS_DC)
{
@@ -33116,6 +33172,19 @@ static int ZEND_VERIFY_ABSTRACT_CLASS_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_USER_OPCODE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ switch (zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL)) {
+ case ZEND_USER_OPCODE_CONTINUE:
+ ZEND_VM_CONTINUE();
+ case ZEND_USER_OPCODE_RETURN:
+ ZEND_VM_RETURN();
+ case ZEND_USER_OPCODE_DISPATCH:
+ default:
+ ZEND_VM_DISPATCH(EX(opline));
+ }
+}
+
void zend_vm_use_old_executor()
{
@@ -33270,16 +33339,17 @@ void zend_vm_use_old_executor()
ZEND_ASSIGN_DIM_HANDLER,
ZEND_ISSET_ISEMPTY_PROP_OBJ_HANDLER,
ZEND_HANDLE_EXCEPTION_HANDLER,
+ ZEND_USER_OPCODE_HANDLER,
ZEND_NULL_HANDLER
};
zend_opcode_handlers = (opcode_handler_t*)labels;
zend_vm_old_executor = 1;
zend_execute = old_execute;
}
-void zend_vm_set_opcode_handler(zend_op* op)
+static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op)
{
if (zend_vm_old_executor) {
- op->handler = zend_opcode_handlers[op->opcode];
+ return zend_opcode_handlers[opcode];
} else {
static const int zend_vm_decode[] = {
_UNUSED_CODE, /* 0 */
@@ -33300,7 +33370,12 @@ void zend_vm_set_opcode_handler(zend_op* op)
_UNUSED_CODE, /* 15 */
_CV_CODE /* 16 = IS_CV */
};
- op->handler = zend_opcode_handlers[op->opcode * 25 + zend_vm_decode[op->op1.op_type] * 5 + zend_vm_decode[op->op2.op_type]];
+ return zend_opcode_handlers[opcode * 25 + zend_vm_decode[op->op1.op_type] * 5 + zend_vm_decode[op->op2.op_type]];
}
}
+void zend_vm_set_opcode_handler(zend_op* op)
+{
+ op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);
+}
+
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index 4d6c0f3611..03d0ae1211 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -703,21 +703,28 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
if (preg_match("/(.*)[{][%]([A-Z_]*)[%][}](.*)/", $line, $m)) {
switch ($m[2]) {
case "DEFINES":
+ out($f,"static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op);\n\n");
switch ($kind) {
case ZEND_VM_KIND_CALL:
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_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_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_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_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL &execute_data TSRMLS_CC\n");
break;
}
break;
@@ -726,6 +733,9 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
break;
case "HELPER_VARS":
if ($kind != ZEND_VM_KIND_CALL) {
+ if ($kind == ZEND_VM_KIND_SWITCH) {
+ out($f,$m[1]."opcode_handler_t dispatch_handler;\n");
+ }
// Emit local variables those are used for helpers' parameters
foreach ($params as $param => $x) {
out($f,$m[1].$param.";\n");
@@ -753,7 +763,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
case "ZEND_VM_CONTINUE_LABEL":
if ($kind == ZEND_VM_KIND_SWITCH) {
// Only SWITCH dispatch method use it
- out($f,$m[1]."zend_vm_continue:".$m[3]."\n");
+ out($f,"zend_vm_continue:".$m[3]."\n");
} else {
skip_blanks($f, $m[1], $m[3]);
}
@@ -765,7 +775,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
out($f, $m[1]."if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0)".$m[3]."\n");
break;
case ZEND_VM_KIND_SWITCH:
- out($f, $m[1]."switch ((int)EX(opline)->handler)".$m[3]."\n");
+ out($f, $m[1]."dispatch_handler = EX(opline)->handler;\nzend_vm_dispatch:\n".$m[1]."switch ((int)dispatch_handler)".$m[3]."\n");
break;
case ZEND_VM_KIND_GOTO:
out($f, $m[1]."goto *(void**)(EX(opline)->handler);".$m[3]."\n");
@@ -974,6 +984,19 @@ function gen_vm($def, $skel) {
// Insert header
out($f, $GLOBALS['header_text']);
+ // Support for ZEND_USER_OPCODE
+ out($f, "static opcode_handler_t zend_user_opcode_handlers[256] = {");
+ for ($i = 0; $i < 255; ++$i) {
+ out($f, "(opcode_handler_t)NULL,");
+ }
+ out($f, "(opcode_handler_t)NULL};\n\n");
+
+ out($f, "static zend_uchar zend_user_opcodes[256] = {");
+ for ($i = 0; $i < 255; ++$i) {
+ out($f, "$i,");
+ }
+ out($f, "255};\n\n");
+
// Generate specialized executor
gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_KIND, "execute", "zend_init_opcodes_handlers", 0);
@@ -984,18 +1007,20 @@ function gen_vm($def, $skel) {
out($f,"#define EX(element) execute_data.element\n\n");
out($f,"#undef ZEND_VM_CONTINUE\n\n");
out($f,"#undef ZEND_VM_RETURN\n\n");
+ out($f,"#undef ZEND_VM_DISPATCH\n\n");
+ out($f,"#undef ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL\n\n");
gen_executor($f, $skl, 0, ZEND_VM_KIND_CALL, "old_execute", "zend_vm_use_old_executor", 1);
}
- // Generate zend_vm_set_opcode_handler() function
- out($f, "void zend_vm_set_opcode_handler(zend_op* op)\n");
+ // Generate zend_vm_get_opcode_handler() function
+ out($f, "static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op)\n");
out($f, "{\n");
if (!ZEND_VM_SPEC) {
- out($f, "\top->handler = zend_opcode_handlers[op->opcode];\n");
+ out($f, "\treturn zend_opcode_handlers[opcode];\n");
} else {
if (ZEND_VM_OLD_EXECUTOR) {
out($f, "\tif (zend_vm_old_executor) {\n");
- out($f, "\t\top->handler = zend_opcode_handlers[op->opcode];\n");
+ out($f, "\t\treturn zend_opcode_handlers[opcode];\n");
out($f, "\t} else {\n");
}
out($f, "\t\tstatic const int zend_vm_decode[] = {\n");
@@ -1017,13 +1042,19 @@ function gen_vm($def, $skel) {
out($f, "\t\t\t_UNUSED_CODE, /* 15 */\n");
out($f, "\t\t\t_CV_CODE /* 16 = IS_CV */\n");
out($f, "\t\t};\n");
- out($f, "\t\top->handler = zend_opcode_handlers[op->opcode * 25 + zend_vm_decode[op->op1.op_type] * 5 + zend_vm_decode[op->op2.op_type]];\n");
+ out($f, "\t\treturn zend_opcode_handlers[opcode * 25 + zend_vm_decode[op->op1.op_type] * 5 + zend_vm_decode[op->op2.op_type]];\n");
if (ZEND_VM_OLD_EXECUTOR) {
out($f, "\t}\n");
}
}
out($f, "}\n\n");
+ // Generate zend_vm_get_opcode_handler() function
+ out($f, "void zend_vm_set_opcode_handler(zend_op* op)\n");
+ out($f, "{\n");
+ out($f, "\top->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);\n");
+ out($f, "}\n\n");
+
fclose($f);
echo "zend_vm_execute.h generated succesfull.\n";
}
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 36dee54f3d..4a907d4ec3 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -145,3 +145,4 @@
#define ZEND_ASSIGN_DIM 147
#define ZEND_ISSET_ISEMPTY_PROP_OBJ 148
#define ZEND_HANDLE_EXCEPTION 149
+#define ZEND_USER_OPCODE 150