/* ** Emit a "load constant" instruction, using either 'OP_LOADK' ** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX' ** instruction with "extra argument". */ int luaK_codek (FuncState *fs, int reg, int k) { if (k <= MAXARG_Bx) return luaK_codeABx(fs, OP_LOADK, reg, k); else { int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); codeextraarg(fs, k); return p; } }
int FuncState::luaK_codek (/*FuncState *fs,*/ int reg, int k) { if (k <= MAXARG_Bx) return luaK_codeABx(OP_LOADK, reg, k); else { int p = luaK_codeABx(OP_LOADKX, reg, 0); codeextraarg(k); return p; } }
int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k) { if (k < MAXARG_Bx) return luaK_codeABx(fs, o, reg, k + 1); else { int p = luaK_codeABx(fs, o, reg, 0); codeextraarg(fs, k); return p; } }
static void lastlistfield (FuncState *fs, struct ConsControl *cc) { if (cc->tostore == 0) return; if (cc->v.k == VCALL) { luaK_setcallreturns(fs, &cc->v, LUA_MULTRET); luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1); } else { if (cc->v.k != VVOID) luaK_exp2nextreg(fs, &cc->v); luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); } fs->freereg = cc->t->info + 1; /* free registers */ }
void luaK_dischargevars (FuncState *fs, expdesc *e) { switch (e->k) { case VLOCAL: { e->k = VNONRELOC; break; } case VUPVAL: { e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); e->k = VRELOCABLE; break; } case VGLOBAL: { e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); e->k = VRELOCABLE; break; } case VINDEXED: { freereg(fs, e->u.s.aux); freereg(fs, e->u.s.info); e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); e->k = VRELOCABLE; break; } case VVARARG: case VCALL: { luaK_setoneret(fs, e); break; } default: break; /* there is one value available (somewhere) */ } }
static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { FuncState *fs = ls->fs; Proto *f = fs->f; int oldsize = f->sizep; int i; #if LUA_MEMORY_STATS luaM_setname(ls->L, "lua.parser.closures"); #endif /* LUA_MEMORY_STATS */ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "constant table overflow"); #if LUA_MEMORY_STATS luaM_setname(ls->L, 0); #endif /* LUA_MEMORY_STATS */ while (oldsize < f->sizep) f->p[oldsize++] = NULL; f->p[fs->np++] = func->f; #if LUA_REFCOUNT /* already got a reference */ /* luarc_addrefproto(func->f); */ #endif /* LUA_REFCOUNT */ luaC_objbarrier(ls->L, f, func->f); init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); for (i=0; i<func->f->nups; i++) { OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); } }
static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { FuncState *fs = GetCurrentFuncState( ls ); Proto *f = fs->f; int oldsize = f->sizep; luaM_growvector(ls->L, f->p, fs->np, f->sizep, MAXARG_Bx, "constant table overflow"); while ( oldsize < f->sizep ) { f->p[ oldsize++ ] = NULL; } f->p[ fs->np++ ] = func->f; luaC_objbarrier( ls->L, f, func->f ); init_exp( v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1) ); for ( int i = 0; i < func->f->nups; i++ ) { OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); } }
static void fornum (LexState *ls, TString *varname, int line) { /* fornum -> NAME = exp1,exp1[,exp1] forbody */ FuncState *fs = GetCurrentFuncState( ls ); int base = fs->freereg; new_localvarliteral(ls, "(for index)", 0); new_localvarliteral(ls, "(for limit)", 1); new_localvarliteral(ls, "(for step)", 2); new_localvar(ls, varname, 3); checknext(ls, '='); exp1(ls); /* initial value */ checknext(ls, ','); exp1(ls); /* limit */ if (testnext(ls, ',')) { exp1(ls); /* optional step */ } else { /* default step = 1 */ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); luaK_reserveregs(fs, 1); } forbody(ls, base, line, 1, 1); }
static void discharge2reg (FuncState *fs, expdesc *e, int reg) { luaK_dischargevars(fs, e); switch (e->k) { case VNIL: { luaK_nil(fs, reg, 1); break; } case VFALSE: case VTRUE: { luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); break; } case VK: { luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); break; } case VKNUM: { luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); break; } case VKINT: { luaK_codeABx(fs, OP_LOADK, reg, luaK_integerK(fs, e->u.ival)); break; } #ifdef LNUM_COMPLEX case VKNUM2: { luaK_codeABx(fs, OP_LOADK, reg, luaK_imagK(fs, e->u.nval)); break; } #endif case VRELOCABLE: { Instruction *pc = &getcode(fs, e); SETARG_A(*pc, reg); break; } case VNONRELOC: { if (reg != e->u.s.info) luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); break; } default: { lua_assert(e->k == VVOID || e->k == VJMP); return; /* nothing to do... */ } } e->u.s.info = reg; e->k = VNONRELOC; }
static void closelistfield (FuncState *fs, struct ConsControl *cc) { if (cc->v.k == VVOID) return; /* there is no list item */ luaK_exp2nextreg(fs, &cc->v); cc->v.k = VVOID; if (cc->tostore == LFIELDS_PER_FLUSH) { luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */ cc->tostore = 0; /* no more items pending */ fs->freereg = cc->t->info + 1; /* free registers */ } }
static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { FuncState *fs = ls->fs; Proto *f = fs->f; int i; luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "constant table overflow"); f->p[fs->np++] = func->f; init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); for (i=0; i<func->f->nups; i++) { OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); } }
static void fornum (LexState *ls, TString *varname, int line) { /* fornum -> NAME = exp1,exp1[,exp1] DO body */ FuncState *fs = ls->fs; int base = fs->freereg; new_localvar(ls, varname, 0); new_localvarstr(ls, "(for limit)", 1); new_localvarstr(ls, "(for step)", 2); check(ls, '='); exp1(ls); /* initial value */ check(ls, ','); exp1(ls); /* limit */ if (testnext(ls, ',')) exp1(ls); /* optional step */ else { /* default step = 1 */ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); luaK_reserveregs(fs, 1); } luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1); luaK_jump(fs); forbody(ls, base, line, 3, 1); }
/* ** adds prototype being created into its parent list of prototypes ** and codes instruction to create new closure */ static void codeclosure (LexState *ls, Proto *clp, expdesc *v) { FuncState *fs = ls->fs->prev; Proto *f = fs->f; /* prototype of function creating new closure */ if (fs->np >= f->sizep) { int oldsize = f->sizep; luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); while (oldsize < f->sizep) f->p[oldsize++] = NULL; } f->p[fs->np++] = clp; luaC_objbarrier(ls->L, f, clp); init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); luaK_exp2nextreg(fs, v); /* fix it at stack top (for GC) */ } static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { lua_State *L = ls->L; Proto *f; fs->prev = ls->fs; /* linked list of funcstates */ fs->ls = ls; ls->fs = fs; fs->pc = 0; fs->lasttarget = 0; fs->jpc = NO_JUMP; fs->freereg = 0; fs->nk = 0;
int FuncState::luaK_codeAsBx(OpCode o, int A, unsigned int sBx) { return luaK_codeABx(o,A,(sBx)+MAXARG_sBx); }