aboutsummaryrefslogtreecommitdiff
path: root/src/lj_ccall.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_ccall.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index 00e753b9..5f95f5d8 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -985,6 +985,14 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
985 fid = ctf->sib; 985 fid = ctf->sib;
986 } 986 }
987 987
988#if LJ_TARGET_ARM64 && LJ_ABI_WIN
989 if ((ct->info & CTF_VARARG)) {
990 nsp -= maxgpr * CTSIZE_PTR; /* May end up with negative nsp. */
991 ngpr = maxgpr;
992 nfpr = CCALL_NARG_FPR;
993 }
994#endif
995
988 /* Walk through all passed arguments. */ 996 /* Walk through all passed arguments. */
989 for (o = L->base+1, narg = 1; o < top; o++, narg++) { 997 for (o = L->base+1, narg = 1; o < top; o++, narg++) {
990 CTypeID did; 998 CTypeID did;
@@ -1035,9 +1043,14 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
1035 align = CTSIZE_PTR-1; 1043 align = CTSIZE_PTR-1;
1036 nsp = (nsp + align) & ~align; 1044 nsp = (nsp + align) & ~align;
1037 } 1045 }
1046#if LJ_TARGET_ARM64 && LJ_ABI_WIN
1047 /* A negative nsp points into cc->gpr. Blame MS for their messy ABI. */
1048 dp = ((uint8_t *)cc->stack) + (int32_t)nsp;
1049#else
1038 dp = ((uint8_t *)cc->stack) + nsp; 1050 dp = ((uint8_t *)cc->stack) + nsp;
1051#endif
1039 nsp += CCALL_PACK_STACKARG ? sz : n * CTSIZE_PTR; 1052 nsp += CCALL_PACK_STACKARG ? sz : n * CTSIZE_PTR;
1040 if (nsp > CCALL_SIZE_STACK) { /* Too many arguments. */ 1053 if ((int32_t)nsp > CCALL_SIZE_STACK) { /* Too many arguments. */
1041 err_nyi: 1054 err_nyi:
1042 lj_err_caller(L, LJ_ERR_FFI_NYICALL); 1055 lj_err_caller(L, LJ_ERR_FFI_NYICALL);
1043 } 1056 }
@@ -1099,6 +1112,9 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
1099#endif 1112#endif
1100 } 1113 }
1101 if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */ 1114 if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */
1115#if LJ_TARGET_ARM64 && LJ_ABI_WIN
1116 if ((int32_t)nsp < 0) nsp = 0;
1117#endif
1102 1118
1103#if LJ_TARGET_X64 || (LJ_TARGET_PPC && !LJ_ABI_SOFTFP) 1119#if LJ_TARGET_X64 || (LJ_TARGET_PPC && !LJ_ABI_SOFTFP)
1104 cc->nfpr = nfpr; /* Required for vararg functions. */ 1120 cc->nfpr = nfpr; /* Required for vararg functions. */