better error messages

This commit is contained in:
Roberto Ierusalimschy
2000-06-28 17:21:06 -03:00
parent b622282973
commit 014a09c509
10 changed files with 230 additions and 104 deletions

108
lcode.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lcode.c,v 1.38 2000/06/21 18:13:56 roberto Exp roberto $ ** $Id: lcode.c,v 1.39 2000/06/26 19:28:31 roberto Exp roberto $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -423,12 +423,9 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
} }
#define VD 100 /* flag for variable delta */
int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
Instruction i = previous_instruction(fs); Instruction i = previous_instruction(fs);
int delta = luaK_opproperties[o].delta; int delta = luaK_opproperties[o].push - luaK_opproperties[o].pop;
int optm = 0; /* 1 when there is an optimization */ int optm = 0; /* 1 when there is an optimization */
switch (o) { switch (o) {
case OP_CLOSURE: { case OP_CLOSURE: {
@@ -621,7 +618,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
case iS: i = CREATE_S(o, arg1); break; case iS: i = CREATE_S(o, arg1); break;
case iAB: i = CREATE_AB(o, arg1, arg2); break; case iAB: i = CREATE_AB(o, arg1, arg2); break;
} }
if (fs->f->debug) { if (fs->debug) {
LexState *ls = fs->ls; LexState *ls = fs->ls;
luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk"); luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk");
luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, "??", MAXARG_U); luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, "??", MAXARG_U);
@@ -636,53 +633,54 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
const struct OpProperties luaK_opproperties[NUM_OPCODES] = { const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
{iO, 0}, /* OP_END */ {iO, 0, 0}, /* OP_END */
{iU, 0}, /* OP_RETURN */ {iU, 0, 0}, /* OP_RETURN */
{iAB, 0}, /* OP_CALL */ {iAB, 0, 0}, /* OP_CALL */
{iAB, 0}, /* OP_TAILCALL */ {iAB, 0, 0}, /* OP_TAILCALL */
{iU, VD}, /* OP_PUSHNIL */ {iU, VD, 0}, /* OP_PUSHNIL */
{iU, VD}, /* OP_POP */ {iU, VD, 0}, /* OP_POP */
{iS, 1}, /* OP_PUSHINT */ {iS, 1, 0}, /* OP_PUSHINT */
{iU, 1}, /* OP_PUSHSTRING */ {iU, 1, 0}, /* OP_PUSHSTRING */
{iU, 1}, /* OP_PUSHNUM */ {iU, 1, 0}, /* OP_PUSHNUM */
{iU, 1}, /* OP_PUSHNEGNUM */ {iU, 1, 0}, /* OP_PUSHNEGNUM */
{iU, 1}, /* OP_PUSHUPVALUE */ {iU, 1, 0}, /* OP_PUSHUPVALUE */
{iU, 1}, /* OP_GETLOCAL */ {iU, 1, 0}, /* OP_GETLOCAL */
{iU, 1}, /* OP_GETGLOBAL */ {iU, 1, 0}, /* OP_GETGLOBAL */
{iO, -1}, /* OP_GETTABLE */ {iO, 1, 2}, /* OP_GETTABLE */
{iU, 0}, /* OP_GETDOTTED */ {iU, 1, 1}, /* OP_GETDOTTED */
{iU, 0}, /* OP_GETINDEXED */ {iU, 1, 1}, /* OP_GETINDEXED */
{iU, 1}, /* OP_PUSHSELF */ {iU, 2, 1}, /* OP_PUSHSELF */
{iU, 1}, /* OP_CREATETABLE */ {iU, 1, 0}, /* OP_CREATETABLE */
{iU, -1}, /* OP_SETLOCAL */ {iU, 0, 1}, /* OP_SETLOCAL */
{iU, -1}, /* OP_SETGLOBAL */ {iU, 0, 1}, /* OP_SETGLOBAL */
{iAB, VD}, /* OP_SETTABLE */ {iAB, VD, 0}, /* OP_SETTABLE */
{iAB, VD}, /* OP_SETLIST */ {iAB, VD, 0}, /* OP_SETLIST */
{iU, VD}, /* OP_SETMAP */ {iU, VD, 0}, /* OP_SETMAP */
{iO, -1}, /* OP_ADD */ {iO, 1, 2}, /* OP_ADD */
{iS, 0}, /* OP_ADDI */ {iS, 1, 1}, /* OP_ADDI */
{iO, -1}, /* OP_SUB */ {iO, 1, 2}, /* OP_SUB */
{iO, -1}, /* OP_MULT */ {iO, 1, 2}, /* OP_MULT */
{iO, -1}, /* OP_DIV */ {iO, 1, 2}, /* OP_DIV */
{iO, -1}, /* OP_POW */ {iO, 1, 2}, /* OP_POW */
{iU, VD}, /* OP_CONCAT */ {iU, VD, 0}, /* OP_CONCAT */
{iO, 0}, /* OP_MINUS */ {iO, 1, 1}, /* OP_MINUS */
{iO, 0}, /* OP_NOT */ {iO, 1, 1}, /* OP_NOT */
{iS, -2}, /* OP_JMPNE */ {iS, 0, 2}, /* OP_JMPNE */
{iS, -2}, /* OP_JMPEQ */ {iS, 0, 2}, /* OP_JMPEQ */
{iS, -2}, /* OP_JMPLT */ {iS, 0, 2}, /* OP_JMPLT */
{iS, -2}, /* OP_JMPLE */ {iS, 0, 2}, /* OP_JMPLE */
{iS, -2}, /* OP_JMPGT */ {iS, 0, 2}, /* OP_JMPGT */
{iS, -2}, /* OP_JMPGE */ {iS, 0, 2}, /* OP_JMPGE */
{iS, -1}, /* OP_JMPT */ {iS, 0, 1}, /* OP_JMPT */
{iS, -1}, /* OP_JMPF */ {iS, 0, 1}, /* OP_JMPF */
{iS, -1}, /* OP_JMPONT */ {iS, 0, 1}, /* OP_JMPONT */
{iS, -1}, /* OP_JMPONF */ {iS, 0, 1}, /* OP_JMPONF */
{iS, 0}, /* OP_JMP */ {iS, 0, 0}, /* OP_JMP */
{iO, 1}, /* OP_PUSHNILJMP */ {iO, 1, 0}, /* OP_PUSHNILJMP */
{iS, 0}, /* OP_FORPREP */ {iS, 0, 0}, /* OP_FORPREP */
{iS, -3}, /* OP_FORLOOP */ {iS, 0, 3}, /* OP_FORLOOP */
{iS, 3}, /* OP_LFORPREP */ {iS, 3, 0}, /* OP_LFORPREP */
{iS, -4}, /* OP_LFORLOOP */ {iS, 0, 4}, /* OP_LFORLOOP */
{iAB, VD} /* OP_CLOSURE */ {iAB, VD, 0} /* OP_CLOSURE */
}; };

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lcode.h,v 1.13 2000/05/22 18:44:46 roberto Exp roberto $ ** $Id: lcode.h,v 1.14 2000/06/16 17:51:40 roberto Exp roberto $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -22,9 +22,12 @@
enum Mode {iO, iU, iS, iAB}; /* instruction format */ enum Mode {iO, iU, iS, iAB}; /* instruction format */
#define VD 100 /* flag for variable delta */
extern const struct OpProperties { extern const struct OpProperties {
char mode; char mode;
signed char delta; unsigned char push;
unsigned char pop;
} luaK_opproperties[]; } luaK_opproperties[];

