aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_crecord.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index d6be897e..0d8c02a5 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -304,6 +304,27 @@ doconv:
304 304
305/* -- C data metamethods -------------------------------------------------- */ 305/* -- C data metamethods -------------------------------------------------- */
306 306
307/* This would be rather difficult in FOLD, so do it here:
308** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k)
309** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz)
310*/
311static TRef crec_reassoc_ofs(jit_State *J, TRef tr, ptrdiff_t *ofsp, MSize sz)
312{
313 IRIns *ir = IR(tref_ref(tr));
314 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) &&
315 ir->o == IR_ADD && irref_isk(ir->op2)) {
316 IRIns *irk = IR(ir->op2);
317 tr = ir->op1;
318#if LJ_64
319 if (irk->o == IR_KINT64)
320 *ofsp += (ptrdiff_t)ir_kint64(irk)->u64 * sz;
321 else
322#endif
323 *ofsp += (ptrdiff_t)irk->i * sz;
324 }
325 return tr;
326}
327
307void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) 328void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
308{ 329{
309 TRef idx, ptr = J->base[0]; 330 TRef idx, ptr = J->base[0];
@@ -333,22 +354,9 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
333#endif 354#endif
334 if (ctype_ispointer(ct->info)) { 355 if (ctype_ispointer(ct->info)) {
335 ptrdiff_t sz = (ptrdiff_t)lj_ctype_size(cts, (sid = ctype_cid(ct->info))); 356 ptrdiff_t sz = (ptrdiff_t)lj_ctype_size(cts, (sid = ctype_cid(ct->info)));
336 IRIns *ir = IR(tref_ref(idx)); 357 idx = crec_reassoc_ofs(J, idx, &ofs, sz);
337 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) &&
338 ir->o == IR_ADD && irref_isk(ir->op2)) {
339 IRIns *irk = IR(ir->op2);
340 idx = ir->op1;
341 /* This would be rather difficult in FOLD, so do it here:
342 ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz)
343 */
344#if LJ_64
345 if (irk->o == IR_KINT64)
346 ofs += (ptrdiff_t)ir_kint64(irk)->u64 * sz;
347 else
348#endif
349 ofs += (ptrdiff_t)irk->i * sz;
350 }
351 idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz)); 358 idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz));
359 ptr = crec_reassoc_ofs(J, ptr, &ofs, 1);
352 ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr); 360 ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr);
353 } 361 }
354 } else if (tref_isstr(idx)) { 362 } else if (tref_isstr(idx)) {