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); }
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)); } }
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)); }
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... }
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); } }
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); }