]> granicus.if.org Git - php/commitdiff
Optimization of init_func_execute_data()
authorDmitry Stogov <dmitry@zend.com>
Tue, 5 Dec 2017 23:53:30 +0000 (02:53 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 5 Dec 2017 23:53:30 +0000 (02:53 +0300)
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_gen.php

index 53ed1ac2a5367be2c70d94cf8070952636b4b5dd..a68e7d12ab4af99e5d35ceb0c1606f225de6076a 100644 (file)
@@ -2150,12 +2150,70 @@ ZEND_API void zend_free_compiled_variables(zend_execute_data *execute_data) /* {
  *                             +----------------------------------------+
  */
 
-static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
+static zend_never_inline void zend_copy_extra_args(EXECUTE_DATA_D)
+{
+       zend_op_array *op_array = &EX(func)->op_array;
+       uint32_t first_extra_arg = op_array->num_args;
+       uint32_t num_args = EX_NUM_ARGS();
+       zval *src;
+       size_t delta;
+       uint32_t count;
+       uint32_t type_flags = 0;
+
+       if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
+               /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
+#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+               opline += first_extra_arg;
+#else
+               EX(opline) += first_extra_arg;
+#endif
+
+       }
+
+       /* move extra args into separate array after all CV and TMP vars */
+       src = EX_VAR_NUM(num_args - 1);
+       delta = op_array->last_var + op_array->T - first_extra_arg;
+       count = num_args - first_extra_arg;
+       if (EXPECTED(delta != 0)) {
+               delta *= sizeof(zval);
+               do {
+                       type_flags |= Z_TYPE_INFO_P(src);
+                       ZVAL_COPY_VALUE((zval*)(((char*)src) + delta), src);
+                       ZVAL_UNDEF(src);
+                       src--;
+               } while (--count);
+       } else {
+               do {
+                       type_flags |= Z_TYPE_INFO_P(src);
+                       src--;
+               } while (--count);
+       }
+       ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
+}
+
+static zend_always_inline void zend_init_cvs(uint32_t first, uint32_t last EXECUTE_DATA_DC)
+{
+       if (EXPECTED(first < last)) {
+               zval *var = EX_VAR_NUM(first);
+               zval *end = EX_VAR_NUM(last);
+
+               do {
+                       ZVAL_UNDEF(var);
+                       var++;
+               } while (var != end);
+       }
+}
+
+static zend_always_inline void i_init_func_execute_data(zend_op_array *op_array, zval *return_value, zend_bool may_be_trampoline EXECUTE_DATA_DC) /* {{{ */
 {
        uint32_t first_extra_arg, num_args;
        ZEND_ASSERT(EX(func) == (zend_function*)op_array);
 
+#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+       opline = op_array->opcodes;
+#else
        EX(opline) = op_array->opcodes;
+#endif
        EX(call) = NULL;
        EX(return_value) = return_value;
 
@@ -2163,54 +2221,27 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
        first_extra_arg = op_array->num_args;
        num_args = EX_NUM_ARGS();
        if (UNEXPECTED(num_args > first_extra_arg)) {
-               if (EXPECTED(!(op_array->fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))) {
-                       zval *end, *src, *dst;
-                       uint32_t type_flags = 0;
-
-                       if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
-                               /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
-                               EX(opline) += first_extra_arg;
-                       }
-
-                       /* move extra args into separate array after all CV and TMP vars */
-                       end = EX_VAR_NUM(first_extra_arg - 1);
-                       src = end + (num_args - first_extra_arg);
-                       dst = src + (op_array->last_var + op_array->T - first_extra_arg);
-                       if (EXPECTED(src != dst)) {
-                               do {
-                                       type_flags |= Z_TYPE_INFO_P(src);
-                                       ZVAL_COPY_VALUE(dst, src);
-                                       ZVAL_UNDEF(src);
-                                       src--;
-                                       dst--;
-                               } while (src != end);
-                       } else {
-                               do {
-                                       type_flags |= Z_TYPE_INFO_P(src);
-                                       src--;
-                               } while (src != end);
-                       }
-                       ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
+               if (!may_be_trampoline || EXPECTED(!(op_array->fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))) {
+                       zend_copy_extra_args(EXECUTE_DATA_C);
                }
        } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
                /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
+#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+               opline += num_args;
+#else
                EX(opline) += num_args;
+#endif
        }
 
        /* Initialize CV variables (skip arguments) */
