com php-src: Fixed USER_OPCODE handling in HYBRID VM .: Zend/zend_vm_execute.h Zend/zend_vm_gen. php

[email protected] (Dmitry Stogov)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    69b4f8ed7978818b30de8840f16c753f0f634fcc
Author:    Dmitry Stogov <[email protected]>         Mon, 15 May 2017 21:17:58 +0300
Parents:   041652bd4186a469d1e0074f87a9b4f7e0970fe8
Branches:  master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=69b4f8ed7978818b30de8840f16c753f0f634fcc

Log:
Fixed USER_OPCODE handling in HYBRID VM.

Changed paths:
  M  Zend/zend_vm_execute.h
  M  Zend/zend_vm_gen.php


Diff:
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 0fd8681..f6e91b1 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -319,6 +319,7 @@ static const uint32_t *zend_spec_handlers;
 static const void **zend_opcode_handlers;
 static int zend_handlers_count;
 static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op);
+static const void *zend_vm_get_real_opcode_handler(zend_uchar opcode, const zend_op* op);
 
 
 #ifdef ZEND_VM_FP_GLOBAL_REG
@@ -399,7 +400,7 @@ typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_H
 #endif
 #define ZEND_VM_INTERRUPT()      ZEND_VM_TAIL_CALL(zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 #define ZEND_VM_LOOP_INTERRUPT() zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_opcode_handler(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_real_opcode_handler(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS);
 
@@ -59305,6 +59306,23 @@ static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op*
 	return zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);
 }
 
+static const void *zend_vm_get_real_opcode_handler(zend_uchar opcode, const zend_op* op)
+{
+	const void *handler = zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);
+#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID
+	zval *zv;
+
+	if (!zend_handlers_table) {
+	init_opcode_serialiser();
+	}
+	zv = zend_hash_index_find(zend_handlers_table, (zend_long)(zend_uintptr_t)handler);
+	ZEND_ASSERT(zv != NULL);
+	return zend_opcode_real_handlers[Z_LVAL_P(zv)];
+#else
+	return handler;
+#endif
+}
+
 ZEND_API 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 9218574..fc51425 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -1587,7 +1587,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
 						out($f,"static zend_op hybrid_return_op;\n");
 						out($f,"#endif\n");
 					}
-					out($f,"static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op);\n\n");
+					out($f,"static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op);\n");
+					out($f,"static const void *zend_vm_get_real_opcode_handler(zend_uchar opcode, const zend_op* op);\n\n");
 					switch ($kind) {
 						case ZEND_VM_KIND_HYBRID:
 							out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
@@ -1690,7 +1691,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
 							out($f,"#endif\n");
 							out($f,"#define ZEND_VM_INTERRUPT()      ZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
 							out($f,"#define ZEND_VM_LOOP_INTERRUPT() zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
-							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_opcode_handler(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_real_opcode_handler(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
 							out($f,"\n");
 							out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS);");
 							out($f,"\n");
@@ -2454,6 +2455,27 @@ function gen_vm($def, $skel) {
 	}
 	out($f, "}\n\n");
 
+	// Generate zend_vm_get_real_opcode_handler() function
+	out($f, "static const void *zend_vm_get_real_opcode_handler(zend_uchar opcode, const zend_op* op)\n");
+	out($f, "{\n");
+	if (!ZEND_VM_SPEC) {
+		out($f, "\tconst void *handler = zend_vm_get_opcode_handler_ex(opcode, op);\n");
+	} else {
+		out($f, "\tconst void *handler = zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);\n");
+	}
+	out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID\n");
+	out($f, "\tzval *zv;\n\n");
+	out($f, "\tif (!zend_handlers_table) {\n");
+	out($f, "\tinit_opcode_serialiser();\n");
+	out($f, "\t}\n");
+	out($f, "\tzv = zend_hash_index_find(zend_handlers_table, (zend_long)(zend_uintptr_t)handler);\n");
+	out($f, "\tZEND_ASSERT(zv != NULL);\n");
+	out($f, "\treturn zend_opcode_real_handlers[Z_LVAL_P(zv)];\n");
+	out($f, "#else\n");
+	out($f, "\treturn handler;\n");
+	out($f, "#endif\n");
+	out($f, "}\n\n");
+
 	// Generate zend_vm_get_opcode_handler() function
 	out($f, "ZEND_API void zend_vm_set_opcode_handler(zend_op* op)\n");
 	out($f, "{\n");
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.