public static int lua_getinfo(lua_State L, string what, lua_Debug ar) { lua_lock(L); CallInfo ci; int func; int i = 0; if (what[i] == '>') { ci = null; func = L.top - 1; imp.api_check(imp.ttisfunction(L, func), "function expected"); i++; L.top--; } else { ci = ar.i_ci; func = ci.func; imp.lua_assert(imp.ttisfunction(L, ci.func)); } Closure cl = imp.ttisclosure(L, func) ? imp.clvalue(L, func) : null; int status = imp.auxgetinfo(L, what, i, ar, cl, ci); if (what.IndexOf('L') >= 0) { imp.collectvalidlines(L, cl); } lua_unlock(L); return(status); }
public static string lua_getlocal(lua_State L, lua_Debug ar, int n) { lua_lock(L); string name = null; if (ar == null) /* information about non-active function? */ { if (imp.isLfunction(L, L.top - 1) == false) /* not a Lua function? */ { name = null; } else /* consider live variables at function start (parameters) */ { name = imp.luaF_getlocalname(imp.clLvalue(L, L.top - 1).p, n, 0); } } else /* active function; get information through 'ar' */ { int pos = 0; /* to avoid warnings */ name = imp.findlocal(L, ar.i_ci, n, ref pos); if (name != null) { imp.setobj2s(L, L.top, pos); imp.api_incr_top(L); } } lua_unlock(L); return(name); }
public static int lua_getstack(lua_State L, int level, lua_Debug ar) { int status = 0; if (level < 0) { return(0); /* invalid (negative) level */ } lua_lock(L); CallInfo ci; for (ci = L.ci; level > 0 && ci != L.base_ci; ci = ci.previous) { level--; } if (level == 0 && ci != L.base_ci) /* level found? */ { status = 1; ar.i_ci = ci; } else { status = 0; /* no such level */ } lua_unlock(L); return(status); }
public static string lua_setlocal(lua_State L, lua_Debug ar, int n) { int pos = 0; /* to avoid warnings */ string name = imp.findlocal(L, ar.i_ci, n, ref pos); lua_lock(L); if (name != null) { imp.setobj2s(L, pos, L.top - 1); L.top--; /* pop value */ } lua_unlock(L); return(name); }
public static void luaL_where(lua_State L, int level) { lua_Debug ar = new lua_Debug(); if (lua_getstack(L, level, ar) != 0) /* check function at level */ { lua_getinfo(L, "Sl", ar); /* get info about it */ if (ar.currentline > 0) /* is there info? */ { lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); return; } } lua_pushliteral(L, ""); /* else, no information available... */ }
public static void funcinfo(lua_Debug ar, Closure cl) { if (ldebug.noLuaClosure(cl)) { ar.source = "=[C]"; ar.linedefined = -1; ar.lastlinedefined = -1; ar.what = "C"; } else { Proto p = cl.l.p; ar.source = p.source == null?getsstr(p.source) : "=?"; ar.linedefined = p.linedefined; ar.lastlinedefined = p.lastlinedefined; ar.what = ar.linedefined == 0 ? "main" : "Lua"; } luaO_chunkid(ref ar.short_src, ar.source, cc.LUA_IDSIZE); }
public static int luaB_costatus(lua_State L) { lua_State co = lco.getco(L); if (L == co) { cc.lua_pushliteral(L, "running"); } else { switch (cc.lua_status(co)) { case cc.LUA_YIELD: cc.lua_pushliteral(L, "suspended"); break; case cc.LUA_OK: { lua_Debug ar = new lua_Debug(); if (cc.lua_getstack(co, 0, ar) > 0) { cc.lua_pushliteral(L, "normal"); } else if (cc.lua_gettop(co) == 0) { cc.lua_pushliteral(L, "dead"); } else { cc.lua_pushliteral(L, "suspended"); } break; } default: cc.lua_pushliteral(L, "dead"); break; } } return(1); }
/* ** {====================================================== ** Generic Buffer manipulation ** ======================================================= */ public static void luaL_traceback(lua_State L, lua_State L1, string msg, int level) { lua_Debug ar = new lua_Debug();; int top = lua_gettop(L); int numlevels = imp.countlevels(L1); int mark = (numlevels > imp.LEVELS1 + imp.LEVELS2) ? imp.LEVELS1 : 0; if (msg != null) { lua_pushfstring(L, "%s\n", msg); } lua_pushliteral(L, "stack traceback:"); while (lua_getstack(L1, level++, ar) != 0) { if (level == mark) { lua_pushliteral(L, "\n\t..."); level = numlevels - imp.LEVELS2; } else { lua_getinfo(L1, "Slnt", ar); lua_pushfstring(L, "\n\t%s:", ar.short_src); if (ar.currentline > 0) { lua_pushfstring(L, "%d:", ar.currentline); } lua_pushliteral(L, " in "); imp.pushfuncname(L, ar); if (ar.istailcall != 0) { lua_pushliteral(L, "\n\t(...tail calls...)"); } lua_concat(L, lua_gettop(L) - top); } } lua_concat(L, lua_gettop(L) - top); }
/* }====================================================== */ /* ** {====================================================== ** Error-report functions ** ======================================================= */ public static int luaL_argerror(lua_State L, int arg, string extramsg) { lua_Debug ar = new lua_Debug(); if (lua_getstack(L, 0, ar) == 0) { return(luaL_error(L, "bad argument #%d (%s)", arg, extramsg)); } lua_getinfo(L, "n", ar); if (ar.namewhat == "method") { arg--; if (arg == 0) { return(luaL_error(L, "calling '%s' on bad self (%s)", ar.name, extramsg)); } } if (ar.name == null) { ar.name = (imp.pushglobalfuncname(L, ar) ? lua_tostring(L, -1) : "?"); } return(luaL_error(L, "bad argument #%d to '%s' (%s)", arg, ar.name, extramsg)); }
public static int countlevels(lua_State L) { lua_Debug ar = new lua_Debug(); int li = 1; int le = 1; while (cc.lua_getstack(L, le, ar) != 0) { li = le; le *= 2; } while (li < le) { int m = (li + le) / 2; if (cc.lua_getstack(L, m, ar) != 0) { li = m + 1; } else { le = m; } } return(le - 1); }
public static void pushfuncname(lua_State L, lua_Debug ar) { if (pushglobalfuncname(L, ar)) /* try first a global name */ { cc.lua_pushfstring(L, "function '%s'", cc.lua_tostring(L, -1)); cc.lua_remove(L, -2); /* remove name */ } else if (ar.namewhat[0] != '\0') /* is there a name from code? */ { cc.lua_pushfstring(L, "%s %s", ar.namewhat, ar.name); /* use it */ } else if (ar.what[0] == 'm') /* main? */ { cc.lua_pushliteral(L, "main chunk"); } else if (ar.what[0] != 'C') /* for Lua functions, use <file:line> */ { cc.lua_pushfstring(L, "function <%s:%d>", ar.short_src, ar.linedefined); } else /* nothing left... */ { cc.lua_pushliteral(L, "?"); } }
/* ** Search for a name for a function in all loaded modules ** (registry._LOADED). */ public static bool pushglobalfuncname(lua_State L, lua_Debug ar) { int top = cc.lua_gettop(L); cc.lua_getinfo(L, "f", ar); /* push function */ cc.lua_getfield(L, cc.LUA_REGISTRYINDEX, "_LOADED"); if (findfield(L, top + 1, 2)) { string name = cc.lua_tostring(L, -1); if (name.Substring(0, 3) == "_G.") /* name start with '_G.'? */ { cc.lua_pushstring(L, name.Substring(3)); /* push name without prefix */ cc.lua_remove(L, -2); /* remove original name */ } cc.lua_copy(L, -1, top + 1); /* move name to proper place */ cc.lua_pop(L, 2); /* remove pushed values */ return(true); } else { cc.lua_settop(L, top); /* remove function and global table */ return(false); } }
public static int auxgetinfo(lua_State L, string what, int index, lua_Debug ar, Closure f, CallInfo ci) { int status = 1; for (int i = index; i < what.Length; i++) { switch (what[i]) { case 'S': { funcinfo(ar, f); break; } case 'l': { ar.currentline = (ci != null && isLua(ci)) ? currentline(L, ci) : -1; break; } case 'u': { ar.nups = (byte)((f == null) ? 0 : f.c.nupvalues); if (ldebug.noLuaClosure(f)) { ar.isvararg = 1; ar.nparams = 0; } else { ar.isvararg = f.l.p.is_vararg; ar.nparams = f.l.p.numparams; } break; } case 't': { ar.istailcall = (byte)((ci != null) ? (ci.callstatus & CIST_TAIL) : 0); break; } case 'n': { /* calling function is a known Lua function? */ if (ci != null && ((ci.callstatus & CIST_TAIL) != 0) && isLua(ci.previous)) { ar.namewhat = getfuncname(L, ci.previous, ref ar.name); } else { ar.namewhat = null; } if (ar.namewhat == null) { ar.namewhat = ""; /* not found */ ar.name = null; } break; } case 'L': goto case 'f'; case 'f': /* handled by lua_getinfo */ break; default: { status = 0; /* invalid option */ break; } } } return(status); }
/* ** Hook set by signal function to stop the interpreter. */ static void lstop(lua_State L, lua_Debug ar) { cc.lua_sethook(L, null, 0, 0); /* reset hook */ cc.luaL_error(L, "interrupted!"); }