LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J);
LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J);
LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_tab_len(jit_State *J);
+LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_hrefk(jit_State *J);
LJ_FUNC int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J);
LJ_FUNC int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim);
LJ_FUNC int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref);
/* Some local macros to save typing. Undef'd at the end. */
#define IR(ref) (&J->cur.ir[(ref)])
#define fins (&J->fold.ins)
+#define fleft (&J->fold.left)
#define fright (&J->fold.right)
/*
return EMITFOLD;
}
+/* HREFK forwarding. */
+TRef LJ_FASTCALL lj_opt_fwd_hrefk(jit_State *J)
+{
+ IRRef tab = fleft->op1;
+ IRRef ref = J->chain[IR_NEWREF];
+ while (ref > tab) {
+ IRIns *newref = IR(ref);
+ if (tab == newref->op1) {
+ if (fright->op1 == newref->op2)
+ return ref; /* Forward from NEWREF. */
+ else
+ goto docse;
+ } else if (aa_table(J, tab, newref->op1) != ALIAS_NO) {
+ goto docse;
+ }
+ ref = newref->prev;
+ }
+ /* No conflicting NEWREF: key location unchanged for HREFK of TDUP. */
+ if (IR(tab)->o == IR_TDUP)
+ fins->t.irt &= ~IRT_GUARD; /* Drop HREFK guard. */
+docse:
+ return CSEFOLD;
+}
+
/* Check whether HREF of TNEW/TDUP can be folded to niltv. */
int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J)
{
#undef IR
#undef fins
+#undef fleft
#undef fright
#endif