aboutsummaryrefslogtreecommitdiff
path: root/src/lj_ccall.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_ccall.c')
-rw-r--r--src/lj_ccall.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index 04e306eb..9001cb5a 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -20,12 +20,15 @@
20#if LJ_TARGET_X86 20#if LJ_TARGET_X86
21/* -- x86 calling conventions --------------------------------------------- */ 21/* -- x86 calling conventions --------------------------------------------- */
22 22
23#define CCALL_PUSH(arg) \
24 *(GPRArg *)((uint8_t *)cc->stack + nsp) = (GPRArg)(arg), nsp += CTSIZE_PTR
25
23#if LJ_ABI_WIN 26#if LJ_ABI_WIN
24 27
25#define CCALL_HANDLE_STRUCTRET \ 28#define CCALL_HANDLE_STRUCTRET \
26 /* Return structs bigger than 8 by reference (on stack only). */ \ 29 /* Return structs bigger than 8 by reference (on stack only). */ \
27 cc->retref = (sz > 8); \ 30 cc->retref = (sz > 8); \
28 if (cc->retref) cc->stack[nsp++] = (GPRArg)dp; 31 if (cc->retref) CCALL_PUSH(dp);
29 32
30#define CCALL_HANDLE_COMPLEXRET CCALL_HANDLE_STRUCTRET 33#define CCALL_HANDLE_COMPLEXRET CCALL_HANDLE_STRUCTRET
31 34
@@ -40,7 +43,7 @@
40 if (ngpr < maxgpr) \ 43 if (ngpr < maxgpr) \
41 cc->gpr[ngpr++] = (GPRArg)dp; \ 44 cc->gpr[ngpr++] = (GPRArg)dp; \
42 else \ 45 else \
43 cc->stack[nsp++] = (GPRArg)dp; \ 46 CCALL_PUSH(dp); \
44 } else { /* Struct with single FP field ends up in FPR. */ \ 47 } else { /* Struct with single FP field ends up in FPR. */ \
45 cc->resx87 = ccall_classify_struct(cts, ctr); \ 48 cc->resx87 = ccall_classify_struct(cts, ctr); \
46 } 49 }
@@ -56,7 +59,7 @@
56 if (ngpr < maxgpr) \ 59 if (ngpr < maxgpr) \
57 cc->gpr[ngpr++] = (GPRArg)dp; \ 60 cc->gpr[ngpr++] = (GPRArg)dp; \
58 else \ 61 else \
59 cc->stack[nsp++] = (GPRArg)dp; 62 CCALL_PUSH(dp);
60 63
61#endif 64#endif
62 65
@@ -67,7 +70,7 @@
67 if (ngpr < maxgpr) \ 70 if (ngpr < maxgpr) \
68 cc->gpr[ngpr++] = (GPRArg)dp; \ 71 cc->gpr[ngpr++] = (GPRArg)dp; \
69 else \ 72 else \
70 cc->stack[nsp++] = (GPRArg)dp; \ 73 CCALL_PUSH(dp); \
71 } 74 }
72 75
73#endif 76#endif
@@ -278,8 +281,8 @@
278 if (ngpr < maxgpr) { \ 281 if (ngpr < maxgpr) { \
279 dp = &cc->gpr[ngpr]; \ 282 dp = &cc->gpr[ngpr]; \
280 if (ngpr + n > maxgpr) { \ 283 if (ngpr + n > maxgpr) { \
281 nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \ 284 nsp += (ngpr + n - maxgpr) * CTSIZE_PTR; /* Assumes contiguous gpr/stack fields. */ \
282 if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \ 285 if (nsp > CCALL_SIZE_STACK) goto err_nyi; /* Too many arguments. */ \
283 ngpr = maxgpr; \ 286 ngpr = maxgpr; \
284 } else { \ 287 } else { \
285 ngpr += n; \ 288 ngpr += n; \
@@ -471,8 +474,8 @@
471 if (ngpr < maxgpr) { \ 474 if (ngpr < maxgpr) { \
472 dp = &cc->gpr[ngpr]; \ 475 dp = &cc->gpr[ngpr]; \
473 if (ngpr + n > maxgpr) { \ 476 if (ngpr + n > maxgpr) { \
474 nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \ 477 nsp += (ngpr + n - maxgpr) * CTSIZE_PTR; /* Assumes contiguous gpr/stack fields. */ \
475 if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \ 478 if (nsp > CCALL_SIZE_STACK) goto err_nyi; /* Too many arguments. */ \
476 ngpr = maxgpr; \ 479 ngpr = maxgpr; \
477 } else { \ 480 } else { \
478 ngpr += n; \ 481 ngpr += n; \
@@ -565,8 +568,8 @@
565 if (ngpr < maxgpr) { \ 568 if (ngpr < maxgpr) { \
566 dp = &cc->gpr[ngpr]; \ 569 dp = &cc->gpr[ngpr]; \
567 if (ngpr + n > maxgpr) { \ 570 if (ngpr + n > maxgpr) { \
568 nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \ 571 nsp += (ngpr + n - maxgpr) * CTSIZE_PTR; /* Assumes contiguous gpr/stack fields. */ \
569 if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \ 572 if (nsp > CCALL_SIZE_STACK) goto err_nyi; /* Too many arguments. */ \
570 ngpr = maxgpr; \ 573 ngpr = maxgpr; \
571 } else { \ 574 } else { \
572 ngpr += n; \ 575 ngpr += n; \
@@ -698,10 +701,11 @@ static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl,
698 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg)); 701 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
699 if (ccall_struct_reg(cc, cts, dp, rcl)) { 702 if (ccall_struct_reg(cc, cts, dp, rcl)) {
700 /* Register overflow? Pass on stack. */ 703 /* Register overflow? Pass on stack. */
701 MSize nsp = cc->nsp, n = rcl[1] ? 2 : 1; 704 MSize nsp = cc->nsp, sz = rcl[1] ? 2*CTSIZE_PTR : CTSIZE_PTR;
702 if (nsp + n > CCALL_MAXSTACK) return 1; /* Too many arguments. */ 705 if (nsp + sz > CCALL_SIZE_STACK)
703 cc->nsp = nsp + n; 706 return 1; /* Too many arguments. */
704 memcpy(&cc->stack[nsp], dp, n*CTSIZE_PTR); 707 cc->nsp = nsp + sz;
708 memcpy((uint8_t *)cc->stack + nsp, dp, sz);
705 } 709 }
706 return 0; /* Ok. */ 710 return 0; /* Ok. */
707} 711}
@@ -1022,22 +1026,23 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
1022 } else { 1026 } else {
1023 sz = CTSIZE_PTR; 1027 sz = CTSIZE_PTR;
1024 } 1028 }
1025 sz = (sz + CTSIZE_PTR-1) & ~(CTSIZE_PTR-1); 1029 n = (sz + CTSIZE_PTR-1) / CTSIZE_PTR; /* Number of GPRs or stack slots needed. */
1026 n = sz / CTSIZE_PTR; /* Number of GPRs or stack slots needed. */
1027 1030
1028 CCALL_HANDLE_REGARG /* Handle register arguments. */ 1031 CCALL_HANDLE_REGARG /* Handle register arguments. */
1029 1032
1030 /* Otherwise pass argument on stack. */ 1033 /* Otherwise pass argument on stack. */
1031 if (CCALL_ALIGN_STACKARG && !rp && (d->info & CTF_ALIGN) > CTALIGN_PTR) { 1034 if (CCALL_ALIGN_STACKARG) { /* Align argument on stack. */
1032 MSize align = (1u << ctype_align(d->info-CTALIGN_PTR)) -1; 1035 MSize align = (1u << ctype_align(d->info)) - 1;
1033 nsp = (nsp + align) & ~align; /* Align argument on stack. */ 1036 if (rp)
1037 align = CTSIZE_PTR-1;
1038 nsp = (nsp + align) & ~align;
1034 } 1039 }
1035 if (nsp + n > CCALL_MAXSTACK) { /* Too many arguments. */ 1040 dp = ((uint8_t *)cc->stack) + nsp;
1041 nsp += n * CTSIZE_PTR;
1042 if (nsp > CCALL_SIZE_STACK) { /* Too many arguments. */
1036 err_nyi: 1043 err_nyi:
1037 lj_err_caller(L, LJ_ERR_FFI_NYICALL); 1044 lj_err_caller(L, LJ_ERR_FFI_NYICALL);
1038 } 1045 }
1039 dp = &cc->stack[nsp];
1040 nsp += n;
1041 isva = 0; 1046 isva = 0;
1042 1047
1043 done: 1048 done:
@@ -1099,10 +1104,10 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
1099#if LJ_TARGET_X64 || (LJ_TARGET_PPC && !LJ_ABI_SOFTFP) 1104#if LJ_TARGET_X64 || (LJ_TARGET_PPC && !LJ_ABI_SOFTFP)
1100 cc->nfpr = nfpr; /* Required for vararg functions. */ 1105 cc->nfpr = nfpr; /* Required for vararg functions. */
1101#endif 1106#endif
1102 cc->nsp = nsp; 1107 cc->nsp = (nsp + CTSIZE_PTR-1) & ~(CTSIZE_PTR-1);
1103 cc->spadj = (CCALL_SPS_FREE + CCALL_SPS_EXTRA)*CTSIZE_PTR; 1108 cc->spadj = (CCALL_SPS_FREE + CCALL_SPS_EXTRA) * CTSIZE_PTR;
1104 if (nsp > CCALL_SPS_FREE) 1109 if (cc->nsp > CCALL_SPS_FREE * CTSIZE_PTR)
1105 cc->spadj += (((nsp-CCALL_SPS_FREE)*CTSIZE_PTR + 15u) & ~15u); 1110 cc->spadj += (((cc->nsp - CCALL_SPS_FREE * CTSIZE_PTR) + 15u) & ~15u);
1106 return gcsteps; 1111 return gcsteps;
1107} 1112}
1108 1113