aboutsummaryrefslogtreecommitdiff
path: root/src/lj_crecord.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_crecord.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index f88cddfd..27f2c1dd 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*/
1105static TRef crec_call_args(jit_State *J, RecordFFData *rd, 1107static 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,14 +1251,17 @@ 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);
1264 CTInfo ctr_info = ctr->info; /* crec_call_args may invalidate ctr. */
1259 IRType t = crec_ct2irt(cts, ctr); 1265 IRType t = crec_ct2irt(cts, ctr);
1260 TRef tr; 1266 TRef tr;
1261 TValue tv; 1267 TValue tv;
@@ -1263,22 +1269,22 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1263 tv.u64 = ((uintptr_t)cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4) >> 2) | U64x(800000000, 00000000); 1269 tv.u64 = ((uintptr_t)cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4) >> 2) | U64x(800000000, 00000000);
1264 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv))) 1270 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv)))
1265 lj_trace_err(J, LJ_TRERR_BLACKL); 1271 lj_trace_err(J, LJ_TRERR_BLACKL);
1266 if (ctype_isvoid(ctr->info)) { 1272 if (ctype_isvoid(ctr_info)) {
1267 t = IRT_NIL; 1273 t = IRT_NIL;
1268 rd->nres = 0; 1274 rd->nres = 0;
1269 } else if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) || 1275 } else if (!(ctype_isnum(ctr_info) || ctype_isptr(ctr_info) ||
1270 ctype_isenum(ctr->info)) || t == IRT_CDATA) { 1276 ctype_isenum(ctr_info)) || t == IRT_CDATA) {
1271 lj_trace_err(J, LJ_TRERR_NYICALL); 1277 lj_trace_err(J, LJ_TRERR_NYICALL);
1272 } 1278 }
1273 if ((ct->info & CTF_VARARG) 1279 if ((info & CTF_VARARG)
1274#if LJ_TARGET_X86 1280#if LJ_TARGET_X86
1275 || ctype_cconv(ct->info) != CTCC_CDECL 1281 || ctype_cconv(info) != CTCC_CDECL
1276#endif 1282#endif
1277 ) 1283 )
1278 func = emitir(IRT(IR_CARG, IRT_NIL), func, 1284 func = emitir(IRT(IR_CARG, IRT_NIL), func,
1279 lj_ir_kint(J, ctype_typeid(cts, ct))); 1285 lj_ir_kint(J, ctype_typeid(cts, ct)));
1280 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func); 1286 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
1281 if (ctype_isbool(ctr->info)) { 1287 if (ctype_isbool(ctr_info)) {
1282 if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) { 1288 if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) {
1283 /* Don't check result if ignored. */ 1289 /* Don't check result if ignored. */
1284 tr = TREF_NIL; 1290 tr = TREF_NIL;
@@ -1294,8 +1300,8 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1294 tr = TREF_TRUE; 1300 tr = TREF_TRUE;
1295 } 1301 }
1296 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) || 1302 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
1297 t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) { 1303 t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr_info)) {
1298 TRef trid = lj_ir_kint(J, ctype_cid(ct->info)); 1304 TRef trid = lj_ir_kint(J, ctype_cid(info));
1299 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr); 1305 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
1300 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); 1306 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1301 } else if (t == IRT_FLOAT || t == IRT_U32) { 1307 } else if (t == IRT_FLOAT || t == IRT_U32) {