Skip to content

Commit 0c31be1

Browse files
morrisonleviclaude
andcommitted
Fix zend_interrupt compilation for non-tailcall VM builds
The call_interrupt_op sentinel approach only applies to TAILCALL VM, where musttail constraints prevent checking ZEND_VM_ENTER_BIT in ZEND_VM_DISPATCH_TO_HELPER. For CALL VM (non-global-reg), zend_interrupt now forwards directly to zend_interrupt_helper_SPEC instead of returning &call_interrupt_op. Guard zend_interrupt (function and forward declaration) with: #if !(defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)) && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL This fixes three failure modes: - Global-reg builds (HYBRID/CALL with FP+IP regs): ZEND_OPCODE_HANDLER_RET is void, making return &call_interrupt_op a constraint violation - CALL non-global-reg builds (x32, Windows): call_interrupt_op was undeclared for non-TAILCALL VM kinds - TAILCALL builds: zend_interrupt (CALL variant) compiled but unused, triggering -Werror=unused-function Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 57d406a commit 0c31be1

2 files changed

Lines changed: 25 additions & 4 deletions

File tree

Zend/zend_vm_execute.h

Lines changed: 10 additions & 2 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: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,14 +1597,21 @@ function gen_halt_handler($f, $kind) {
15971597
function gen_interrupt_func($f, $kind, $spec) {
15981598
$cconv = $kind === ZEND_VM_KIND_TAILCALL ? 'ZEND_OPCODE_HANDLER_CCONV' : 'ZEND_OPCODE_HANDLER_FUNC_CCONV';
15991599
$variant = $kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL' : '';
1600+
if ($kind !== ZEND_VM_KIND_TAILCALL) {
1601+
/* Guard: exclude global-reg builds (void return) and TAILCALL builds (have own variant) */
1602+
out($f, "#if !(defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)) && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL\n");
1603+
}
16001604
out($f, "static ZEND_COLD zend_never_inline ZEND_OPCODE_HANDLER_RET {$cconv} zend_interrupt{$variant}(ZEND_OPCODE_HANDLER_ARGS) {\n");
16011605
out($f,"\tSAVE_OPLINE();\n");
16021606
if ($kind === ZEND_VM_KIND_TAILCALL) {
16031607
out($f,"\tZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
16041608
} else {
1605-
out($f, "\treturn &call_interrupt_op;\n");
1609+
out($f, "\treturn zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
16061610
}
16071611
out($f, "}\n");
1612+
if ($kind !== ZEND_VM_KIND_TAILCALL) {
1613+
out($f, "#endif\n");
1614+
}
16081615
}
16091616

16101617
function extra_spec_name($extra_spec) {
@@ -1860,7 +1867,11 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
18601867
out($f, "#pragma push_macro(\"ZEND_VM_INTERRUPT\")\n");
18611868
out($f, "#undef ZEND_VM_INTERRUPT\n");
18621869
out($f, "#define ZEND_VM_CONTINUE(handler) return opline\n");
1863-
out($f, "#define ZEND_VM_INTERRUPT() return zend_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
1870+
out($f, "#if !(defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)) && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL\n");
1871+
out($f, "# define ZEND_VM_INTERRUPT() return zend_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
1872+
out($f, "#else\n");
1873+
out($f, "# define ZEND_VM_INTERRUPT() return zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
1874+
out($f, "#endif\n");
18641875
out($f, $delayed_helpers);
18651876
out($f, "#pragma pop_macro(\"ZEND_VM_INTERRUPT\")\n");
18661877
out($f, "#pragma pop_macro(\"ZEND_VM_CONTINUE\")\n");
@@ -2056,7 +2067,9 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
20562067
}
20572068
out($f,"\n");
20582069
out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS);\n");
2070+
out($f,"#if !(defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)) && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL\n");
20592071
out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt(ZEND_OPCODE_HANDLER_ARGS);\n");
2072+
out($f,"#endif\n");
20602073
out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
20612074
out($f,"\n");
20622075
break;

0 commit comments

Comments
 (0)