aboutsummaryrefslogtreecommitdiff
path: root/src/lj_crecord.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_crecord.c')
-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 216144f3..80e25ef8 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -988,12 +988,15 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
988 } 988 }
989} 989}
990 990
991/* Record argument conversions. */ 991/* Record argument conversions.
992** Note: may reallocate cts->tab and invalidate CType pointers.
993*/
992static TRef crec_call_args(jit_State *J, RecordFFData *rd, 994static TRef crec_call_args(jit_State *J, RecordFFData *rd,
993 CTState *cts, CType *ct) 995 CTState *cts, CType *ct)
994{ 996{
995 TRef args[CCI_NARGS_MAX]; 997 TRef args[CCI_NARGS_MAX];
996 CTypeID fid; 998 CTypeID fid;
999 CTInfo info = ct->info; /* lj_ccall_ctid_vararg may invalidate ct pointer. */
997 MSize i, n; 1000 MSize i, n;
998 TRef tr, *base; 1001 TRef tr, *base;
999 cTValue *o; 1002 cTValue *o;
@@ -1002,9 +1005,9 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1002 TRef *arg0 = NULL, *arg1 = NULL; 1005 TRef *arg0 = NULL, *arg1 = NULL;
1003#endif 1006#endif
1004 int ngpr = 0; 1007 int ngpr = 0;
1005 if (ctype_cconv(ct->info) == CTCC_THISCALL) 1008 if (ctype_cconv(info) == CTCC_THISCALL)
1006 ngpr = 1; 1009 ngpr = 1;
1007 else if (ctype_cconv(ct->info) == CTCC_FASTCALL) 1010 else if (ctype_cconv(info) == CTCC_FASTCALL)
1008 ngpr = 2; 1011 ngpr = 2;
1009#endif 1012#endif
1010 1013
@@ -1029,7 +1032,7 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1029 lua_assert(ctype_isfield(ctf->info)); 1032 lua_assert(ctype_isfield(ctf->info));
1030 did = ctype_cid(ctf->info); 1033 did = ctype_cid(ctf->info);
1031 } else { 1034 } else {
1032 if (!(ct->info & CTF_VARARG)) 1035 if (!(info & CTF_VARARG))
1033 lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */ 1036 lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */
1034 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */ 1037 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */
1035 } 1038 }
@@ -1112,14 +1115,17 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1112{ 1115{
1113 CTState *cts = ctype_ctsG(J2G(J)); 1116 CTState *cts = ctype_ctsG(J2G(J));
1114 CType *ct = ctype_raw(cts, cd->ctypeid); 1117 CType *ct = ctype_raw(cts, cd->ctypeid);
1118 CTInfo info;
1115 IRType tp = IRT_PTR; 1119 IRType tp = IRT_PTR;
1116 if (ctype_isptr(ct->info)) { 1120 if (ctype_isptr(ct->info)) {
1117 tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; 1121 tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
1118 ct = ctype_rawchild(cts, ct); 1122 ct = ctype_rawchild(cts, ct);
1119 } 1123 }
1120 if (ctype_isfunc(ct->info)) { 1124 info = ct->info; /* crec_call_args may invalidate ct pointer. */
1125 if (ctype_isfunc(info)) {
1121 TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR); 1126 TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR);
1122 CType *ctr = ctype_rawchild(cts, ct); 1127 CType *ctr = ctype_rawchild(cts, ct);
1128 CTInfo ctr_info = ctr->info; /* crec_call_args may invalidate ctr. */
1123 IRType t = crec_ct2irt(cts, ctr); 1129 IRType t = crec_ct2irt(cts, ctr);
1124 TRef tr; 1130 TRef tr;
1125 TValue tv; 1131 TValue tv;
@@ -1128,22 +1134,22 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1128 cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4)); 1134 cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4));
1129 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv))) 1135 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv)))
1130 lj_trace_err(J, LJ_TRERR_BLACKL); 1136 lj_trace_err(J, LJ_TRERR_BLACKL);
1131 if (ctype_isvoid(ctr->info)) { 1137 if (ctype_isvoid(ctr_info)) {
1132 t = IRT_NIL; 1138 t = IRT_NIL;
1133 rd->nres = 0; 1139 rd->nres = 0;
1134 } else if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) || 1140 } else if (!(ctype_isnum(ctr_info) || ctype_isptr(ctr_info) ||
1135 ctype_isenum(ctr->info)) || t == IRT_CDATA) { 1141 ctype_isenum(ctr_info)) || t == IRT_CDATA) {
1136 lj_trace_err(J, LJ_TRERR_NYICALL); 1142 lj_trace_err(J, LJ_TRERR_NYICALL);
1137 } 1143 }
1138 if ((ct->info & CTF_VARARG) 1144 if ((info & CTF_VARARG)
1139#if LJ_TARGET_X86 1145#if LJ_TARGET_X86
1140 || ctype_cconv(ct->info) != CTCC_CDECL 1146 || ctype_cconv(info) != CTCC_CDECL
1141#endif 1147#endif
1142 ) 1148 )
1143 func = emitir(IRT(IR_CARG, IRT_NIL), func, 1149 func = emitir(IRT(IR_CARG, IRT_NIL), func,
1144 lj_ir_kint(J, ctype_typeid(cts, ct))); 1150 lj_ir_kint(J, ctype_typeid(cts, ct)));
1145 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func); 1151 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
1146 if (ctype_isbool(ctr->info)) { 1152 if (ctype_isbool(ctr_info)) {
1147 if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) { 1153 if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) {
1148 /* Don't check result if ignored. */ 1154 /* Don't check result if ignored. */
1149 tr = TREF_NIL; 1155 tr = TREF_NIL;
@@ -1159,8 +1165,8 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1159 tr = TREF_TRUE; 1165 tr = TREF_TRUE;
1160 } 1166 }
1161 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) || 1167 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
1162 t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) { 1168 t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr_info)) {
1163 TRef trid = lj_ir_kint(J, ctype_cid(ct->info)); 1169 TRef trid = lj_ir_kint(J, ctype_cid(info));
1164 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr); 1170 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
1165 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); 1171 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1166 } else if (t == IRT_FLOAT || t == IRT_U32) { 1172 } else if (t == IRT_FLOAT || t == IRT_U32) {