public static int lua_getstack(LuaState L, int level, lua_Debug ar) { int status; CallInfo ci; lua_lock(L); for (ci = L.ci; level > 0 && ci > L.base_ci[0]; CallInfo.dec(ref ci)) { level--; if (f_isLua(ci)) /* Lua function? */ level -= ci.tailcalls; /* skip lost tail calls */ } if (level == 0 && ci > L.base_ci[0]) { /* level found? */ status = 1; ar.i_ci = ci - L.base_ci[0]; } else if (level < 0) { /* level is of a lost tail call? */ status = 1; ar.i_ci = 0; } else status = 0; /* no such level */ lua_unlock(L); return status; }
public extern static int lua_getinfo(lua_State L, string what, ref lua_Debug ar);
/* ** {====================================================== ** Error-report functions ** ======================================================= */ public static int luaL_argerror(LuaState L, int narg, CharPtr extramsg) { lua_Debug ar = new lua_Debug(); if (lua_getstack(L, 0, ar) == 0) /* no stack frame? */ return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); lua_getinfo(L, "n", ar); if (strcmp(ar.namewhat, "method") == 0) { narg--; /* do not count `self' */ if (narg == 0) /* error is in the self argument itself? */ return luaL_error(L, "calling " + LUA_QS + " on bad self ({1})", ar.name, extramsg); } if (ar.name == null) ar.name = "?"; return luaL_error(L, "bad argument #%d to " + LUA_QS + " (%s)", narg, ar.name, extramsg); }
public const int LEVELS2 = 10; /* size of the second part of the stack */ private static int db_errorfb (lua_State L) { int level; bool firstpart = true; /* still before eventual `...' */ int arg; lua_State L1 = getthread(L, out arg); lua_Debug ar = new lua_Debug(); if (lua_isnumber(L, arg+2) != 0) { level = (int)lua_tointeger(L, arg+2); lua_pop(L, 1); } else level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ if (lua_gettop(L) == arg) lua_pushliteral(L, ""); else if (lua_isstring(L, arg+1)==0) return 1; /* message is not a string */ else lua_pushliteral(L, "\n"); lua_pushliteral(L, "stack traceback:"); while (lua_getstack(L1, level++, ar) != 0) { if (level > LEVELS1 && firstpart) { /* no more than `LEVELS2' more levels? */ if (lua_getstack(L1, level+LEVELS2, ar)==0) level--; /* keep going */ else { lua_pushliteral(L, "\n\t..."); /* too many levels */ while (lua_getstack(L1, level+LEVELS2, ar) != 0) /* find last levels */ level++; } firstpart = false; continue; } lua_pushliteral(L, "\n\t"); lua_getinfo(L1, "Snl", ar); lua_pushfstring(L, "%s:", ar.short_src); if (ar.currentline > 0) lua_pushfstring(L, "%d:", ar.currentline); if (ar.namewhat != '\0') /* is there a name? */ lua_pushfstring(L, " in function " + LUA_QS, ar.name); else { if (ar.what == 'm') /* main? */ lua_pushfstring(L, " in main chunk"); else if (ar.what == 'C' || ar.what == 't') lua_pushliteral(L, " ?"); /* C function or tail call */ else lua_pushfstring(L, " in function <%s:%d>", ar.short_src, ar.linedefined); } lua_concat(L, lua_gettop(L) - arg); } lua_concat(L, lua_gettop(L) - arg); return 1; }
private static int db_setlocal (lua_State L) { int arg; lua_State L1 = getthread(L, out arg); lua_Debug ar = new lua_Debug(); if (lua_getstack(L1, luaL_checkint(L, arg+1), ar)==0) /* out of range? */ return luaL_argerror(L, arg+1, "level out of range"); luaL_checkany(L, arg+3); lua_settop(L, arg+3); lua_xmove(L, L1, 1); lua_pushstring(L, lua_setlocal(L1, ar, luaL_checkint(L, arg+2))); return 1; }
public static void luaD_callhook (lua_State L, int event_, int line) { lua_Hook hook = L.hook; if ((hook!=null) && (L.allowhook!=0)) { ptrdiff_t top = savestack(L, L.top); ptrdiff_t ci_top = savestack(L, L.ci.top); lua_Debug ar = new lua_Debug(); ar.event_ = event_; ar.currentline = line; if (event_ == LUA_HOOKTAILRET) ar.i_ci = 0; /* tail call; no debug information about it */ else ar.i_ci = L.ci - L.base_ci; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ L.ci.top = L.top + LUA_MINSTACK; lua_assert(L.ci.top <= L.stack_last); L.allowhook = 0; /* cannot call hooks inside a hook */ lua_unlock(L); hook(L, ar); lua_lock(L); lua_assert(L.allowhook==0); L.allowhook = 1; L.ci.top = restorestack(L, ci_top); L.top = restorestack(L, top); } }
public static extern int lua_getstack(lua_State L, int level, lua_Debug ar);
private static void getfunc(LuaState L, int opt) { if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); else { lua_Debug ar = new lua_Debug(); int level = (opt != 0) ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); if (lua_getstack(L, level, ar) == 0) luaL_argerror(L, 1, "invalid level"); lua_getinfo(L, "f", ar); if (lua_isnil(L, -1)) luaL_error(L, "no function environment for tail call at level %d", level); } }
private static int db_getinfo(lua_State L) { lua_Debug ar = new lua_Debug(); int arg; lua_State L1 = getthread(L, out arg); CharPtr options = luaL_optstring(L, arg + 2, "flnSu"); if (lua_isnumber(L, arg + 1) != 0) { if (lua_getstack(L1, (int)lua_tointeger(L, arg + 1), ar) == 0) { lua_pushnil(L); /* level out of range */ return(1); } } else if (lua_isfunction(L, arg + 1)) { lua_pushfstring(L, ">%s", options); options = lua_tostring(L, -1); lua_pushvalue(L, arg + 1); lua_xmove(L, L1, 1); } else { return(luaL_argerror(L, arg + 1, "function or level expected")); } if (lua_getinfo(L1, options, ar) == 0) { return(luaL_argerror(L, arg + 2, "invalid option")); } lua_createtable(L, 0, 2); if (strchr(options, 'S') != null) { settabss(L, "source", ar.source); settabss(L, "short_src", ar.short_src); settabsi(L, "linedefined", ar.linedefined); settabsi(L, "lastlinedefined", ar.lastlinedefined); settabss(L, "what", ar.what); } if (strchr(options, 'l') != null) { settabsi(L, "currentline", ar.currentline); } if (strchr(options, 'u') != null) { settabsi(L, "nups", ar.nups); } if (strchr(options, 'n') != null) { settabss(L, "name", ar.name); settabss(L, "namewhat", ar.namewhat); } if (strchr(options, 'L') != null) { treatstackoption(L, L1, "activelines"); } if (strchr(options, 'f') != null) { treatstackoption(L, L1, "func"); } return(1); /* return table */ }
public const int LEVELS2 = 10; /* size of the second part of the stack */ private static int db_errorfb(lua_State L) { int level; bool firstpart = true; /* still before eventual `...' */ int arg; lua_State L1 = getthread(L, out arg); lua_Debug ar = new lua_Debug(); if (lua_isnumber(L, arg + 2) != 0) { level = (int)lua_tointeger(L, arg + 2); lua_pop(L, 1); } else { level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ } if (lua_gettop(L) == arg) { lua_pushliteral(L, ""); } else if (lua_isstring(L, arg + 1) == 0) { return(1); /* message is not a string */ } else { lua_pushliteral(L, "\n"); } lua_pushliteral(L, "stack traceback:"); while (lua_getstack(L1, level++, ar) != 0) { if (level > LEVELS1 && firstpart) { /* no more than `LEVELS2' more levels? */ if (lua_getstack(L1, level + LEVELS2, ar) == 0) { level--; /* keep going */ } else { lua_pushliteral(L, "\n\t..."); /* too many levels */ while (lua_getstack(L1, level + LEVELS2, ar) != 0) /* find last levels */ { level++; } } firstpart = false; continue; } lua_pushliteral(L, "\n\t"); lua_getinfo(L1, "Snl", ar); lua_pushfstring(L, "%s:", ar.short_src); if (ar.currentline > 0) { lua_pushfstring(L, "%d:", ar.currentline); } if (ar.namewhat != '\0') /* is there a name? */ { lua_pushfstring(L, " in function " + LUA_QS, ar.name); } else { if (ar.what == 'm') /* main? */ { lua_pushfstring(L, " in main chunk"); } else if (ar.what == 'C' || ar.what == 't') { lua_pushliteral(L, " ?"); /* C function or tail call */ } else { lua_pushfstring(L, " in function <%s:%d>", ar.short_src, ar.linedefined); } } lua_concat(L, lua_gettop(L) - arg); } lua_concat(L, lua_gettop(L) - arg); return(1); }
static extern IntPtr _lua_setlocal(lua_State L, lua_Debug ar, int n);
public static String lua_setlocal(lua_State L, lua_Debug ar, int n) { return Marshal.PtrToStringAnsi(_lua_setlocal(L, ar, n)); }
public static int lua_getstack(IntPtr L, int level, ref lua_Debug ar) { return(NativeMethods.lua_getstack(L, level, ref ar)); }
/* ** Calls 'lua_getinfo' and collects all results in a new table. */ private static int db_getinfo(lua_State L) { lua_Debug ar = new lua_Debug(); int arg; lua_State L1 = getthread(L, out arg); CharPtr options = luaL_optstring(L, arg + 2, "flnStu"); if (lua_isfunction(L, arg + 1)) /* info about a function? */ { options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ lua_xmove(L, L1, 1); } else /* stack level */ { if (0 == lua_getstack(L1, luaL_checkint(L, arg + 1), ar)) { lua_pushnil(L); /* level out of range */ return(1); } } if (lua_getinfo(L1, options, ar) == 0) { return(luaL_argerror(L, arg + 2, "invalid option")); } lua_newtable(L); /* table to collect results */ if (strchr(options, 'S') != null) { settabss(L, "source", ar.source); settabss(L, "short_src", ar.short_src); settabsi(L, "linedefined", ar.linedefined); settabsi(L, "lastlinedefined", ar.lastlinedefined); settabss(L, "what", ar.what); } if (strchr(options, 'l') != null) { settabsi(L, "currentline", ar.currentline); } if (strchr(options, 'u') != null) { settabsi(L, "nups", ar.nups); settabsi(L, "nparams", ar.nparams); settabsb(L, "isvararg", ar.isvararg); } if (strchr(options, 'n') != null) { settabss(L, "name", ar.name); settabss(L, "namewhat", ar.namewhat); } if (strchr(options, 't') != null) { settabsb(L, "istailcall", ar.istailcall); } if (strchr(options, 'L') != null) { treatstackoption(L, L1, "activelines"); } if (strchr(options, 'f') != null) { treatstackoption(L, L1, "func"); } return(1); /* return table */ }
private static void info_tailcall(lua_Debug ar) { ar.name = ar.namewhat = ""; ar.what = "tail"; ar.lastlinedefined = ar.linedefined = ar.currentline = -1; ar.source = "=(tail call)"; luaO_chunkid(ar.short_src, ar.source, LUA_IDSIZE); ar.nups = 0; }
private static int auxgetinfo(lua_State L, CharPtr what, lua_Debug ar, Closure f, CallInfo ci) { int status = 1; for (; what[0] != 0; what = what.next()) { switch (what[0]) { case 'S': { funcinfo(ar, f); break; } case 'l': { ar.currentline = (ci != null && isLua(ci) != 0) ? currentline(ci) : -1; break; } case 'u': { ar.nups = (f == null) ? (byte)0 : f.c.nupvalues; //FIXME:(added) if (noLuaClosure(f)) { ar.isvararg = (char)1; ar.nparams = 0; } else { ar.isvararg = (char)(f.l.p.is_vararg); //FIXME: added (char) ar.nparams = f.l.p.numparams; } break; } case 't': { ar.istailcall = (ci != null) ? (char)(ci.callstatus & CIST_TAIL) : (char)0; //FIXME: added (char) break; } case 'n': { /* calling function is a known Lua function? */ if (ci != null && (ci.callstatus & CIST_TAIL) == 0 && isLua(ci.previous) != 0) { 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': case 'f': /* handled by lua_getinfo */ break; default: status = 0; break; /* invalid option */ } } return(status); }
private static int costatus(LuaState L, LuaState co) { if (L == co) return CO_RUN; switch (lua_status(co)) { case LUA_YIELD: return CO_SUS; case 0: { lua_Debug ar = new lua_Debug(); if (lua_getstack(co, 0, ar) > 0) /* does it have frames? */ return CO_NOR; /* it is running */ else if (lua_gettop(co) == 0) return CO_DEAD; else return CO_SUS; /* initial state */ } default: /* some error occured */ return CO_DEAD; } }
/* }====================================================== */ /* ** {====================================================== ** 'module' function ** ======================================================= */ private static void setfenv(lua_State L) { lua_Debug ar = new lua_Debug(); if (lua_getstack(L, 1, ar) == 0 || lua_getinfo(L, "f", ar) == 0 || /* get calling function */ lua_iscfunction(L, -1)) luaL_error(L, LUA_QL("module") + " not called from a Lua function"); lua_pushvalue(L, -2); lua_setfenv(L, -2); lua_pop(L, 1); }
public static extern int lua_getinfo(lua_State L, string what, lua_Debug ar);
public static int lua_getinfo(LuaState L, CharPtr what, lua_Debug ar) { int status; Closure f = null; CallInfo ci = null; lua_lock(L); if (what == '>') { StkId func = L.top - 1; luai_apicheck(L, ttisfunction(func)); what = what.next(); /* skip the '>' */ f = clvalue(func); StkId.dec(ref L.top); /* pop function */ } else if (ar.i_ci != 0) { /* no tail call? */ ci = L.base_ci[ar.i_ci]; lua_assert(ttisfunction(ci.func)); f = clvalue(ci.func); } status = auxgetinfo(L, what, ar, f, ci); if (strchr(what, 'f') != null) { if (f == null) setnilvalue(L.top); else setclvalue(L, L.top, f); incr_top(L); } if (strchr(what, 'L') != null) collectvalidlines(L, f); lua_unlock(L); return status; }
public static extern string lua_setlocal(lua_State L, lua_Debug ar, int n);
public static CharPtr lua_getlocal(LuaState L, lua_Debug ar, int n) { CallInfo ci = L.base_ci[ar.i_ci]; CharPtr name = findlocal(L, ci, n); lua_lock(L); if (name != null) luaA_pushobject(L, ci.base_[n - 1]); lua_unlock(L); return name; }
private static int db_getlocal (lua_State L) { int arg; lua_State L1 = getthread(L, out arg); lua_Debug ar = new lua_Debug(); CharPtr name; if (lua_getstack(L1, luaL_checkint(L, arg+1), ar)==0) /* out of range? */ return luaL_argerror(L, arg+1, "level out of range"); name = lua_getlocal(L1, ar, luaL_checkint(L, arg+2)); if (name != null) { lua_xmove(L1, L, 1); lua_pushstring(L, name); lua_pushvalue(L, -2); return 2; } else { lua_pushnil(L); return 1; } }
public static CharPtr lua_setlocal(LuaState L, lua_Debug ar, int n) { CallInfo ci = L.base_ci[ar.i_ci]; CharPtr name = findlocal(L, ci, n); lua_lock(L); if (name != null) setobjs2s(L, ci.base_[n - 1], L.top - 1); StkId.dec(ref L.top); /* pop value */ lua_unlock(L); return name; }
private static void hookf (lua_State L, lua_Debug ar) { lua_pushlightuserdata(L, KEY_HOOK); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushlightuserdata(L, L); lua_rawget(L, -2); if (lua_isfunction(L, -1)) { lua_pushstring(L, hooknames[(int)ar.event_]); if (ar.currentline >= 0) lua_pushinteger(L, ar.currentline); else lua_pushnil(L); lua_assert(lua_getinfo(L, "lS", ar)); lua_call(L, 2, 0); } }
private static int auxgetinfo(LuaState L, CharPtr what, lua_Debug ar, Closure f, CallInfo ci) { int status = 1; if (f == null) { info_tailcall(ar); return status; } for (; what[0] != 0; what = what.next()) { switch (what[0]) { case 'S': { funcinfo(ar, f); break; } case 'l': { ar.currentline = (ci != null) ? currentline(L, ci) : -1; break; } case 'u': { ar.nups = f.c.nupvalues; break; } case 'n': { ar.namewhat = (ci != null) ? getfuncname(L, ci, ref ar.name) : null; if (ar.namewhat == null) { ar.namewhat = ""; /* not found */ ar.name = null; } break; } case 'L': case 'f': /* handled by lua_getinfo */ break; default: status = 0; break;/* invalid option */ } } return status; }
private static int db_getinfo (lua_State L) { lua_Debug ar = new lua_Debug(); int arg; lua_State L1 = getthread(L, out arg); CharPtr options = luaL_optstring(L, arg+2, "flnSu"); if (lua_isnumber(L, arg+1) != 0) { if (lua_getstack(L1, (int)lua_tointeger(L, arg+1), ar)==0) { lua_pushnil(L); /* level out of range */ return 1; } } else if (lua_isfunction(L, arg+1)) { lua_pushfstring(L, ">%s", options); options = lua_tostring(L, -1); lua_pushvalue(L, arg+1); lua_xmove(L, L1, 1); } else return luaL_argerror(L, arg+1, "function or level expected"); if (lua_getinfo(L1, options, ar)==0) return luaL_argerror(L, arg+2, "invalid option"); lua_createtable(L, 0, 2); if (strchr(options, 'S') != null) { settabss(L, "source", ar.source); settabss(L, "short_src", ar.short_src); settabsi(L, "linedefined", ar.linedefined); settabsi(L, "lastlinedefined", ar.lastlinedefined); settabss(L, "what", ar.what); } if (strchr(options, 'l') != null) settabsi(L, "currentline", ar.currentline); if (strchr(options, 'u') != null) settabsi(L, "nups", ar.nups); if (strchr(options, 'n') != null) { settabss(L, "name", ar.name); settabss(L, "namewhat", ar.namewhat); } if (strchr(options, 'L') != null) treatstackoption(L, L1, "activelines"); if (strchr(options, 'f') != null) treatstackoption(L, L1, "func"); return 1; /* return table */ }
private static void funcinfo(lua_Debug ar, Closure cl) { if (cl.c.isC != 0) { ar.source = "=[CLR]"; ar.linedefined = -1; ar.lastlinedefined = -1; ar.what = "CLR"; } else { ar.source = getstr(cl.l.p.source); ar.linedefined = cl.l.p.linedefined; ar.lastlinedefined = cl.l.p.lastlinedefined; ar.what = (ar.linedefined == 0) ? "main" : "Lua"; } luaO_chunkid(ar.short_src, ar.source, LUA_IDSIZE); }
public static void luaL_where(LuaState 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 extern static int lua_getstack(lua_State L, int level, ref lua_Debug ar);