private static void errorlimit(FuncState fs, int limit, CharPtr what) { CharPtr msg = (fs.f.linedefined == 0) ? Lua.luaO_pushfstring(fs.L, "main function has more than %d %s", limit, what) : Lua.luaO_pushfstring(fs.L, "function at line %d has more than %d %s", fs.f.linedefined, limit, what); Lua.luaX_lexerror(fs.ls, msg, 0); }
private static void body(LexState ls, expdesc e, int needself, int line) { /* body . `(' parlist `)' chunk END */ FuncState new_fs = new FuncState(); open_func(ls, new_fs); new_fs.f.linedefined = line; checknext(ls, '('); if (needself != 0) { new_localvarliteral(ls, "self", 0); adjustlocalvars(ls, 1); } parlist(ls); checknext(ls, ')'); chunk(ls); new_fs.f.lastlinedefined = ls.linenumber; check_match(ls, (int)RESERVED.TK_END, (int)RESERVED.TK_FUNCTION, line); close_func(ls); pushclosure(ls, new_fs, e); }
private static void closelistfield(FuncState fs, ConsControl cc) { if (cc.v.k == expkind.VVOID) return; /* there is no list item */ Lua.luaK_exp2nextreg(fs, cc.v); cc.v.k = expkind.VVOID; if (cc.tostore == Lua.LFIELDS_PER_FLUSH) { Lua.luaK_setlist(fs, cc.t.u.s.info, cc.na, cc.tostore); /* flush */ cc.tostore = 0; /* no more items pending */ } }
private static void lastlistfield(FuncState fs, ConsControl cc) { if (cc.tostore == 0) return; if (hasmultret(cc.v.k) != 0) { Lua.luaK_setmultret(fs, cc.v); Lua.luaK_setlist(fs, cc.t.u.s.info, cc.na, Lua.LUA_MULTRET); cc.na--; /* do not count last expression (unknown number of elements) */ } else { if (cc.v.k != expkind.VVOID) Lua.luaK_exp2nextreg(fs, cc.v); Lua.luaK_setlist(fs, cc.t.u.s.info, cc.na, cc.tostore); } }
private static void open_func(LexState ls, FuncState fs) { LuaState L = ls.L; Proto f = Lua.luaF_newproto(L); fs.f = f; fs.prev = ls.fs; /* linked list of funcstates */ fs.ls = ls; fs.L = L; ls.fs = fs; fs.pc = 0; fs.lasttarget = -1; fs.jpc = Lua.NO_JUMP; fs.freereg = 0; fs.nk = 0; fs.np = 0; fs.nlocvars = 0; fs.nactvar = 0; fs.bl = null; f.source = ls.source; f.maxstacksize = 2; /* registers 0/1 are always valid */ fs.h = Lua.luaH_new(L, 0, 0); /* anchor table of constants and prototype (to avoid being collected) */ Lua.sethvalue2s(L, L.top, fs.h); Lua.incr_top(L); Lua.setptvalue2s(L, L.top, f); Lua.incr_top(L); }
public static Proto luaY_parser(LuaState L, ZIO z, Mbuffer buff, CharPtr name) { LexState lexstate = new LexState(); FuncState funcstate = new FuncState(); lexstate.buff = buff; Lua.luaX_setinput(L, lexstate, z, Lua.luaS_new(L, name)); open_func(lexstate, funcstate); funcstate.f.is_vararg = Lua.VARARG_ISVARARG; /* main func. is always vararg */ Lua.luaX_next(lexstate); /* read first token */ System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; chunk(lexstate); check(lexstate, (int)RESERVED.TK_EOS); close_func(lexstate); Lua.lua_assert(funcstate.prev == null); Lua.lua_assert(funcstate.f.nups == 0); Lua.lua_assert(lexstate.fs == null); return funcstate.f; }
private static void pushclosure(LexState ls, FuncState func, expdesc v) { FuncState fs = ls.fs; Proto f = fs.f; int oldsize = f.sizep; int i; Lua.luaM_growvector(ls.L, ref f.p, fs.np, ref f.sizep, Lua.MAXARG_Bx, "constant table overflow"); while (oldsize < f.sizep) f.p[oldsize++] = null; f.p[fs.np++] = func.f; Lua.luaC_objbarrier(ls.L, f, func.f); init_exp(v, expkind.VRELOCABLE, Lua.luaK_codeABx(fs, OpCode.OP_CLOSURE, 0, fs.np - 1)); for (i = 0; i < func.f.nups; i++) { OpCode o = ((int)func.upvalues[i].k == (int)expkind.VLOCAL) ? OpCode.OP_MOVE : OpCode.OP_GETUPVAL; Lua.luaK_codeABC(fs, o, 0, func.upvalues[i].info, 0); } }
public static void luaY_checklimit(FuncState fs, int v, int l, CharPtr m) { if ((v) > (l)) errorlimit(fs, l, m); }
private static void enterblock(FuncState fs, BlockCnt bl, lu_byte isbreakable) { bl.breaklist = Lua.NO_JUMP; bl.continuelist = Lua.NO_JUMP; bl.isbreakable = isbreakable; bl.nactvar = fs.nactvar; bl.upval = 0; bl.previous = fs.bl; fs.bl = bl; Lua.lua_assert(fs.freereg == fs.nactvar); }
private static void leaveblock(FuncState fs) { BlockCnt bl = fs.bl; fs.bl = bl.previous; removevars(fs.ls, bl.nactvar); if (bl.upval != 0) Lua.luaK_codeABC(fs, OpCode.OP_CLOSE, bl.nactvar, 0, 0); /* a block either controls scope or breaks (never both) */ Lua.lua_assert((bl.isbreakable == 0) || (bl.upval == 0)); Lua.lua_assert(bl.nactvar == fs.nactvar); fs.freereg = fs.nactvar; /* free registers */ Lua.luaK_patchtohere(fs, bl.breaklist); }
public static LocVar getlocvar(FuncState fs, int i) { return fs.f.locvars[fs.actvar[i]]; }
private static expkind singlevaraux(FuncState fs, TString n, expdesc var, int base_) { if (fs == null) { /* no more levels? */ init_exp(var, expkind.VGLOBAL, Lua.NO_REG); /* default is global variable */ return expkind.VGLOBAL; } else { int v = searchvar(fs, n); /* look up at current level */ if (v >= 0) { init_exp(var, expkind.VLOCAL, v); if (base_ == 0) markupval(fs, v); /* local will be used as an upval */ return expkind.VLOCAL; } else { /* not found at current level; try upper one */ if (singlevaraux(fs.prev, n, var, 0) == expkind.VGLOBAL) return expkind.VGLOBAL; var.u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ var.k = expkind.VUPVAL; /* upvalue in this level */ return expkind.VUPVAL; } } }
private static void markupval(FuncState fs, int level) { BlockCnt bl = fs.bl; while ((bl != null) && bl.nactvar > level) bl = bl.previous; if (bl != null) bl.upval = 1; }
private static int searchvar(FuncState fs, TString n) { int i; for (i = fs.nactvar - 1; i >= 0; i--) { if (n == getlocvar(fs, i).varname) return i; } return -1; /* not found */ }
private static int indexupvalue(FuncState fs, TString name, expdesc v) { int i; Proto f = fs.f; int oldsize = f.sizeupvalues; for (i = 0; i < f.nups; i++) { if ((int)fs.upvalues[i].k == (int)v.k && fs.upvalues[i].info == v.u.s.info) { Lua.lua_assert(f.upvalues[i] == name); return i; } } /* new one */ luaY_checklimit(fs, f.nups + 1, Lua.LUAI_MAXUPVALUES, "upvalues"); Lua.luaM_growvector(fs.L, ref f.upvalues, f.nups, ref f.sizeupvalues, Lua.MAX_INT, ""); while (oldsize < f.sizeupvalues) f.upvalues[oldsize++] = null; f.upvalues[f.nups] = name; Lua.luaC_objbarrier(fs.L, f, name); Lua.lua_assert(v.k == expkind.VLOCAL || v.k == expkind.VUPVAL); fs.upvalues[f.nups].k = Lua.cast_byte(v.k); fs.upvalues[f.nups].info = Lua.cast_byte(v.u.s.info); return f.nups++; }