@@ -3314,6 +3314,27 @@ static PRUNTIME_FUNCTION zend_jit_unwind_callback(DWORD64 pc, PVOID context)
33143314
33153315static void zend_jit_setup_unwinder(void)
33163316{
3317+ #if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
3318+ /* TAILCALL VM: fixed_save_regset=0, no registers pushed in prologue.
3319+ * fixed_stack_frame_size=40, fixed_call_stack_size=48 (16+IR_SHADOW_ARGS).
3320+ * Prologue is: sub rsp, 0x58 (88 bytes = 40+48). */
3321+ static const unsigned char uw_data[] = {
3322+ 0x01, // Version=1, Flags=0
3323+ 0x04, // Size of prolog (sub rsp,imm8 = 4 bytes: 48 83 ec 58)
3324+ 0x01, // Count of unwind codes
3325+ 0x00, // Frame Register=none
3326+ 0x04, 0xa2, // offset 4: UWOP_ALLOC_SMALL info=10, alloc=(10+1)*8=88
3327+ 0x00, 0x00, // padding
3328+ };
3329+ /* Exit call variant: base 88 + 304 (shadow+GP+FP+padding) = 392 (0x188) */
3330+ static const unsigned char uw_data_exitcall[] = {
3331+ 0x01, // Version=1, Flags=0
3332+ 0x07, // Size of prolog (sub rsp,imm32 = 7 bytes: 48 81 ec 88 01 00 00)
3333+ 0x02, // Count of unwind codes
3334+ 0x00, // Frame Register=none
3335+ 0x07, 0x01, 0x31, 0x00, // offset 7: UWOP_ALLOC_LARGE info=0, size/8=49, alloc=392
3336+ };
3337+ #else
33173338 /* Hardcoded SEH unwind data for JIT-ed PHP functions with "fixed stack frame" */
33183339 static const unsigned char uw_data[] = {
33193340 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
@@ -3348,6 +3369,7 @@ static void zend_jit_setup_unwinder(void)
33483369 0x02, 0x50, // 1: pushq %rbp
33493370 0x01, 0x30, // 0: pushq %rbx
33503371 };
3372+ #endif
33513373
33523374 zend_jit_uw_func = (PRUNTIME_FUNCTION)*dasm_ptr;
33533375 *dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) * 4 +
0 commit comments