148
ldebug.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ldebug.c,v 1.23 2000/06/12 13:52:05 roberto Exp roberto $ ** $Id: ldebug.c,v 1.24 2000/06/26 19:28:31 roberto Exp roberto $
** Debug Interface ** Debug Interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -13,10 +13,12 @@
#include "lapi.h" #include "lapi.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lcode.h"
#include "ldebug.h" #include "ldebug.h"
#include "ldo.h" #include "ldo.h"
#include "lfunc.h" #include "lfunc.h"
#include "lobject.h" #include "lobject.h"
#include "lopcodes.h"
#include "lstate.h" #include "lstate.h"
#include "ltable.h" #include "ltable.h"
#include "ltm.h" #include "ltm.h"
@@ -97,6 +99,13 @@ static int lua_nups (StkId f) {
} }
static int lua_currentpc (StkId f) {
CallInfo *ci = infovalue(f);
LUA_ASSERT(L, ttype(f) == TAG_LMARK, "function has no pc");
return (*ci->pc - 1) - ci->func->f.l->code;
}
static int lua_currentline (StkId f) { static int lua_currentline (StkId f) {
if (ttype(f) != TAG_LMARK) if (ttype(f) != TAG_LMARK)
return -1; /* only active lua functions have current-line information */ return -1; /* only active lua functions have current-line information */
@@ -104,15 +113,11 @@ static int lua_currentline (StkId f) {
CallInfo *ci = infovalue(f); CallInfo *ci = infovalue(f);
int *lines = ci->func->f.l->lines; int *lines = ci->func->f.l->lines;
if (!lines) return -1; /* no static debug information */ if (!lines) return -1; /* no static debug information */
else return lines[ci->pc]; else return lines[lua_currentpc(f)];
} }
} }
static int lua_currentpc (StkId f) {
return infovalue(f)->pc;
}
static Proto *getluaproto (StkId f) { static Proto *getluaproto (StkId f) {
return (ttype(f) == TAG_LMARK) ? infovalue(f)->func->f.l : NULL; return (ttype(f) == TAG_LMARK) ? infovalue(f)->func->f.l : NULL;
@@ -225,17 +230,136 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
} }
/*
** {======================================================
** Symbolic Execution
** =======================================================
*/
static void call_index_error (lua_State *L, TObject *o, const char *v) { static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
luaL_verror(L, "attempt to %.10s a %.10s value", v, lua_type(L, o)); int stack[MAXSTACK]; /* stores last instruction that changes each value */
const Instruction *code = pt->code;
int top = pt->numparams;
int pc = 0;
if (pt->is_vararg) /* varargs? */
top++; /* `arg' */
while (pc < lastpc) {
const Instruction i = code[pc++];
switch (GET_OPCODE(i)) {
case OP_CALL: {
int nresults = GETARG_B(i);
if (nresults == MULT_RET) nresults = 1;
top = GETARG_A(i);
while (nresults--)
stack[top++] = pc-1;
break;
}
case OP_PUSHNIL: {
int n;
for (n=0; n<GETARG_U(i); n++)
stack[top++] = pc-1;
break;
}
case OP_POP: {
top -= GETARG_U(i);
break;
}
case OP_SETTABLE:
case OP_SETLIST: {
top -= GETARG_B(i);
break;
}
case OP_SETMAP: {
top -= 2*GETARG_U(i);
break;
}
case OP_CONCAT: {
top -= GETARG_U(i);
stack[top++] = pc-1;
break;
}
case OP_JMPONT:
case OP_JMPONF: {
int newpc = pc + GETARG_S(i);
if (newpc >= lastpc) {
stack[top-1] = pc-1; /* value generated by or-and */
pc = newpc; /* do the jump */
}
else
top--; /* original code did not jump; condition was false */
break;
}
case OP_PUSHNILJMP: {
break; /* do not `push', to compensate next instruction */
}
case OP_CLOSURE: {
top -= GETARG_B(i);
stack[top++] = pc-1;
break;
}
default: {
int n;
LUA_ASSERT(NULL, luaK_opproperties[GET_OPCODE(i)].push != VD,
"invalid opcode for default");
top -= luaK_opproperties[GET_OPCODE(i)].pop;
for (n=0; n<luaK_opproperties[GET_OPCODE(i)].push; n++)
stack[top++] = pc-1;
}
}
}
return code[stack[stackpos]];
} }
void luaG_callerror (lua_State *L, TObject *func) { static const char *getname (lua_State *L, StkId obj, const char **name) {
call_index_error(L, func, "call"); StkId func = aux_stackedfunction(L, 0, obj);
if (func == NULL || ttype(func) != TAG_LMARK)
return NULL; /* not a Lua function */
else {
Proto *p = infovalue(func)->func->f.l;
int pc = lua_currentpc(func);
int stackpos = obj - (func+1); /* func+1 == function base */
Instruction i = luaG_symbexec(p, pc, stackpos);
switch (GET_OPCODE(i)) {
case OP_GETGLOBAL: {
*name = p->kstr[GETARG_U(i)]->str;
return "global";
}
case OP_GETLOCAL: {
*name = luaF_getlocalname(p, GETARG_U(i)+1, pc);
return (*name) ? "local" : NULL;
}
case OP_PUSHSELF:
case OP_GETDOTTED: {
*name = p->kstr[GETARG_U(i)]->str;
return "field";
}
default:
return NULL; /* no usefull name found */
}
}
} }
void luaG_indexerror (lua_State *L, TObject *t) { /* }====================================================== */
call_index_error(L, t, "index");
static void call_index_error (lua_State *L, StkId o, const char *op,
const char *tp) {
const char *name;
const char *kind = getname(L, o, &name);
if (kind)
luaL_verror(L, "%s `%s' is not a %s", kind, name, tp);
else
luaL_verror(L, "attempt to %.10s a %.10s value", op, lua_type(L, o));
}
void luaG_callerror (lua_State *L, StkId func) {
call_index_error(L, func, "call", "function");
}
void luaG_indexerror (lua_State *L, StkId t) {
call_index_error(L, t, "index", "table");
} }

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: $ ** $Id: ldebug.h,v 1.1 2000/01/14 17:15:44 roberto Exp roberto $
** Auxiliary functions from Debug Interface module ** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -8,12 +8,12 @@
#define ldebug_h #define ldebug_h
#include "lobject.h" #include "lstate.h"
#include "luadebug.h" #include "luadebug.h"
void luaG_callerror (lua_State *L, TObject *func); void luaG_callerror (lua_State *L, StkId func);
void luaG_indexerror (lua_State *L, TObject *t); void luaG_indexerror (lua_State *L, StkId t);
#endif #endif

