Example #1
0
		public FuncState()
		{
			Proto = new LuaProto();
			H = new Dictionary<TValue, int>();
			NumActVar = 0;
			FreeReg = 0;
		}
Example #2
0
 private void DumpUpvalues(LuaProto proto)
 {
     DumpVector(proto.Upvalues, (upval) => {
         DumpByte(upval.InStack ? (byte)1 : (byte)0);
         DumpByte((byte)upval.Index);
     });
 }
Example #3
0
 public FuncState()
 {
     Proto     = new LuaProto();
     H         = new Dictionary <TValue, int>();
     NumActVar = 0;
     FreeReg   = 0;
 }
Example #4
0
        private void FuncInfo(LuaDebug ar, StkId func)
        {
            Utl.Assert(func.V.TtIsFunction());
            if (func.V.ClIsLuaClosure())
            {
                LuaLClosureValue lcl = func.V.ClLValue();
                LuaProto         p   = lcl.Proto;
                ar.Source          = string.IsNullOrEmpty(p.Source) ? "=?" : p.Source;
                ar.LineDefined     = p.LineDefined;
                ar.LastLineDefined = p.LastLineDefined;
                ar.What            = (ar.LineDefined == 0) ? "main" : "Lua";
            }
            else if (func.V.ClIsCsClosure())
            {
                ar.Source          = "=[C#]";
                ar.LineDefined     = -1;
                ar.LastLineDefined = -1;
                ar.What            = "C#";
            }
            else
            {
                throw new System.NotImplementedException();
            }

            if (ar.Source.Length > LuaDef.LUA_IDSIZE)
            {
                ar.ShortSrc = ar.Source.Substring(0, LuaDef.LUA_IDSIZE);
            }
            else
            {
                ar.ShortSrc = ar.Source;
            }
        }
Example #5
0
 private void CollectValidLines(StkId func)
 {
     Utl.Assert(func.V.TtIsFunction());
     if (func.V.ClIsLuaClosure())
     {
         LuaLClosureValue lcl      = func.V.ClLValue();
         LuaProto         p        = lcl.Proto;
         List <int>       lineinfo = p.LineInfo;
         LuaTable         t        = new LuaTable(this);
         Top.V.SetHValue(t);
         IncrTop();
         TValue v = new TValue();
         v.SetBValue(true);
         for (int i = 0; i < lineinfo.Count; ++i)
         {
             t.SetInt(lineinfo[i], ref v);
         }
     }
     else if (func.V.ClIsCsClosure())
     {
         Top.V.SetNilValue();
         IncrTop();
     }
     else
     {
         throw new System.NotImplementedException();
     }
 }
Example #6
0
        private void DumpConstants(LuaProto proto)
        {
            DumpVector(proto.K, (k) => {
                var t = k.V.Tt;
                DumpByte((byte)t);
                switch (t)
                {
                case (int)LuaType.LUA_TNIL:
                    break;

                case (int)LuaType.LUA_TBOOLEAN:
                    DumpBool(k.V.BValue());
                    break;

                case (int)LuaType.LUA_TNUMBER:
                    DumpBlock(BitConverter.GetBytes(k.V.NValue));
                    break;

                case (int)LuaType.LUA_TSTRING:
                    DumpString(k.V.SValue());
                    break;

                default:
                    Utl.Assert(false);
                    break;
                }
            });

            DumpVector(proto.P, (p) => {
                DumpFunction(p);
            });
        }
Example #7
0
        private int AdjustVarargs(LuaProto p, int actual)
        {
            // 有 `...' 的情况
            // 调用前: func (base)fixed-p1 fixed-p2 var-p1 var-p2 top
            // 调用后: func nil            nil      var-p1 var-p2 (base)fixed-p1 fixed-p2 (reserved...) top
            //
            // 没有 `...' 的情况
            // func (base)fixed-p1 fixed-p2 (reserved...) top

            int NumFixArgs = p.NumParams;

            Utl.Assert(actual >= NumFixArgs, "AdjustVarargs (actual >= NumFixArgs) is false");

            int fixedArg  = Top.Index - actual; // first fixed argument
            int stackBase = Top.Index;          // final position of first argument

            for (int i = stackBase; i < stackBase + NumFixArgs; ++i)
            {
                Stack[i].V.SetObj(ref Stack[fixedArg].V);
                Stack[fixedArg++].V.SetNilValue();
            }

            Top = Stack[stackBase + NumFixArgs];
            return(stackBase);
        }
Example #8
0
        private string GetFuncName(CallInfo ci, out string name)
        {
            LuaProto    proto = GetCurrentLuaFunc(ci).Proto; // calling function
            int         pc    = ci.CurrentPc;                // calling instruction index
            Instruction ins   = proto.Code[pc];              // calling instruction

            TMS tm;

            switch (ins.GET_OPCODE())
            {
            case OpCode.OP_CALL:
            case OpCode.OP_TAILCALL:                      /* get function name */
                return(GetObjName(proto, pc, ins.GETARG_A(), out name));

            case OpCode.OP_TFORCALL: {                      /* for iterator */
                name = "for iterator";
                return("for iterator");
            }

            /* all other instructions can call only through metamethods */
            case OpCode.OP_SELF:
            case OpCode.OP_GETTABUP:
            case OpCode.OP_GETTABLE: tm = TMS.TM_INDEX; break;

            case OpCode.OP_SETTABUP:
            case OpCode.OP_SETTABLE: tm = TMS.TM_NEWINDEX; break;

            case OpCode.OP_EQ: tm = TMS.TM_EQ; break;

            case OpCode.OP_ADD: tm = TMS.TM_ADD; break;

            case OpCode.OP_SUB: tm = TMS.TM_SUB; break;

            case OpCode.OP_MUL: tm = TMS.TM_MUL; break;

            case OpCode.OP_DIV: tm = TMS.TM_DIV; break;

            case OpCode.OP_MOD: tm = TMS.TM_MOD; break;

            case OpCode.OP_POW: tm = TMS.TM_POW; break;

            case OpCode.OP_UNM: tm = TMS.TM_UNM; break;

            case OpCode.OP_LEN: tm = TMS.TM_LEN; break;

            case OpCode.OP_LT: tm = TMS.TM_LT; break;

            case OpCode.OP_LE: tm = TMS.TM_LE; break;

            case OpCode.OP_CONCAT: tm = TMS.TM_CONCAT; break;

            default:
                name = null;
                return(null);                         /* else no useful name can be found */
            }

            name = GetTagMethodName(tm);
            return("metamethod");
        }
