예제 #1
0
 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);
 }
예제 #2
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);
 }
예제 #3
0
 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 */
     }
 }
예제 #4
0
 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);
     }
 }
예제 #5
0
 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);
 }
예제 #6
0
 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;
 }
예제 #7
0
 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);
     }
 }
예제 #8
0
 public static void luaY_checklimit(FuncState fs, int v, int l, CharPtr m)
 {
     if ((v) > (l)) errorlimit(fs, l, m);
 }
예제 #9
0
 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);
 }
예제 #10
0
 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);
 }
예제 #11
0
 public static LocVar getlocvar(FuncState fs, int i)
 {
     return fs.f.locvars[fs.actvar[i]];
 }
예제 #12
0
 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;
         }
     }
 }
예제 #13
0
 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;
 }
예제 #14
0
 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 */
 }
예제 #15
0
 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++;
 }