@@ -1594,6 +1594,19 @@ function gen_halt_handler($f, $kind) {
15941594 out ($ f ,"} \n\n" );
15951595}
15961596
1597+ function gen_interrupt_func ($ f , $ kind , $ spec ) {
1598+ $ cconv = $ kind === ZEND_VM_KIND_TAILCALL ? 'ZEND_OPCODE_HANDLER_CCONV ' : 'ZEND_OPCODE_HANDLER_FUNC_CCONV ' ;
1599+ $ variant = $ kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL ' : '' ;
1600+ out ($ f , "static ZEND_COLD zend_never_inline ZEND_OPCODE_HANDLER_RET {$ cconv } zend_interrupt {$ variant }(ZEND_OPCODE_HANDLER_ARGS) { \n" );
1601+ out ($ f ,"\tSAVE_OPLINE(); \n" );
1602+ if ($ kind === ZEND_VM_KIND_TAILCALL ) {
1603+ out ($ f ,"\tZEND_VM_TAIL_CALL(zend_interrupt_helper " .($ spec ?"_SPEC " :"" )."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); \n" );
1604+ } else {
1605+ out ($ f , "\treturn &call_interrupt_op; \n" );
1606+ }
1607+ out ($ f , "} \n" );
1608+ }
1609+
15971610function extra_spec_name ($ extra_spec ) {
15981611 global $ prefix ;
15991612
@@ -1804,10 +1817,12 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
18041817 switch ($ kind ) {
18051818 case ZEND_VM_KIND_CALL :
18061819 gen_null_handler ($ f , $ kind );
1820+ gen_interrupt_func ($ f , $ kind , $ spec );
18071821 break ;
18081822 case ZEND_VM_KIND_TAILCALL :
18091823 gen_null_handler ($ f , $ kind );
18101824 gen_halt_handler ($ f , $ kind );
1825+ gen_interrupt_func ($ f , $ kind , $ spec );
18111826 break ;
18121827 case ZEND_VM_KIND_SWITCH :
18131828 out ($ f ,"default: ZEND_NULL_LABEL: \n" );
@@ -1845,7 +1860,7 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
18451860 out ($ f , "#pragma push_macro( \"ZEND_VM_INTERRUPT \") \n" );
18461861 out ($ f , "#undef ZEND_VM_INTERRUPT \n" );
18471862 out ($ f , "#define ZEND_VM_CONTINUE(handler) return opline \n" );
1848- out ($ f , "#define ZEND_VM_INTERRUPT() return zend_interrupt_helper " .( $ spec ? " _SPEC " : "" ). " ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU) \n" );
1863+ out ($ f , "#define ZEND_VM_INTERRUPT() return zend_interrupt( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); \n" );
18491864 out ($ f , $ delayed_helpers );
18501865 out ($ f , "#pragma pop_macro( \"ZEND_VM_INTERRUPT \") \n" );
18511866 out ($ f , "#pragma pop_macro( \"ZEND_VM_CONTINUE \") \n" );
@@ -1901,6 +1916,9 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
19011916 out ($ f ,"#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL \n\n" );
19021917 out ($ f ,"static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs; \n" );
19031918 out ($ f ,"#endif \n" );
1919+ out ($ f ,"#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL \n\n" );
1920+ out ($ f ,"static const zend_op call_interrupt_op; \n" );
1921+ out ($ f ,"#endif \n\n" );
19041922 }
19051923 out ($ f ,"#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) || !ZEND_VM_SPEC \n" );
19061924 out ($ f ,"static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op); \n" );
@@ -2038,6 +2056,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
20382056 }
20392057 out ($ f ,"\n" );
20402058 out ($ f ,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt_helper " .($ spec ?"_SPEC " :"" )."(ZEND_OPCODE_HANDLER_ARGS); \n" );
2059+ out ($ f ,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt(ZEND_OPCODE_HANDLER_ARGS); \n" );
20412060 out ($ f ,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS); \n" );
20422061 out ($ f ,"\n" );
20432062 break ;
@@ -2136,15 +2155,13 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
21362155 out ($ f ,"# define ZEND_VM_DISPATCH_TO_HELPER(call) \\\n" );
21372156 out ($ f ," do { \\\n" );
21382157 out ($ f ," opline = call; \\\n" );
2139- out ($ f ," if (UNEXPECTED(((uintptr_t)opline & ZEND_VM_ENTER_BIT))) { \\\n" );
2140- out ($ f ," return opline; \\\n" );
2141- out ($ f ," } \\\n" );
21422158 out ($ f ," ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); \\\n" );
21432159 out ($ f ," } while (0) \n" );
21442160 out ($ f ,"# define ZEND_VM_DISPATCH_TO_LEAVE_HELPER(helper) opline = &call_leave_op; SAVE_OPLINE(); ZEND_VM_CONTINUE() \n" );
2145- out ($ f ,"# define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_helper " .( $ spec ? " _SPEC " : "" ). " _TAILCALL (ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) \n" );
2161+ out ($ f ,"# define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_TAILCALL (ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) \n" );
21462162 out ($ f ,"\n" );
21472163 out ($ f ,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper " .($ spec ?"_SPEC " :"" )."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS); \n" );
2164+ out ($ f ,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS); \n" );
21482165 out ($ f ,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS); \n" );
21492166 out ($ f ,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS); \n" );
21502167 out ($ f ,"static zend_never_inline const zend_op *ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(zend_execute_data *ex, const zend_op *opline); \n" );
@@ -2155,6 +2172,9 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
21552172 out ($ f ,"static const zend_op call_leave_op = { \n" );
21562173 out ($ f ," .handler = zend_leave_helper_SPEC_TAILCALL, \n" );
21572174 out ($ f ,"}; \n" );
2175+ out ($ f ,"static const zend_op call_interrupt_op = { \n" );
2176+ out ($ f ," .handler = zend_interrupt_helper_SPEC_TAILCALL, \n" );
2177+ out ($ f ,"}; \n" );
21582178 out ($ f ,"\n" );
21592179
21602180 gen_executor_code ($ f , $ spec , ZEND_VM_KIND_TAILCALL , $ m [1 ]);
0 commit comments