diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-06-28 17:21:06 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-06-28 17:21:06 -0300 |
| commit | 014a09c5095be3ef11366530e4630ee817a526a7 (patch) | |
| tree | 1460ff0d01cd4adf8fac2609ca2ba90411babf2c /ldebug.c | |
| parent | b62228297372c7b24b6661ac1bdd7df2e8ece64e (diff) | |
| download | lua-014a09c5095be3ef11366530e4630ee817a526a7.tar.gz lua-014a09c5095be3ef11366530e4630ee817a526a7.tar.bz2 lua-014a09c5095be3ef11366530e4630ee817a526a7.zip | |
better error messages
Diffstat (limited to 'ldebug.c')
| -rw-r--r-- | ldebug.c | 148 |
1 files changed, 136 insertions, 12 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 1.23 2000/06/12 13:52:05 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.24 2000/06/26 19:28:31 roberto Exp roberto $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -13,10 +13,12 @@ | |||
| 13 | 13 | ||
| 14 | #include "lapi.h" | 14 | #include "lapi.h" |
| 15 | #include "lauxlib.h" | 15 | #include "lauxlib.h" |
| 16 | #include "lcode.h" | ||
| 16 | #include "ldebug.h" | 17 | #include "ldebug.h" |
| 17 | #include "ldo.h" | 18 | #include "ldo.h" |
| 18 | #include "lfunc.h" | 19 | #include "lfunc.h" |
| 19 | #include "lobject.h" | 20 | #include "lobject.h" |
| 21 | #include "lopcodes.h" | ||
| 20 | #include "lstate.h" | 22 | #include "lstate.h" |
| 21 | #include "ltable.h" | 23 | #include "ltable.h" |
| 22 | #include "ltm.h" | 24 | #include "ltm.h" |
| @@ -97,6 +99,13 @@ static int lua_nups (StkId f) { | |||
| 97 | } | 99 | } |
| 98 | 100 | ||
| 99 | 101 | ||
| 102 | static int lua_currentpc (StkId f) { | ||
| 103 | CallInfo *ci = infovalue(f); | ||
| 104 | LUA_ASSERT(L, ttype(f) == TAG_LMARK, "function has no pc"); | ||
| 105 | return (*ci->pc - 1) - ci->func->f.l->code; | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 100 | static int lua_currentline (StkId f) { | 109 | static int lua_currentline (StkId f) { |
| 101 | if (ttype(f) != TAG_LMARK) | 110 | if (ttype(f) != TAG_LMARK) |
| 102 | return -1; /* only active lua functions have current-line information */ | 111 | return -1; /* only active lua functions have current-line information */ |
| @@ -104,15 +113,11 @@ static int lua_currentline (StkId f) { | |||
| 104 | CallInfo *ci = infovalue(f); | 113 | CallInfo *ci = infovalue(f); |
| 105 | int *lines = ci->func->f.l->lines; | 114 | int *lines = ci->func->f.l->lines; |
| 106 | if (!lines) return -1; /* no static debug information */ | 115 | if (!lines) return -1; /* no static debug information */ |
| 107 | else return lines[ci->pc]; | 116 | else return lines[lua_currentpc(f)]; |
| 108 | } | 117 | } |
| 109 | } | 118 | } |
| 110 | 119 | ||
| 111 | 120 | ||
| 112 | static int lua_currentpc (StkId f) { | ||
| 113 | return infovalue(f)->pc; | ||
| 114 | } | ||
| 115 | |||
| 116 | 121 | ||
| 117 | static Proto *getluaproto (StkId f) { | 122 | static Proto *getluaproto (StkId f) { |
| 118 | return (ttype(f) == TAG_LMARK) ? infovalue(f)->func->f.l : NULL; | 123 | 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) { | |||
| 225 | } | 230 | } |
| 226 | 231 | ||
| 227 | 232 | ||
| 233 | /* | ||
| 234 | ** {====================================================== | ||
| 235 | ** Symbolic Execution | ||
| 236 | ** ======================================================= | ||
| 237 | */ | ||
| 238 | |||
| 239 | static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { | ||
| 240 | int stack[MAXSTACK]; /* stores last instruction that changes each value */ | ||
| 241 | const Instruction *code = pt->code; | ||
| 242 | int top = pt->numparams; | ||
| 243 | int pc = 0; | ||
| 244 | if (pt->is_vararg) /* varargs? */ | ||
| 245 | top++; /* `arg' */ | ||
| 246 | while (pc < lastpc) { | ||
| 247 | const Instruction i = code[pc++]; | ||
| 248 | switch (GET_OPCODE(i)) { | ||
| 249 | case OP_CALL: { | ||
| 250 | int nresults = GETARG_B(i); | ||
| 251 | if (nresults == MULT_RET) nresults = 1; | ||
| 252 | top = GETARG_A(i); | ||
| 253 | while (nresults--) | ||
| 254 | stack[top++] = pc-1; | ||
| 255 | break; | ||
| 256 | } | ||
| 257 | case OP_PUSHNIL: { | ||
| 258 | int n; | ||
| 259 | for (n=0; n<GETARG_U(i); n++) | ||
| 260 | stack[top++] = pc-1; | ||
| 261 | break; | ||
| 262 | } | ||
| 263 | case OP_POP: { | ||
| 264 | top -= GETARG_U(i); | ||
| 265 | break; | ||
| 266 | } | ||
| 267 | case OP_SETTABLE: | ||
| 268 | case OP_SETLIST: { | ||
| 269 | top -= GETARG_B(i); | ||
| 270 | break; | ||
| 271 | } | ||
| 272 | case OP_SETMAP: { | ||
| 273 | top -= 2*GETARG_U(i); | ||
| 274 | break; | ||
| 275 | } | ||
| 276 | case OP_CONCAT: { | ||
| 277 | top -= GETARG_U(i); | ||
| 278 | stack[top++] = pc-1; | ||
| 279 | break; | ||
| 280 | } | ||
| 281 | case OP_JMPONT: | ||
| 282 | case OP_JMPONF: { | ||
| 283 | int newpc = pc + GETARG_S(i); | ||
| 284 | if (newpc >= lastpc) { | ||
| 285 | stack[top-1] = pc-1; /* value generated by or-and */ | ||
| 286 | pc = newpc; /* do the jump */ | ||
| 287 | } | ||
| 288 | else | ||
| 289 | top--; /* original code did not jump; condition was false */ | ||
| 290 | break; | ||
| 291 | } | ||
| 292 | case OP_PUSHNILJMP: { | ||
| 293 | break; /* do not `push', to compensate next instruction */ | ||
| 294 | } | ||
| 295 | case OP_CLOSURE: { | ||
| 296 | top -= GETARG_B(i); | ||
| 297 | stack[top++] = pc-1; | ||
| 298 | break; | ||
| 299 | } | ||
| 300 | default: { | ||
| 301 | int n; | ||
| 302 | LUA_ASSERT(NULL, luaK_opproperties[GET_OPCODE(i)].push != VD, | ||
| 303 | "invalid opcode for default"); | ||
| 304 | top -= luaK_opproperties[GET_OPCODE(i)].pop; | ||
| 305 | for (n=0; n<luaK_opproperties[GET_OPCODE(i)].push; n++) | ||
| 306 | stack[top++] = pc-1; | ||
| 307 | } | ||
| 308 | } | ||
| 309 | } | ||
| 310 | return code[stack[stackpos]]; | ||
| 311 | } | ||
| 312 | |||
| 313 | |||
| 314 | static const char *getname (lua_State *L, StkId obj, const char **name) { | ||
| 315 | StkId func = aux_stackedfunction(L, 0, obj); | ||
| 316 | if (func == NULL || ttype(func) != TAG_LMARK) | ||
| 317 | return NULL; /* not a Lua function */ | ||
| 318 | else { | ||
| 319 | Proto *p = infovalue(func)->func->f.l; | ||
| 320 | int pc = lua_currentpc(func); | ||
| 321 | int stackpos = obj - (func+1); /* func+1 == function base */ | ||
| 322 | Instruction i = luaG_symbexec(p, pc, stackpos); | ||
| 323 | switch (GET_OPCODE(i)) { | ||
| 324 | case OP_GETGLOBAL: { | ||
| 325 | *name = p->kstr[GETARG_U(i)]->str; | ||
| 326 | return "global"; | ||
| 327 | } | ||
| 328 | case OP_GETLOCAL: { | ||
| 329 | *name = luaF_getlocalname(p, GETARG_U(i)+1, pc); | ||
| 330 | return (*name) ? "local" : NULL; | ||
| 331 | } | ||
| 332 | case OP_PUSHSELF: | ||
| 333 | case OP_GETDOTTED: { | ||
| 334 | *name = p->kstr[GETARG_U(i)]->str; | ||
| 335 | return "field"; | ||
| 336 | } | ||
| 337 | default: | ||
| 338 | return NULL; /* no usefull name found */ | ||
| 339 | } | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | |||
| 344 | /* }====================================================== */ | ||
| 345 | |||
| 228 | 346 | ||
| 229 | static void call_index_error (lua_State *L, TObject *o, const char *v) { | 347 | static void call_index_error (lua_State *L, StkId o, const char *op, |
| 230 | luaL_verror(L, "attempt to %.10s a %.10s value", v, lua_type(L, o)); | 348 | const char *tp) { |
| 349 | const char *name; | ||
| 350 | const char *kind = getname(L, o, &name); | ||
| 351 | if (kind) | ||
| 352 | luaL_verror(L, "%s `%s' is not a %s", kind, name, tp); | ||
| 353 | else | ||
| 354 | luaL_verror(L, "attempt to %.10s a %.10s value", op, lua_type(L, o)); | ||
| 231 | } | 355 | } |
| 232 | 356 | ||
| 233 | 357 | ||
| 234 | void luaG_callerror (lua_State *L, TObject *func) { | 358 | void luaG_callerror (lua_State *L, StkId func) { |
| 235 | call_index_error(L, func, "call"); | 359 | call_index_error(L, func, "call", "function"); |
| 236 | } | 360 | } |
| 237 | 361 | ||
| 238 | 362 | ||
| 239 | void luaG_indexerror (lua_State *L, TObject *t) { | 363 | void luaG_indexerror (lua_State *L, StkId t) { |
| 240 | call_index_error(L, t, "index"); | 364 | call_index_error(L, t, "index", "table"); |
| 241 | } | 365 | } |
