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 | |
| parent | 578d1da00d4144caaf2ea7406680f76adcfc5af1 (diff) | |
| download | lua-938092489b9df19c9da7481c68d74dd7e0104949.tar.gz lua-938092489b9df19c9da7481c68d74dd7e0104949.tar.bz2 lua-938092489b9df19c9da7481c68d74dd7e0104949.zip | |
erroneous objects may not live in the stack
| -rw-r--r-- | ldebug.c | 73 | ||||
| -rw-r--r-- | ldebug.h | 6 | ||||
| -rw-r--r-- | lvm.c | 12 | ||||
| -rw-r--r-- | lvm.h | 6 |
4 files changed, 61 insertions, 36 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 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.h,v 1.15 2001/06/28 19:58:57 roberto Exp $ | 2 | ** $Id: ldebug.h,v 1.16 2001/11/28 20:13:13 roberto Exp roberto $ |
| 3 | ** Auxiliary functions from Debug Interface module | 3 | ** Auxiliary functions from Debug Interface module |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -12,9 +12,9 @@ | |||
| 12 | #include "luadebug.h" | 12 | #include "luadebug.h" |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | void luaG_typeerror (lua_State *L, StkId o, const char *op); | 15 | void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); |
| 16 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); | 16 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); |
| 17 | void luaG_aritherror (lua_State *L, StkId p1, TObject *p2); | 17 | void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); |
| 18 | int luaG_getline (int *lineinfo, int pc, int refline, int *refi); | 18 | int luaG_getline (int *lineinfo, int pc, int refline, int *refi); |
| 19 | void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); | 19 | void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); |
| 20 | int luaG_checkcode (const Proto *pt); | 20 | int luaG_checkcode (const Proto *pt); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.218 2002/03/04 21:33:09 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.219 2002/03/08 19:10:32 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -125,7 +125,7 @@ static void callTM (lua_State *L, const TObject *f, | |||
| 125 | ** Receives the table at `t' and the key at `key'. | 125 | ** Receives the table at `t' and the key at `key'. |
| 126 | ** leaves the result at `res'. | 126 | ** leaves the result at `res'. |
| 127 | */ | 127 | */ |
| 128 | void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { | 128 | void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId res) { |
| 129 | const TObject *tm; | 129 | const TObject *tm; |
| 130 | int loop = 0; | 130 | int loop = 0; |
| 131 | init: | 131 | init: |
| @@ -151,7 +151,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { | |||
| 151 | callTMres(L, tm, t, key, res); | 151 | callTMres(L, tm, t, key, res); |
| 152 | else { | 152 | else { |
| 153 | if (++loop == MAXTAGLOOP) luaD_error(L, "loop in gettable"); | 153 | if (++loop == MAXTAGLOOP) luaD_error(L, "loop in gettable"); |
| 154 | t = (StkId)tm; /* ?? */ | 154 | t = tm; |
| 155 | goto init; /* return luaV_gettable(L, tm, key, res); */ | 155 | goto init; /* return luaV_gettable(L, tm, key, res); */ |
| 156 | } | 156 | } |
| 157 | } | 157 | } |
| @@ -160,7 +160,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { | |||
| 160 | /* | 160 | /* |
| 161 | ** Receives table at `t', key at `key' and value at `val'. | 161 | ** Receives table at `t', key at `key' and value at `val'. |
| 162 | */ | 162 | */ |
| 163 | void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { | 163 | void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) { |
| 164 | const TObject *tm; | 164 | const TObject *tm; |
| 165 | int loop = 0; | 165 | int loop = 0; |
| 166 | init: | 166 | init: |
| @@ -181,7 +181,7 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { | |||
| 181 | callTM(L, tm, t, key, val); | 181 | callTM(L, tm, t, key, val); |
| 182 | else { | 182 | else { |
| 183 | if (++loop == MAXTAGLOOP) luaD_error(L, "loop in settable"); | 183 | if (++loop == MAXTAGLOOP) luaD_error(L, "loop in settable"); |
| 184 | t = (StkId)tm; /* ?? */ | 184 | t = tm; |
| 185 | goto init; /* luaV_settable(L, tm, key, val); */ | 185 | goto init; /* luaV_settable(L, tm, key, val); */ |
| 186 | } | 186 | } |
| 187 | } | 187 | } |
| @@ -198,7 +198,7 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, | |||
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | 200 | ||
| 201 | static void call_arith (lua_State *L, StkId p1, TObject *p2, | 201 | static void call_arith (lua_State *L, StkId p1, const TObject *p2, |
| 202 | StkId res, TMS event) { | 202 | StkId res, TMS event) { |
| 203 | if (!call_binTM(L, p1, p2, res, event)) | 203 | if (!call_binTM(L, p1, p2, res, event)) |
| 204 | luaG_aritherror(L, p1, p2); | 204 | luaG_aritherror(L, p1, p2); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.h,v 1.36 2002/02/07 17:24:05 roberto Exp roberto $ | 2 | ** $Id: lvm.h,v 1.37 2002/03/04 21:33:09 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -21,8 +21,8 @@ | |||
| 21 | 21 | ||
| 22 | const TObject *luaV_tonumber (const TObject *obj, TObject *n); | 22 | const TObject *luaV_tonumber (const TObject *obj, TObject *n); |
| 23 | int luaV_tostring (lua_State *L, TObject *obj); | 23 | int luaV_tostring (lua_State *L, TObject *obj); |
| 24 | void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res); | 24 | void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId res); |
| 25 | void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val); | 25 | void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val); |
| 26 | StkId luaV_execute (lua_State *L); | 26 | StkId luaV_execute (lua_State *L); |
| 27 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); | 27 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); |
| 28 | void luaV_strconc (lua_State *L, int total, int last); | 28 | void luaV_strconc (lua_State *L, int total, int last); |
