From e6e760ca9f021703551d2093697908644ab76829 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Wed, 9 Oct 2013 20:34:40 +0200 Subject: [PATCH] Compile getfenv(0). --- src/lib_base.c | 2 +- src/lj_asm.c | 13 ++++++++++++- src/lj_ffrecord.c | 13 +++++++++++++ src/lj_ir.h | 2 ++ src/lj_opt_fold.c | 3 +++ 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/lib_base.c b/src/lib_base.c index 1665faee..a19926a7 100644 --- a/src/lib_base.c +++ b/src/lib_base.c @@ -136,7 +136,7 @@ LJLIB_ASM(setmetatable) LJLIB_REC(.) return FFH_RES(1); } -LJLIB_CF(getfenv) +LJLIB_CF(getfenv) LJLIB_REC(.) { GCfunc *fn; cTValue *o = L->base; diff --git a/src/lj_asm.c b/src/lj_asm.c index 0d6875a6..fb364c74 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -699,7 +699,7 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref) emit_loadu64(as, dest, ir_kint64(ir)->u64); return; #endif - } else { + } else if (ir->o != IR_KPRI) { lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL); emit_loadi(as, dest, ir->i); @@ -1191,6 +1191,16 @@ static void asm_newref(ASMState *as, IRIns *ir) asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2); } +static void asm_lref(ASMState *as, IRIns *ir) +{ + Reg r = ra_dest(as, ir, RSET_GPR); +#if LJ_TARGET_X86ORX64 + ra_left(as, r, ASMREF_L); +#else + ra_leftov(as, r, ASMREF_L); +#endif +} + /* -- Calls --------------------------------------------------------------- */ /* Collect arguments from CALL* and CARG instructions. */ @@ -1624,6 +1634,7 @@ static void asm_ir(ASMState *as, IRIns *ir) case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break; case IR_FREF: asm_fref(as, ir); break; case IR_STRREF: asm_strref(as, ir); break; + case IR_LREF: asm_lref(as, ir); break; /* Loads and stores. */ case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD: diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 29916e71..de74a3ec 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c @@ -422,6 +422,19 @@ static void LJ_FASTCALL recff_xpcall(jit_State *J, RecordFFData *rd) } /* else: Interpreter will throw. */ } +static void LJ_FASTCALL recff_getfenv(jit_State *J, RecordFFData *rd) +{ + TRef tr = J->base[0]; + /* Only support getfenv(0) for now. */ + if (tref_isint(tr) && tref_isk(tr) && IR(tref_ref(tr))->i == 0) { + TRef trl = emitir(IRT(IR_LREF, IRT_THREAD), 0, 0); + J->base[0] = emitir(IRT(IR_FLOAD, IRT_TAB), trl, IRFL_THREAD_ENV); + return; + } + recff_nyiu(J); + UNUSED(rd); +} + /* -- Math library fast functions ----------------------------------------- */ static void LJ_FASTCALL recff_math_abs(jit_State *J, RecordFFData *rd) diff --git a/src/lj_ir.h b/src/lj_ir.h index f50132ea..bd2723cd 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -97,6 +97,7 @@ _(UREFC, LW, ref, lit) \ _(FREF, R , ref, lit) \ _(STRREF, N , ref, ref) \ + _(LREF, L , ___, ___) \ \ /* Loads and Stores. These must be in the same order. */ \ _(ALOAD, L , ref, ___) \ @@ -193,6 +194,7 @@ IRFPMDEF(FPMENUM) _(STR_LEN, offsetof(GCstr, len)) \ _(FUNC_ENV, offsetof(GCfunc, l.env)) \ _(FUNC_PC, offsetof(GCfunc, l.pc)) \ + _(THREAD_ENV, offsetof(lua_State, env)) \ _(TAB_META, offsetof(GCtab, metatable)) \ _(TAB_ARRAY, offsetof(GCtab, array)) \ _(TAB_NODE, offsetof(GCtab, node)) \ diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 2ca04a69..a3c8723b 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -2104,6 +2104,7 @@ LJFOLDF(fwd_href_tdup) ** an aliased table, as it may invalidate all of the pointers and fields. ** Only HREF needs the NEWREF check -- AREF and HREFK already depend on ** FLOADs. And NEWREF itself is treated like a store (see below). +** LREF is constant (per trace) since coroutine switches are not inlined. */ LJFOLD(FLOAD TNEW IRFL_TAB_ASIZE) LJFOLDF(fload_tab_tnew_asize) @@ -2221,6 +2222,8 @@ LJFOLDF(fload_cdata_ptr_int64_cnew) } LJFOLD(FLOAD any IRFL_STR_LEN) +LJFOLD(FLOAD any IRFL_FUNC_ENV) +LJFOLD(FLOAD any IRFL_THREAD_ENV) LJFOLD(FLOAD any IRFL_CDATA_CTYPEID) LJFOLD(FLOAD any IRFL_CDATA_PTR) LJFOLD(FLOAD any IRFL_CDATA_INT)