lua

A copy of the Lua development repository
Log | Files | Refs | README

commit daf09c476fe375d8a9a47bc1294a1cd430290226
parent e238efc5367a8d88757dd84df0683e1d8d9f9211
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Thu, 10 Aug 2000 16:50:25 -0300

still better error messages

Diffstat:
Mlcode.c | 5++---
Mldebug.c | 84++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mldebug.h | 6+++---
Mldo.c | 4++--
Mlvm.c | 34++++++++++++++++++++--------------
5 files changed, 67 insertions(+), 66 deletions(-)

diff --git a/lcode.c b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.45 2000/08/09 14:49:13 roberto Exp roberto $ +** $Id: lcode.c,v 1.46 2000/08/09 19:16:57 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -333,7 +333,6 @@ void luaK_tostack (LexState *ls, expdesc *v, int onlyone) { luaK_deltastack(fs, -1); /* next PUSHes may be skipped */ } p_nil = code_label(fs, OP_PUSHNILJMP, 0); - luaK_deltastack(fs, -1); /* next PUSH is skipped */ p_1 = code_label(fs, OP_PUSHINT, 1); luaK_patchlist(fs, j, luaK_getlabel(fs)); } @@ -690,7 +689,7 @@ const struct OpProperties luaK_opproperties[NUM_OPCODES] = { {iS, 0, 1}, /* OP_JMPONT */ {iS, 0, 1}, /* OP_JMPONF */ {iS, 0, 0}, /* OP_JMP */ - {iO, 1, 0}, /* OP_PUSHNILJMP */ + {iO, 0, 0}, /* OP_PUSHNILJMP */ {iS, 0, 0}, /* OP_FORPREP */ {iS, 0, 3}, /* OP_FORLOOP */ {iS, 3, 0}, /* OP_LFORPREP */ diff --git a/ldebug.c b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.30 2000/08/08 20:42:07 roberto Exp roberto $ +** $Id: ldebug.c,v 1.31 2000/08/09 19:16:57 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -57,7 +57,7 @@ lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) { static StkId aux_stackedfunction (lua_State *L, int level, StkId top) { int i; - for (i = (top-1)-L->stack; i>=0; i--) { + for (i = (top-1) - L->stack; i>=0; i--) { if (is_T_MARK(L->stack[i].ttype)) { if (level == 0) return L->stack+i; @@ -214,7 +214,7 @@ static const char *travglobals (lua_State *L, const TObject *o) { } -static void lua_getobjname (lua_State *L, StkId f, lua_Debug *ar) { +static void lua_getname (lua_State *L, StkId f, lua_Debug *ar) { TObject o; setnormalized(&o, f); /* try to find a name for given function */ @@ -247,7 +247,7 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { ar->nups = lua_nups(func); break; case 'n': - lua_getobjname(L, func, ar); + lua_getname(L, func, ar); break; case 'f': setnormalized(L->top, func); @@ -267,8 +267,16 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { ** ======================================================= */ + +static int pushpc (int *stack, int pc, int top, int n) { + while (n--) + stack[top++] = pc-1; + return top; +} + + static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { - int stack[MAXSTACK]; /* stores last instruction that changes each value */ + int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */ const Instruction *code = pt->code; int top = pt->numparams; int pc = 0; @@ -276,7 +284,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { top++; /* `arg' */ while (pc < lastpc) { const Instruction i = code[pc++]; - LUA_ASSERT(top <= pt->maxstacksize, "wrong stack"); + LUA_ASSERT(0 <= top && top <= pt->maxstacksize, "wrong stack"); switch (GET_OPCODE(i)) { case OP_RETURN: { LUA_ASSERT(top >= GETARG_U(i), "wrong stack"); @@ -287,9 +295,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { int nresults = GETARG_B(i); if (nresults == MULT_RET) nresults = 1; LUA_ASSERT(top >= GETARG_A(i), "wrong stack"); - top = GETARG_A(i); - while (nresults--) - stack[top++] = pc-1; + top = pushpc(stack, pc, GETARG_A(i), nresults); break; } case OP_TAILCALL: { @@ -298,9 +304,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { break; } case OP_PUSHNIL: { - int n; - for (n=0; n<GETARG_U(i); n++) - stack[top++] = pc-1; + top = pushpc(stack, pc, top, GETARG_U(i)); break; } case OP_POP: { @@ -321,33 +325,27 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { stack[top++] = pc-1; break; } - case OP_JMPONT: - case OP_JMPONF: { - int newpc = pc + GETARG_S(i); - if (lastpc < newpc) - top--; /* original code did not jump; condition was false */ - else { - stack[top-1] = pc-1; /* value generated by or-and */ - pc = newpc; /* do the jump */ - } - 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(luaK_opproperties[GET_OPCODE(i)].push != VD, + OpCode op = GET_OPCODE(i); + LUA_ASSERT(luaK_opproperties[op].push != VD, "invalid opcode for default"); - top -= luaK_opproperties[GET_OPCODE(i)].pop; + top -= luaK_opproperties[op].pop; LUA_ASSERT(top >= 0, "wrong stack"); - for (n=0; n<luaK_opproperties[GET_OPCODE(i)].push; n++) - stack[top++] = pc-1; + top = pushpc(stack, pc, top, luaK_opproperties[op].push); + if (ISJUMP(op)) { + int newpc = pc + GETARG_S(i); + /* jump is forward and do not skip `lastpc'? */ + if (pc < newpc && newpc <= lastpc) { + if (op == OP_JMPONT || op == OP_JMPONF) + stack[top++] = pc-1; /* do not pop when jumping */ + pc = newpc; /* do the jump */ + } + } } } } @@ -355,7 +353,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { } -static const char *getname (lua_State *L, StkId obj, const char **name) { +static const char *getobjname (lua_State *L, StkId obj, const char **name) { StkId func = aux_stackedfunction(L, 0, obj); if (func == NULL || ttype(func) != TAG_LMARK) return NULL; /* not a Lua function */ @@ -389,23 +387,21 @@ static const char *getname (lua_State *L, StkId obj, const char **name) { /* }====================================================== */ -static void call_index_error (lua_State *L, StkId o, const char *op, - const char *tp) { +void luaG_typeerror (lua_State *L, StkId o, const char *op) { const char *name; - const char *kind = getname(L, o, &name); + const char *kind = getobjname(L, o, &name); + const char *t = lua_type(L, o); if (kind) - luaL_verror(L, "%s `%s' is not a %s", kind, name, tp); + luaL_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)", + op, kind, name, t); 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"); + luaL_verror(L, "attempt to %.30s a %.10s value", op, t); } -void luaG_indexerror (lua_State *L, StkId t) { - call_index_error(L, t, "index", "table"); +void luaG_binerror (lua_State *L, StkId p1, lua_Type t, const char *op) { + if (ttype(p1) == t) p1++; + LUA_ASSERT(ttype(p1) != t, "must be an error"); + luaG_typeerror(L, p1, op); } diff --git a/ldebug.h b/ldebug.h @@ -1,5 +1,5 @@ /* -** $Id: ldebug.h,v 1.2 2000/06/28 20:20:36 roberto Exp roberto $ +** $Id: ldebug.h,v 1.3 2000/08/08 18:26:05 roberto Exp roberto $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ @@ -12,8 +12,8 @@ #include "luadebug.h" -void luaG_callerror (lua_State *L, StkId func); -void luaG_indexerror (lua_State *L, StkId t); +void luaG_typeerror (lua_State *L, StkId o, const char *op); +void luaG_binerror (lua_State *L, StkId p1, lua_Type t, const char *op); int luaG_getline (int *lineinfo, int pc, int refline, int *refi); diff --git a/ldo.c b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.83 2000/08/08 20:42:07 roberto Exp roberto $ +** $Id: ldo.c,v 1.84 2000/08/09 19:16:57 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -202,7 +202,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) == TAG_NIL) - luaG_callerror(L, func); + luaG_typeerror(L, func, "call"); luaD_openstack(L, func); *func = *im; /* tag method is the new function to be called */ goto retry; /* retry the call */ diff --git a/lvm.c b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.123 2000/08/09 14:49:41 roberto Exp roberto $ +** $Id: lvm.c,v 1.124 2000/08/09 19:16:57 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -121,7 +121,7 @@ void luaV_gettable (lua_State *L, StkId top) { im = luaT_getimbyObj(L, table, IM_GETTABLE); if (ttype(im) == TAG_NIL) { L->top = top; - luaG_indexerror(L, table); + luaG_typeerror(L, table, "index"); } } else { /* object is a table... */ @@ -156,7 +156,7 @@ void luaV_settable (lua_State *L, StkId t, StkId top) { L->top = top; im = luaT_getimbyObj(L, t, IM_SETTABLE); if (ttype(im) == TAG_NIL) - luaG_indexerror(L, t); + luaG_typeerror(L, t, "index"); } else { /* object is a table... */ im = luaT_getim(L, hvalue(t)->htag, IM_SETTABLE); @@ -223,7 +223,7 @@ void luaV_setglobal (lua_State *L, TString *s, StkId top) { } -static void call_binTM (lua_State *L, StkId top, IMS event, const char *msg) { +static int call_binTM (lua_State *L, StkId top, IMS event) { /* try first operand */ const TObject *im = luaT_getimbyObj(L, top-2, event); L->top = top; @@ -232,16 +232,18 @@ static void call_binTM (lua_State *L, StkId top, IMS event, const char *msg) { if (ttype(im) == TAG_NIL) { im = luaT_getim(L, 0, event); /* try a `global' method */ if (ttype(im) == TAG_NIL) - lua_error(L, msg); + return 0; /* error */ } } lua_pushstring(L, luaT_eventname[event]); luaD_callTM(L, im, 3, 1); + return 1; } static void call_arith (lua_State *L, StkId top, IMS event) { - call_binTM(L, top, event, "unexpected type in arithmetic operation"); + if (!call_binTM(L, top, event)) + luaG_binerror(L, top-2, TAG_NUMBER, "perform arithmetic on"); } @@ -276,7 +278,8 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) luaD_checkstack(L, 2); *top++ = *l; *top++ = *r; - call_binTM(L, top, IM_LT, "unexpected type in comparison"); + if (!call_binTM(L, top, IM_LT)) + lua_error(L, "unexpected type in comparison"); L->top--; return (ttype(L->top) != TAG_NIL); } @@ -286,8 +289,10 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) static void strconc (lua_State *L, int total, StkId top) { do { int n = 2; /* number of elements handled in this pass (at least 2) */ - if (tostring(L, top-2) || tostring(L, top-1)) - call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation"); + if (tostring(L, top-2) || tostring(L, top-1)) { + if (!call_binTM(L, top, IM_CONCAT)) + luaG_binerror(L, top-2, TAG_STRING, "concat"); + } else if (tsvalue(top-1)->u.s.len > 0) { /* if len=0, do nothing */ /* at least two string values; get as many as possible */ lint32 tl = (lint32)tsvalue(top-1)->u.s.len + @@ -508,7 +513,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_ADD: - if (tonumber(top-1) || tonumber(top-2)) + if (tonumber(top-2) || tonumber(top-1)) call_arith(L, top, IM_ADD); else nvalue(top-2) += nvalue(top-1); @@ -526,7 +531,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; case OP_SUB: - if (tonumber(top-1) || tonumber(top-2)) + if (tonumber(top-2) || tonumber(top-1)) call_arith(L, top, IM_SUB); else nvalue(top-2) -= nvalue(top-1); @@ -534,7 +539,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; case OP_MULT: - if (tonumber(top-1) || tonumber(top-2)) + if (tonumber(top-2) || tonumber(top-1)) call_arith(L, top, IM_MUL); else nvalue(top-2) *= nvalue(top-1); @@ -542,7 +547,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; case OP_DIV: - if (tonumber(top-1) || tonumber(top-2)) + if (tonumber(top-2) || tonumber(top-1)) call_arith(L, top, IM_DIV); else nvalue(top-2) /= nvalue(top-1); @@ -550,7 +555,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; case OP_POW: - call_binTM(L, top, IM_POW, "undefined operation"); + if (!call_binTM(L, top, IM_POW)) + lua_error(L, "undefined operation"); top--; break;