diff options
| author | Mike Pall <mike> | 2025-05-28 20:39:05 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2025-05-28 20:39:05 +0200 |
| commit | 852c3a08aef8e3709e37622a23e74c655dc2926a (patch) | |
| tree | a45588cdc8855cfd12da2493dc38b1653de7ab04 /src | |
| parent | eec7a8016c3381b949b5d84583800d05897fa960 (diff) | |
| parent | 9c8eb7cfe10ef5939d9b358a0bd805a610818ba5 (diff) | |
| download | luajit-852c3a08aef8e3709e37622a23e74c655dc2926a.tar.gz luajit-852c3a08aef8e3709e37622a23e74c655dc2926a.tar.bz2 luajit-852c3a08aef8e3709e37622a23e74c655dc2926a.zip | |
Merge branch 'master' into v2.1
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_ccall.c | 21 | ||||
| -rw-r--r-- | src/lj_crecord.c | 21 |
2 files changed, 26 insertions, 16 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 | */ | ||
| 905 | CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o) | 907 | CTypeID 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 | */ | ||
| 933 | static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, | 937 | static 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. */ |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index f88cddfd..bbf002bd 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
| @@ -1101,12 +1101,15 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) | |||
| 1101 | crec_finalizer(J, trcd, 0, fin); | 1101 | crec_finalizer(J, trcd, 0, fin); |
| 1102 | } | 1102 | } |
| 1103 | 1103 | ||
| 1104 | /* Record argument conversions. */ | 1104 | /* Record argument conversions. |
| 1105 | ** Note: may reallocate cts->tab and invalidate CType pointers. | ||
| 1106 | */ | ||
| 1105 | static TRef crec_call_args(jit_State *J, RecordFFData *rd, | 1107 | static TRef crec_call_args(jit_State *J, RecordFFData *rd, |
| 1106 | CTState *cts, CType *ct) | 1108 | CTState *cts, CType *ct) |
| 1107 | { | 1109 | { |
| 1108 | TRef args[CCI_NARGS_MAX]; | 1110 | TRef args[CCI_NARGS_MAX]; |
| 1109 | CTypeID fid; | 1111 | CTypeID fid; |
| 1112 | CTInfo info = ct->info; /* lj_ccall_ctid_vararg may invalidate ct pointer. */ | ||
| 1110 | MSize i, n; | 1113 | MSize i, n; |
| 1111 | TRef tr, *base; | 1114 | TRef tr, *base; |
| 1112 | cTValue *o; | 1115 | cTValue *o; |
| @@ -1115,9 +1118,9 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd, | |||
| 1115 | TRef *arg0 = NULL, *arg1 = NULL; | 1118 | TRef *arg0 = NULL, *arg1 = NULL; |
| 1116 | #endif | 1119 | #endif |
| 1117 | int ngpr = 0; | 1120 | int ngpr = 0; |
| 1118 | if (ctype_cconv(ct->info) == CTCC_THISCALL) | 1121 | if (ctype_cconv(info) == CTCC_THISCALL) |
| 1119 | ngpr = 1; | 1122 | ngpr = 1; |
| 1120 | else if (ctype_cconv(ct->info) == CTCC_FASTCALL) | 1123 | else if (ctype_cconv(info) == CTCC_FASTCALL) |
| 1121 | ngpr = 2; | 1124 | ngpr = 2; |
| 1122 | #elif LJ_TARGET_ARM64 && LJ_TARGET_OSX | 1125 | #elif LJ_TARGET_ARM64 && LJ_TARGET_OSX |
| 1123 | int ngpr = CCALL_NARG_GPR; | 1126 | int ngpr = CCALL_NARG_GPR; |
| @@ -1144,7 +1147,7 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd, | |||
| 1144 | lj_assertJ(ctype_isfield(ctf->info), "field expected"); | 1147 | lj_assertJ(ctype_isfield(ctf->info), "field expected"); |
| 1145 | did = ctype_cid(ctf->info); | 1148 | did = ctype_cid(ctf->info); |
| 1146 | } else { | 1149 | } else { |
| 1147 | if (!(ct->info & CTF_VARARG)) | 1150 | if (!(info & CTF_VARARG)) |
| 1148 | lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */ | 1151 | lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */ |
| 1149 | #if LJ_TARGET_ARM64 && LJ_TARGET_OSX | 1152 | #if LJ_TARGET_ARM64 && LJ_TARGET_OSX |
| 1150 | if (ngpr >= 0) { | 1153 | if (ngpr >= 0) { |
| @@ -1248,12 +1251,14 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd) | |||
| 1248 | { | 1251 | { |
| 1249 | CTState *cts = ctype_ctsG(J2G(J)); | 1252 | CTState *cts = ctype_ctsG(J2G(J)); |
| 1250 | CType *ct = ctype_raw(cts, cd->ctypeid); | 1253 | CType *ct = ctype_raw(cts, cd->ctypeid); |
| 1254 | CTInfo info; | ||
| 1251 | IRType tp = IRT_PTR; | 1255 | IRType tp = IRT_PTR; |
| 1252 | if (ctype_isptr(ct->info)) { | 1256 | if (ctype_isptr(ct->info)) { |
| 1253 | tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; | 1257 | tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; |
| 1254 | ct = ctype_rawchild(cts, ct); | 1258 | ct = ctype_rawchild(cts, ct); |
| 1255 | } | 1259 | } |
| 1256 | if (ctype_isfunc(ct->info)) { | 1260 | info = ct->info; /* crec_call_args may invalidate ct pointer. */ |
| 1261 | if (ctype_isfunc(info)) { | ||
| 1257 | TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR); | 1262 | TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR); |
| 1258 | CType *ctr = ctype_rawchild(cts, ct); | 1263 | CType *ctr = ctype_rawchild(cts, ct); |
| 1259 | IRType t = crec_ct2irt(cts, ctr); | 1264 | IRType t = crec_ct2irt(cts, ctr); |
| @@ -1270,9 +1275,9 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd) | |||
| 1270 | ctype_isenum(ctr->info)) || t == IRT_CDATA) { | 1275 | ctype_isenum(ctr->info)) || t == IRT_CDATA) { |
| 1271 | lj_trace_err(J, LJ_TRERR_NYICALL); | 1276 | lj_trace_err(J, LJ_TRERR_NYICALL); |
| 1272 | } | 1277 | } |
| 1273 | if ((ct->info & CTF_VARARG) | 1278 | if ((info & CTF_VARARG) |
| 1274 | #if LJ_TARGET_X86 | 1279 | #if LJ_TARGET_X86 |
| 1275 | || ctype_cconv(ct->info) != CTCC_CDECL | 1280 | || ctype_cconv(info) != CTCC_CDECL |
| 1276 | #endif | 1281 | #endif |
| 1277 | ) | 1282 | ) |
| 1278 | func = emitir(IRT(IR_CARG, IRT_NIL), func, | 1283 | func = emitir(IRT(IR_CARG, IRT_NIL), func, |
| @@ -1295,7 +1300,7 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd) | |||
| 1295 | } | 1300 | } |
| 1296 | } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) || | 1301 | } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) || |
| 1297 | t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) { | 1302 | t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) { |
| 1298 | TRef trid = lj_ir_kint(J, ctype_cid(ct->info)); | 1303 | TRef trid = lj_ir_kint(J, ctype_cid(info)); |
| 1299 | tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr); | 1304 | tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr); |
| 1300 | if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); | 1305 | if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); |
| 1301 | } else if (t == IRT_FLOAT || t == IRT_U32) { | 1306 | } else if (t == IRT_FLOAT || t == IRT_U32) { |