-       if (EXPECTED((int)num_args < op_array->last_var)) {
-               zval *var = EX_VAR_NUM(num_args);
-               zval *end = EX_VAR_NUM(op_array->last_var);
-
-               do {
-                       ZVAL_UNDEF(var);
-                       var++;
-               } while (var != end);
-       }
+       zend_init_cvs(num_args, op_array->last_var EXECUTE_DATA_CC);
 
        EX_LOAD_RUN_TIME_CACHE(op_array);
 
        EG(current_execute_data) = execute_data;
+#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+       EX(opline) = opline;
+#endif
 }
 /* }}} */
 
@@ -2242,14 +2273,28 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
 }
 /* }}} */
 
-ZEND_API void zend_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
+ZEND_API void zend_init_func_execute_data(zend_execute_data *ex, zend_op_array *op_array, zval *return_value) /* {{{ */
 {
+#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+       zend_execute_data *orig_execute_data = execute_data;
+       const zend_op *orig_opline = opline;
+       execute_data = ex;
+#else
+       zend_execute_data *execute_data = ex;
+#endif
+
        EX(prev_execute_data) = EG(current_execute_data);
        if (!op_array->run_time_cache) {
                op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
                memset(op_array->run_time_cache, 0, op_array->cache_size);
        }
-       i_init_func_execute_data(execute_data, op_array, return_value);
+       i_init_func_execute_data(op_array, return_value, 1 EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+    EX(opline) = opline;
+       opline = orig_opline;
+       execute_data = orig_execute_data;
+#endif
 }
 /* }}} */
 
index fe6c3109ce7d2ee986d9011bb8d8fb5637e51ee3..3f5f2dc21cc48195a424983a79f3a7ccfa272022 100644 (file)
@@ -3556,9 +3556,11 @@ ZEND_VM_HOT_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL))
        }
 
        call->prev_execute_data = execute_data;
-       i_init_func_execute_data(call, &fbc->op_array, ret);
+       execute_data = call;
+       i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+       LOAD_OPLINE();
 
-       ZEND_VM_ENTER();
+       ZEND_VM_ENTER_EX();
 }
 
 ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
@@ -3579,9 +3581,11 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
                }
 
                call->prev_execute_data = execute_data;
-               i_init_func_execute_data(call, &fbc->op_array, ret);
+               execute_data = call;
+               i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+               LOAD_OPLINE();
 
-               ZEND_VM_ENTER();
+               ZEND_VM_ENTER_EX();
        } else {
                zval retval;
                ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
@@ -3675,11 +3679,15 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
                }
 
                call->prev_execute_data = execute_data;
-               i_init_func_execute_data(call, &fbc->op_array, ret);
+               execute_data = call;
+               i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
 
                if (EXPECTED(zend_execute_ex == execute_ex)) {
-                       ZEND_VM_ENTER();
+                       LOAD_OPLINE();
+                       ZEND_VM_ENTER_EX();
                } else {
+                       execute_data = EX(prev_execute_data);
+                       LOAD_OPLINE();
                        ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
                        zend_execute_ex(call);
                }
@@ -7834,10 +7842,14 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
                if (UNEXPECTED(!fbc->op_array.run_time_cache)) {
                        init_func_run_time_cache(&fbc->op_array);
                }
-               i_init_func_execute_data(call, &fbc->op_array, ret);
+               execute_data = call;
+               i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
                if (EXPECTED(zend_execute_ex == execute_ex)) {
-                       ZEND_VM_ENTER();
+                       LOAD_OPLINE();
+                       ZEND_VM_ENTER_EX();
                } else {
+                       execute_data = EX(prev_execute_data);
+                       LOAD_OPLINE();
                        ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
                        zend_execute_ex(call);
                }
