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.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index f003d756..d5f092ea 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -901,7 +901,9 @@ static void ccall_copy_struct(CCallState *cc, CType *ctr, void *dp, void *sp,
901 901
902/* -- Common C call handling ---------------------------------------------- */ 902/* -- Common C call handling ---------------------------------------------- */
903 903
904/* Infer the destination CTypeID for a vararg argument. */ 904/* Infer the destination CTypeID for a vararg argument.
905** Note: may reallocate cts->tab and invalidate CType pointers.
906*/
905CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o) 907CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o)
906{ 908{
907 if (tvisnumber(o)) { 909 if (tvisnumber(o)) {
@@ -929,13 +931,16 @@ CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o)
929 } 931 }
930} 932}
931 933
932/* Setup arguments for C call. */ 934/* Setup arguments for C call.
935** Note: may reallocate cts->tab and invalidate CType pointers.
936*/
933static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, 937static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
934 CCallState *cc) 938 CCallState *cc)
935{ 939{
936 int gcsteps = 0; 940 int gcsteps = 0;
937 TValue *o, *top = L->top; 941 TValue *o, *top = L->top;
938 CTypeID fid; 942 CTypeID fid;
943 CTInfo info = ct->info; /* lj_ccall_ctid_vararg may invalidate ct pointer. */
939 CType *ctr; 944 CType *ctr;
940 MSize maxgpr, ngpr = 0, nsp = 0, narg; 945 MSize maxgpr, ngpr = 0, nsp = 0, narg;
941#if CCALL_NARG_FPR 946#if CCALL_NARG_FPR
@@ -954,7 +959,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
954#if LJ_TARGET_X86 959#if LJ_TARGET_X86
955 /* x86 has several different calling conventions. */ 960 /* x86 has several different calling conventions. */
956 cc->resx87 = 0; 961 cc->resx87 = 0;
957 switch (ctype_cconv(ct->info)) { 962 switch (ctype_cconv(info)) {
958 case CTCC_FASTCALL: maxgpr = 2; break; 963 case CTCC_FASTCALL: maxgpr = 2; break;
959 case CTCC_THISCALL: maxgpr = 1; break; 964 case CTCC_THISCALL: maxgpr = 1; break;
960 default: maxgpr = 0; break; 965 default: maxgpr = 0; break;
@@ -971,7 +976,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
971 } else if (ctype_iscomplex(ctr->info) || ctype_isstruct(ctr->info)) { 976 } else if (ctype_iscomplex(ctr->info) || ctype_isstruct(ctr->info)) {
972 /* Preallocate cdata object and anchor it after arguments. */ 977 /* Preallocate cdata object and anchor it after arguments. */
973 CTSize sz = ctr->size; 978 CTSize sz = ctr->size;
974 GCcdata *cd = lj_cdata_new(cts, ctype_cid(ct->info), sz); 979 GCcdata *cd = lj_cdata_new(cts, ctype_cid(info), sz);
975 void *dp = cdataptr(cd); 980 void *dp = cdataptr(cd);
976 setcdataV(L, L->top++, cd); 981 setcdataV(L, L->top++, cd);
977 if (ctype_isstruct(ctr->info)) { 982 if (ctype_isstruct(ctr->info)) {
@@ -994,7 +999,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
994 } 999 }
995 1000
996#if LJ_TARGET_ARM64 && LJ_ABI_WIN 1001#if LJ_TARGET_ARM64 && LJ_ABI_WIN
997 if ((ct->info & CTF_VARARG)) { 1002 if ((info & CTF_VARARG)) {
998 nsp -= maxgpr * CTSIZE_PTR; /* May end up with negative nsp. */ 1003 nsp -= maxgpr * CTSIZE_PTR; /* May end up with negative nsp. */
999 ngpr = maxgpr; 1004 ngpr = maxgpr;
1000 nfpr = CCALL_NARG_FPR; 1005 nfpr = CCALL_NARG_FPR;
@@ -1015,7 +1020,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
1015 lj_assertL(ctype_isfield(ctf->info), "field expected"); 1020 lj_assertL(ctype_isfield(ctf->info), "field expected");
1016 did = ctype_cid(ctf->info); 1021 did = ctype_cid(ctf->info);
1017 } else { 1022 } else {
1018 if (!(ct->info & CTF_VARARG)) 1023 if (!(info & CTF_VARARG))
1019 lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too many arguments. */ 1024 lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too many arguments. */
1020 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */ 1025 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */
1021 isva = 1; 1026 isva = 1;
@@ -1186,11 +1191,11 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
1186 ct = ctype_rawchild(cts, ct); 1191 ct = ctype_rawchild(cts, ct);
1187 } 1192 }
1188 if (ctype_isfunc(ct->info)) { 1193 if (ctype_isfunc(ct->info)) {
1194 CTypeID id = ctype_typeid(cts, ct);
1189 CCallState cc; 1195 CCallState cc;
1190 int gcsteps, ret; 1196 int gcsteps, ret;
1191 cc.func = (void (*)(void))cdata_getptr(cdataptr(cd), sz); 1197 cc.func = (void (*)(void))cdata_getptr(cdataptr(cd), sz);
1192 gcsteps = ccall_set_args(L, cts, ct, &cc); 1198 gcsteps = ccall_set_args(L, cts, ct, &cc);
1193 ct = (CType *)((intptr_t)ct-(intptr_t)cts->tab);
1194 cts->cb.slot = ~0u; 1199 cts->cb.slot = ~0u;
1195 lj_vm_ffi_call(&cc); 1200 lj_vm_ffi_call(&cc);
1196 if (cts->cb.slot != ~0u) { /* Blacklist function that called a callback. */ 1201 if (cts->cb.slot != ~0u) { /* Blacklist function that called a callback. */
@@ -1198,7 +1203,7 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
1198 tv.u64 = ((uintptr_t)(void *)cc.func >> 2) | U64x(800000000, 00000000); 1203 tv.u64 = ((uintptr_t)(void *)cc.func >> 2) | U64x(800000000, 00000000);
1199 setboolV(lj_tab_set(L, cts->miscmap, &tv), 1); 1204 setboolV(lj_tab_set(L, cts->miscmap, &tv), 1);
1200 } 1205 }
1201 ct = (CType *)((intptr_t)ct+(intptr_t)cts->tab); /* May be reallocated. */ 1206 ct = ctype_get(cts, id); /* Table may have been reallocated. */
1202 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret); 1207 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret);
1203#if LJ_TARGET_X86 && LJ_ABI_WIN 1208#if LJ_TARGET_X86 && LJ_ABI_WIN
1204 /* Automatically detect __stdcall and fix up C function declaration. */ 1209 /* Automatically detect __stdcall and fix up C function declaration. */