Example #9
0
        private void LoadConstants(LuaProto proto)
        {
            var n = LoadInt();

#if DEBUG_UNDUMP
            ClientLog.Instance.Log("Load Constants:" + n);
#endif
            proto.K.Clear();
            for (int i = 0; i < n; ++i)
            {
                int t = (int)LoadByte();
#if DEBUG_UNDUMP
                ClientLog.Instance.Log("Constant Type:" + t);
#endif
                var v = new StkId();
                switch (t)
                {
                case (int)LuaType.LUA_TNIL:
                    v.V.SetNilValue();
                    proto.K.Add(v);
                    break;

                case (int)LuaType.LUA_TBOOLEAN:
                    v.V.SetBValue(LoadBoolean());
                    proto.K.Add(v);
                    break;

                case (int)LuaType.LUA_TNUMBER:
                    v.V.SetNValue(LoadNumber());
                    proto.K.Add(v);
                    break;

                case (int)LuaType.LUA_TSTRING:
#if DEBUG_UNDUMP
                    ClientLog.Instance.Log("LuaType.LUA_TSTRING");
#endif
                    v.V.SetSValue(LoadString());
                    proto.K.Add(v);
                    break;

                default:
                    throw new UndumpException(
                              "LoadConstants unknown type: " + t);
                }
            }

            n = LoadInt();
#if DEBUG_UNDUMP
            ClientLog.Instance.Log("Load Functions:" + n);
#endif
            proto.P.Clear();
            for (int i = 0; i < n; ++i)
            {
                proto.P.Add(LoadFunction());
            }
        }
Example #10
0
        public LuaLClosureValue(LuaProto p)
        {
            Proto = p;

            Upvals = new LuaUpvalue[p.Upvalues.Count];
            for (int i = 0; i < p.Upvalues.Count; ++i)
            {
                Upvals[i] = new LuaUpvalue();
            }
        }
Example #11
0
 private void DumpFunction(LuaProto proto)
 {
     DumpInt(proto.LineDefined);
     DumpInt(proto.LastLineDefined);
     DumpByte((byte)proto.NumParams);
     DumpByte(proto.IsVarArg ? (byte)1 : (byte)0);
     DumpByte((byte)proto.MaxStackSize);
     DumpCode(proto);
     DumpConstants(proto);
     DumpUpvalues(proto);
     DumpDebug(proto);
 }
Example #12
0
 private string F_GetLocalName( LuaProto proto, int localNumber, int pc )
 {
     for( int i=0;
         i<proto.LocVars.Count && proto.LocVars[i].StartPc <= pc;
         ++i )
     {
         if( pc < proto.LocVars[i].EndPc ) { // is variable active?
             --localNumber;
             if( localNumber == 0 )
                 return proto.LocVars[i].VarName;
         }
     }
     return null;
 }
Example #13
0
        public static DumpStatus Dump(
            LuaProto proto, LuaWriter writer, bool strip)
        {
            var d = new DumpState();

            d.Writer = writer;
            d.Strip  = strip;
            d.Status = DumpStatus.OK;

            d.DumpHeader();
            d.DumpFunction(proto);

            return(d.Status);
        }
Example #14
0
        private void LoadCode(LuaProto proto)
        {
            var n = LoadInt();

#if DEBUG_UNDUMP
            ClientLog.Instance.Log("LoadCode n:" + n);
#endif
            proto.Code.Clear();
            for (int i = 0; i < n; ++i)
            {
                proto.Code.Add(LoadInstruction());
#if DEBUG_UNDUMP
                ClientLog.Instance.Log("Count:" + proto.Code.Count);
                ClientLog.Instance.Log("LoadInstruction:" + proto.Code[proto.Code.Count - 1]);
#endif
            }
        }
Example #15
0
        private void LoadUpvalues(LuaProto proto)
        {
            int n = LoadInt();

#if DEBUG_UNDUMP
            ULDebug.Log("Load Upvalues:" + n);
#endif
            proto.Upvalues.Clear();
            for (int i = 0; i < n; ++i)
            {
                UpvalDesc upvalDesc = new UpvalDesc();
                upvalDesc.Name    = null;
                upvalDesc.InStack = LoadBoolean();
                upvalDesc.Index   = (int)LoadByte();
                proto.Upvalues.Add(upvalDesc);
            }
        }
Example #16
0
        private void LoadCode(LuaProto proto)
        {
            int n = LoadInt();

#if DEBUG_UNDUMP
            ULDebug.Log("LoadCode n:" + n);
#endif
            proto.Code.Clear();
            for (int i = 0; i < n; ++i)
            {
                proto.Code.Add(LoadInstruction());
#if DEBUG_UNDUMP
                ULDebug.Log("Count:" + proto.Code.Count);
                ULDebug.Log("LoadInstruction:" + proto.Code[proto.Code.Count - 1]);
#endif
            }
        }
Example #17
0
 private string F_GetLocalName(LuaProto proto, int localNumber, int pc)
 {
     for (int i = 0;
          i < proto.LocVars.Count && proto.LocVars[i].StartPc <= pc;
          ++i)
     {
         if (pc < proto.LocVars[i].EndPc)                    // is variable active?
         {
             --localNumber;
             if (localNumber == 0)
             {
                 return(proto.LocVars[i].VarName);
             }
         }
     }
     return(null);
 }
Example #18
0
        private void DumpDebug(LuaProto proto)
        {
            DumpString(Strip ? null : proto.Source);

            DumpVector((Strip ? null : proto.LineInfo), delegate(int line) {
                DumpInt(line);
            });

            DumpVector((Strip ? null : proto.LocVars), delegate(LocVar locvar) {
                DumpString(locvar.VarName);
                DumpInt(locvar.StartPc);
                DumpInt(locvar.EndPc);
            });

            DumpVector((Strip ? null : proto.Upvalues), delegate(UpvalDesc upval) {
                DumpString(upval.Name);
            });
        }
Example #19
0
        private void DumpDebug(LuaProto proto)
        {
            DumpString(Strip ? null : proto.Source);

            DumpVector((Strip ? null : proto.LineInfo), (line) => {
                DumpInt(line);
            });

            DumpVector((Strip ? null : proto.LocVars), (locvar) => {
                DumpString(locvar.VarName);
                DumpInt(locvar.StartPc);
                DumpInt(locvar.EndPc);
            });

            DumpVector((Strip ? null : proto.Upvalues), (upval) => {
                DumpString(upval.Name);
            });
        }
Example #20
0
        private LuaProto LoadFunction()
        {
#if DEBUG_UNDUMP
            ClientLog.Instance.Log("LoadFunction enter");
#endif

            LuaProto proto = new LuaProto();
            proto.LineDefined     = LoadInt();
            proto.LastLineDefined = LoadInt();
            proto.NumParams       = LoadByte();
            proto.IsVarArg        = LoadBoolean();
            proto.MaxStackSize    = LoadByte();

            LoadCode(proto);
            LoadConstants(proto);
            LoadUpvalues(proto);
            LoadDebug(proto);
            return(proto);
        }
