static void discharge2reg(ktap_funcstate *fs, ktap_expdesc *e, int reg) { codegen_dischargevars(fs, e); switch (e->k) { case VNIL: { codegen_nil(fs, reg, 1); break; } case VFALSE: case VTRUE: { codegen_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); break; } case VEVENT: codegen_codeABC(fs, OP_EVENT, reg, 0, 0); break; case VEVENTNAME: codegen_codeABC(fs, OP_EVENTNAME, reg, 0, 0); break; case VEVENTARG: codegen_codeABC(fs, OP_EVENTARG, reg, e->u.info, 0); break; case VK: { codegen_codek(fs, reg, e->u.info); break; } case VKNUM: { codegen_codek(fs, reg, codegen_numberK(fs, e->u.nval)); break; } case VRELOCABLE: { ktap_instruction *pc = &getcode(fs, e); SETARG_A(*pc, reg); break; } case VNONRELOC: { if (reg != e->u.info) codegen_codeABC(fs, OP_MOVE, reg, e->u.info, 0); break; } default: ktap_assert(e->k == VVOID || e->k == VJMP); return; /* nothing to do... */ } e->u.info = reg; e->k = VNONRELOC; }
static void adjust_assign(ktap_lexstate *ls, int nvars, int nexps, ktap_expdesc *e) { ktap_funcstate *fs = ls->fs; int extra = nvars - nexps; if (hasmultret(e->k)) { extra++; /* includes call itself */ if (extra < 0) extra = 0; codegen_setreturns(fs, e, extra); /* last exp. provides the difference */ if (extra > 1) codegen_reserveregs(fs, extra-1); } else { if (e->k != VVOID) codegen_exp2nextreg(fs, e); /* close last expression */ if (extra > 0) { int reg = fs->freereg; codegen_reserveregs(fs, extra); codegen_nil(fs, reg, extra); } } }