FFI: Unify stack setup for C calls in interpreter.
This commit is contained in:
@@ -20,12 +20,15 @@
|
||||
#if LJ_TARGET_X86
|
||||
/* -- x86 calling conventions --------------------------------------------- */
|
||||
|
||||
#define CCALL_PUSH(arg) \
|
||||
*(GPRArg *)((uint8_t *)cc->stack + nsp) = (GPRArg)(arg), nsp += CTSIZE_PTR
|
||||
|
||||
#if LJ_ABI_WIN
|
||||
|
||||
#define CCALL_HANDLE_STRUCTRET \
|
||||
/* Return structs bigger than 8 by reference (on stack only). */ \
|
||||
cc->retref = (sz > 8); \
|
||||
if (cc->retref) cc->stack[nsp++] = (GPRArg)dp;
|
||||
if (cc->retref) CCALL_PUSH(dp);
|
||||
|
||||
#define CCALL_HANDLE_COMPLEXRET CCALL_HANDLE_STRUCTRET
|
||||
|
||||
@@ -40,7 +43,7 @@
|
||||
if (ngpr < maxgpr) \
|
||||
cc->gpr[ngpr++] = (GPRArg)dp; \
|
||||
else \
|
||||
cc->stack[nsp++] = (GPRArg)dp; \
|
||||
CCALL_PUSH(dp); \
|
||||
} else { /* Struct with single FP field ends up in FPR. */ \
|
||||
cc->resx87 = ccall_classify_struct(cts, ctr); \
|
||||
}
|
||||
@@ -56,7 +59,7 @@
|
||||
if (ngpr < maxgpr) \
|
||||
cc->gpr[ngpr++] = (GPRArg)dp; \
|
||||
else \
|
||||
cc->stack[nsp++] = (GPRArg)dp;
|
||||
CCALL_PUSH(dp);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -67,7 +70,7 @@
|
||||
if (ngpr < maxgpr) \
|
||||
cc->gpr[ngpr++] = (GPRArg)dp; \
|
||||
else \
|
||||
cc->stack[nsp++] = (GPRArg)dp; \
|
||||
CCALL_PUSH(dp); \
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -278,8 +281,8 @@
|
||||
if (ngpr < maxgpr) { \
|
||||
dp = &cc->gpr[ngpr]; \
|
||||
if (ngpr + n > maxgpr) { \
|
||||
nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \
|
||||
if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \
|
||||
nsp += (ngpr + n - maxgpr) * CTSIZE_PTR; /* Assumes contiguous gpr/stack fields. */ \
|
||||
if (nsp > CCALL_SIZE_STACK) goto err_nyi; /* Too many arguments. */ \
|
||||
ngpr = maxgpr; \
|
||||
} else { \
|
||||
ngpr += n; \
|
||||
@@ -471,8 +474,8 @@
|
||||
if (ngpr < maxgpr) { \
|
||||
dp = &cc->gpr[ngpr]; \
|
||||
if (ngpr + n > maxgpr) { \
|
||||
nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \
|
||||
if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \
|
||||
nsp += (ngpr + n - maxgpr) * CTSIZE_PTR; /* Assumes contiguous gpr/stack fields. */ \
|
||||
if (nsp > CCALL_SIZE_STACK) goto err_nyi; /* Too many arguments. */ \
|
||||
ngpr = maxgpr; \
|
||||
} else { \
|
||||
ngpr += n; \
|
||||
@@ -565,8 +568,8 @@
|
||||
if (ngpr < maxgpr) { \
|
||||
dp = &cc->gpr[ngpr]; \
|
||||
if (ngpr + n > maxgpr) { \
|
||||
nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \
|
||||
if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \
|
||||
nsp += (ngpr + n - maxgpr) * CTSIZE_PTR; /* Assumes contiguous gpr/stack fields. */ \
|
||||
if (nsp > CCALL_SIZE_STACK) goto err_nyi; /* Too many arguments. */ \
|
||||
ngpr = maxgpr; \
|
||||
} else { \
|
||||
ngpr += n; \
|
||||
@@ -698,10 +701,11 @@ static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl,
|
||||
lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
|
||||
if (ccall_struct_reg(cc, cts, 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. */
|
||||
cc->nsp = nsp + n;
|
||||
memcpy(&cc->stack[nsp], dp, n*CTSIZE_PTR);
|
||||
MSize nsp = cc->nsp, sz = rcl[1] ? 2*CTSIZE_PTR : CTSIZE_PTR;
|
||||
if (nsp + sz > CCALL_SIZE_STACK)
|
||||
return 1; /* Too many arguments. */
|
||||
cc->nsp = nsp + sz;
|
||||
memcpy((uint8_t *)cc->stack + nsp, dp, sz);
|
||||
}
|
||||
return 0; /* Ok. */
|
||||
}
|
||||
@@ -1022,22 +1026,23 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
||||
} else {
|
||||
sz = CTSIZE_PTR;
|
||||
}
|
||||
sz = (sz + CTSIZE_PTR-1) & ~(CTSIZE_PTR-1);
|
||||
n = sz / CTSIZE_PTR; /* Number of GPRs or stack slots needed. */
|
||||
n = (sz + CTSIZE_PTR-1) / CTSIZE_PTR; /* Number of GPRs or stack slots needed. */
|
||||
|
||||
CCALL_HANDLE_REGARG /* Handle register arguments. */
|
||||
|
||||
/* Otherwise pass argument on stack. */
|
||||
if (CCALL_ALIGN_STACKARG && !rp && (d->info & CTF_ALIGN) > CTALIGN_PTR) {
|
||||
MSize align = (1u << ctype_align(d->info-CTALIGN_PTR)) -1;
|
||||
nsp = (nsp + align) & ~align; /* Align argument on stack. */
|
||||
if (CCALL_ALIGN_STACKARG) { /* Align argument on stack. */
|
||||
MSize align = (1u << ctype_align(d->info)) - 1;
|
||||
if (rp)
|
||||
align = CTSIZE_PTR-1;
|
||||
nsp = (nsp + align) & ~align;
|
||||
}
|
||||
if (nsp + n > CCALL_MAXSTACK) { /* Too many arguments. */
|
||||
dp = ((uint8_t *)cc->stack) + nsp;
|
||||
nsp += n * CTSIZE_PTR;
|
||||
if (nsp > CCALL_SIZE_STACK) { /* Too many arguments. */
|
||||
err_nyi:
|
||||
lj_err_caller(L, LJ_ERR_FFI_NYICALL);
|
||||
}
|
||||
dp = &cc->stack[nsp];
|
||||
nsp += n;
|
||||
isva = 0;
|
||||
|
||||
done:
|
||||
@@ -1099,10 +1104,10 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
||||
#if LJ_TARGET_X64 || (LJ_TARGET_PPC && !LJ_ABI_SOFTFP)
|
||||
cc->nfpr = nfpr; /* Required for vararg functions. */
|
||||
#endif
|
||||
cc->nsp = nsp;
|
||||
cc->spadj = (CCALL_SPS_FREE + CCALL_SPS_EXTRA)*CTSIZE_PTR;
|
||||
if (nsp > CCALL_SPS_FREE)
|
||||
cc->spadj += (((nsp-CCALL_SPS_FREE)*CTSIZE_PTR + 15u) & ~15u);
|
||||
cc->nsp = (nsp + CTSIZE_PTR-1) & ~(CTSIZE_PTR-1);
|
||||
cc->spadj = (CCALL_SPS_FREE + CCALL_SPS_EXTRA) * CTSIZE_PTR;
|
||||
if (cc->nsp > CCALL_SPS_FREE * CTSIZE_PTR)
|
||||
cc->spadj += (((cc->nsp - CCALL_SPS_FREE * CTSIZE_PTR) + 15u) & ~15u);
|
||||
return gcsteps;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user