Example #21
0
        private void LoadUpvalues(LuaProto proto)
        {
            var n = LoadInt();

#if DEBUG_UNDUMP
            ClientLog.Instance.Log("Load Upvalues:" + n);
#endif
            proto.Upvalues.Clear();
            for (int i = 0; i < n; ++i)
            {
                proto.Upvalues.Add(
                    new UpvalDesc()
                {
                    Name    = null,
                    InStack = LoadBoolean(),
                    Index   = (int)LoadByte()
                });
            }
        }
Example #22
0
        private void LoadDebug(LuaProto proto)
        {
            int n;

            proto.Source = LoadString();

            // LineInfo
            n = LoadInt();
#if DEBUG_UNDUMP
            ClientLog.Instance.Log("Load LineInfo:" + n);
#endif
            proto.LineInfo.Clear();
            for (int i = 0; i < n; ++i)
            {
                proto.LineInfo.Add(LoadInt());
            }

            // LocalVar
            n = LoadInt();
#if DEBUG_UNDUMP
            ClientLog.Instance.Log("Load LocalVar:" + n);
#endif
            proto.LocVars.Clear();
            for (int i = 0; i < n; ++i)
            {
                proto.LocVars.Add(
                    new LocVar()
                {
                    VarName = LoadString(),
                    StartPc = LoadInt(),
                    EndPc   = LoadInt(),
                });
            }

            // Upvalues' name
            n = LoadInt();
            for (int i = 0; i < n; ++i)
            {
                proto.Upvalues[i].Name = LoadString();
            }
        }
Example #23
0
        private StkId AdjustVarargs( LuaProto p, int actual )
        {
            // 有 `...' 的情况
            // 调用前: func (base)fixed-p1 fixed-p2 var-p1 var-p2 top
            // 调用后: func nil            nil      var-p1 var-p2 (base)fixed-p1 fixed-p2 (reserved...) top
            //
            // 没有 `...' 的情况
            // func (base)fixed-p1 fixed-p2 (reserved...) top

            int NumFixArgs = p.NumParams;
            Utl.Assert( actual >= NumFixArgs, "AdjustVarargs (actual >= NumFixArgs) is false" );

            StkId fixedArg = Top - actual; 		// first fixed argument
            StkId stackBase = Top;				// final position of first argument
            for( int i=0; i<NumFixArgs; ++i )
            {
                Top.ValueInc 		= fixedArg.Value;
                fixedArg.ValueInc 	= new LuaNil();
            }
            return stackBase;
        }
Example #24
0
        private void LoadDebug(LuaProto proto)
        {
            int n;

            proto.Source = LoadString();

            // LineInfo
            n = LoadInt();
#if DEBUG_UNDUMP
            ULDebug.Log("Load LineInfo:" + n);
#endif
            proto.LineInfo.Clear();
            for (int i = 0; i < n; ++i)
            {
                proto.LineInfo.Add(LoadInt());
            }

            // LocalVar
            n = LoadInt();
#if DEBUG_UNDUMP
            ULDebug.Log("Load LocalVar:" + n);
#endif
            proto.LocVars.Clear();
            for (int i = 0; i < n; ++i)
            {
                LocVar locVar = new LocVar();
                locVar.VarName = LoadString();
                locVar.StartPc = LoadInt();
                locVar.EndPc   = LoadInt();
                proto.LocVars.Add(locVar);
            }

            // Upvalues' name
            n = LoadInt();
            for (int i = 0; i < n; ++i)
            {
                proto.Upvalues[i].Name = LoadString();
            }
        }
Example #25
0
        private void V_PushClosure(LuaProto p, LuaUpvalue[] encup, int stackBase, StkId ra)
        {
            var ncl = new LuaLClosureValue(p);

            ra.V.SetClLValue(ncl);
            for (int i = 0; i < p.Upvalues.Count; ++i)
            {
                // ULDebug.Log( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ V_PushClosure i:" + i );
                // ULDebug.Log( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ V_PushClosure InStack:" + p.Upvalues[i].InStack );
                // ULDebug.Log( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ V_PushClosure Index:" + p.Upvalues[i].Index );

                if (p.Upvalues[i].InStack)                  // upvalue refers to local variable
                {
                    ncl.Upvals[i] = F_FindUpval(
                        Stack[stackBase + p.Upvalues[i].Index]);
                }
                else                    // get upvalue from enclosing function
                {
                    ncl.Upvals[i] = encup[p.Upvalues[i].Index];
                }
            }
        }
Example #26
0
 private void KName(LuaProto proto, int pc, int c, out string name)
 {
     if (Instruction.ISK(c))                // is `c' a constant
     {
         var val = proto.K[Instruction.INDEXK(c)];
         if (val.V.TtIsString())                  // literal constant?
         {
             name = val.V.SValue();
             return;
         }
         // else no reasonable name found
     }
     else               // `c' is a register
     {
         string what = GetObjName(proto, pc, c, out name);
         if (what == "constant")         // found a constant name
         {
             return;                     // `name' already filled
         }
         // else no reasonable name found
     }
     name = "?";             // no reasonable name found
 }
Example #27
0
 private void LoadCode( LuaProto proto )
 {
     var n = LoadInt();
     #if DEBUG_UNDUMP
     ULDebug.Log( "LoadCode n:" + n );
     #endif
     proto.Code.Clear();
     for( int i=0; i<n; ++i )
     {
         proto.Code.Add( LoadInstruction() );
     #if DEBUG_UNDUMP
         ULDebug.Log( "Count:" + proto.Code.Count );
         ULDebug.Log( "LoadInstruction:" + proto.Code[proto.Code.Count-1] );
     #endif
     }
 }
Example #28
0
 private string UpvalName(LuaProto p, int uv)
 {
     // TODO
     return("(UpvalName:NotImplemented)");
 }
Example #29
0
        private int FindSetReg(LuaProto proto, int lastpc, int reg)
        {
            var setreg = -1;             // keep last instruction that changed `reg'

            for (int pc = 0; pc < lastpc; ++pc)
            {
                var ins = proto.Code[pc];
                var op  = ins.GET_OPCODE();
                var a   = ins.GETARG_A();
                switch (op)
                {
                case OpCode.OP_LOADNIL: {
                    var b = ins.GETARG_B();
                    // set registers from `a' to `a+b'
                    if (a <= reg && reg <= a + b)
                    {
                        setreg = pc;
                    }
                    break;
                }

                case OpCode.OP_TFORCALL: {
                    // effect all regs above its base
                    if (reg >= a + 2)
                    {
                        setreg = pc;
                    }
                    break;
                }

                case OpCode.OP_CALL:
                case OpCode.OP_TAILCALL: {
                    // effect all registers above base
                    if (reg >= a)
                    {
                        setreg = pc;
                    }
                    break;
                }

                case OpCode.OP_JMP: {
                    var b    = ins.GETARG_sBx();
                    var dest = pc + 1 + b;
                    // jump is forward and do not skip `lastpc'
                    if (pc < dest && dest <= lastpc)
                    {
                        pc += b;                                 // do the jump
                    }
                    break;
                }

                case OpCode.OP_TEST: {
                    // jumped code can change `a'
                    if (reg == a)
                    {
                        setreg = pc;
                    }
                    break;
                }

                default: {
                    // any instruction that set A
                    if (Coder.TestAMode(op) && reg == a)
                    {
                        setreg = pc;
                    }
                    break;
                }
                }
            }
            return(setreg);
        }
