Beispiel #1
0
 private void PushFuncName(LuaDebug ar)
 {
     if (ar.NameWhat.Length > 0 && ar.NameWhat[0] != '\0')              // is there a name?
     {
         API.PushString(string.Format("function '{0}'", ar.Name));
     }
     else if (ar.What.Length > 0 && ar.What[0] == 'm')              // main?
     {
         API.PushString("main chunk");
     }
     else if (ar.What.Length > 0 && ar.What[0] == 'C')
     {
         if (PushGlobalFuncName(ar))
         {
             API.PushString(string.Format("function '{0}'", API.ToString(-1)));
             API.Remove(-2);                       //remove name
         }
         else
         {
             API.PushString("?");
         }
     }
     else
     {
         API.PushString(string.Format("function <{0}:{1}>", ar.ShortSrc, ar.LineDefined));
     }
 }
Beispiel #2
0
        private int CountLevels()
        {
            LuaDebug ar = new LuaDebug();
            int      li = 1;
            int      le = 1;

            // find an upper bound
            while (API.GetStack(le, ar))
            {
                li  = le;
                le *= 2;
            }
            // do a binary search
            while (li < le)
            {
                int m = (li + le) / 2;
                if (API.GetStack(m, ar))
                {
                    li = m + 1;
                }
                else
                {
                    le = m;
                }
            }
            return(le - 1);
        }
Beispiel #3
0
        private void FuncInfo(LuaDebug ar, StkId func)
        {
            Utl.Assert(func.V.TtIsFunction());
            if (func.V.ClIsLuaClosure())
            {
                var lcl = func.V.ClLValue();
                var 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;
            }
        }
Beispiel #4
0
        public int L_ArgError(int narg, string extraMsg)
        {
            LuaDebug ar = new LuaDebug();

            if (!API.GetStack(0, ar))                // no stack frame ?
            {
                return(L_Error("bad argument {0} ({1})", narg, extraMsg));
            }

            GetInfo("n", ar);
            if (ar.NameWhat == "method")
            {
                narg--;                 // do not count 'self'
                if (narg == 0)          // error is in the self argument itself?
                {
                    return(L_Error("calling '{0}' on bad self", ar.Name));
                }
            }
            if (ar.Name == null)
            {
                ar.Name = PushGlobalFuncName(ar) ? API.ToString(-1) : "?";
            }
            return(L_Error("bad argument {0} to '{1}' ({2})",
                           narg, ar.Name, extraMsg));
        }
Beispiel #5
0
        private const int LEVELS2 = 10;         // size of the second part of the stack

        public void L_Where(int level)
        {
            LuaDebug ar = new LuaDebug();

            if (API.GetStack(level, ar))             // check function at level
            {
                GetInfo("Sl", ar);                   // get info about it
                if (ar.CurrentLine > 0)              // is there info?
                {
                    API.PushString(string.Format("{0}:{1}: ", ar.ShortSrc, ar.CurrentLine));
                    return;
                }
            }
            API.PushString("");               // else, no information available...
        }
Beispiel #6
0
        private bool PushGlobalFuncName(LuaDebug ar)
        {
            int top = API.GetTop();

            GetInfo("f", ar);
            API.PushGlobalTable();
            if (FindField(top + 1, 2))
            {
                API.Copy(-1, top + 1);
                API.Pop(2);
                return(true);
            }
            else
            {
                API.SetTop(top);                   // remove function and global table
                return(false);
            }
        }
