mirror of https://github.com/lua/lua
first version of extra debug information (NAME)
This commit is contained in:
parent
4fbe775154
commit
298d0abff7
66
ldebug.c
66
ldebug.c
|
@ -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");
|
||||
}
|
||||
|
|
5
ldo.c
5
ldo.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ldo.c,v 1.60 1999/12/23 18:19:57 roberto Exp roberto $
|
||||
** $Id: ldo.c,v 1.61 1999/12/27 17:33:22 roberto Exp roberto $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -13,6 +13,7 @@
|
|||
#define LUA_REENTRANT
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "ldebug.h"
|
||||
#include "ldo.h"
|
||||
#include "lgc.h"
|
||||
#include "lmem.h"
|
||||
|
@ -220,7 +221,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
|
|||
default: { /* `func' is not a function; check the `function' tag method */
|
||||
const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
|
||||
if (ttype(im) == LUA_T_NIL)
|
||||
lua_error(L, "call expression not a function");
|
||||
luaG_callerror(L, func);
|
||||
luaD_openstack(L, func);
|
||||
*func = *im; /* tag method is the new function to be called */
|
||||
goto retry; /* retry the call (without calling callhook again) */
|
||||
|
|
29
lobject.h
29
lobject.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lobject.h,v 1.41 1999/12/23 18:19:57 roberto Exp roberto $
|
||||
** $Id: lobject.h,v 1.42 1999/12/27 17:33:22 roberto Exp roberto $
|
||||
** Type definitions for Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -72,16 +72,25 @@ typedef enum {
|
|||
LUA_T_LPROTO = -4, /* fixed tag for Lua functions */
|
||||
LUA_T_CPROTO = -5, /* fixed tag for C functions */
|
||||
LUA_T_NIL = -6, /* last "pre-defined" tag */
|
||||
|
||||
LUA_T_LCLOSURE = -7, /* Lua closure */
|
||||
LUA_T_CCLOSURE = -8, /* C closure */
|
||||
|
||||
LUA_T_LCLMARK = -9 ,/* mark for Lua closures */
|
||||
LUA_T_CCLMARK = -10,/* mark for C closures */
|
||||
LUA_T_LMARK = -11, /* mark for Lua prototypes */
|
||||
LUA_T_CMARK = -12, /* mark for C prototypes */
|
||||
LUA_T_LINE = -13
|
||||
|
||||
LUA_T_LINE = -13,
|
||||
LUA_T_NGLOBAL = -14,
|
||||
LUA_T_NLOCAL = -15,
|
||||
LUA_T_NDOT = -16
|
||||
} lua_Type;
|
||||
|
||||
#define NUM_TAGS 7
|
||||
#define NUM_TAGS 7 /* tags for values visible from Lua */
|
||||
|
||||
|
||||
#define LAST_REGULAR_TAG LUA_T_CCLOSURE /* after that, are all marks */
|
||||
|
||||
/*
|
||||
** chech whether `t' is a mark; ttypes are negative numbers, so the
|
||||
|
@ -91,13 +100,13 @@ typedef enum {
|
|||
|
||||
|
||||
typedef union {
|
||||
lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */
|
||||
real n; /* LUA_T_NUMBER */
|
||||
struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */
|
||||
struct TProtoFunc *tf; /* LUA_T_LPROTO, LUA_T_LMARK */
|
||||
struct Closure *cl; /* LUA_T_[CL]CLOSURE, LUA_T_[CL]CLMARK */
|
||||
struct Hash *a; /* LUA_T_ARRAY */
|
||||
int i; /* LUA_T_LINE */
|
||||
lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */
|
||||
real n; /* LUA_T_NUMBER */
|
||||
struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */
|
||||
struct TProtoFunc *tf; /* LUA_T_LPROTO, LUA_T_LMARK */
|
||||
struct Closure *cl; /* LUA_T_[CL]CLOSURE, LUA_T_[CL]CLMARK */
|
||||
struct Hash *a; /* LUA_T_ARRAY */
|
||||
int i; /* LUA_T_LINE */
|
||||
} Value;
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lopcodes.h,v 1.34 1999/11/25 18:59:43 roberto Exp roberto $
|
||||
** $Id: lopcodes.h,v 1.35 1999/12/27 17:33:22 roberto Exp roberto $
|
||||
** Opcodes for Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -102,6 +102,9 @@ CLOSURE,/* b c v_c-v_1 closure(CNST[b], v_c-v_1) */
|
|||
SETLINEW,/* w - - LINE=w */
|
||||
SETLINE,/* b - - LINE=b */
|
||||
|
||||
SETNAMEW,/* w c - - NAME=CNST[w],c */
|
||||
SETNAME,/* b c - - NAME=CNST[b],c */
|
||||
|
||||
LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */
|
||||
LONGARG /* b (add b*(1<<16) to arg of next instruction) */
|
||||
|
||||
|
|
38
lvm.c
38
lvm.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lvm.c,v 1.75 1999/12/23 18:19:57 roberto Exp roberto $
|
||||
** $Id: lvm.c,v 1.76 1999/12/27 17:33:22 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -12,6 +12,7 @@
|
|||
#define LUA_REENTRANT
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "ldebug.h"
|
||||
#include "ldo.h"
|
||||
#include "lfunc.h"
|
||||
#include "lgc.h"
|
||||
|
@ -33,7 +34,7 @@
|
|||
|
||||
|
||||
/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */
|
||||
#define EXTRA_STACK 5
|
||||
#define EXTRA_STACK 6
|
||||
|
||||
|
||||
|
||||
|
@ -105,7 +106,7 @@ void luaV_gettable (lua_State *L) {
|
|||
if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
|
||||
im = luaT_getimbyObj(L, table, IM_GETTABLE);
|
||||
if (ttype(im) == LUA_T_NIL)
|
||||
lua_error(L, "indexed expression not a table");
|
||||
luaG_indexerror(L, table);
|
||||
}
|
||||
else { /* object is a table... */
|
||||
int tg = table->value.a->htag;
|
||||
|
@ -138,7 +139,7 @@ void luaV_settable (lua_State *L, StkId t) {
|
|||
if (ttype(t) != LUA_T_ARRAY) { /* not a table, get `settable' method */
|
||||
im = luaT_getimbyObj(L, t, IM_SETTABLE);
|
||||
if (ttype(im) == LUA_T_NIL)
|
||||
lua_error(L, "indexed expression not a table");
|
||||
luaG_indexerror(L, t);
|
||||
}
|
||||
else { /* object is a table... */
|
||||
im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE);
|
||||
|
@ -587,17 +588,28 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
|||
|
||||
case SETLINEW: aux += highbyte(L, *pc++);
|
||||
case SETLINE: aux += *pc++;
|
||||
L->top = top;
|
||||
if ((base-1)->ttype != LUA_T_LINE) {
|
||||
/* open space for LINE value */
|
||||
luaD_openstack(L, base);
|
||||
base->ttype = LUA_T_LINE;
|
||||
base++;
|
||||
top++;
|
||||
if ((base-2)->ttype != LUA_T_LINE) {
|
||||
/* open space for LINE and NAME values */
|
||||
int i = top-base;
|
||||
while (i--) base[i+2] = base[i];
|
||||
base += 2;
|
||||
top += 2;
|
||||
(base-1)->ttype = LUA_T_NIL; /* initial value for NAME */
|
||||
(base-2)->ttype = LUA_T_LINE;
|
||||
}
|
||||
(base-1)->value.i = aux;
|
||||
if (L->linehook)
|
||||
(base-2)->value.i = aux;
|
||||
if (L->linehook) {
|
||||
L->top = top;
|
||||
luaD_lineHook(L, aux);
|
||||
}
|
||||
break;
|
||||
|
||||
case SETNAMEW: aux += highbyte(L, *pc++);
|
||||
case SETNAME: aux += *pc++;
|
||||
if ((base-2)->ttype == LUA_T_LINE) { /* function has debug info? */
|
||||
(base-1)->ttype = -(*pc++);
|
||||
(base-1)->value.i = aux;
|
||||
}
|
||||
break;
|
||||
|
||||
case LONGARGW: aux += highbyte(L, *pc++);
|
||||
|
|
Loading…
Reference in New Issue