diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_ccall.c | 18 |
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. */ |