diff options
Diffstat (limited to 'src/lj_ccall.c')
-rw-r--r-- | src/lj_ccall.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c index f2eceb6d..3f548c30 100644 --- a/src/lj_ccall.c +++ b/src/lj_ccall.c | |||
@@ -140,7 +140,7 @@ | |||
140 | int rcl[2]; rcl[0] = rcl[1] = 0; \ | 140 | int rcl[2]; rcl[0] = rcl[1] = 0; \ |
141 | if (!ccall_classify_struct(cts, d, rcl, 0)) { \ | 141 | if (!ccall_classify_struct(cts, d, rcl, 0)) { \ |
142 | cc->nsp = nsp; cc->ngpr = ngpr; cc->nfpr = nfpr; \ | 142 | cc->nsp = nsp; cc->ngpr = ngpr; cc->nfpr = nfpr; \ |
143 | if (ccall_struct_arg(cc, cts, d, rcl, o)) goto err_nyi; \ | 143 | if (ccall_struct_arg(cc, cts, d, rcl, o, narg)) goto err_nyi; \ |
144 | nsp = cc->nsp; ngpr = cc->ngpr; nfpr = cc->nfpr; \ | 144 | nsp = cc->nsp; ngpr = cc->ngpr; nfpr = cc->nfpr; \ |
145 | continue; \ | 145 | continue; \ |
146 | } /* Pass all other structs by value on stack. */ | 146 | } /* Pass all other structs by value on stack. */ |
@@ -278,11 +278,12 @@ static int ccall_struct_reg(CCallState *cc, GPRArg *dp, int *rcl) | |||
278 | 278 | ||
279 | /* Pass a small struct argument. */ | 279 | /* Pass a small struct argument. */ |
280 | static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl, | 280 | static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl, |
281 | TValue *o) | 281 | TValue *o, int narg) |
282 | { | 282 | { |
283 | GPRArg dp[2]; | 283 | GPRArg dp[2]; |
284 | dp[0] = dp[1] = 0; | 284 | dp[0] = dp[1] = 0; |
285 | lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, 0); /* Convert to temp. struct. */ | 285 | /* Convert to temp. struct. */ |
286 | lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg)); | ||
286 | if (!ccall_struct_reg(cc, dp, rcl)) { /* Register overflow? Pass on stack. */ | 287 | if (!ccall_struct_reg(cc, dp, rcl)) { /* Register overflow? Pass on stack. */ |
287 | MSize nsp = cc->nsp, n = rcl[1] ? 2 : 1; | 288 | MSize nsp = cc->nsp, n = rcl[1] ? 2 : 1; |
288 | if (nsp + n > CCALL_MAXSTACK) return 1; /* Too many arguments. */ | 289 | if (nsp + n > CCALL_MAXSTACK) return 1; /* Too many arguments. */ |
@@ -347,7 +348,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, | |||
347 | TValue *o, *top = L->top; | 348 | TValue *o, *top = L->top; |
348 | CTypeID fid; | 349 | CTypeID fid; |
349 | CType *ctr; | 350 | CType *ctr; |
350 | MSize maxgpr, ngpr = 0, nsp = 0; | 351 | MSize maxgpr, ngpr = 0, nsp = 0, narg; |
351 | #if CCALL_NARG_FPR | 352 | #if CCALL_NARG_FPR |
352 | MSize nfpr = 0; | 353 | MSize nfpr = 0; |
353 | #endif | 354 | #endif |
@@ -401,7 +402,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, | |||
401 | } | 402 | } |
402 | 403 | ||
403 | /* Walk through all passed arguments. */ | 404 | /* Walk through all passed arguments. */ |
404 | for (o = L->base+1; o < top; o++) { | 405 | for (o = L->base+1, narg = 1; o < top; o++, narg++) { |
405 | CTypeID did; | 406 | CTypeID did; |
406 | CType *d; | 407 | CType *d; |
407 | CTSize sz; | 408 | CTSize sz; |
@@ -466,7 +467,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, | |||
466 | *(void **)dp = rp; | 467 | *(void **)dp = rp; |
467 | dp = rp; | 468 | dp = rp; |
468 | } | 469 | } |
469 | lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, 0); | 470 | lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg)); |
470 | #if LJ_TARGET_X64 && LJ_ABI_WIN | 471 | #if LJ_TARGET_X64 && LJ_ABI_WIN |
471 | if (isva) { /* Windows/x64 mirrors varargs in both register sets. */ | 472 | if (isva) { /* Windows/x64 mirrors varargs in both register sets. */ |
472 | if (nfpr == ngpr) | 473 | if (nfpr == ngpr) |