Inline-Lua
view release on metacpan or search on metacpan
ffi/target/release/build/mlua-sys-6a99a2ae50f12319/out/luajit-build/build/src/lj_parse.c view on Meta::CPAN
*ip = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*ip));
return bcemit_jmp(fs);
}
}
if (e->k != VNONRELOC) {
bcreg_reserve(fs, 1);
expr_toreg_nobranch(fs, e, fs->freereg-1);
}
bcemit_AD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info);
pc = bcemit_jmp(fs);
expr_free(fs, e);
return pc;
}
/* Emit branch on true condition. */
static void bcemit_branch_t(FuncState *fs, ExpDesc *e)
{
BCPos pc;
expr_discharge(fs, e);
if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE)
pc = NO_JMP; /* Never jump. */
else if (e->k == VJMP)
invertcond(fs, e), pc = e->u.s.info;
else if (e->k == VKFALSE || e->k == VKNIL)
expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs);
else
pc = bcemit_branch(fs, e, 0);
jmp_append(fs, &e->f, pc);
jmp_tohere(fs, e->t);
e->t = NO_JMP;
}
/* Emit branch on false condition. */
static void bcemit_branch_f(FuncState *fs, ExpDesc *e)
{
BCPos pc;
expr_discharge(fs, e);
if (e->k == VKNIL || e->k == VKFALSE)
pc = NO_JMP; /* Never jump. */
else if (e->k == VJMP)
pc = e->u.s.info;
else if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE)
expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs);
else
pc = bcemit_branch(fs, e, 1);
jmp_append(fs, &e->t, pc);
jmp_tohere(fs, e->f);
e->f = NO_JMP;
}
/* -- Bytecode emitter for operators -------------------------------------- */
/* Try constant-folding of arithmetic operators. */
static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2)
{
TValue o;
lua_Number n;
if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0;
n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD);
setnumV(&o, n);
if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */
if (LJ_DUALNUM) {
int32_t k = lj_num2int(n);
if ((lua_Number)k == n) {
setintV(&e1->u.nval, k);
return 1;
}
}
setnumV(&e1->u.nval, n);
return 1;
}
/* Emit arithmetic operator. */
static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
{
BCReg rb, rc, t;
uint32_t op;
if (foldarith(opr, e1, e2))
return;
if (opr == OPR_POW) {
op = BC_POW;
rc = expr_toanyreg(fs, e2);
rb = expr_toanyreg(fs, e1);
} else {
op = opr-OPR_ADD+BC_ADDVV;
/* Must discharge 2nd operand first since VINDEXED might free regs. */
expr_toval(fs, e2);
if (expr_isnumk(e2) && (rc = const_num(fs, e2)) <= BCMAX_C)
op -= BC_ADDVV-BC_ADDVN;
else
rc = expr_toanyreg(fs, e2);
/* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */
lj_assertFS(expr_isnumk(e1) || e1->k == VNONRELOC,
"bad expr type %d", e1->k);
expr_toval(fs, e1);
/* Avoid two consts to satisfy bytecode constraints. */
if (expr_isnumk(e1) && !expr_isnumk(e2) &&
(t = const_num(fs, e1)) <= BCMAX_B) {
rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV;
} else {
rb = expr_toanyreg(fs, e1);
}
}
/* Using expr_free might cause asserts if the order is wrong. */
if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--;
if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--;
e1->u.s.info = bcemit_ABC(fs, op, 0, rb, rc);
e1->k = VRELOCABLE;
}
/* Emit comparison operator. */
static void bcemit_comp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
{
ExpDesc *eret = e1;
BCIns ins;
expr_toval(fs, e1);
if (opr == OPR_EQ || opr == OPR_NE) {
BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV;
BCReg ra;
if (expr_isk(e1)) { e1 = e2; e2 = eret; } /* Need constant in 2nd arg. */
ra = expr_toanyreg(fs, e1); /* First arg must be in a reg. */
( run in 2.786 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )