diff options
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 32 |
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 | */ | ||
992 | static TRef crec_call_args(jit_State *J, RecordFFData *rd, | 994 | static 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) { |