/* local addr, mcode, mfmiter = jit.util.mcode(func, block) */ static int ju_mcode(lua_State *L) { Proto *pt = check_LCL(L)->l.p; if (pt->jit_szmcode == 0) { /* Not compiled (yet): return nil, status. */ lua_pushnil(L); lua_pushinteger(L, pt->jit_status); return 2; } else { jit_Mfm *mfm; jit_MCTrailer tr; int block = luaL_checkint(L, 2); tr.mcode = (char *)pt->jit_mcode; tr.sz = pt->jit_szmcode; while (--block > 0) { memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz), sizeof(jit_MCTrailer)); if (tr.sz == 0) return 0; } mfm = JIT_MCMFM(tr.mcode, tr.sz); while (*mfm != JIT_MFM_STOP) mfm--; /* Search for end of mcode. */ lua_pushnumber(L, (lua_Number)(size_t)tr.mcode); lua_pushlstring(L, (const char *)tr.mcode, (char *)mfm-(char *)tr.mcode); lua_pushlightuserdata(L, (void *)JIT_MCMFM(tr.mcode, tr.sz)); lua_pushvalue(L, 1); /* Must hold onto function to avoid GC. */ lua_pushcclosure(L, ju_mfmiter, 2); return 3; } }
/* Note: the function itself is _not_ compiled (use jit.compile()). */ static int j_compilesub(lua_State *L) { Closure *cl = check_LCL(L); int stoponerror = lua_toboolean(L, 2); /* Stop on first error? */ lua_settop(L, 2); return compstatus(L, rec_compile(L, cl->l.p, cl->l.env, stoponerror)); }
/* local op, a, b, c, test = jit.util.bytecode(func, pc) */ static int ju_bytecode(lua_State *L) { Proto *pt = check_LCL(L)->l.p; int pc = luaL_checkint(L, 2); if (pc >= 1 && pc <= pt->sizecode) { Instruction ins = pt->code[pc-1]; OpCode op = GET_OPCODE(ins); if (pc > 1 && (((int)OP_SETLIST) << POS_OP) == (pt->code[pc-2] & (MASK1(SIZE_OP,POS_OP) | MASK1(SIZE_C,POS_C)))) { lua_pushstring(L, luaP_opnames[OP_SETLIST]); lua_pushnumber(L, (lua_Number)ins); /* Fake extended op. */ return 1; } if (op >= NUM_OPCODES) return 0; /* Just in case. */ lua_pushstring(L, luaP_opnames[op]); lua_pushinteger(L, GETARG_A(ins)); switch (getOpMode(op)) { case iABC: { int b = GETARG_B(ins), c = GETARG_C(ins); switch (getBMode(op)) { case OpArgN: lua_pushnil(L); break; case OpArgK: if (ISK(b)) b = -1-INDEXK(b); case OpArgR: case OpArgU: lua_pushinteger(L, b); break; } switch (getCMode(op)) { case OpArgN: lua_pushnil(L); break; case OpArgK: if (ISK(c)) c = -1-INDEXK(c); case OpArgR: case OpArgU: lua_pushinteger(L, c); break; } lua_pushboolean(L, testTMode(op)); return 5; } case iABx: { int bx = GETARG_Bx(ins); lua_pushinteger(L, getBMode(op) == OpArgK ? -1-bx : bx); return 3; } case iAsBx: lua_pushinteger(L, GETARG_sBx(ins)); return 3; } } return 0; }
/* local nup = jit.util.closurenup(func, idx) */ static int ju_closurenup(lua_State *L) { Closure *cl = check_LCL(L); Proto *pt = cl->l.p; int idx = luaL_checkint(L, 2); if (idx >= 0 && idx < pt->sizep) { lua_pushinteger(L, pt->p[idx]->nups); return 1; } return 0; }
/* local upvalue, ok = jit.util.upvalue(func, idx) */ static int ju_upvalue(lua_State *L) { Closure *cl = check_LCL(L); Proto *pt = cl->l.p; int idx = luaL_checkint(L, 2); if (idx >= 0 && idx < pt->nups) { setobj2s(L, L->top-1, cl->l.upvals[idx]->v); lua_pushboolean(L, 1); return 2; } lua_pushnil(L); lua_pushboolean(L, 0); return 2; }
/* local const, ok = jit.util.const(func, idx) */ static int ju_const(lua_State *L) { Proto *pt = check_LCL(L)->l.p; int idx = luaL_checkint(L, 2); if (idx < 0) idx = -idx; /* Handle both positive and negative indices. */ if (idx >= 1 && idx <= pt->sizek) { setobj2s(L, L->top-1, &pt->k[idx-1]); lua_pushboolean(L, 1); return 2; } lua_pushnil(L); lua_pushboolean(L, 0); return 2; }