diff options
-rw-r--r-- | src/lj_crecord.c | 38 |
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 | */ | ||
311 | static 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 | |||
307 | void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) | 328 | void 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)) { |