Example #30
0
        public LuaLClosure( LuaProto proto )
        {
            Proto = proto;

            Upvals = new List<LuaUpvalue>();
            for( int i=0; i<proto.Upvalues.Count; ++i )
            {
                Upvals.Add( null );
            }
        }
Example #31
0
        private void V_Execute()
        {
            ExecuteEnvironment env;
            CallInfo           ci = CI;

newframe:
            Utl.Assert(ci == CI);
            var cl = Stack[ci.FuncIndex].V.ClLValue();

            env.Stack = Stack;
            env.K     = cl.Proto.K;
            env.Base  = ci.BaseIndex;

#if DEBUG_NEW_FRAME
            ULDebug.Log("#### NEW FRAME #########################################################################");
            ULDebug.Log("## cl:" + cl);
            ULDebug.Log("## Base:" + env.Base);
            ULDebug.Log("########################################################################################");
#endif

            while (true)
            {
                Instruction i = ci.SavedPc.ValueInc;
                env.I = i;

#if DEBUG_SRC_INFO
                int    line = 0;
                string src  = "";
                if (ci.IsLua)
                {
                    line = GetCurrentLine(ci);
                    src  = GetCurrentLuaFunc(ci).Proto.Source;
                }
#endif

                StkId ra = env.RA;

#if DEBUG_DUMP_INS_STACK
#if DEBUG_DUMP_INS_STACK_EX
                DumpStack(env.Base, i.ToString());
#else
                DumpStack(env.Base);
#endif
#endif

#if DEBUG_INSTRUCTION
                ULDebug.Log(System.DateTime.Now + " [VM] ======================================================================== Instruction: " + i
#if DEBUG_INSTRUCTION_WITH_STACK
                            + "\n" + DumpStackToString(env.Base.Index)
#endif
                            );
#endif

#if DEBUG_RECORD_INS
                InstructionHistory.Enqueue(i);
                if (InstructionHistory.Count > 100)
                {
                    InstructionHistory.Dequeue();
                }
#endif

                switch (i.GET_OPCODE())
                {
                case OpCode.OP_MOVE:
                {
                    var rb = env.RB;

#if DEBUG_OP_MOVE
                    ULDebug.Log("[VM] ==== OP_MOVE rb:" + rb);
                    ULDebug.Log("[VM] ==== OP_MOVE ra:" + ra);
#endif

                    ra.V.SetObj(ref rb.V);
                    break;
                }

                case OpCode.OP_LOADK:
                {
                    var rb = env.K[i.GETARG_Bx()];
                    ra.V.SetObj(ref rb.V);
                    break;
                }

                case OpCode.OP_LOADKX:
                {
                    Utl.Assert(ci.SavedPc.Value.GET_OPCODE() == OpCode.OP_EXTRAARG);
                    var rb = env.K[ci.SavedPc.ValueInc.GETARG_Ax()];
                    ra.V.SetObj(ref rb.V);
                    break;
                }

                case OpCode.OP_LOADBOOL:
                {
                    ra.V.SetBValue(i.GETARG_B() != 0);
                    if (i.GETARG_C() != 0)
                    {
                        ci.SavedPc.Index += 1;                                 // skip next instruction (if C)
                    }
                    break;
                }

                case OpCode.OP_LOADNIL:
                {
                    int b     = i.GETARG_B();
                    int index = ra.Index;
                    do
                    {
                        Stack[index++].V.SetNilValue();
                    } while (b-- > 0);
                    break;
                }

                case OpCode.OP_GETUPVAL:
                {
                    int b = i.GETARG_B();
                    ra.V.SetObj(ref cl.Upvals[b].V.V);

#if DEBUG_OP_GETUPVAL
                    // for( var j=0; j<cl.Upvals.Length; ++j)
                    // {
                    //  ULDebug.Log("[VM] ==== GETUPVAL upval:" + cl.Upvals[j] );
                    // }
                    ULDebug.Log("[VM] ==== GETUPVAL b:" + b);
                    ULDebug.Log("[VM] ==== GETUPVAL ra:" + ra);
#endif
                    break;
                }

                case OpCode.OP_GETTABUP:
                {
                    int b   = i.GETARG_B();
                    var key = env.RKC;
                    V_GetTable(cl.Upvals[b].V, key, ra);
#if DEBUG_OP_GETTABUP
                    ULDebug.Log("[VM] ==== OP_GETTABUP key:" + key);
                    ULDebug.Log("[VM] ==== OP_GETTABUP val:" + ra);
#endif
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_GETTABLE:
                {
                    var tbl = env.RB;
                    var key = env.RKC;
                    var val = ra;
                    V_GetTable(tbl, key, val);
#if DEBUG_OP_GETTABLE
                    ULDebug.Log("[VM] ==== OP_GETTABLE key:" + key.ToString());
                    ULDebug.Log("[VM] ==== OP_GETTABLE val:" + val.ToString());
#endif
                    break;
                }

                case OpCode.OP_SETTABUP:
                {
                    int a = i.GETARG_A();

                    var key = env.RKB;
                    var val = env.RKC;
                    V_SetTable(cl.Upvals[a].V, key, val);
#if DEBUG_OP_SETTABUP
                    ULDebug.Log("[VM] ==== OP_SETTABUP key:" + key.Value);
                    ULDebug.Log("[VM] ==== OP_SETTABUP val:" + val.Value);
#endif
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_SETUPVAL:
                {
                    int b  = i.GETARG_B();
                    var uv = cl.Upvals[b];
                    uv.V.V.SetObj(ref ra.V);
#if DEBUG_OP_SETUPVAL
                    ULDebug.Log("[VM] ==== SETUPVAL b:" + b);
                    ULDebug.Log("[VM] ==== SETUPVAL ra:" + ra);
#endif
                    break;
                }

                case OpCode.OP_SETTABLE:
                {
                    var key = env.RKB;
                    var val = env.RKC;
#if DEBUG_OP_SETTABLE
                    ULDebug.Log("[VM] ==== OP_SETTABLE key:" + key.ToString());
                    ULDebug.Log("[VM] ==== OP_SETTABLE val:" + val.ToString());
#endif
                    V_SetTable(ra, key, val);
                    break;
                }

                case OpCode.OP_NEWTABLE:
                {
                    int b   = i.GETARG_B();
                    int c   = i.GETARG_C();
                    var tbl = new LuaTable(this);
                    ra.V.SetHValue(tbl);
                    if (b > 0 || c > 0)
                    {
                        tbl.Resize(b, c);
                    }
                    break;
                }

                case OpCode.OP_SELF:
                {
                    // OP_SELF put function referenced by a table on ra
                    // and the table on ra+1
                    //
                    // RB:  table
                    // RKC: key
                    var ra1 = Stack[ra.Index + 1];
                    var rb  = env.RB;
                    ra1.V.SetObj(ref rb.V);
                    V_GetTable(rb, env.RKC, ra);
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_ADD:
                {
                    var rkb = env.RKB;
                    var rkc = env.RKC;
                    if (rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
                    {
                        ra.V.SetNValue(rkb.V.NValue + rkc.V.NValue);
                    }
                    else
                    {
                        V_Arith(ra, rkb, rkc, TMS.TM_ADD);
                    }

                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_SUB:
                {
                    var rkb = env.RKB;
                    var rkc = env.RKC;
                    if (rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
                    {
                        ra.V.SetNValue(rkb.V.NValue - rkc.V.NValue);
                    }
                    else
                    {
                        V_Arith(ra, rkb, rkc, TMS.TM_SUB);
                    }
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_MUL:
                {
                    var rkb = env.RKB;
                    var rkc = env.RKC;
                    if (rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
                    {
                        ra.V.SetNValue(rkb.V.NValue * rkc.V.NValue);
                    }
                    else
                    {
                        V_Arith(ra, rkb, rkc, TMS.TM_MUL);
                    }
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_DIV:
                {
                    var rkb = env.RKB;
                    var rkc = env.RKC;
                    if (rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
                    {
                        ra.V.SetNValue(rkb.V.NValue / rkc.V.NValue);
                    }
                    else
                    {
                        V_Arith(ra, rkb, rkc, TMS.TM_DIV);
                    }
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_MOD:
                {
                    var rkb = env.RKB;
                    var rkc = env.RKC;
                    if (rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
                    {
                        ra.V.SetNValue(Utl.LuaMod(rkb.V.NValue, rkc.V.NValue));
                    }
                    else
                    {
                        V_Arith(ra, rkb, rkc, TMS.TM_MOD);
                    }
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_POW:
                {
                    var rkb = env.RKB;
                    var rkc = env.RKC;
                    if (rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
                    {
                        ra.V.SetNValue(Math.Pow(rkb.V.NValue, rkc.V.NValue));
                    }
                    else
                    {
                        V_Arith(ra, rkb, rkc, TMS.TM_POW);
                    }
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_UNM:
                {
                    var rb = env.RB;
                    if (rb.V.TtIsNumber())
                    {
                        ra.V.SetNValue(-rb.V.NValue);
                    }
                    else
                    {
                        V_Arith(ra, rb, rb, TMS.TM_UNM);
                        env.Base = ci.BaseIndex;
                    }
                    break;
                }

                case OpCode.OP_NOT:
                {
                    var rb = env.RB;
                    ra.V.SetBValue(IsFalse(ref rb.V));
                    break;
                }

                case OpCode.OP_LEN:
                {
                    V_ObjLen(ra, env.RB);
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_CONCAT:
                {
                    int b = i.GETARG_B();
                    int c = i.GETARG_C();
                    Top = Stack[env.Base + c + 1];
                    V_Concat(c - b + 1);
                    env.Base = ci.BaseIndex;

                    ra = env.RA;                             // 'V_Concat' may invoke TMs and move the stack
                    StkId rb = env.RB;
                    ra.V.SetObj(ref rb.V);

                    Top = Stack[ci.TopIndex];                             // restore top
                    break;
                }

                case OpCode.OP_JMP:
                {
                    V_DoJump(ci, i, 0);
                    break;
                }

                case OpCode.OP_EQ:
                {
                    var lhs      = env.RKB;
                    var rhs      = env.RKC;
                    var expectEq = i.GETARG_A() != 0;
#if DEBUG_OP_EQ
                    ULDebug.Log("[VM] ==== OP_EQ lhs:" + lhs);
                    ULDebug.Log("[VM] ==== OP_EQ rhs:" + rhs);
                    ULDebug.Log("[VM] ==== OP_EQ expectEq:" + expectEq);
                    ULDebug.Log("[VM] ==== OP_EQ (lhs.V == rhs.V):" + (lhs.V == rhs.V));
#endif
                    if ((lhs.V == rhs.V) != expectEq)
                    {
                        ci.SavedPc.Index += 1;                                 // skip next jump instruction
                    }
                    else
                    {
                        V_DoNextJump(ci);
                    }
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_LT:
                {
                    var expectCmpResult = i.GETARG_A() != 0;
                    if (V_LessThan(env.RKB, env.RKC) != expectCmpResult)
                    {
                        ci.SavedPc.Index += 1;
                    }
                    else
                    {
                        V_DoNextJump(ci);
                    }
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_LE:
                {
                    var expectCmpResult = i.GETARG_A() != 0;
                    if (V_LessEqual(env.RKB, env.RKC) != expectCmpResult)
                    {
                        ci.SavedPc.Index += 1;
                    }
                    else
                    {
                        V_DoNextJump(ci);
                    }
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_TEST:
                {
                    if ((i.GETARG_C() != 0) ?
                        IsFalse(ref ra.V) : !IsFalse(ref ra.V))
                    {
                        ci.SavedPc.Index += 1;
                    }
                    else
                    {
                        V_DoNextJump(ci);
                    }

                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_TESTSET:
                {
                    var rb = env.RB;
                    if ((i.GETARG_C() != 0) ?
                        IsFalse(ref rb.V) : !IsFalse(ref rb.V))
                    {
                        ci.SavedPc.Index += 1;
                    }
                    else
                    {
                        ra.V.SetObj(ref rb.V);
                        V_DoNextJump(ci);
                    }
                    env.Base = ci.BaseIndex;
                    break;
                }

                case OpCode.OP_CALL:
                {
                    int b        = i.GETARG_B();
                    int nresults = i.GETARG_C() - 1;
                    if (b != 0)
                    {
                        Top = Stack[ra.Index + b];
                    }                                                             // else previous instruction set top
                    if (D_PreCall(ra, nresults))                                  // C# function?
                    {
                        if (nresults >= 0)
                        {
                            Top = Stack[ci.TopIndex];
                        }
                        env.Base = ci.BaseIndex;
                    }
                    else                               // Lua function
                    {
                        ci             = CI;
                        ci.CallStatus |= CallStatus.CIST_REENTRY;
                        goto newframe;
                    }
                    break;
                }

                case OpCode.OP_TAILCALL:
                {
                    int b = i.GETARG_B();
                    if (b != 0)
                    {
                        Top = Stack[ra.Index + b];
                    }                                                                           // else previous instruction set top

                    Utl.Assert(i.GETARG_C() - 1 == LuaDef.LUA_MULTRET);

                    var called = D_PreCall(ra, LuaDef.LUA_MULTRET);

                    // C# function ?
                    if (called)
                    {
                        env.Base = ci.BaseIndex;
                    }

                    // LuaFunciton
                    else
                    {
                        var   nci   = CI;                                             // called frame
                        var   oci   = BaseCI[CI.Index - 1];                           // caller frame
                        StkId nfunc = Stack[nci.FuncIndex];                           // called function
                        StkId ofunc = Stack[oci.FuncIndex];                           // caller function
                        var   ncl   = nfunc.V.ClLValue();
                        var   ocl   = ofunc.V.ClLValue();

                        // last stack slot filled by 'precall'
                        int lim = nci.BaseIndex + ncl.Proto.NumParams;

                        if (cl.Proto.P.Count > 0)
                        {
                            F_Close(Stack[env.Base]);
                        }

                        // move new frame into old one
                        var nindex = nfunc.Index;
                        var oindex = ofunc.Index;
                        while (nindex < lim)
                        {
                            Stack[oindex++].V.SetObj(ref Stack[nindex++].V);
                        }

                        oci.BaseIndex   = ofunc.Index + (nci.BaseIndex - nfunc.Index);
                        oci.TopIndex    = ofunc.Index + (Top.Index - nfunc.Index);
                        Top             = Stack[oci.TopIndex];
                        oci.SavedPc     = nci.SavedPc;
                        oci.CallStatus |= CallStatus.CIST_TAIL;
                        ci              = CI = oci;

                        ocl = ofunc.V.ClLValue();
                        Utl.Assert(Top.Index == oci.BaseIndex + ocl.Proto.MaxStackSize);

                        goto newframe;
                    }

                    break;
                }

                case OpCode.OP_RETURN:
                {
                    int b = i.GETARG_B();
                    if (b != 0)
                    {
                        Top = Stack[ra.Index + b - 1];
                    }
                    if (cl.Proto.P.Count > 0)
                    {
                        F_Close(Stack[env.Base]);
                    }
                    b = D_PosCall(ra.Index);
                    if ((ci.CallStatus & CallStatus.CIST_REENTRY) == 0)
                    {
                        return;
                    }
                    else
                    {
                        ci = CI;
                        if (b != 0)
                        {
                            Top = Stack[ci.TopIndex];
                        }
                        goto newframe;
                    }
                }

                case OpCode.OP_FORLOOP:
                {
                    var ra1 = Stack[ra.Index + 1];
                    var ra2 = Stack[ra.Index + 2];
                    var ra3 = Stack[ra.Index + 3];

                    var step  = ra2.V.NValue;
                    var idx   = ra.V.NValue + step;                                     // increment index
                    var limit = ra1.V.NValue;

                    if ((0 < step) ? idx <= limit
                                                                           : limit <= idx)
                    {
                        ci.SavedPc.Index += i.GETARG_sBx();                 // jump back
                        ra.V.SetNValue(idx);                                // updateinternal index...
                        ra3.V.SetNValue(idx);                               // ... and external index
                    }

                    break;
                }

                case OpCode.OP_FORPREP:
                {
                    var init  = new TValue();
                    var limit = new TValue();
                    var step  = new TValue();

                    var ra1 = Stack[ra.Index + 1];
                    var ra2 = Stack[ra.Index + 2];

                    // WHY: why limit is not used ?

                    if (!V_ToNumber(ra, ref init))
                    {
                        G_RunError("'for' initial value must be a number");
                    }
                    if (!V_ToNumber(ra1, ref limit))
                    {
                        G_RunError("'for' limit must be a number");
                    }
                    if (!V_ToNumber(ra2, ref step))
                    {
                        G_RunError("'for' step must be a number");
                    }

                    ra.V.SetNValue(init.NValue - step.NValue);
                    ci.SavedPc.Index += i.GETARG_sBx();

                    break;
                }

                case OpCode.OP_TFORCALL:
                {
                    int rai = ra.Index;
                    int cbi = ra.Index + 3;
                    Stack[cbi + 2].V.SetObj(ref Stack[rai + 2].V);
                    Stack[cbi + 1].V.SetObj(ref Stack[rai + 1].V);
                    Stack[cbi].V.SetObj(ref Stack[rai].V);

                    StkId callBase = Stack[cbi];
                    Top = Stack[cbi + 3];                           // func. +2 args (state and index)

                    D_Call(callBase, i.GETARG_C(), true);

                    env.Base = ci.BaseIndex;

                    Top   = Stack[ci.TopIndex];
                    i     = ci.SavedPc.ValueInc;                                // go to next instruction
                    env.I = i;
                    ra    = env.RA;

                    DumpStack(env.Base);
#if DEBUG_INSTRUCTION
                    ULDebug.Log("[VM] ============================================================ OP_TFORCALL Instruction: " + i);
#endif

                    Utl.Assert(i.GET_OPCODE() == OpCode.OP_TFORLOOP);
                    goto l_tforloop;
                }

                case OpCode.OP_TFORLOOP:
l_tforloop:
                    {
                        StkId ra1 = Stack[ra.Index + 1];
                        if (!ra1.V.TtIsNil())                           // continue loop?
                        {
                            ra.V.SetObj(ref ra1.V);
                            ci.SavedPc += i.GETARG_sBx();
                        }
                        break;
                    }

                // sets the values for a range of array elements in a table(RA)
                // RA -> table
                // RB -> number of elements to set
                // C  -> encodes the block number of the table to be initialized
                // the values used to initialize the table are located in
                //   R(A+1), R(A+2) ...
                case OpCode.OP_SETLIST:
                {
                    int n = i.GETARG_B();
                    int c = i.GETARG_C();
                    if (n == 0)
                    {
                        n = (Top.Index - ra.Index) - 1;
                    }
                    if (c == 0)
                    {
                        Utl.Assert(ci.SavedPc.Value.GET_OPCODE() == OpCode.OP_EXTRAARG);
                        c = ci.SavedPc.ValueInc.GETARG_Ax();
                    }

                    var tbl = ra.V.HValue();
                    Utl.Assert(tbl != null);

                    int last = ((c - 1) * LuaDef.LFIELDS_PER_FLUSH) + n;
                    int rai  = ra.Index;
                    for (; n > 0; --n)
                    {
                        tbl.SetInt(last--, ref Stack[rai + n].V);
                    }
#if DEBUG_OP_SETLIST
                    ULDebug.Log("[VM] ==== OP_SETLIST ci.Top:" + ci.Top.Index);
                    ULDebug.Log("[VM] ==== OP_SETLIST Top:" + Top.Index);
#endif
                    Top = Stack[ci.TopIndex];                             // correct top (in case of previous open call)
                    break;
                }

                case OpCode.OP_CLOSURE:
                {
                    LuaProto p = cl.Proto.P[i.GETARG_Bx()];
                    V_PushClosure(p, cl.Upvals, env.Base, ra);
#if DEBUG_OP_CLOSURE
                    ULDebug.Log("OP_CLOSURE:" + ra.Value);
                    var racl = ra.Value as LuaLClosure;
                    if (racl != null)
                    {
                        for (int ii = 0; ii < racl.Upvals.Count; ++ii)
                        {
                            ULDebug.Log(ii + " ) " + racl.Upvals[ii]);
                        }
                    }
#endif
                    break;
                }

                /// <summary>
                /// VARARG implements the vararg operator `...' in expressions.
                /// VARARG copies B-1 parameters into a number of registers
                /// starting from R(A), padding with nils if there aren't enough values.
                /// If B is 0, VARARG copies as many values as it can based on
                /// the number of parameters passed.
                /// If a fixed number of values is required, B is a value greater than 1.
                /// If any number of values is required, B is 0.
                /// </summary>
                case OpCode.OP_VARARG:
                {
                    int b = i.GETARG_B() - 1;
                    int n = (env.Base - ci.FuncIndex) - cl.Proto.NumParams - 1;
                    if (b < 0)                              // B == 0?
                    {
                        b = n;
                        D_CheckStack(n);
                        ra  = env.RA;                                // previous call may change the stack
                        Top = Stack[ra.Index + n];
                    }

                    var p = ra.Index;
                    var q = env.Base - n;
                    for (int j = 0; j < b; ++j)
                    {
                        if (j < n)
                        {
                            Stack[p++].V.SetObj(ref Stack[q++].V);
                        }
                        else
                        {
                            Stack[p++].V.SetNilValue();
                        }
                    }
                    break;
                }

                case OpCode.OP_EXTRAARG:
                {
                    Utl.Assert(false);
                    V_NotImplemented(i);
                    break;
                }

                default:
                    V_NotImplemented(i);
                    break;
                }
            }
        }
Example #32
0
        private LuaProto LoadFunction()
        {
            #if DEBUG_UNDUMP
            ULDebug.Log( "LoadFunction enter" );
            #endif

            LuaProto proto = new LuaProto();
            proto.LineDefined = LoadInt();
            proto.LastLineDefined = LoadInt();
            proto.NumParams = LoadByte();
            proto.IsVarArg  = LoadBoolean();
            proto.MaxStackSize = LoadByte();

            LoadCode(proto);
            LoadConstants(proto);
            LoadUpvalues(proto);
            LoadDebug(proto);
            return proto;
        }
Example #33
0
        public LuaLClosureValue(LuaProto p)
        {
            Proto = p;

            Upvals = new LuaUpvalue[p.Upvalues.Count];
            for(int i=0; i<p.Upvalues.Count; ++i)
                { Upvals[i] = new LuaUpvalue(); }
        }
Example #34
0
        private void V_PushClosure( LuaProto p, List<LuaUpvalue> encup, StkId stackBase, StkId ra )
        {
            LuaLClosure ncl = new LuaLClosure( p );
            ra.Value = ncl;
            for( int i=0; i<p.Upvalues.Count; ++i )
            {
                // Debug.Log( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ V_PushClosure i:" + i );
                // Debug.Log( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ V_PushClosure InStack:" + p.Upvalues[i].InStack );
                // Debug.Log( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ V_PushClosure Index:" + p.Upvalues[i].Index );

                if( p.Upvalues[i].InStack ) // upvalue refers to local variable
                    ncl.Upvals[i] = F_FindUpval( stackBase + p.Upvalues[i].Index );
                else	// get upvalue from enclosing function
                    ncl.Upvals[i] = encup[ p.Upvalues[i].Index ];
            }
        }
Example #35
0
        /// <summary>
        /// return true if function has been executed
        /// </summary>
        private bool D_PreCall(StkId func, int nResults)
        {
            // prepare for Lua call

#if DEBUG_D_PRE_CALL
            ULDebug.Log("============================ D_PreCall func:" + func);
#endif

            int funcIndex = func.Index;
            if (!func.V.TtIsFunction())
            {
                // not a function
                // retry with `function' tag method
                func = tryFuncTM(func);

                // now it must be a function
                return(D_PreCall(func, nResults));
            }

            if (func.V.ClIsLuaClosure())
            {
                LuaLClosureValue cl = func.V.ClLValue();
                Utl.Assert(cl != null);
                LuaProto p = cl.Proto;

                D_CheckStack(p.MaxStackSize + p.NumParams);
                func = Stack[funcIndex];

                // 补全参数
                int n = (Top.Index - func.Index) - 1;
                for ( ; n < p.NumParams; ++n)
                {
                    StkId.inc(ref Top).V.SetNilValue();
                }

                int stackBase = (!p.IsVarArg) ? (func.Index + 1) : AdjustVarargs(p, n);

                CI            = ExtendCI();
                CI.NumResults = nResults;
                CI.FuncIndex  = func.Index;
                CI.BaseIndex  = stackBase;
                CI.TopIndex   = stackBase + p.MaxStackSize;
                Utl.Assert(CI.TopIndex <= StackLast);
                CI.SavedPc    = new InstructionPtr(p.Code, 0);
                CI.CallStatus = CallStatus.CIST_LUA;

                Top = Stack[CI.TopIndex];

                return(false);
            }

            if (func.V.ClIsCsClosure())
            {
                LuaCsClosureValue cscl = func.V.ClCsValue();
                Utl.Assert(cscl != null);

                D_CheckStack(LuaDef.LUA_MINSTACK);
                func = Stack[funcIndex];

                CI            = ExtendCI();
                CI.NumResults = nResults;
                CI.FuncIndex  = func.Index;
                CI.TopIndex   = Top.Index + LuaDef.LUA_MINSTACK;
                CI.CallStatus = CallStatus.CIST_NONE;

                // do the actual call
                int n = cscl.F(this);

                // poscall
                D_PosCall(Top.Index - n);

                return(true);
            }

            throw new System.NotImplementedException();
        }
Example #36
0
 private void DumpCode(LuaProto proto)
 {
     DumpVector(proto.Code, delegate(Instruction ins) {
         DumpBlock(BitConverter.GetBytes((uint)ins));
     });
 }
Example #37
0
		private void V_PushClosure( LuaProto p, LuaUpvalue[] encup, int stackBase, StkId ra )
		{
			var ncl = new LuaLClosureValue( p );
			ra.V.SetClLValue(ncl);
			for( int i=0; i<p.Upvalues.Count; ++i )
			{
				// ULDebug.Log( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ V_PushClosure i:" + i );
				// ULDebug.Log( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ V_PushClosure InStack:" + p.Upvalues[i].InStack );
				// ULDebug.Log( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ V_PushClosure Index:" + p.Upvalues[i].Index );

				if( p.Upvalues[i].InStack ) // upvalue refers to local variable
					ncl.Upvals[i] = F_FindUpval(
						Stack[stackBase + p.Upvalues[i].Index] );
				else	// get upvalue from enclosing function
					ncl.Upvals[i] = encup[ p.Upvalues[i].Index ];
			}
		}
Example #38
0
        private void LoadConstants( LuaProto proto )
        {
            var n = LoadInt();
            #if DEBUG_UNDUMP
            ULDebug.Log( "Load Constants:" + n );
            #endif
            proto.K.Clear();
            for( int i=0; i<n; ++i )
            {
                int t = (int)LoadByte();
            #if DEBUG_UNDUMP
                ULDebug.Log( "Constant Type:" + t );
            #endif
                var v = new StkId();
                switch( t )
                {
                    case (int)LuaType.LUA_TNIL:
                        v.V.SetNilValue();
                        proto.K.Add( v );
                        break;

                    case (int)LuaType.LUA_TBOOLEAN:
                        v.V.SetBValue(LoadBoolean());
                        proto.K.Add( v );
                        break;

                    case (int)LuaType.LUA_TNUMBER:
                        v.V.SetNValue(LoadNumber());
                        proto.K.Add( v );
                        break;

                    case (int)LuaType.LUA_TSTRING:
            #if DEBUG_UNDUMP
                        ULDebug.Log( "LuaType.LUA_TSTRING" );
            #endif
                        v.V.SetSValue(LoadString());
                        proto.K.Add( v );
                        break;

                    default:
                        throw new UndumpException(
                            "LoadConstants unknown type: " + t );
                }
            }

            n = LoadInt();
            #if DEBUG_UNDUMP
            ULDebug.Log( "Load Functions:" + n );
            #endif
            proto.P.Clear();
            for( int i=0; i<n; ++i )
            {
                proto.P.Add( LoadFunction() );
            }
        }
Example #39
0
        private void LoadDebug( LuaProto proto )
        {
            int n;
            proto.Source = LoadString();

            // LineInfo
            n = LoadInt();
            #if DEBUG_UNDUMP
            ULDebug.Log( "Load LineInfo:" + n );
            #endif
            proto.LineInfo.Clear();
            for( int i=0; i<n; ++i )
            {
                proto.LineInfo.Add( LoadInt() );
            }

            // LocalVar
            n = LoadInt();
            #if DEBUG_UNDUMP
            ULDebug.Log( "Load LocalVar:" + n );
            #endif
            proto.LocVars.Clear();
            for( int i=0; i<n; ++i )
            {
                proto.LocVars.Add(
                    new LocVar()
                    {
                        VarName = LoadString(),
                        StartPc = LoadInt(),
                        EndPc   = LoadInt(),
                    } );
            }

            // Upvalues' name
            n = LoadInt();
            for( int i=0; i<n; ++i )
            {
                proto.Upvalues[i].Name = LoadString();
            }
        }
Example #40
0
 private void DumpCode(LuaProto proto)
 {
     DumpVector(proto.Code, (ins) => {
         DumpBlock(BitConverter.GetBytes((uint)ins));
     });
 }
Example #41
0
 private void LoadUpvalues( LuaProto proto )
 {
     var n = LoadInt();
     #if DEBUG_UNDUMP
     ULDebug.Log( "Load Upvalues:" + n );
     #endif
     proto.Upvalues.Clear();
     for( int i=0; i<n; ++i )
     {
         proto.Upvalues.Add(
             new UpvalDesc()
             {
                 Name = null,
                 InStack = LoadBoolean(),
                 Index = (int)LoadByte()
             } );
     }
 }
Example #42
0
        private void LoadConstants( LuaProto proto )
        {
            var n = LoadInt();
            #if DEBUG_UNDUMP
            Debug.Log( "Load Constants:" + n );
            #endif
            proto.K.Clear();
            for( int i=0; i<n; ++i )
            {
                int t = (int)LoadByte();
            #if DEBUG_UNDUMP
                Debug.Log( "Constant Type:" + t );
            #endif
                switch( t )
                {
                    case (int)LuaType.LUA_TNIL:
                        proto.K.Add( new LuaNil() );
                        break;

                    case (int)LuaType.LUA_TBOOLEAN:
                        proto.K.Add( new LuaBoolean( LoadBoolean() ) );
                        break;

                    case (int)LuaType.LUA_TNUMBER:
                        proto.K.Add( new LuaNumber( LoadNumber() ) );
                        break;

                    case (int)LuaType.LUA_TSTRING:
            #if DEBUG_UNDUMP
                        Debug.Log( "LuaType.LUA_TSTRING" );
            #endif
                        proto.K.Add( new LuaString( LoadString() ) );
                        break;

                    default:
                        throw new UndumpException(
                            "LoadConstants unknown type: " + t );
                }
            }

            n = LoadInt();
            #if DEBUG_UNDUMP
            Debug.Log( "Load Functions:" + n );
            #endif
            proto.P.Clear();
            for( int i=0; i<n; ++i )
            {
                proto.P.Add( LoadFunction() );
            }
        }
Example #43
0
        private string GetObjName(LuaProto proto, int lastpc, int reg,
                                  out string name)
        {
            name = F_GetLocalName(proto, reg + 1, lastpc);
            if (name != null)              // is a local?
            {
                return("local");
            }

            // else try symbolic execution
            var pc = FindSetReg(proto, lastpc, reg);

            if (pc != -1)
            {
                var ins = proto.Code[pc];
                var op  = ins.GET_OPCODE();
                switch (op)
                {
                case OpCode.OP_MOVE: {
                    var b = ins.GETARG_B();                             // move from `b' to `a'
                    if (b < ins.GETARG_A())
                    {
                        return(GetObjName(proto, pc, b, out name));
                    }
                    break;
                }

                case OpCode.OP_GETTABUP:
                case OpCode.OP_GETTABLE: {
                    var k  = ins.GETARG_C();
                    var t  = ins.GETARG_B();
                    var vn = (op == OpCode.OP_GETTABLE)
                                                        ? F_GetLocalName(proto, t + 1, pc)
                                                        : UpvalName(proto, t);
                    KName(proto, pc, k, out name);
                    return((vn == LuaDef.LUA_ENV) ? "global" : "field");
                }

                case OpCode.OP_GETUPVAL: {
                    name = UpvalName(proto, ins.GETARG_B());
                    return("upvalue");
                }

                case OpCode.OP_LOADK:
                case OpCode.OP_LOADKX: {
                    var b = (op == OpCode.OP_LOADK)
                                                        ? ins.GETARG_Bx()
                                                        : proto.Code[pc + 1].GETARG_Ax();
                    var val = proto.K[b];
                    if (val.V.TtIsString())
                    {
                        name = val.V.SValue();
                        return("constant");
                    }
                    break;
                }

                case OpCode.OP_SELF: {
                    var k = ins.GETARG_C();                             // key index
                    KName(proto, pc, k, out name);
                    return("method");
                }

                default: break;                         // go through to return null
                }
            }

            return(null);            // could not find reasonable name
        }
Example #44
0
		private LuaProto AddPrototype()
		{
			var p = new LuaProto();
			CurFunc.Proto.P.Add( p );
			return p;
		}