|
@@ -140,7 +140,7 @@
|
|
|
int rcl[2]; rcl[0] = rcl[1] = 0; \
|
|
|
if (!ccall_classify_struct(cts, d, rcl, 0)) { \
|
|
|
cc->nsp = nsp; cc->ngpr = ngpr; cc->nfpr = nfpr; \
|
|
|
- if (ccall_struct_arg(cc, cts, d, rcl, o)) goto err_nyi; \
|
|
|
+ if (ccall_struct_arg(cc, cts, d, rcl, o, narg)) goto err_nyi; \
|
|
|
nsp = cc->nsp; ngpr = cc->ngpr; nfpr = cc->nfpr; \
|
|
|
continue; \
|
|
|
} /* Pass all other structs by value on stack. */
|
|
@@ -278,11 +278,12 @@ static int ccall_struct_reg(CCallState *cc, GPRArg *dp, int *rcl)
|
|
|
|
|
|
/* Pass a small struct argument. */
|
|
|
static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl,
|
|
|
- TValue *o)
|
|
|
+ TValue *o, int narg)
|
|
|
{
|
|
|
GPRArg dp[2];
|
|
|
dp[0] = dp[1] = 0;
|
|
|
- lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, 0); /* Convert to temp. struct. */
|
|
|
+ /* Convert to temp. struct. */
|
|
|
+ lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
|
|
|
if (!ccall_struct_reg(cc, dp, rcl)) { /* Register overflow? Pass on stack. */
|
|
|
MSize nsp = cc->nsp, n = rcl[1] ? 2 : 1;
|
|
|
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,
|
|
|
TValue *o, *top = L->top;
|
|
|
CTypeID fid;
|
|
|
CType *ctr;
|
|
|
- MSize maxgpr, ngpr = 0, nsp = 0;
|
|
|
+ MSize maxgpr, ngpr = 0, nsp = 0, narg;
|
|
|
#if CCALL_NARG_FPR
|
|
|
MSize nfpr = 0;
|
|
|
#endif
|
|
@@ -401,7 +402,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
|
|
}
|
|
|
|
|
|
/* Walk through all passed arguments. */
|
|
|
- for (o = L->base+1; o < top; o++) {
|
|
|
+ for (o = L->base+1, narg = 1; o < top; o++, narg++) {
|
|
|
CTypeID did;
|
|
|
CType *d;
|
|
|
CTSize sz;
|
|
@@ -466,7 +467,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
|
|
*(void **)dp = rp;
|
|
|
dp = rp;
|
|
|
}
|
|
|
- lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, 0);
|
|
|
+ lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
|
|
|
#if LJ_TARGET_X64 && LJ_ABI_WIN
|
|
|
if (isva) { /* Windows/x64 mirrors varargs in both register sets. */
|
|
|
if (nfpr == ngpr)
|