8
ldo.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ldo.c,v 1.79 2000/06/16 17:16:34 roberto Exp roberto $ ** $Id: ldo.c,v 1.80 2000/06/26 19:28:31 roberto Exp roberto $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -103,7 +103,7 @@ void luaD_openstack (lua_State *L, StkId pos) {
} }
void luaD_lineHook (lua_State *L, StkId func, int line) { void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
if (L->allowhooks) { if (L->allowhooks) {
lua_Debug ar; lua_Debug ar;
struct C_Lua_Stack oldCLS = L->Cstack; struct C_Lua_Stack oldCLS = L->Cstack;
@@ -113,7 +113,7 @@ void luaD_lineHook (lua_State *L, StkId func, int line) {
ar.event = "line"; ar.event = "line";
ar.currentline = line; ar.currentline = line;
L->allowhooks = 0; /* cannot call hooks inside a hook */ L->allowhooks = 0; /* cannot call hooks inside a hook */
(*L->linehook)(L, &ar); (*linehook)(L, &ar);
L->allowhooks = 1; L->allowhooks = 1;
L->top = old_top; L->top = old_top;
L->Cstack = oldCLS; L->Cstack = oldCLS;
@@ -187,7 +187,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
case TAG_LCLOSURE: { case TAG_LCLOSURE: {
CallInfo ci; CallInfo ci;
ci.func = clvalue(func); ci.func = clvalue(func);
ci.pc = 0; ci.line = 0;
ttype(func) = TAG_LMARK; ttype(func) = TAG_LMARK;
infovalue(func) = &ci; infovalue(func) = &ci;
if (callhook) if (callhook)

4
ldo.h
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ldo.h,v 1.19 2000/03/29 20:19:20 roberto Exp roberto $ ** $Id: ldo.h,v 1.20 2000/04/14 18:12:35 roberto Exp $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -22,7 +22,7 @@
void luaD_init (lua_State *L, int stacksize); void luaD_init (lua_State *L, int stacksize);
void luaD_adjusttop (lua_State *L, StkId base, int extra); void luaD_adjusttop (lua_State *L, StkId base, int extra);
void luaD_openstack (lua_State *L, StkId pos); void luaD_openstack (lua_State *L, StkId pos);
void luaD_lineHook (lua_State *L, StkId func, int line); void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
void luaD_call (lua_State *L, StkId func, int nResults); void luaD_call (lua_State *L, StkId func, int nResults);
void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
int luaD_protectedrun (lua_State *L); int luaD_protectedrun (lua_State *L);

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lobject.h,v 1.67 2000/06/08 18:27:13 roberto Exp roberto $ ** $Id: lobject.h,v 1.68 2000/06/26 19:28:31 roberto Exp roberto $
** Type definitions for Lua objects ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -122,7 +122,6 @@ typedef struct Proto {
int *lines; /* source line that generated each opcode */ int *lines; /* source line that generated each opcode */
int lineDefined; int lineDefined;
TString *source; TString *source;
int debug; /* flag for debug information */
int numparams; int numparams;
int is_vararg; int is_vararg;
int maxstacksize; int maxstacksize;
@@ -171,9 +170,10 @@ typedef struct Hash {
** informations about a call (for debugging) ** informations about a call (for debugging)
*/ */
typedef struct CallInfo { typedef struct CallInfo {
int pc; /* current pc of called function */
int line; /* current line */
struct Closure *func; /* function being called */ struct Closure *func; /* function being called */
const Instruction **pc; /* current pc of called function */
int lastpc; /* last pc traced */
int line; /* current line */
} CallInfo; } CallInfo;

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lparser.c,v 1.99 2000/06/26 19:28:31 roberto Exp roberto $ ** $Id: lparser.c,v 1.100 2000/06/28 17:06:07 roberto Exp roberto $
** LL(1) Parser and code generator for Lua ** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -154,7 +154,7 @@ static int checkname (LexState *ls) {
static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) { static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) {
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
if (fs->f->debug) { if (fs->debug) {
Proto *f = fs->f; Proto *f = fs->f;
luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT); luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT);
f->locvars[fs->nvars].varname = varname; f->locvars[fs->nvars].varname = varname;
@@ -359,7 +359,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
open_func(&lexstate, &funcstate); open_func(&lexstate, &funcstate);
next(&lexstate); /* read first token */ next(&lexstate); /* read first token */
funcstate.f->debug = L->debug; /* previous `next' may scan a pragma */ funcstate.debug = L->debug; /* previous `next' may scan a pragma */
chunk(&lexstate); chunk(&lexstate);
check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
close_func(&lexstate); close_func(&lexstate);
@@ -1085,7 +1085,7 @@ static void body (LexState *ls, int needself, int line) {
FuncState new_fs; FuncState new_fs;
open_func(ls, &new_fs); open_func(ls, &new_fs);
new_fs.f->lineDefined = line; new_fs.f->lineDefined = line;
new_fs.f->debug = ls->L->debug; new_fs.debug = ls->L->debug;
check(ls, '('); check(ls, '(');
if (needself) { if (needself) {
new_localvarstr(ls, "self", 0); new_localvarstr(ls, "self", 0);

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lparser.h,v 1.18 2000/06/21 18:13:56 roberto Exp roberto $ ** $Id: lparser.h,v 1.19 2000/06/26 19:28:31 roberto Exp roberto $
** LL(1) Parser and code generator for Lua ** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -47,6 +47,7 @@ typedef struct FuncState {
int stacklevel; /* number of values on activation register */ int stacklevel; /* number of values on activation register */
int nlocalvar; /* number of active local variables */ int nlocalvar; /* number of active local variables */
int nupvalues; /* number of upvalues */ int nupvalues; /* number of upvalues */
int debug; /* flag for debug information */
int nvars; /* number of entries in f->locvars */ int nvars; /* number of entries in f->locvars */
struct Breaklabel *bl; /* chain of breakable blocks */ struct Breaklabel *bl; /* chain of breakable blocks */
expdesc upvalues[MAXUPVALUES]; /* upvalues */ expdesc upvalues[MAXUPVALUES]; /* upvalues */

32
lvm.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 1.117 2000/06/26 19:28:31 roberto Exp roberto $ ** $Id: lvm.c,v 1.118 2000/06/27 19:00:36 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -67,20 +67,19 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */
} }
static void traceexec (lua_State *L, StkId base, int pc, StkId top) { static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
CallInfo *ci = infovalue(base-1); CallInfo *ci = infovalue(base-1);
int oldpc = ci->pc; int *lines = ci->func->f.l->lines;
ci->pc = pc; int pc = (*ci->pc - 1) - ci->func->f.l->code;
if (L->linehook && ci->func->f.l->debug) { if (lines) {
int *lines = ci->func->f.l->lines; /* calls linehook when enters a new line or jumps back (loop) */
LUA_ASSERT(L, lines, "must have debug information"); if (lines[pc] != ci->line || pc <= ci->lastpc) {
/* calls linehook when jumps back (loop) or enters a new line */
if (pc <= oldpc || lines[pc] != ci->line) {
ci->line = lines[pc]; ci->line = lines[pc];
L->top = top; L->top = top;
luaD_lineHook(L, base-2, lines[pc]); luaD_lineHook(L, base-2, lines[pc], linehook);
} }
} }
ci->lastpc = pc;
} }
@@ -113,7 +112,7 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
** Receives the table at top-2 and the index at top-1. ** Receives the table at top-2 and the index at top-1.
*/ */
void luaV_gettable (lua_State *L, StkId top) { void luaV_gettable (lua_State *L, StkId top) {
TObject *table = top-2; StkId table = top-2;
const TObject *im; const TObject *im;
if (ttype(table) != TAG_TABLE) { /* not a table, get gettable TM */ if (ttype(table) != TAG_TABLE) { /* not a table, get gettable TM */
im = luaT_getimbyObj(L, table, IM_GETTABLE); im = luaT_getimbyObj(L, table, IM_GETTABLE);
@@ -348,7 +347,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
StkId top; /* keep top local, for performance */ StkId top; /* keep top local, for performance */
const Instruction *pc = tf->code; const Instruction *pc = tf->code;
TString **kstr = tf->kstr; TString **kstr = tf->kstr;
int debug = tf->debug; lua_Hook linehook = L->linehook;
infovalue(base-1)->pc = &pc;
luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
if (tf->is_vararg) { /* varargs? */ if (tf->is_vararg) { /* varargs? */
adjust_varargs(L, base, tf->numparams); adjust_varargs(L, base, tf->numparams);
@@ -359,9 +359,9 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
top = L->top; top = L->top;
/* main loop of interpreter */ /* main loop of interpreter */
for (;;) { for (;;) {
if (debug) const Instruction i = *pc++;
traceexec(L, base, pc - tf->code, top); if (linehook)
{const Instruction i = *pc++; traceexec(L, base, top, linehook);
switch (GET_OPCODE(i)) { switch (GET_OPCODE(i)) {
case OP_END: case OP_END:
@@ -705,5 +705,5 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
break; break;
} }
}} }
} }