Skip to content

Commit 57d406a

Browse files
arnaud-lbmorrisonlevi
authored andcommitted
call_interrupt_op
1 parent 914efeb commit 57d406a

3 files changed

Lines changed: 60 additions & 10 deletions

File tree

Zend/zend_vm_def.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10523,7 +10523,12 @@ ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
1052310523
ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY)
1052410524
{
1052510525
zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
10526+
#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
10527+
/* opline is &call_interrupt_op. Load orig opline. */
10528+
LOAD_OPLINE();
10529+
#else
1052610530
SAVE_OPLINE();
10531+
#endif
1052710532
if (zend_atomic_bool_load_ex(&EG(timed_out))) {
1052810533
zend_timeout();
1052910534
} else if (zend_interrupt_function) {

Zend/zend_vm_execute.h

Lines changed: 30 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Zend/zend_vm_gen.php

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
15971610
function 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

Comments
 (0)