1dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 2dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** $Id: ldebug.c,v 2.90 2012/08/16 17:34:28 roberto Exp $ 3dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Debug Interface 4dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** See Copyright Notice in lua.h 5dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 6dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 7dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 8dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <stdarg.h> 9dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <stddef.h> 10dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <string.h> 11dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 12dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 13dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define ldebug_c 14dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_CORE 15dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 16dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lua.h" 17dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 18dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lapi.h" 19dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lcode.h" 20dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "ldebug.h" 21dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "ldo.h" 22dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lfunc.h" 23dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lobject.h" 24dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lopcodes.h" 25dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lstate.h" 26dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lstring.h" 27dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "ltable.h" 28dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "ltm.h" 29dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lvm.h" 30dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 31dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 32dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 33dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) 34dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 35dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 36dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); 37dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 38dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 39dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int currentpc (CallInfo *ci) { 40dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_assert(isLua(ci)); 41dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return pcRel(ci->u.l.savedpc, ci_func(ci)->p); 42dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 43dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 44dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 45dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int currentline (CallInfo *ci) { 46dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return getfuncline(ci_func(ci)->p, currentpc(ci)); 47dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 48dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 49dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 50dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 51dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** this function can be called asynchronous (e.g. during a signal) 52dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 53dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { 54dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (func == NULL || mask == 0) { /* turn off hooks? */ 55dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com mask = 0; 56dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com func = NULL; 57dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 58dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (isLua(L->ci)) 59dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com L->oldpc = L->ci->u.l.savedpc; 60dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com L->hook = func; 61dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com L->basehookcount = count; 62dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com resethookcount(L); 63dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com L->hookmask = cast_byte(mask); 64dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 1; 65dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 66dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 67dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 68dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUA_API lua_Hook lua_gethook (lua_State *L) { 69dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return L->hook; 70dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 71dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 72dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 73dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUA_API int lua_gethookmask (lua_State *L) { 74dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return L->hookmask; 75dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 76dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 77dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 78dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUA_API int lua_gethookcount (lua_State *L) { 79dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return L->basehookcount; 80dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 81dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 82dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 83dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { 84dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int status; 85dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com CallInfo *ci; 86dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (level < 0) return 0; /* invalid (negative) level */ 87dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_lock(L); 88dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) 89dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com level--; 90dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (level == 0 && ci != &L->base_ci) { /* level found? */ 91dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com status = 1; 92dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->i_ci = ci; 93dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 94dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else status = 0; /* no such level */ 95dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_unlock(L); 96dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return status; 97dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 98dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 99dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 100dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *upvalname (Proto *p, int uv) { 101dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); 102dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (s == NULL) return "?"; 103dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else return getstr(s); 104dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 105dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 106dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 107dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *findvararg (CallInfo *ci, int n, StkId *pos) { 108dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int nparams = clLvalue(ci->func)->p->numparams; 109dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (n >= ci->u.l.base - ci->func - nparams) 110dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return NULL; /* no such vararg */ 111dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { 112dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *pos = ci->func + nparams + n; 113dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return "(*vararg)"; /* generic name for any vararg */ 114dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 115dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 116dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 117dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 118dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *findlocal (lua_State *L, CallInfo *ci, int n, 119dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com StkId *pos) { 120dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *name = NULL; 121dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com StkId base; 122dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (isLua(ci)) { 123dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (n < 0) /* access to vararg values? */ 124dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return findvararg(ci, -n, pos); 125dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { 126dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com base = ci->u.l.base; 127dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); 128dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 129dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 130dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else 131dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com base = ci->func + 1; 132dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (name == NULL) { /* no 'standard' name? */ 133dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com StkId limit = (ci == L->ci) ? L->top : ci->next->func; 134dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ 135dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com name = "(*temporary)"; /* generic name for any valid slot */ 136dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else 137dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return NULL; /* no name */ 138dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 139dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *pos = base + (n - 1); 140dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return name; 141dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 142dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 143dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 144dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 145dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *name; 146dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_lock(L); 147dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (ar == NULL) { /* information about non-active function? */ 148dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (!isLfunction(L->top - 1)) /* not a Lua function? */ 149dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com name = NULL; 150dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else /* consider live variables at function start (parameters) */ 151dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); 152dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 153dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { /* active function; get information through 'ar' */ 154dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com StkId pos = 0; /* to avoid warnings */ 155dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com name = findlocal(L, ar->i_ci, n, &pos); 156dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (name) { 157dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setobj2s(L, L->top, pos); 158dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com api_incr_top(L); 159dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 160dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 161dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_unlock(L); 162dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return name; 163dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 164dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 165dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 166dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { 167dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com StkId pos = 0; /* to avoid warnings */ 168dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *name = findlocal(L, ar->i_ci, n, &pos); 169dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_lock(L); 170dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (name) 171dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setobjs2s(L, pos, L->top - 1); 172dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com L->top--; /* pop value */ 173dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_unlock(L); 174dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return name; 175dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 176dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 177dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 178dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void funcinfo (lua_Debug *ar, Closure *cl) { 179dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (noLuaClosure(cl)) { 180dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->source = "=[C]"; 181dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->linedefined = -1; 182dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->lastlinedefined = -1; 183dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->what = "C"; 184dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 185dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { 186dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com Proto *p = cl->l.p; 187dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->source = p->source ? getstr(p->source) : "=?"; 188dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->linedefined = p->linedefined; 189dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->lastlinedefined = p->lastlinedefined; 190dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->what = (ar->linedefined == 0) ? "main" : "Lua"; 191dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 192dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); 193dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 194dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 195dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 196dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void collectvalidlines (lua_State *L, Closure *f) { 197dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (noLuaClosure(f)) { 198dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setnilvalue(L->top); 199dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com api_incr_top(L); 200dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 201dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { 202dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int i; 203dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com TValue v; 204dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int *lineinfo = f->l.p->lineinfo; 205dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com Table *t = luaH_new(L); /* new table to store active lines */ 206dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com sethvalue(L, L->top, t); /* push it on stack */ 207dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com api_incr_top(L); 208dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ 209dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ 210dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ 211dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 212dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 213dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 214dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 215dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, 216dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com Closure *f, CallInfo *ci) { 217dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int status = 1; 218dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (; *what; what++) { 219dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com switch (*what) { 220dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case 'S': { 221dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com funcinfo(ar, f); 222dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 223dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 224dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case 'l': { 225dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; 226dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 227dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 228dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case 'u': { 229dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->nups = (f == NULL) ? 0 : f->c.nupvalues; 230dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (noLuaClosure(f)) { 231dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->isvararg = 1; 232dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->nparams = 0; 233dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 234dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { 235dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->isvararg = f->l.p->is_vararg; 236dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->nparams = f->l.p->numparams; 237dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 238dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 239dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 240dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case 't': { 241dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; 242dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 243dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 244dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case 'n': { 245dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* calling function is a known Lua function? */ 246dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) 247dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->namewhat = getfuncname(L, ci->previous, &ar->name); 248dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else 249dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->namewhat = NULL; 250dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (ar->namewhat == NULL) { 251dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->namewhat = ""; /* not found */ 252dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ar->name = NULL; 253dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 254dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 255dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 256dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case 'L': 257dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case 'f': /* handled by lua_getinfo */ 258dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 259dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com default: status = 0; /* invalid option */ 260dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 261dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 262dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return status; 263dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 264dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 265dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 266dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { 267dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int status; 268dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com Closure *cl; 269dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com CallInfo *ci; 270dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com StkId func; 271dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_lock(L); 272dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (*what == '>') { 273dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ci = NULL; 274dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com func = L->top - 1; 275dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com api_check(L, ttisfunction(func), "function expected"); 276dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com what++; /* skip the '>' */ 277dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com L->top--; /* pop function */ 278dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 279dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { 280dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ci = ar->i_ci; 281dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com func = ci->func; 282dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_assert(ttisfunction(ci->func)); 283dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 284dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com cl = ttisclosure(func) ? clvalue(func) : NULL; 285dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com status = auxgetinfo(L, what, ar, cl, ci); 286dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (strchr(what, 'f')) { 287dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setobjs2s(L, L->top, func); 288dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com api_incr_top(L); 289dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 290dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (strchr(what, 'L')) 291dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com collectvalidlines(L, cl); 292dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_unlock(L); 293dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return status; 294dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 295dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 296dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 297dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 298dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {====================================================== 299dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Symbolic Execution 300dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** ======================================================= 301dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 302dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 303dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *getobjname (Proto *p, int lastpc, int reg, 304dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char **name); 305dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 306dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 307dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 308dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** find a "name" for the RK value 'c' 309dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 310dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void kname (Proto *p, int pc, int c, const char **name) { 311dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (ISK(c)) { /* is 'c' a constant? */ 312dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com TValue *kvalue = &p->k[INDEXK(c)]; 313dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (ttisstring(kvalue)) { /* literal constant? */ 314dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *name = svalue(kvalue); /* it is its own name */ 315dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return; 316dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 317dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* else no reasonable name found */ 318dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 319dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { /* 'c' is a register */ 320dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *what = getobjname(p, pc, c, name); /* search for 'c' */ 321dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (what && *what == 'c') { /* found a constant name? */ 322dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return; /* 'name' already filled */ 323dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 324dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* else no reasonable name found */ 325dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 326dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *name = "?"; /* no reasonable name found */ 327dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 328dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 329dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 330dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 331dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** try to find last instruction before 'lastpc' that modified register 'reg' 332dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 333dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int findsetreg (Proto *p, int lastpc, int reg) { 334dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int pc; 335dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int setreg = -1; /* keep last instruction that changed 'reg' */ 336dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (pc = 0; pc < lastpc; pc++) { 337dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com Instruction i = p->code[pc]; 338dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com OpCode op = GET_OPCODE(i); 339dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int a = GETARG_A(i); 340dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com switch (op) { 341dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_LOADNIL: { 342dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int b = GETARG_B(i); 343dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ 344dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setreg = pc; 345dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 346dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 347dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_TFORCALL: { 348dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (reg >= a + 2) setreg = pc; /* affect all regs above its base */ 349dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 350dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 351dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_CALL: 352dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_TAILCALL: { 353dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (reg >= a) setreg = pc; /* affect all registers above base */ 354dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 355dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 356dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_JMP: { 357dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int b = GETARG_sBx(i); 358dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int dest = pc + 1 + b; 359dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* jump is forward and do not skip `lastpc'? */ 360dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (pc < dest && dest <= lastpc) 361dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com pc += b; /* do the jump */ 362dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 363dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 364dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_TEST: { 365dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (reg == a) setreg = pc; /* jumped code can change 'a' */ 366dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 367dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 368dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com default: 369dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (testAMode(op) && reg == a) /* any instruction that set A */ 370dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setreg = pc; 371dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 372dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 373dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 374dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return setreg; 375dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 376dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 377dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 378dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *getobjname (Proto *p, int lastpc, int reg, 379dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char **name) { 380dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int pc; 381dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *name = luaF_getlocalname(p, reg + 1, lastpc); 382dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (*name) /* is a local? */ 383dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return "local"; 384dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* else try symbolic execution */ 385dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com pc = findsetreg(p, lastpc, reg); 386dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (pc != -1) { /* could find instruction? */ 387dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com Instruction i = p->code[pc]; 388dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com OpCode op = GET_OPCODE(i); 389dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com switch (op) { 390dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_MOVE: { 391dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int b = GETARG_B(i); /* move from 'b' to 'a' */ 392dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (b < GETARG_A(i)) 393dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return getobjname(p, pc, b, name); /* get name for 'b' */ 394dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 395dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 396dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_GETTABUP: 397dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_GETTABLE: { 398dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int k = GETARG_C(i); /* key index */ 399dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int t = GETARG_B(i); /* table index */ 400dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ 401dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ? luaF_getlocalname(p, t + 1, pc) 402dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com : upvalname(p, t); 403dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com kname(p, pc, k, name); 404dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; 405dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 406dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_GETUPVAL: { 407dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *name = upvalname(p, GETARG_B(i)); 408dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return "upvalue"; 409dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 410dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_LOADK: 411dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_LOADKX: { 412dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int b = (op == OP_LOADK) ? GETARG_Bx(i) 413dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com : GETARG_Ax(p->code[pc + 1]); 414dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (ttisstring(&p->k[b])) { 415dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *name = svalue(&p->k[b]); 416dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return "constant"; 417dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 418dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com break; 419dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 420dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_SELF: { 421dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int k = GETARG_C(i); /* key index */ 422dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com kname(p, pc, k, name); 423dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return "method"; 424dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 425dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com default: break; /* go through to return NULL */ 426dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 427dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 428dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return NULL; /* could not find reasonable name */ 429dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 430dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 431dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 432dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { 433dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com TMS tm; 434dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com Proto *p = ci_func(ci)->p; /* calling function */ 435dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int pc = currentpc(ci); /* calling instruction index */ 436dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com Instruction i = p->code[pc]; /* calling instruction */ 437dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com switch (GET_OPCODE(i)) { 438dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_CALL: 439dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_TAILCALL: /* get function name */ 440dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return getobjname(p, pc, GETARG_A(i), name); 441dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_TFORCALL: { /* for iterator */ 442dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *name = "for iterator"; 443dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return "for iterator"; 444dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 445dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* all other instructions can call only through metamethods */ 446dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_SELF: 447dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_GETTABUP: 448dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_GETTABLE: tm = TM_INDEX; break; 449dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_SETTABUP: 450dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_SETTABLE: tm = TM_NEWINDEX; break; 451dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_EQ: tm = TM_EQ; break; 452dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_ADD: tm = TM_ADD; break; 453dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_SUB: tm = TM_SUB; break; 454dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_MUL: tm = TM_MUL; break; 455dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_DIV: tm = TM_DIV; break; 456dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_MOD: tm = TM_MOD; break; 457dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_POW: tm = TM_POW; break; 458dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_UNM: tm = TM_UNM; break; 459dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_LEN: tm = TM_LEN; break; 460dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_LT: tm = TM_LT; break; 461dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_LE: tm = TM_LE; break; 462dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com case OP_CONCAT: tm = TM_CONCAT; break; 463dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com default: 464dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return NULL; /* else no useful name can be found */ 465dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 466dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *name = getstr(G(L)->tmname[tm]); 467dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return "metamethod"; 468dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 469dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 470dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */ 471dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 472dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 473dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 474dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 475dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** only ANSI way to check whether a pointer points to an array 476dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** (used only for error messages, so efficiency is not a big concern) 477dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 478dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int isinstack (CallInfo *ci, const TValue *o) { 479dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com StkId p; 480dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (p = ci->u.l.base; p < ci->top; p++) 481dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (o == p) return 1; 482dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 0; 483dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 484dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 485dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 486dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *getupvalname (CallInfo *ci, const TValue *o, 487dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char **name) { 488dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com LClosure *c = ci_func(ci); 489dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int i; 490dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (i = 0; i < c->nupvalues; i++) { 491dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (c->upvals[i]->v == o) { 492dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *name = upvalname(c->p, i); 493dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return "upvalue"; 494dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 495dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 496dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return NULL; 497dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 498dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 499dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 500dff7e11c2000d6745261de046d76b1500a05ece9reed@google.coml_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { 501dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com CallInfo *ci = L->ci; 502dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *name = NULL; 503dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *t = objtypename(o); 504dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *kind = NULL; 505dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (isLua(ci)) { 506dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ 507dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (!kind && isinstack(ci, o)) /* no? try a register */ 508dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com kind = getobjname(ci_func(ci)->p, currentpc(ci), 509dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com cast_int(o - ci->u.l.base), &name); 510dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 511dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (kind) 512dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", 513dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com op, kind, name, t); 514dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else 515dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaG_runerror(L, "attempt to %s a %s value", op, t); 516dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 517dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 518dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 519dff7e11c2000d6745261de046d76b1500a05ece9reed@google.coml_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) { 520dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; 521dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_assert(!ttisstring(p1) && !ttisnumber(p2)); 522dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaG_typeerror(L, p1, "concatenate"); 523dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 524dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 525dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 526dff7e11c2000d6745261de046d76b1500a05ece9reed@google.coml_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { 527dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com TValue temp; 528dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (luaV_tonumber(p1, &temp) == NULL) 529dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com p2 = p1; /* first operand is wrong */ 530dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaG_typeerror(L, p2, "perform arithmetic on"); 531dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 532dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 533dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 534dff7e11c2000d6745261de046d76b1500a05ece9reed@google.coml_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { 535dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *t1 = objtypename(p1); 536dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *t2 = objtypename(p2); 537dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (t1 == t2) 538dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaG_runerror(L, "attempt to compare two %s values", t1); 539dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else 540dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaG_runerror(L, "attempt to compare %s with %s", t1, t2); 541dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 542dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 543dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 544dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void addinfo (lua_State *L, const char *msg) { 545dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com CallInfo *ci = L->ci; 546dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (isLua(ci)) { /* is Lua code? */ 547dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com char buff[LUA_IDSIZE]; /* add file:line information */ 548dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int line = currentline(ci); 549dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com TString *src = ci_func(ci)->p->source; 550dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (src) 551dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaO_chunkid(buff, getstr(src), LUA_IDSIZE); 552dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { /* no source available; use "?" instead */ 553dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com buff[0] = '?'; buff[1] = '\0'; 554dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 555dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); 556dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 557dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 558dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 559dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 560dff7e11c2000d6745261de046d76b1500a05ece9reed@google.coml_noret luaG_errormsg (lua_State *L) { 561dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (L->errfunc != 0) { /* is there an error handling function? */ 562dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com StkId errfunc = restorestack(L, L->errfunc); 563dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); 564dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setobjs2s(L, L->top, L->top - 1); /* move argument */ 565dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setobjs2s(L, L->top - 1, errfunc); /* push function */ 566dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com L->top++; 567dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaD_call(L, L->top - 2, 1, 0); /* call it */ 568dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 569dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaD_throw(L, LUA_ERRRUN); 570dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 571dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 572dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 573dff7e11c2000d6745261de046d76b1500a05ece9reed@google.coml_noret luaG_runerror (lua_State *L, const char *fmt, ...) { 574dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com va_list argp; 575dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com va_start(argp, fmt); 576dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com addinfo(L, luaO_pushvfstring(L, fmt, argp)); 577dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com va_end(argp); 578dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaG_errormsg(L); 579dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 580dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 581