|
|
@ -1,5 +1,5 @@ |
|
|
|
/*
|
|
|
|
** $Id: ldebug.c,v 1.1 1999/12/14 18:31:20 roberto Exp roberto $ |
|
|
|
** $Id: ldebug.c,v 1.2 1999/12/23 18:19:57 roberto Exp roberto $ |
|
|
|
** Debug Interface |
|
|
|
** See Copyright Notice in lua.h |
|
|
|
*/ |
|
|
@ -8,6 +8,8 @@ |
|
|
|
#define LUA_REENTRANT |
|
|
|
|
|
|
|
#include "lapi.h" |
|
|
|
#include "lauxlib.h" |
|
|
|
#include "ldebug.h" |
|
|
|
#include "lfunc.h" |
|
|
|
#include "lobject.h" |
|
|
|
#include "lstate.h" |
|
|
@ -17,6 +19,10 @@ |
|
|
|
#include "luadebug.h" |
|
|
|
|
|
|
|
|
|
|
|
static int hasdebuginfo (lua_State *L, lua_Function f) { |
|
|
|
return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
lua_LHFunction lua_setlinehook (lua_State *L, lua_LHFunction func) { |
|
|
|
lua_LHFunction old = L->linehook; |
|
|
@ -52,6 +58,29 @@ lua_Function lua_stackedfunction (lua_State *L, int level) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const char *luaG_getname (lua_State *L, const char **name) { |
|
|
|
lua_Function f = lua_stackedfunction(L, 0); |
|
|
|
if (f == LUA_NOOBJECT || !hasdebuginfo(L, f) || ttype(f+2) == LUA_T_NIL) |
|
|
|
return NULL; /* no name available */ |
|
|
|
else { |
|
|
|
int i = (f+2)->value.i; |
|
|
|
if (ttype(f) == LUA_T_LCLMARK) |
|
|
|
f = protovalue(f); |
|
|
|
LUA_ASSERT(L, ttype(f) == LUA_T_LMARK, "must be a Lua function"); |
|
|
|
LUA_ASSERT(L, ttype(&tfvalue(f)->consts[i]) == LUA_T_STRING, ""); |
|
|
|
*name = tsvalue(&tfvalue(f)->consts[i])->str; |
|
|
|
switch (ttype(f+2)) { |
|
|
|
case LUA_T_NGLOBAL: return "global"; |
|
|
|
case LUA_T_NLOCAL: return "local"; |
|
|
|
case LUA_T_NDOT: return "field"; |
|
|
|
default: |
|
|
|
LUA_INTERNALERROR(L, "invalid tag for NAME"); |
|
|
|
return NULL; /* unreacheable; to avoid warnings */ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int lua_nups (lua_State *L, lua_Function f) { |
|
|
|
UNUSED(L); |
|
|
|
switch (luaA_normalizedtype(f)) { |
|
|
@ -64,7 +93,7 @@ int lua_nups (lua_State *L, lua_Function f) { |
|
|
|
|
|
|
|
|
|
|
|
int lua_currentline (lua_State *L, lua_Function f) { |
|
|
|
return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1; |
|
|
|
return hasdebuginfo(L, f) ? (f+1)->value.i : -1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -77,9 +106,10 @@ lua_Object lua_getlocal (lua_State *L, lua_Function f, int local_number, |
|
|
|
TProtoFunc *fp = luaA_protovalue(f)->value.tf; |
|
|
|
*name = luaF_getlocalname(fp, local_number, lua_currentline(L, f)); |
|
|
|
if (*name) { |
|
|
|
/* if "*name", there must be a LUA_T_LINE */ |
|
|
|
/* therefore, f+2 points to function base */ |
|
|
|
return luaA_putluaObject(L, (f+2)+(local_number-1)); |
|
|
|
/* if "*name", there must be a LUA_T_LINE and a NAME */ |
|
|
|
/* therefore, f+3 points to function base */ |
|
|
|
LUA_ASSERT(L, ttype(f+1) == LUA_T_LINE, ""); |
|
|
|
return luaA_putluaObject(L, (f+3)+(local_number-1)); |
|
|
|
} |
|
|
|
else |
|
|
|
return LUA_NOOBJECT; |
|
|
@ -98,9 +128,8 @@ int lua_setlocal (lua_State *L, lua_Function f, int local_number) { |
|
|
|
luaA_checkCparams(L, 1); |
|
|
|
--L->top; |
|
|
|
if (name) { |
|
|
|
/* if "name", there must be a LUA_T_LINE */ |
|
|
|
/* therefore, f+2 points to function base */ |
|
|
|
*((f+2)+(local_number-1)) = *L->top; |
|
|
|
LUA_ASSERT(L, ttype(f+1) == LUA_T_LINE, ""); |
|
|
|
*((f+3)+(local_number-1)) = *L->top; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
else |
|
|
@ -148,3 +177,24 @@ const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) { |
|
|
|
else return ""; /* not found at all */ |
|
|
|
} |
|
|
|
|
|
|
|
static void call_index_error (lua_State *L, TObject *o, const char *tp, |
|
|
|
const char *v) { |
|
|
|
const char *name; |
|
|
|
const char *kind = luaG_getname(L, &name); |
|
|
|
if (kind) { /* is there a name? */ |
|
|
|
luaL_verror(L, "%.10s `%.30s' is not a %.10s", kind, name, tp); |
|
|
|
} |
|
|
|
else { |
|
|
|
luaL_verror(L, "attempt to %.10s a %.10s value", v, lua_type(L, o)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void luaG_callerror (lua_State *L, TObject *func) { |
|
|
|
call_index_error(L, func, "function", "call"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void luaG_indexerror (lua_State *L, TObject *t) { |
|
|
|
call_index_error(L, t, "table", "index"); |
|
|
|
} |
|
|
|