index a2350823c136c783f3f430486bc661cf3dc02029..1aa04cab8e70871f9fb3b74d7b4c32850e05a4cb 100644 (file)
@@ -400,12 +400,15 @@ typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_H
 #define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()
 #define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()
 #if defined(ZEND_VM_FP_GLOBAL_REG)
-# define ZEND_VM_ENTER()           execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()
+# define ZEND_VM_ENTER_EX()        ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()
+# define ZEND_VM_ENTER()           execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()
 # define ZEND_VM_LEAVE()           ZEND_VM_CONTINUE()
 #elif defined(ZEND_VM_IP_GLOBAL_REG)
-# define ZEND_VM_ENTER()           opline = EG(current_execute_data)->opline; return 1
+# define ZEND_VM_ENTER_EX()        return  1
+# define ZEND_VM_ENTER()           opline = EG(current_execute_data)->opline; ZEND_VM_ENTER_EX()
 # define ZEND_VM_LEAVE()           return  2
 #else
+# define ZEND_VM_ENTER_EX()        return  1
 # define ZEND_VM_ENTER()           return  1
 # define ZEND_VM_LEAVE()           return  2
 #endif
@@ -660,9 +663,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV
        }
 
        call->prev_execute_data = execute_data;
-       i_init_func_execute_data(call, &fbc->op_array, ret);
+       execute_data = call;
+       i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+       LOAD_OPLINE();
 
-       ZEND_VM_ENTER();
+       ZEND_VM_ENTER_EX();
 }
 
 static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -682,9 +687,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV
        }
 
        call->prev_execute_data = execute_data;
-       i_init_func_execute_data(call, &fbc->op_array, ret);
+       execute_data = call;
+       i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+       LOAD_OPLINE();
 
-       ZEND_VM_ENTER();
+       ZEND_VM_ENTER_EX();
 }
 
 static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -705,9 +712,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
                }
 
                call->prev_execute_data = execute_data;
-               i_init_func_execute_data(call, &fbc->op_array, ret);
+               execute_data = call;
+               i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+               LOAD_OPLINE();
 
-               ZEND_VM_ENTER();
+               ZEND_VM_ENTER_EX();
        } else {
                zval retval;
                ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
@@ -783,9 +792,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
                }
 
                call->prev_execute_data = execute_data;
-               i_init_func_execute_data(call, &fbc->op_array, ret);
+               execute_data = call;
+               i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+               LOAD_OPLINE();
 
-               ZEND_VM_ENTER();
+               ZEND_VM_ENTER_EX();
        } else {
                zval retval;
                ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
@@ -879,11 +890,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
                }
 
                call->prev_execute_data = execute_data;
-               i_init_func_execute_data(call, &fbc->op_array, ret);
+               execute_data = call;
+               i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
 
                if (EXPECTED(zend_execute_ex == execute_ex)) {
-                       ZEND_VM_ENTER();
+                       LOAD_OPLINE();
+                       ZEND_VM_ENTER_EX();
                } else {
+                       execute_data = EX(prev_execute_data);
+                       LOAD_OPLINE();
                        ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
                        zend_execute_ex(call);
                }
@@ -1002,11 +1017,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
                }
 
                call->prev_execute_data = execute_data;
-               i_init_func_execute_data(call, &fbc->op_array, ret);
+               execute_data = call;
+               i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
 
                if (EXPECTED(zend_execute_ex == execute_ex)) {
-                       ZEND_VM_ENTER();
+                       LOAD_OPLINE();
+                       ZEND_VM_ENTER_EX();
                } else {
+                       execute_data = EX(prev_execute_data);
+                       LOAD_OPLINE();
                        ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
                        zend_execute_ex(call);
                }
