diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-03-19 09:45:25 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-03-19 09:45:25 -0300 |
| commit | 938092489b9df19c9da7481c68d74dd7e0104949 (patch) | |
| tree | 0f7ce5978e29afb39677045e817a850f23148215 /ldebug.c | |
| parent | 578d1da00d4144caaf2ea7406680f76adcfc5af1 (diff) | |
| download | lua-938092489b9df19c9da7481c68d74dd7e0104949.tar.gz lua-938092489b9df19c9da7481c68d74dd7e0104949.tar.bz2 lua-938092489b9df19c9da7481c68d74dd7e0104949.zip | |
erroneous objects may not live in the stack
Diffstat (limited to 'ldebug.c')
| -rw-r--r-- | ldebug.c | 73 |
1 files changed, 49 insertions, 24 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 1.101 2002/03/08 19:10:32 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.102 2002/03/11 12:45:00 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 | */ |
| @@ -439,6 +439,15 @@ int luaG_checkcode (const Proto *pt) { | |||
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | 441 | ||
| 442 | static const char *kname (Proto *p, int c) { | ||
| 443 | c = c - MAXSTACK; | ||
| 444 | if (c >= 0 && ttype(&p->k[c]) == LUA_TSTRING) | ||
| 445 | return svalue(&p->k[c]); | ||
| 446 | else | ||
| 447 | return "?"; | ||
| 448 | } | ||
| 449 | |||
| 450 | |||
| 442 | static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, | 451 | static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, |
| 443 | const char **name) { | 452 | const char **name) { |
| 444 | if (isLmark(ci)) { /* an active Lua function? */ | 453 | if (isLmark(ci)) { /* an active Lua function? */ |
| @@ -463,13 +472,17 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, | |||
| 463 | return getobjname(L, ci, b, name); /* get name for `b' */ | 472 | return getobjname(L, ci, b, name); /* get name for `b' */ |
| 464 | break; | 473 | break; |
| 465 | } | 474 | } |
| 466 | case OP_GETTABLE: | 475 | case OP_GETTABLE: { |
| 467 | case OP_SELF: { | 476 | *name = luaF_getlocalname(p, GETARG_B(i)+1, pc); |
| 468 | int c = GETARG_C(i) - MAXSTACK; | 477 | if (*name && *name[0] == '*') { |
| 469 | if (c >= 0 && ttype(&p->k[c]) == LUA_TSTRING) { | 478 | *name = kname(p, GETARG_C(i)); |
| 470 | *name = svalue(&p->k[c]); | 479 | return "global"; |
| 471 | return "field"; | ||
| 472 | } | 480 | } |
| 481 | /* else go through */ | ||
| 482 | } | ||
| 483 | case OP_SELF: { | ||
| 484 | *name = kname(p, GETARG_C(i)); | ||
| 485 | return "field"; | ||
| 473 | break; | 486 | break; |
| 474 | } | 487 | } |
| 475 | default: break; | 488 | default: break; |
| @@ -479,26 +492,38 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, | |||
| 479 | } | 492 | } |
| 480 | 493 | ||
| 481 | 494 | ||
| 495 | static Instruction getcurrentinstr (lua_State *L, CallInfo *ci) { | ||
| 496 | if (ci == L->base_ci || !isLmark(ci)) | ||
| 497 | return (Instruction)(-1); /* not an active Lua function */ | ||
| 498 | else | ||
| 499 | return ci_func(ci)->l.p->code[currentpc(L, ci)]; | ||
| 500 | } | ||
| 501 | |||
| 502 | |||
| 482 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { | 503 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { |
| 504 | Instruction i; | ||
| 483 | ci--; /* calling function */ | 505 | ci--; /* calling function */ |
| 484 | if (ci == L->base_ci || !isLmark(ci)) | 506 | i = getcurrentinstr(L, ci); |
| 485 | return NULL; /* not an active Lua function */ | 507 | return (GET_OPCODE(i) == OP_CALL ? getobjname(L, ci, GETARG_A(i), name) |
| 486 | else { | 508 | : NULL); /* no useful name found */ |
| 487 | Proto *p = ci_func(ci)->l.p; | 509 | } |
| 488 | int pc = currentpc(L, ci); | 510 | |
| 489 | Instruction i; | 511 | |
| 490 | i = p->code[pc]; | 512 | /* only ANSI way to check whether a pointer points to an array */ |
| 491 | return (GET_OPCODE(i) == OP_CALL | 513 | static int isinstack (CallInfo *ci, const TObject *o) { |
| 492 | ? getobjname(L, ci, GETARG_A(i), name) | 514 | StkId p; |
| 493 | : NULL); /* no useful name found */ | 515 | for (p = ci->base; p < ci->top; p++) |
| 494 | } | 516 | if (o == p) return 1; |
| 517 | return 0; | ||
| 495 | } | 518 | } |
| 496 | 519 | ||
| 497 | 520 | ||
| 498 | void luaG_typeerror (lua_State *L, StkId o, const char *op) { | 521 | void luaG_typeerror (lua_State *L, const TObject *o, const char *op) { |
| 499 | const char *name; | 522 | const char *name; |
| 500 | const char *kind = getobjname(L, L->ci, o - L->ci->base, &name); /* ?? */ | ||
| 501 | const char *t = luaT_typenames[ttype(o)]; | 523 | const char *t = luaT_typenames[ttype(o)]; |
| 524 | const char *kind = NULL; | ||
| 525 | if (isinstack(L->ci, o)) | ||
| 526 | kind = getobjname(L, L->ci, o - L->ci->base, &name); | ||
| 502 | if (kind) | 527 | if (kind) |
| 503 | luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)", | 528 | luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)", |
| 504 | op, kind, name, t); | 529 | op, kind, name, t); |
| @@ -514,11 +539,11 @@ void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { | |||
| 514 | } | 539 | } |
| 515 | 540 | ||
| 516 | 541 | ||
| 517 | void luaG_aritherror (lua_State *L, StkId p1, TObject *p2) { | 542 | void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2) { |
| 518 | TObject temp; | 543 | TObject temp; |
| 519 | if (luaV_tonumber(p1, &temp) != NULL) | 544 | if (luaV_tonumber(p1, &temp) == NULL) |
| 520 | p1 = p2; /* first operand is OK; error is in the second */ | 545 | p2 = p1; /* first operand is wrong */ |
| 521 | luaG_typeerror(L, p1, "perform arithmetic on"); | 546 | luaG_typeerror(L, p2, "perform arithmetic on"); |
| 522 | } | 547 | } |
| 523 | 548 | ||
| 524 | 549 | ||