Beispiel #7
0
        public void L_Traceback(ILuaState otherLua, string msg, int level)
        {
            LuaState oLua      = otherLua as LuaState;
            LuaDebug ar        = new LuaDebug();
            int      top       = API.GetTop();
            int      numLevels = oLua.CountLevels();
            int      mark      = (numLevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;

            if (msg != null)
            {
                API.PushString(string.Format("{0}\n", msg));
            }
            API.PushString("stack traceback:");
            while (otherLua.GetStack(level++, ar))
            {
                if (level == mark) // too many levels?
                {
                    API.PushString("\n\t...");
                    level = numLevels - LEVELS2; // and skip to last ones
                }
                else
                {
                    oLua.GetInfo("Slnt", ar);
                    API.PushString(string.Format("\n\t{0}:", ar.ShortSrc));
                    if (ar.CurrentLine > 0)
                    {
                        API.PushString(string.Format("{0}:", ar.CurrentLine));
                    }
                    API.PushString(" in ");
                    PushFuncName(ar);
                    if (ar.IsTailCall)
                    {
                        API.PushString("\n\t(...tail calls...)");
                    }
                    API.Concat(API.GetTop() - top);
                }
            }

            API.Concat(API.GetTop() - top);
        }
Beispiel #8
0
        public int GetInfo(string what, LuaDebug ar)
        {
            CallInfo ci;
            StkId    func;

            int pos = 0;

            if (what[pos] == '>')
            {
                ci   = null;
                func = Stack[Top.Index - 1];

                Utl.ApiCheck(func.V.TtIsFunction(), "function expected");
                pos++;

                Top = Stack[Top.Index - 1];
            }
            else
            {
                ci   = BaseCI[ar.ActiveCIIndex];
                func = Stack[ci.FuncIndex];
                Utl.Assert(Stack[ci.FuncIndex].V.TtIsFunction());
            }

            // var IsClosure( func.Value ) ? func.Value
            int status = AuxGetInfo(what, ar, func, ci);

            if (what.Contains("f"))
            {
                Top.V.SetObj(ref func.V);
                IncrTop();
            }
            if (what.Contains("L"))
            {
                CollectValidLines(func);
            }
            return(status);
        }
Beispiel #9
0
        bool ILuaAPI.GetStack(int level, LuaDebug ar)
        {
            if (level < 0)
            {
                return(false);
            }

            int index;

            for (index = CI.Index; level > 0 && index > 0; --index)
            {
                level--;
            }

            bool status = false;

            if (level == 0 && index > 0)
            {
                status           = true;
                ar.ActiveCIIndex = index;
            }
            return(status);
        }
Beispiel #10
0
        private int AuxGetInfo(string what, LuaDebug ar, StkId func, CallInfo ci)
        {
            int status = 1;

            for (int i = 0; i < what.Length; ++i)
            {
                char c = what[i];
                switch (c)
                {
                case 'S':
                {
                    FuncInfo(ar, func);
                    break;
                }

                case 'l':
                {
                    ar.CurrentLine = (ci != null && ci.IsLua) ? GetCurrentLine(ci) : -1;
                    break;
                }

                case 'u':
                {
                    Utl.Assert(func.V.TtIsFunction());
                    if (func.V.ClIsLuaClosure())
                    {
                        var lcl = func.V.ClLValue();
                        ar.NumUps    = lcl.Upvals.Length;
                        ar.IsVarArg  = lcl.Proto.IsVarArg;
                        ar.NumParams = lcl.Proto.NumParams;
                    }
                    else if (func.V.ClIsCsClosure())
                    {
                        var ccl = func.V.ClCsValue();
                        ar.NumUps    = ccl.Upvals.Length;
                        ar.IsVarArg  = true;
                        ar.NumParams = 0;
                    }
                    else
                    {
                        throw new System.NotImplementedException();
                    }
                    break;
                }

                case 't':
                {
                    ar.IsTailCall = (ci != null)
                                                        ? ((ci.CallStatus & CallStatus.CIST_TAIL) != 0)
                                                        : false;
                    break;
                }

                case 'n':
                {
                    var prevCI = BaseCI[ci.Index - 1];
                    if (ci != null &&
                        ((ci.CallStatus & CallStatus.CIST_TAIL) == 0) &&
                        prevCI.IsLua)
                    {
                        ar.NameWhat = GetFuncName(prevCI, out ar.Name);
                    }
                    else
                    {
                        ar.NameWhat = null;
                    }
                    if (ar.NameWhat == null)
                    {
                        ar.NameWhat = "";                                 // not found
                        ar.Name     = null;
                    }
                    break;
                }

                case 'L':
                case 'f':                         // handled by GetInfo
                    break;

                default: status = 0;                         // invalid option
                    break;
                }
            }
            return(status);
        }