Browse files

- Some architectural changes:

 a) We specialize opcodes according to op_type fields. Each opcode has to
    be marked with which op_type's it uses.
 b) We support different execution methods. Function handlers, switch()
    and goto dispatching. goto seems to be the fastest but it really
    depends on the compiler and how well it optimizes. I suggest playing
    around with optimization flags.

- Warning: Things might break so keep us posted on how things are going.
  (Dmitry, Andi)
  • Loading branch information...
1 parent d179ac7 commit 8eb8850c907040b2dbf3e4e8abbd1f6869bed457 @andigutmans andigutmans committed Sep 8, 2004
Showing with 5,350 additions and 3,818 deletions.
  1. +1 −1 Zend/zend_compile.h
  2. +1 −1 Zend/zend_exceptions.c
  3. +363 −3,812 Zend/zend_execute.c
  4. +0 −2 Zend/zend_execute.h
  5. +2 −1 Zend/zend_execute_API.c
  6. +3 −1 Zend/zend_opcode.c
  7. +362 −0 Zend/zend_vm.h
  8. +3,968 −0 Zend/zend_vm_handlers.h
  9. +650 −0 Zend/zend_vm_spec.h
View
2 Zend/zend_compile.h
@@ -72,7 +72,7 @@ typedef struct _zend_execute_data zend_execute_data;
typedef int (*opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);
-extern ZEND_API opcode_handler_t zend_opcode_handlers[512];
+extern ZEND_API opcode_handler_t *zend_opcode_handlers;
struct _zend_op {
opcode_handler_t handler;
View
2 Zend/zend_exceptions.c
@@ -175,7 +175,7 @@ ZEND_METHOD(error_exception, __construct)
if (argc >= 4) {
zend_update_property_string(default_exception_ce, object, "file", sizeof("file")-1, filename TSRMLS_CC);
if (argc < 5) {
- lineno = 0; // invalidate lineno
+ lineno = 0; /* invalidate lineno */
}
zend_update_property_long(default_exception_ce, object, "line", sizeof("line")-1, lineno TSRMLS_CC);
}
View
4,175 Zend/zend_execute.c
363 additions, 3,812 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
2 Zend/zend_execute.h
@@ -167,8 +167,6 @@ void zend_shutdown_timeout_thread();
#define active_opline (*EG(opline_ptr))
-void zend_assign_to_variable_reference(znode *result, zval **variable_ptr_ptr, zval **value_ptr_ptr, temp_variable *Ts TSRMLS_DC);
-
/* The following tries to resolve the classname of a zval of type object.
* Since it is slow it should be only used in error messages.
*/
View
3 Zend/zend_execute_API.c
@@ -30,6 +30,7 @@
#include "zend_constants.h"
#include "zend_extensions.h"
#include "zend_exceptions.h"
+#include "zend_vm.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
@@ -1073,7 +1074,7 @@ void execute_new_code(TSRMLS_D)
opline->op2.u.constant.is_ref = 1;
opline->op2.u.constant.refcount = 2;
}
- opline->handler = zend_opcode_handlers[opline->opcode];
+ ZEND_VM_SET_OPCODE_HANDLER(opline);
opline++;
}
View
4 Zend/zend_opcode.c
@@ -27,6 +27,8 @@
#include "zend_extensions.h"
#include "zend_API.h"
+#include "zend_vm.h"
+
static void zend_extension_op_array_ctor_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
{
if (extension->op_array_ctor) {
@@ -361,7 +363,7 @@ int pass_two(zend_op_array *op_array TSRMLS_DC)
opline->op2.u.jmp_addr = &op_array->opcodes[opline->op2.u.opline_num];
break;
}
- opline->handler = zend_opcode_handlers[opline->opcode];
+ ZEND_VM_SET_OPCODE_HANDLER(opline);
opline++;
}
View
362 Zend/zend_vm.h
@@ -0,0 +1,362 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend Engine |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2004 Zend Technologies Ltd. (http://www.zend.com) |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.00 of the Zend license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.zend.com/license/2_00.txt. |
+ | If you did not receive a copy of the Zend license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@zend.com so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef ZEND_VM_H
+#define ZEND_VM_H
+
+#define ZEND_VM_KIND_CALL 1
+#define ZEND_VM_KIND_SWITCH 2
+#define ZEND_VM_KIND_GOTO 3
+
+/* #define ZEND_VM_KIND ZEND_VM_KIND_CALL */
+#define ZEND_VM_SPEC
+
+/* don't edit the rest of the file */
+
+#define _CONST_CODE 0
+#define _TMP_CODE 1
+#define _VAR_CODE 2
+#define _UNUSED_CODE 3
+
+#ifndef ZEND_VM_KIND
+# ifdef __GNUC__
+# define ZEND_VM_KIND ZEND_VM_KIND_GOTO
+# else
+# define ZEND_VM_KIND ZEND_VM_KIND_SWITCH
+# endif
+#endif
+
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+# define ZEND_VM_ALWAYS_INLINE __attribute__ ((always_inline))
+void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
+/*extern void zend_error_noreturn(int type, const char *format, ...) __asm__("zend_error") __attribute__ ((noreturn));*/
+#else
+# define ZEND_VM_ALWAYS_INLINE
+# define zend_error_noreturn zend_error
+#endif
+
+#ifndef ZEND_VM_SPEC
+# define ZEND_VM_CODE(opcode, op1, op2) opcode
+# define ZEND_VM_SPEC_OPCODE(opcode, op1, op2) opcode
+# define ZEND_VM_SET_OPCODE_HANDLER(opline) \
+ opline->handler = zend_opcode_handlers[opline->opcode];
+#else
+static const int zend_vm_decode[] = {
+ _UNUSED_CODE, /* 0 */
+ _CONST_CODE, /* 1 = IS_CONST */
+ _TMP_CODE, /* 2 = IS_TMP_VAR */
+ _UNUSED_CODE, /* 3 */
+ _VAR_CODE, /* 4 = IS_VAR */
+ _UNUSED_CODE, /* 5 */
+ _UNUSED_CODE, /* 6 */
+ _UNUSED_CODE, /* 7 */
+ _UNUSED_CODE /* 8 = IS_UNUSED */
+};
+
+# define ZEND_VM_CODE(opcode, op1, op2) \
+ opcode * 16 + op1 * 4 + op2
+# define ZEND_VM_SPEC_OPCODE(opcode, op1, op2) \
+ ZEND_VM_CODE(opcode, zend_vm_decode[op1], zend_vm_decode[op2])
+# define ZEND_VM_SET_OPCODE_HANDLER(opline) \
+ opline->handler = zend_opcode_handlers[ZEND_VM_SPEC_OPCODE(opline->opcode, opline->op1.op_type, opline->op2.op_type)]
+#endif
+
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_CALL
+
+# define EXECUTE_DATA execute_data
+
+# define ZEND_VM_HELPER_VAR(X)
+
+# define ZEND_VM_DISPATCH() \
+ if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0)
+
+# define ZEND_VM_CONTINUE_LABEL
+
+# define ZEND_VM_HANDLER(OP) \
+ static int OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+
+# define ZEND_VM_HANDLER_EX(OP) \
+ static int OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+
+# define ZEND_VM_HELPER(NAME) \
+ static int NAME(ZEND_OPCODE_HANDLER_ARGS)
+
+# define ZEND_VM_HELPER_EX(NAME,PARAM) \
+ static int NAME(PARAM, ZEND_OPCODE_HANDLER_ARGS)
+
+# define ZEND_VM_SPEC_HANDLER(OP, CODE) \
+ static int OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+
+# define ZEND_VM_SPEC_HANDLER_EX(OP, CODE) \
+ static int OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+
+# define ZEND_VM_SPEC_HELPER(NAME) \
+ static int NAME(ZEND_OPCODE_HANDLER_ARGS)
+
+# define ZEND_VM_SPEC_HELPER_EX(NAME,PARAM) \
+ static int NAME(PARAM, ZEND_OPCODE_HANDLER_ARGS)
+
+# define ZEND_VM_NULL_HANDLER() \
+ int ZEND_VM_NULL(ZEND_OPCODE_HANDLER_ARGS)
+
+# define ZEND_VM_DISPATCH_TO_HANDLER(OP) \
+ return OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
+
+# define ZEND_VM_DISPATCH_TO_HELPER(NAME) \
+ return NAME(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
+
+# define ZEND_VM_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
+ return NAME(VAL, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HANDLER(OP) \
+ return OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER(NAME) \
+ return NAME(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
+ return NAME(VAL, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
+
+# define ZEND_VM_CONTINUE() \
+ return 0
+
+# define ZEND_VM_NEXT_OPCODE() \
+ CHECK_SYMBOL_TABLES() \
+ EX(opline)++; \
+ return 0
+
+# define ZEND_VM_SET_OPCODE(new_op) \
+ CHECK_SYMBOL_TABLES() \
+ EX(opline) = new_op
+
+# define ZEND_VM_INC_OPCODE() \
+ if (!EG(exception)) { \
+ CHECK_SYMBOL_TABLES() \
+ EX(opline)++; \
+ }
+
+# define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
+ if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \
+ free_alloca(EX(Ts)); \
+ } else { \
+ efree(EX(Ts)); \
+ } \
+ EG(in_execution) = EX(original_in_execution); \
+ EG(current_execute_data) = EX(prev_execute_data); \
+ return 1;
+
+# define ZEND_VM_LABEL(OP) OP##_HANDLER
+# define ZEND_VM_NULL_LABEL ZEND_VM_NULL
+# define ZEND_VM_SPEC_LABEL(OP,CODE) OP##_HANDLER
+# define ZEND_VM_SPEC_NULL_LABEL ZEND_VM_NULL
+
+#elif ZEND_VM_KIND == ZEND_VM_KIND_SWITCH
+
+# define EXECUTE_DATA &execute_data
+
+# define ZEND_VM_HELPER_VAR(X) X;
+
+# define ZEND_VM_DISPATCH() \
+ switch ((int)EX(opline)->handler)
+
+# define ZEND_VM_CONTINUE_LABEL \
+ zend_vm_continue:
+
+# define ZEND_VM_HANDLER(OP) \
+ case OP:
+
+# define ZEND_VM_HANDLER_EX(OP) \
+ case OP: \
+ OP##_LABEL:
+
+# define ZEND_VM_HELPER(NAME) \
+ NAME:
+
+# define ZEND_VM_HELPER_EX(NAME,PARAM) \
+ NAME:
+
+# define ZEND_VM_SPEC_HANDLER(OP, CODE) \
+ case CODE:
+
+# define ZEND_VM_SPEC_HANDLER_EX(OP, CODE) \
+ case CODE: \
+ OP##_LABEL:
+
+# define ZEND_VM_SPEC_HELPER(NAME) \
+ NAME:
+
+# define ZEND_VM_SPEC_HELPER_EX(NAME,PARAM) \
+ NAME:
+
+# define ZEND_VM_NULL_HANDLER() \
+ default:
+
+# define ZEND_VM_DISPATCH_TO_HANDLER(OP) \
+ goto OP##_LABEL
+
+# define ZEND_VM_DISPATCH_TO_HELPER(NAME) \
+ goto NAME
+
+# define ZEND_VM_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
+ VAR = VAL; \
+ goto NAME
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HANDLER(OP) \
+ goto OP##_LABEL
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER(NAME) \
+ goto NAME
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
+ VAR = VAL; \
+ goto NAME
+
+# define ZEND_VM_CONTINUE() \
+ goto zend_vm_continue
+
+# define ZEND_VM_NEXT_OPCODE() \
+ CHECK_SYMBOL_TABLES() \
+ EX(opline)++; \
+ ZEND_VM_CONTINUE()
+
+# define ZEND_VM_SET_OPCODE(new_op) \
+ CHECK_SYMBOL_TABLES() \
+ EX(opline) = new_op
+
+# define ZEND_VM_INC_OPCODE() \
+ if (!EG(exception)) { \
+ CHECK_SYMBOL_TABLES() \
+ EX(opline)++; \
+ }
+
+# define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
+ if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \
+ free_alloca(EX(Ts)); \
+ } else { \
+ efree(EX(Ts)); \
+ } \
+ EG(in_execution) = EX(original_in_execution); \
+ EG(current_execute_data) = EX(prev_execute_data); \
+ return;
+
+# define ZEND_VM_LABEL(OP) (opcode_handler_t)OP
+# define ZEND_VM_NULL_LABEL (opcode_handler_t)-1
+# define ZEND_VM_SPEC_LABEL(OP,CODE) (opcode_handler_t)(CODE)
+# define ZEND_VM_SPEC_NULL_LABEL (opcode_handler_t)-1
+
+#elif ZEND_VM_KIND == ZEND_VM_KIND_GOTO
+
+# define EXECUTE_DATA &execute_data
+
+# define ZEND_VM_HELPER_VAR(X) X;
+
+# define ZEND_VM_DISPATCH() \
+ goto *(void**)(EX(opline)->handler);
+
+# define ZEND_VM_CONTINUE_LABEL
+
+# define ZEND_VM_HANDLER(OP) \
+ OP##_HANDLER:
+
+# define ZEND_VM_HANDLER_EX(OP) \
+ OP##_HANDLER:
+
+# define ZEND_VM_HELPER(NAME) \
+ NAME:
+
+# define ZEND_VM_HELPER_EX(NAME,PARAM) \
+ NAME:
+
+# define ZEND_VM_SPEC_HANDLER(OP, CODE) \
+ OP##_HANDLER:
+
+# define ZEND_VM_SPEC_HANDLER_EX(OP, CODE) \
+ OP##_HANDLER:
+
+# define ZEND_VM_SPEC_HELPER(NAME) \
+ NAME:
+
+# define ZEND_VM_SPEC_HELPER_EX(NAME,PARAM) \
+ NAME:
+
+# define ZEND_VM_NULL_HANDLER() \
+ ZEND_VM_NULL:
+
+# define ZEND_VM_DISPATCH_TO_HANDLER(OP) \
+ goto OP##_HANDLER
+
+# define ZEND_VM_DISPATCH_TO_HELPER(NAME) \
+ goto NAME
+
+# define ZEND_VM_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
+ VAR = VAL; \
+ goto NAME
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HANDLER(OP) \
+ goto OP##_HANDLER
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER(NAME) \
+ goto NAME
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
+ VAR = VAL; \
+ goto NAME
+
+# define ZEND_VM_CONTINUE() \
+ goto *(void**)(EX(opline)->handler)
+
+# define ZEND_VM_NEXT_OPCODE() \
+ CHECK_SYMBOL_TABLES() \
+ EX(opline)++; \
+ ZEND_VM_CONTINUE()
+
+# define ZEND_VM_SET_OPCODE(new_op) \
+ CHECK_SYMBOL_TABLES() \
+ EX(opline) = new_op
+
+# define ZEND_VM_INC_OPCODE() \
+ if (!EG(exception)) { \
+ CHECK_SYMBOL_TABLES() \
+ EX(opline)++; \
+ }
+
+# define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
+ if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \
+ free_alloca(EX(Ts)); \
+ } else { \
+ efree(EX(Ts)); \
+ } \
+ EG(in_execution) = EX(original_in_execution); \
+ EG(current_execute_data) = EX(prev_execute_data); \
+ return;
+
+# define ZEND_VM_LABEL(OP) (opcode_handler_t)&&OP##_HANDLER
+# define ZEND_VM_NULL_LABEL &&ZEND_VM_NULL
+# define ZEND_VM_SPEC_LABEL(OP,CODE) (opcode_handler_t)&&OP##_HANDLER
+# define ZEND_VM_SPEC_NULL_LABEL &&ZEND_VM_NULL
+
+#else
+# error "Unknown ZEND_VM_KIND"
+#endif
+
+#define ZEND_VM_CONTINUE_JMP() ZEND_VM_CONTINUE()
+
+#endif
View
3,968 Zend/zend_vm_handlers.h
3,968 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
650 Zend/zend_vm_spec.h
@@ -0,0 +1,650 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend Engine |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2004 Zend Technologies Ltd. (http://www.zend.com) |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.00 of the Zend license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.zend.com/license/2_00.txt. |
+ | If you did not receive a copy of the Zend license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@zend.com so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+/*
+ Don't edit this file.
+ It produces the specialized version of executor's opcode handlers and helpers,
+ those are defined in zend_vm_handlers.h
+*/
+
+#define IS_ANY (1<<7)
+#define _ANY_CODE 0
+
+#define SPEC2(X,Y) SPEC_##X##Y
+#define SPEC(X,Y) SPEC2(X,Y)
+
+#define SPEC2_0(X,Y) SPEC_##X##Y()
+#define SPEC_0(X,Y) SPEC2_0(X,Y)
+
+#define SPEC2_1(X,Y,Z) SPEC_##X##Y(Z)
+#define SPEC_1(X,Y,Z) SPEC2_1(X,Y,Z)
+
+#define OP1_TYPE \
+ SPEC(OP1_TYPE, OP1_TYPE_PREFIX)
+#define OP1_TYPE_CODE \
+ SPEC(OP1_TYPE_PREFIX, _CODE)
+#define GET_OP1_ZVAL_PTR(T) \
+ SPEC_1(GET_OP1_ZVAL_PTR, OP1_TYPE_PREFIX, T)
+#define GET_OP1_ZVAL_PTR_PTR(T) \
+ SPEC_1(GET_OP1_ZVAL_PTR_PTR, OP1_TYPE_PREFIX, T)
+#define GET_OP1_OBJ_ZVAL_PTR(T) \
+ SPEC_1(GET_OP1_OBJ_ZVAL_PTR, OP1_TYPE_PREFIX, T)
+#define GET_OP1_OBJ_ZVAL_PTR_PTR(T) \
+ SPEC_1(GET_OP1_OBJ_ZVAL_PTR_PTR, OP1_TYPE_PREFIX, T)
+#define IS_OP1_TMP_FREE() \
+ SPEC_0(IS_OP1_TMP_FREE, OP1_TYPE_PREFIX)
+#define FREE_OP1() \
+ SPEC_0(FREE_OP1, OP1_TYPE_PREFIX)
+#define FREE_OP1_IF_VAR() \
+ SPEC_0(FREE_OP1_IF_VAR, OP1_TYPE_PREFIX)
+#define FREE_OP1_VAR_PTR() \
+ SPEC_0(FREE_OP1_VAR_PTR, OP1_TYPE_PREFIX)
+
+#define OP2_TYPE \
+ SPEC(OP2_TYPE, OP2_TYPE_PREFIX)
+#define OP2_TYPE_CODE \
+ SPEC(OP2_TYPE_PREFIX, _CODE)
+#define GET_OP2_ZVAL_PTR(T) \
+ SPEC_1(GET_OP2_ZVAL_PTR, OP2_TYPE_PREFIX, T)
+#define GET_OP2_ZVAL_PTR_PTR(T) \
+ SPEC_1(GET_OP2_ZVAL_PTR_PTR, OP2_TYPE_PREFIX, T)
+#define GET_OP2_OBJ_ZVAL_PTR(T) \
+ SPEC_1(GET_OP2_OBJ_ZVAL_PTR, OP2_TYPE_PREFIX, T)
+#define GET_OP2_OBJ_ZVAL_PTR_PTR(T) \
+ SPEC_1(GET_OP2_OBJ_ZVAL_PTR_PTR, OP2_TYPE_PREFIX, T)
+#define IS_OP2_TMP_FREE() \
+ SPEC_0(IS_OP2_TMP_FREE, OP2_TYPE_PREFIX)
+#define FREE_OP2() \
+ SPEC_0(FREE_OP2, OP2_TYPE_PREFIX)
+#define FREE_OP2_IF_VAR() \
+ SPEC_0(FREE_OP2_IF_VAR, OP2_TYPE_PREFIX)
+#define FREE_OP2_VAR_PTR() \
+ SPEC_0(FREE_OP2_VAR_PTR, OP2_TYPE_PREFIX)
+
+#define SPEC__ANY_CODE _ANY_CODE
+#define SPEC__CONST_CODE _CONST_CODE
+#define SPEC__TMP_CODE _TMP_CODE
+#define SPEC__VAR_CODE _VAR_CODE
+#define SPEC__UNUSED_CODE _UNUSED_CODE
+
+#define SPEC_OP1_TYPE_ANY opline->op1.op_type
+#define SPEC_OP1_TYPE_CONST IS_CONST
+#define SPEC_OP1_TYPE_TMP IS_TMP_VAR
+#define SPEC_OP1_TYPE_VAR IS_VAR
+#define SPEC_OP1_TYPE_UNUSED IS_UNUSED
+
+#define SPEC_GET_OP1_ZVAL_PTR_ANY(T) _get_zval_ptr(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_ZVAL_PTR_CONST(T) _get_zval_ptr_const(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_ZVAL_PTR_TMP(T) _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_ZVAL_PTR_VAR(T) _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_ZVAL_PTR_UNUSED(T) _get_zval_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+
+#define SPEC_GET_OP1_ZVAL_PTR_PTR_ANY(T) _get_zval_ptr_ptr(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_ZVAL_PTR_PTR_CONST(T) _get_zval_ptr_ptr_const(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_ZVAL_PTR_PTR_TMP(T) _get_zval_ptr_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_ZVAL_PTR_PTR_VAR(T) _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_ZVAL_PTR_PTR_UNUSED(T) _get_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_ANY(T) _get_obj_zval_ptr(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_CONST(T) _get_obj_zval_ptr_const(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_TMP(T) _get_obj_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_VAR(T) _get_obj_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_UNUSED(T) _get_obj_zval_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_PTR_ANY(T) _get_obj_zval_ptr_ptr(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_PTR_CONST(T) _get_obj_zval_ptr_ptr_const(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_PTR_TMP(T) _get_obj_zval_ptr_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_PTR_VAR(T) _get_obj_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+#define SPEC_GET_OP1_OBJ_ZVAL_PTR_PTR_UNUSED(T) _get_obj_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)
+
+#define SPEC_IS_OP1_TMP_FREE_ANY() IS_TMP_FREE(free_op1)
+#define SPEC_IS_OP1_TMP_FREE_CONST() 0
+#define SPEC_IS_OP1_TMP_FREE_TMP() 1
+#define SPEC_IS_OP1_TMP_FREE_VAR() IS_TMP_FREE(free_op1)
+#define SPEC_IS_OP1_TMP_FREE_UNUSED() 0
+
+#define SPEC_FREE_OP1_ANY() FREE_OP(free_op1);
+#define SPEC_FREE_OP1_CONST()
+#define SPEC_FREE_OP1_TMP() zval_dtor(free_op1.var)
+#define SPEC_FREE_OP1_VAR() FREE_OP(free_op1);
+#define SPEC_FREE_OP1_UNUSED()
+
+#define SPEC_FREE_OP1_IF_VAR_ANY() FREE_OP_IF_VAR(free_op1);
+#define SPEC_FREE_OP1_IF_VAR_CONST()
+#define SPEC_FREE_OP1_IF_VAR_TMP()
+#define SPEC_FREE_OP1_IF_VAR_VAR() FREE_OP_IF_VAR(free_op1);
+#define SPEC_FREE_OP1_IF_VAR_UNUSED()
+
+#define SPEC_FREE_OP1_VAR_PTR_ANY() FREE_OP_VAR_PTR(free_op1);
+#define SPEC_FREE_OP1_VAR_PTR_CONST()
+#define SPEC_FREE_OP1_VAR_PTR_TMP()
+#define SPEC_FREE_OP1_VAR_PTR_VAR() FREE_OP_VAR_PTR(free_op1);
+#define SPEC_FREE_OP1_VAR_PTR_UNUSED()
+
+#define SPEC_OP2_TYPE_ANY opline->op2.op_type
+#define SPEC_OP2_TYPE_CONST IS_CONST
+#define SPEC_OP2_TYPE_TMP IS_TMP_VAR
+#define SPEC_OP2_TYPE_VAR IS_VAR
+#define SPEC_OP2_TYPE_UNUSED IS_UNUSED
+
+#define SPEC_GET_OP2_ZVAL_PTR_ANY(T) _get_zval_ptr(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_ZVAL_PTR_CONST(T) _get_zval_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_ZVAL_PTR_TMP(T) _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_ZVAL_PTR_VAR(T) _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_ZVAL_PTR_UNUSED(T) _get_zval_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+
+#define SPEC_GET_OP2_ZVAL_PTR_PTR_ANY(T) _get_zval_ptr_ptr(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_ZVAL_PTR_PTR_CONST(T) _get_zval_ptr_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_ZVAL_PTR_PTR_TMP(T) _get_zval_ptr_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_ZVAL_PTR_PTR_VAR(T) _get_zval_ptr_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_ZVAL_PTR_PTR_UNUSED(T) _get_zval_ptr_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_ANY(T) _get_obj_zval_ptr(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_CONST(T) _get_obj_zval_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_TMP(T) _get_obj_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_VAR(T) _get_obj_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_UNUSED(T) _get_obj_zval_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_PTR_ANY(T) _get_obj_zval_ptr_ptr(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_PTR_CONST(T) _get_obj_zval_ptr_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_PTR_TMP(T) _get_obj_zval_ptr_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_PTR_VAR(T) _get_obj_zval_ptr_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+#define SPEC_GET_OP2_OBJ_ZVAL_PTR_PTR_UNUSED(T) _get_obj_zval_ptr_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC)
+
+#define SPEC_IS_OP2_TMP_FREE_ANY() IS_TMP_FREE(free_op2)
+#define SPEC_IS_OP2_TMP_FREE_CONST() 0
+#define SPEC_IS_OP2_TMP_FREE_TMP() 1
+#define SPEC_IS_OP2_TMP_FREE_VAR() IS_TMP_FREE(free_op2)
+#define SPEC_IS_OP2_TMP_FREE_UNUSED() 0
+
+#define SPEC_FREE_OP2_ANY() FREE_OP(free_op2);
+#define SPEC_FREE_OP2_CONST()
+#define SPEC_FREE_OP2_TMP() zval_dtor(free_op2.var)
+#define SPEC_FREE_OP2_VAR() FREE_OP(free_op2);
+#define SPEC_FREE_OP2_UNUSED()
+
+#define SPEC_FREE_OP2_IF_VAR_ANY() FREE_OP_IF_VAR(free_op2);
+#define SPEC_FREE_OP2_IF_VAR_CONST()
+#define SPEC_FREE_OP2_IF_VAR_TMP()
+#define SPEC_FREE_OP2_IF_VAR_VAR() FREE_OP_IF_VAR(free_op2);
+#define SPEC_FREE_OP2_IF_VAR_UNUSED()
+
+#define SPEC_FREE_OP2_VAR_PTR_ANY() FREE_OP_VAR_PTR(free_op2);
+#define SPEC_FREE_OP2_VAR_PTR_CONST()
+#define SPEC_FREE_OP2_VAR_PTR_TMP()
+#define SPEC_FREE_OP2_VAR_PTR_VAR() FREE_OP_VAR_PTR(free_op2);
+#define SPEC_FREE_OP2_VAR_PTR_UNUSED()
+
+#ifndef ZEND_VM_SPEC
+
+# define OP1_OP2_MASK(OP1T, OP2T) 1
+# define HAVE_OP(OP) 1
+
+# define ZEND_VM_C_GOTO(LABEL) goto LABEL
+# define ZEND_VM_C_LABEL(LABEL) LABEL
+
+# undef OP1
+# undef OP2
+# define OP1 IS_ANY
+# define OP2 IS_ANY
+# include "zend_vm_handlers.h"
+
+#else
+
+# define M_ANY (IS_ANY)
+# define M_CONST (IS_CONST)
+# define M_TMP (IS_TMP_VAR)
+# define M_VAR (IS_VAR)
+# define M_UNUSED (IS_UNUSED)
+# define M_CONST_TMP (IS_CONST|IS_TMP_VAR)
+# define M_CONST_VAR (IS_CONST|IS_VAR)
+# define M_CONST_UNUSED (IS_CONST|IS_UNUSED)
+# define M_CONST_TMP_VAR (IS_CONST|IS_TMP_VAR|IS_VAR)
+# define M_CONST_TMP_UNUSED (IS_CONST|IS_TMP_VAR|IS_UNUSED)
+# define M_CONST_VAR_UNUSED (IS_CONST|IS_VAR|IS_UNUSED)
+# define M_CONST_TMP_VAR_UNUSED (IS_CONST|IS_TMP_VAR|IS_VAR|IS_UNUSED)
+# define M_TMP_VAR (IS_TMP_VAR|IS_VAR)
+# define M_TMP_UNUSED (IS_TMP_VAR|IS_UNUSED)
+# define M_TMP_VAR_UNUSED (IS_TMP_VAR|IS_VAR|IS_UNUSED)
+# define M_VAR_UNUSED (IS_VAR|IS_UNUSED)
+
+# define OP1_OP2_MASK(OP1T, OP2T) \
+ ((OP1 & (OP1T)) && (OP2 & (OP2T)))
+
+# define OPDEF(OP,OP1M,OP2M) \
+ ((OP1 & (OP1M)) && (OP2 & (OP2M)))
+
+# define HAVE_OP(OP) \
+ OP##_SPEC()
+
+# define ZEND_VM_SPEC_C_GOTO2(LABEL, OP1T, OP2T) \
+ goto LABEL##OP1T##OP2T
+# define ZEND_VM_SPEC_C_GOTO1(LABEL, OP1T, OP2T) \
+ ZEND_VM_SPEC_C_GOTO2(LABEL, OP1T, OP2T)
+# define ZEND_VM_C_GOTO(LABEL) \
+ ZEND_VM_SPEC_C_GOTO1(LABEL, OP1_TYPE_PREFIX, OP2_TYPE_PREFIX)
+
+# define ZEND_VM_SPEC_C_LABEL2(LABEL, OP1T, OP2T) \
+ LABEL##OP1T##OP2T
+# define ZEND_VM_SPEC_C_LABEL1(LABEL, OP1T, OP2T) \
+ ZEND_VM_SPEC_C_LABEL2(LABEL, OP1T, OP2T)
+# define ZEND_VM_C_LABEL(LABEL) \
+ ZEND_VM_SPEC_C_LABEL1(LABEL, OP1_TYPE_PREFIX, OP2_TYPE_PREFIX)
+
+# define ZEND_VM_SPEC_HANDLER2(OP, OP1T, OP2T, CODE) \
+ ZEND_VM_SPEC_HANDLER(OP##OP1T##OP2T, CODE)
+# define ZEND_VM_SPEC_HANDLER1(OP, OP1T, OP2T, CODE) \
+ ZEND_VM_SPEC_HANDLER2(OP, OP1T, OP2T, CODE)
+# undef ZEND_VM_HANDLER
+# define ZEND_VM_HANDLER(OP) \
+ ZEND_VM_SPEC_HANDLER1(OP##_SPEC, OP1_TYPE_PREFIX, OP2_TYPE_PREFIX, ZEND_VM_CODE(OP,OP1_TYPE_CODE,OP2_TYPE_CODE))
+
+# define ZEND_VM_SPEC_HANDLER_EX2(OP, OP1T, OP2T, CODE) \
+ ZEND_VM_SPEC_HANDLER_EX(OP##OP1T##OP2T, CODE)
+# define ZEND_VM_SPEC_HANDLER_EX1(OP, OP1T, OP2T, CODE) \
+ ZEND_VM_SPEC_HANDLER_EX2(OP, OP1T, OP2T, CODE)
+# undef ZEND_VM_HANDLER_EX
+# define ZEND_VM_HANDLER_EX(OP) \
+ ZEND_VM_SPEC_HANDLER_EX1(OP##_SPEC, OP1_TYPE_PREFIX, OP2_TYPE_PREFIX, ZEND_VM_CODE(OP,OP1_TYPE_CODE,OP2_TYPE_CODE))
+
+# define ZEND_VM_SPEC_HELPER2(OP, OP1T, OP2T) \
+ ZEND_VM_SPEC_HELPER(OP##OP1T##OP2T)
+# define ZEND_VM_SPEC_HELPER1(OP, OP1T, OP2T) \
+ ZEND_VM_SPEC_HELPER2(OP, OP1T, OP2T)
+# undef ZEND_VM_HELPER
+# define ZEND_VM_HELPER(OP) \
+ ZEND_VM_SPEC_HELPER1(OP, OP1_TYPE_PREFIX, OP2_TYPE_PREFIX)
+
+# define ZEND_VM_SPEC_HELPER_EX2(OP, OP1T, OP2T, PARAM) \
+ ZEND_VM_SPEC_HELPER_EX(OP##OP1T##OP2T, PARAM)
+# define ZEND_VM_SPEC_HELPER_EX1(OP, OP1T, OP2T, PARAM) \
+ ZEND_VM_SPEC_HELPER_EX2(OP, OP1T, OP2T, PARAM)
+# undef ZEND_VM_HELPER_EX
+# define ZEND_VM_HELPER_EX(OP, PARAM) \
+ ZEND_VM_SPEC_HELPER_EX1(OP, OP1_TYPE_PREFIX, OP2_TYPE_PREFIX, PARAM)
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HANDLER2(OP, OP1T, OP2T) \
+ ZEND_VM_SPEC_DISPATCH_TO_HANDLER(OP##OP1T##OP2T)
+# define ZEND_VM_SPEC_DISPATCH_TO_HANDLER1(OP, OP1T, OP2T) \
+ ZEND_VM_SPEC_DISPATCH_TO_HANDLER2(OP, OP1T, OP2T)
+# undef ZEND_VM_DISPATCH_TO_HANDLER
+# define ZEND_VM_DISPATCH_TO_HANDLER(OP) \
+ ZEND_VM_SPEC_DISPATCH_TO_HANDLER1(OP##_SPEC, OP1_TYPE_PREFIX, OP2_TYPE_PREFIX)
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER2(OP, OP1T, OP2T) \
+ ZEND_VM_SPEC_DISPATCH_TO_HELPER(OP##OP1T##OP2T)
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER1(OP, OP1T, OP2T) \
+ ZEND_VM_SPEC_DISPATCH_TO_HELPER2(OP, OP1T, OP2T)
+# undef ZEND_VM_DISPATCH_TO_HELPER
+# define ZEND_VM_DISPATCH_TO_HELPER(OP) \
+ ZEND_VM_SPEC_DISPATCH_TO_HELPER1(OP, OP1_TYPE_PREFIX, OP2_TYPE_PREFIX)
+
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX2(OP, OP1T, OP2T, VAR, VAL) \
+ ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX(OP##OP1T##OP2T, VAR, VAL)
+# define ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX1(OP, OP1T, OP2T, VAR, VAL) \
+ ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX2(OP, OP1T, OP2T, VAR, VAL)
+# undef ZEND_VM_DISPATCH_TO_HELPER_EX
+# define ZEND_VM_DISPATCH_TO_HELPER_EX(OP, VAR, VAL) \
+ ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX1(OP, OP1_TYPE_PREFIX, OP2_TYPE_PREFIX, VAR, VAL)
+
+# undef OP1
+# undef OP2
+# define OP1 IS_ANY
+# define OP2 IS_ANY
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_CONST
+# define OP2 IS_ANY
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_TMP_VAR
+# define OP2 IS_ANY
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_VAR
+# define OP2 IS_ANY
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_UNUSED
+# define OP2 IS_ANY
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_ANY
+# define OP2 IS_CONST
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_ANY
+# define OP2 IS_TMP_VAR
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_ANY
+# define OP2 IS_VAR
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_ANY
+# define OP2 IS_UNUSED
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_UNUSED
+# define OP2 IS_UNUSED
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_UNUSED
+# define OP2 IS_CONST
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_UNUSED
+# define OP2 IS_TMP_VAR
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_UNUSED
+# define OP2 IS_VAR
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_CONST
+# define OP2 IS_UNUSED
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_TMP_VAR
+# define OP2 IS_UNUSED
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_VAR
+# define OP2 IS_UNUSED
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_CONST
+# define OP2 IS_CONST
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_CONST
+# define OP2 IS_TMP_VAR
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_CONST
+# define OP2 IS_VAR
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_TMP_VAR
+# define OP2 IS_CONST
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_TMP_VAR
+# define OP2 IS_TMP_VAR
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_TMP_VAR
+# define OP2 IS_VAR
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_VAR
+# define OP2 IS_CONST
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_VAR
+# define OP2 IS_TMP_VAR
+# include "zend_vm_handlers.h"
+
+# undef OP1
+# undef OP2
+# define OP1 IS_VAR
+# define OP2 IS_VAR
+# include "zend_vm_handlers.h"
+
+/* LABELS */
+
+# undef M_ANY
+# undef M_CONST
+# undef M_TMP
+# undef M_VAR
+# undef M_UNUSED
+# undef M_CONST_TMP
+# undef M_CONST_VAR
+# undef M_CONST_UNUSED
+# undef M_CONST_TMP_VAR
+# undef M_CONST_TMP_UNUSED
+# undef M_CONST_VAR_UNUSED
+# undef M_CONST_TMP_VAR_UNUSED
+# undef M_TMP_VAR
+# undef M_TMP_UNUSED
+# undef M_TMP_VAR_UNUSED
+# undef M_VAR_UNUSED
+
+# undef OPDEF
+
+# define OPDEF(OP, OP1M, OP2M) \
+ SPEC_LABELS1_##OP1M(OP##_SPEC, OP, OP2M)
+
+# define SPEC_LABELS1_M_ANY(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _ANY, _ANY, _ANY, _ANY)
+# define SPEC_LABELS1_M_UNUSED(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _NULL, _NULL, _NULL, _UNUSED)
+# define SPEC_LABELS1_M_VAR(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _NULL, _NULL, _VAR, _NULL)
+# define SPEC_LABELS1_M_VAR_UNUSED(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _NULL, _NULL, _VAR, _UNUSED)
+# define SPEC_LABELS1_M_TMP(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _NULL, _TMP, _NULL, _NULL)
+# define SPEC_LABELS1_M_TMP_UNUSED(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _NULL, _TMP, _NULL, _UNUSED)
+# define SPEC_LABELS1_M_TMP_VAR(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _NULL, _TMP, _VAR, _NULL)
+# define SPEC_LABELS1_M_TMP_VAR_UNUSED(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _NULL, _TMP, _VAR, _UNUSED)
+# define SPEC_LABELS1_M_CONST(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _CONST, _NULL, _NULL, _NULL)
+# define SPEC_LABELS1_M_CONST_UNUSED(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _CONST, _NULL, _NULL, _UNUSED)
+# define SPEC_LABELS1_M_CONST_VAR(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _CONST, _NULL, _VAR, _NULL)
+# define SPEC_LABELS1_M_CONST_VAR_UNUSED(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _CONST, _NULL, _VAR, _UNUSED)
+# define SPEC_LABELS1_M_CONST_TMP(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _CONST, _TMP, _NULL, _NULL)
+# define SPEC_LABELS1_M_CONST_TMP_UNUSED(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _CONST, _TMP, _NULL, _UNUSED)
+# define SPEC_LABELS1_M_CONST_TMP_VAR(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _CONST, _TMP, _VAR, _NULL)
+# define SPEC_LABELS1_M_CONST_TMP_VAR_UNUSED(OP, CODE, OP2M) \
+ SPEC_LABELS2_##OP2M(OP, CODE, _CONST, _TMP, _VAR, _UNUSED)
+
+# define SPEC_LABELS2_M_ANY(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _ANY, _ANY, _ANY, _ANY)
+# define SPEC_LABELS2_M_UNUSED(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _NULL, _NULL, _NULL, _UNUSED)
+# define SPEC_LABELS2_M_VAR(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _NULL, _NULL, _VAR, _NULL)
+# define SPEC_LABELS2_M_VAR_UNUSED(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _NULL, _NULL, _VAR, _UNUSED)
+# define SPEC_LABELS2_M_TMP(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _NULL, _TMP, _NULL, _NULL)
+# define SPEC_LABELS2_M_TMP_UNUSED(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _NULL, _TMP, _NULL, _UNUSED)
+# define SPEC_LABELS2_M_TMP_VAR(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _NULL, _TMP, _VAR, _NULL)
+# define SPEC_LABELS2_M_TMP_VAR_UNUSED(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _NULL, _TMP, _VAR, _UNUSED)
+# define SPEC_LABELS2_M_CONST(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _CONST, _NULL, _NULL, _NULL)
+# define SPEC_LABELS2_M_CONST_UNUSED(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _CONST, _NULL, _NULL, _UNUSED)
+# define SPEC_LABELS2_M_CONST_VAR(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _CONST, _NULL, _VAR, _NULL)
+# define SPEC_LABELS2_M_CONST_VAR_UNUSED(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _CONST, _NULL, _VAR, _UNUSED)
+# define SPEC_LABELS2_M_CONST_TMP(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _CONST, _TMP, _NULL, _NULL)
+# define SPEC_LABELS2_M_CONST_TMP_UNUSED(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _CONST, _TMP, _NULL, _UNUSED)
+# define SPEC_LABELS2_M_CONST_TMP_VAR(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _CONST, _TMP, _VAR, _NULL)
+# define SPEC_LABELS2_M_CONST_TMP_VAR_UNUSED(OP, CODE, OP1C, OP1T, OP1V, OP1U) \
+ SPEC_LABELS(OP, CODE, OP1C, OP1T, OP1V, OP1U, _CONST, _TMP, _VAR, _UNUSED)
+
+# define LABELS_1(OP,CODE,OP1,OP2C,OP2T,OP2V,OP2U) \
+ OP1##OP2C(OP,CODE), \
+ OP1##OP2T(OP,CODE), \
+ OP1##OP2V(OP,CODE), \
+ OP1##OP2U(OP,CODE)
+
+# define SPEC_LABELS(OP,CODE,OP1C,OP1T,OP1V,OP1U,OP2C,OP2T,OP2V,OP2U) \
+ LABELS_1(OP,CODE,SPEC_LABEL##OP1C,OP2C,OP2T,OP2V,OP2U), \
+ LABELS_1(OP,CODE,SPEC_LABEL##OP1T,OP2C,OP2T,OP2V,OP2U), \
+ LABELS_1(OP,CODE,SPEC_LABEL##OP1V,OP2C,OP2T,OP2V,OP2U), \
+ LABELS_1(OP,CODE,SPEC_LABEL##OP1U,OP2C,OP2T,OP2V,OP2U)
+
+# define SPEC_LABEL_CONST_NULL(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_TMP_NULL(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_VAR_NULL(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_UNUSED_NULL(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_ANY_NULL(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_NULL_CONST(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_NULL_TMP(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_NULL_VAR(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_NULL_UNUSED(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_NULL_ANY(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_NULL_NULL(OP,CODE) ZEND_VM_SPEC_NULL_LABEL
+# define SPEC_LABEL_ANY_ANY(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_ANY_ANY, ZEND_VM_CODE(CODE, _ANY_CODE, _ANY_CODE))
+# define SPEC_LABEL_ANY_CONST(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_ANY_CONST, ZEND_VM_CODE(CODE, _ANY_CODE, _CONST_CODE))
+# define SPEC_LABEL_ANY_TMP(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_ANY_TMP, ZEND_VM_CODE(CODE, _ANY_CODE, _TMP_CODE))
+# define SPEC_LABEL_ANY_VAR(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_ANY_VAR, ZEND_VM_CODE(CODE, _ANY_CODE, _VAR_CODE))
+# define SPEC_LABEL_ANY_UNUSED(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_ANY_UNUSED, ZEND_VM_CODE(CODE, _ANY_CODE, _UNUSED_CODE))
+# define SPEC_LABEL_CONST_ANY(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_CONST_ANY, ZEND_VM_CODE(CODE, _CONST_CODE, _ANY_CODE))
+# define SPEC_LABEL_CONST_CONST(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_CONST_CONST, ZEND_VM_CODE(CODE, _CONST_CODE, _CONST_CODE))
+# define SPEC_LABEL_CONST_TMP(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_CONST_TMP, ZEND_VM_CODE(CODE, _CONST_CODE, _TMP_CODE))
+# define SPEC_LABEL_CONST_VAR(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_CONST_VAR, ZEND_VM_CODE(CODE, _CONST_CODE, _VAR_CODE))
+# define SPEC_LABEL_CONST_UNUSED(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_CONST_UNUSED, ZEND_VM_CODE(CODE, _CONST_CODE, _UNUSED_CODE))
+# define SPEC_LABEL_TMP_ANY(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_TMP_ANY, ZEND_VM_CODE(CODE, _TMP_CODE, _ANY_CODE))
+# define SPEC_LABEL_TMP_CONST(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_TMP_CONST, ZEND_VM_CODE(CODE, _TMP_CODE, _CONST_CODE))
+# define SPEC_LABEL_TMP_TMP(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_TMP_TMP, ZEND_VM_CODE(CODE, _TMP_CODE, _TMP_CODE))
+# define SPEC_LABEL_TMP_VAR(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_TMP_VAR, ZEND_VM_CODE(CODE, _TMP_CODE, _VAR_CODE))
+# define SPEC_LABEL_TMP_UNUSED(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_TMP_UNUSED, ZEND_VM_CODE(CODE, _TMP_CODE, _UNUSED_CODE))
+# define SPEC_LABEL_VAR_ANY(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_VAR_ANY, ZEND_VM_CODE(CODE, _VAR_CODE, _ANY_CODE))
+# define SPEC_LABEL_VAR_CONST(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_VAR_CONST, ZEND_VM_CODE(CODE, _VAR_CODE, _CONST_CODE))
+# define SPEC_LABEL_VAR_TMP(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_VAR_TMP, ZEND_VM_CODE(CODE, _VAR_CODE, _TMP_CODE))
+# define SPEC_LABEL_VAR_VAR(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_VAR_VAR, ZEND_VM_CODE(CODE, _VAR_CODE, _VAR_CODE))
+# define SPEC_LABEL_VAR_UNUSED(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_VAR_UNUSED, ZEND_VM_CODE(CODE, _VAR_CODE, _UNUSED_CODE))
+# define SPEC_LABEL_UNUSED_ANY(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_UNUSED_ANY, ZEND_VM_CODE(CODE, _UNUSED_CODE, _ANY_CODE))
+# define SPEC_LABEL_UNUSED_CONST(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_UNUSED_CONST, ZEND_VM_CODE(CODE, _UNUSED_CODE, _CONST_CODE))
+# define SPEC_LABEL_UNUSED_TMP(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_UNUSED_TMP, ZEND_VM_CODE(CODE, _UNUSED_CODE, _TMP_CODE))
+# define SPEC_LABEL_UNUSED_VAR(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_UNUSED_VAR, ZEND_VM_CODE(CODE, _UNUSED_CODE, _VAR_CODE))
+# define SPEC_LABEL_UNUSED_UNUSED(OP,CODE) \
+ ZEND_VM_SPEC_LABEL(OP##_UNUSED_UNUSED, ZEND_VM_CODE(CODE, _UNUSED_CODE, _UNUSED_CODE))
+
+# undef ZEND_VM_NULL_LABEL
+# define ZEND_VM_NULL_LABEL \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL, \
+ ZEND_VM_SPEC_NULL_LABEL
+
+# undef ZEND_VM_LABEL
+# define ZEND_VM_LABEL(OP) \
+ OP##_SPEC()
+
+#endif
+
+ZEND_VM_NULL_HANDLER()
+{
+ zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", EX(opline)->opcode, EX(opline)->op1.op_type, EX(opline)->op2.op_type);
+ ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
+}

0 comments on commit 8eb8850

Please sign in to comment.