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