void luaK_tostack (LexState *ls, expdesc *v, int onlyone) { FuncState *fs = ls->fs; if (!discharge(fs, v)) { /* `v' is an expression? */ OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]); if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) { /* expression has no jumps */ if (onlyone) luaK_setcallreturns(fs, 1); /* call must return 1 value */ } else { /* expression has jumps */ int final; /* position after whole expression */ int j = NO_JUMP; /* eventual jump over values */ int p_nil = NO_JUMP; /* position of an eventual PUSHNIL */ int p_1 = NO_JUMP; /* position of an eventual PUSHINT */ if (ISJUMP(previous) || need_value(fs, v->u.l.f, OP_JMPONF) || need_value(fs, v->u.l.t, OP_JMPONT)) { /* expression needs values */ if (ISJUMP(previous)) luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */ else { j = code_label(fs, OP_JMP, NO_JUMP); /* to jump over both pushes */ /* correct stack for compiler and symbolic execution */ luaK_adjuststack(fs, 1); } p_nil = code_label(fs, OP_PUSHNILJMP, 0); p_1 = code_label(fs, OP_PUSHINT, 1); luaK_patchlist(fs, j, luaK_getlabel(fs)); } final = luaK_getlabel(fs); luaK_patchlistaux(fs, v->u.l.f, p_nil, OP_JMPONF, final); luaK_patchlistaux(fs, v->u.l.t, p_1, OP_JMPONT, final); v->u.l.f = v->u.l.t = NO_JUMP; }
static void exp2reg (FuncState *fs, expdesc *e, int reg) { discharge2reg(fs, e, reg); if (e->k == VJMP) luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ if (hasjumps(e)) { int final; /* position after whole expression */ int p_f = NO_JUMP; /* position of an eventual LOAD false */ int p_t = NO_JUMP; /* position of an eventual LOAD true */ if (need_value(fs, e->t) || need_value(fs, e->f)) { int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); p_f = code_label(fs, reg, 0, 1); p_t = code_label(fs, reg, 1, 0); luaK_patchtohere(fs, fj); } final = luaK_getlabel(fs); patchlistaux(fs, e->f, final, reg, p_f); patchlistaux(fs, e->t, final, reg, p_t); }
static void exp2reg (FuncState *fs, expdesc *e, int reg) { discharge2reg(fs, e, reg); if (e->k == VJMP) luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ if (hasjumps(e)) { if (e->k != VJMP) luaK_goiftrue(fs, e); int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); int p_f = code_label(fs, reg, 0, 1); luaK_patchtohere(fs, fj); int p_t = code_label(fs, reg, 1, 0); patchlistaux(fs, e->f, p_f); patchlistaux(fs, e->t, p_t); } e->f = e->t = NO_JUMP; e->u.info = reg; e->k = VNONRELOC; }