@@ -2000,10 +2019,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
                if (UNEXPECTED(!fbc->op_array.run_time_cache)) {
                        init_func_run_time_cache(&fbc->op_array);
                }
-               i_init_func_execute_data(call, &fbc->op_array, ret);
+               execute_data = call;
+               i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
                if (EXPECTED(zend_execute_ex == execute_ex)) {
-                       ZEND_VM_ENTER();
+                       LOAD_OPLINE();
+                       ZEND_VM_ENTER_EX();
                } else {
+                       execute_data = EX(prev_execute_data);
+                       LOAD_OPLINE();
                        ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
                        zend_execute_ex(call);
                }
index 7610da49e7e859b30fd2c00c6695ffaa06dac8b0..996cacf9e282488c6284b25916660fa78cffaec5 100644 (file)
@@ -1675,12 +1675,15 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                                                        out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
                                                        out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
                                                        out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG)\n");
-                                                       out($f,"# define ZEND_VM_ENTER()           execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+                                                       out($f,"# define ZEND_VM_ENTER_EX()        ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+                                                       out($f,"# define ZEND_VM_ENTER()           execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
                                                        out($f,"# define ZEND_VM_LEAVE()           ZEND_VM_CONTINUE()\n");
                                                        out($f,"#elif defined(ZEND_VM_IP_GLOBAL_REG)\n");
-                                                       out($f,"# define ZEND_VM_ENTER()           opline = EG(current_execute_data)->opline; return 1\n");
+                                                       out($f,"# define ZEND_VM_ENTER_EX()        return  1\n");
+                                                       out($f,"# define ZEND_VM_ENTER()           opline = EG(current_execute_data)->opline; ZEND_VM_ENTER_EX()\n");
                                                        out($f,"# define ZEND_VM_LEAVE()           return  2\n");
                                                        out($f,"#else\n");
+                                                       out($f,"# define ZEND_VM_ENTER_EX()        return  1\n");
                                                        out($f,"# define ZEND_VM_ENTER()           return  1\n");
                                                        out($f,"# define ZEND_VM_LEAVE()           return  2\n");
                                                        out($f,"#endif\n");
@@ -1719,7 +1722,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                                                        out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\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_ENTER()    execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+                                                       out($f,"#define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+                                                       out($f,"#define ZEND_VM_ENTER()    execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
                                                        out($f,"#define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n");
                                                        out($f,"#define ZEND_VM_INTERRUPT()              goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
                                                        out($f,"#define ZEND_VM_LOOP_INTERRUPT()         goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
@@ -1755,7 +1759,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                                                        }
                                                        out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
                                                        out($f,"#define ZEND_VM_RETURN()   return\n");
-                                                       out($f,"#define ZEND_VM_ENTER()    execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+                                                       out($f,"#define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+                                                       out($f,"#define ZEND_VM_ENTER()    execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
                                                        out($f,"#define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n");
                                                        out($f,"#define ZEND_VM_INTERRUPT()              goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
                                                        out($f,"#define ZEND_VM_LOOP_INTERRUPT()         goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
@@ -2658,11 +2663,13 @@ function gen_vm($def, $skel) {
                out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
                out($f,"#undef ZEND_VM_CONTINUE\n");
                out($f,"#undef ZEND_VM_RETURN\n");
+               out($f,"#undef ZEND_VM_ENTER_EX\n");
                out($f,"#undef ZEND_VM_ENTER\n");
                out($f,"#undef ZEND_VM_LEAVE\n");
                out($f,"#undef ZEND_VM_DISPATCH\n");
                out($f,"#define ZEND_VM_CONTINUE()   return  0\n");
                out($f,"#define ZEND_VM_RETURN()     return -1\n");
+               out($f,"#define ZEND_VM_ENTER_EX()   return  1\n");
                out($f,"#define ZEND_VM_ENTER()      return  1\n");
                out($f,"#define ZEND_VM_LEAVE()      return  2\n");
                out($f,"#define ZEND_VM_INTERRUPT()  return zend_interrupt_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");