浏览代码

erroneous objects may not live in the stack

Roberto Ierusalimschy 23 年之前
父节点
当前提交
938092489b
共有 4 个文件被更改,包括 61 次插入36 次删除
  1. 49 24
      ldebug.c
  2. 3 3
      ldebug.h
  3. 6 6
      lvm.c
  4. 3 3
      lvm.h

+ 49 - 24
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.101 2002/03/08 19:10:32 roberto Exp roberto $
+** $Id: ldebug.c,v 1.102 2002/03/11 12:45:00 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -439,6 +439,15 @@ int luaG_checkcode (const Proto *pt) {
 }
 
 
+static const char *kname (Proto *p, int c) {
+  c = c - MAXSTACK;
+  if (c >= 0 && ttype(&p->k[c]) == LUA_TSTRING)
+    return svalue(&p->k[c]);
+  else
+    return "?";
+}
+
+
 static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
                                const char **name) {
   if (isLmark(ci)) {  /* an active Lua function? */
@@ -463,13 +472,17 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
           return getobjname(L, ci, b, name);  /* get name for `b' */
         break;
       }
-      case OP_GETTABLE:
-      case OP_SELF: {
-        int c = GETARG_C(i) - MAXSTACK;
-        if (c >= 0 && ttype(&p->k[c]) == LUA_TSTRING) {
-          *name = svalue(&p->k[c]);
-          return "field";
+      case OP_GETTABLE: {
+        *name = luaF_getlocalname(p, GETARG_B(i)+1, pc);
+        if (*name && *name[0] == '*') {
+          *name = kname(p, GETARG_C(i));
+          return "global";
         }
+        /* else go through */
+      }
+      case OP_SELF: {
+        *name = kname(p, GETARG_C(i));
+        return "field";
         break;
       }
       default: break;
@@ -479,26 +492,38 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
 }
 
 
+static Instruction getcurrentinstr (lua_State *L, CallInfo *ci) {
+  if (ci == L->base_ci || !isLmark(ci))
+    return (Instruction)(-1);  /* not an active Lua function */
+  else
+    return ci_func(ci)->l.p->code[currentpc(L, ci)];
+}
+
+
 static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
+  Instruction i;
   ci--;  /* calling function */
-  if (ci == L->base_ci || !isLmark(ci))
-    return NULL;  /* not an active Lua function */
-  else {
-    Proto *p = ci_func(ci)->l.p;
-    int pc = currentpc(L, ci);
-    Instruction i;
-    i = p->code[pc];
-    return (GET_OPCODE(i) == OP_CALL
-             ? getobjname(L, ci, GETARG_A(i), name)
-             : NULL);  /* no useful name found */
-  }
+  i = getcurrentinstr(L, ci);
+  return (GET_OPCODE(i) == OP_CALL ? getobjname(L, ci, GETARG_A(i), name)
+                                   : NULL);  /* no useful name found */
+}
+
+
+/* only ANSI way to check whether a pointer points to an array */
+static int isinstack (CallInfo *ci, const TObject *o) {
+  StkId p;
+  for (p = ci->base; p < ci->top; p++)
+    if (o == p) return 1;
+  return 0;
 }
 
 
-void luaG_typeerror (lua_State *L, StkId o, const char *op) {
+void luaG_typeerror (lua_State *L, const TObject *o, const char *op) {
   const char *name;
-  const char *kind = getobjname(L, L->ci, o - L->ci->base, &name);  /* ?? */
   const char *t = luaT_typenames[ttype(o)];
+  const char *kind = NULL;
+  if (isinstack(L->ci, o))
+    kind = getobjname(L, L->ci, o - L->ci->base, &name);
   if (kind)
     luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
                 op, kind, name, t);
@@ -514,11 +539,11 @@ void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
 }
 
 
-void luaG_aritherror (lua_State *L, StkId p1, TObject *p2) {
+void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2) {
   TObject temp;
-  if (luaV_tonumber(p1, &temp) != NULL)
-    p1 = p2;  /* first operand is OK; error is in the second */
-  luaG_typeerror(L, p1, "perform arithmetic on");
+  if (luaV_tonumber(p1, &temp) == NULL)
+    p2 = p1;  /* first operand is wrong */
+  luaG_typeerror(L, p2, "perform arithmetic on");
 }
 
 

+ 3 - 3
ldebug.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.h,v 1.15 2001/06/28 19:58:57 roberto Exp $
+** $Id: ldebug.h,v 1.16 2001/11/28 20:13:13 roberto Exp roberto $
 ** Auxiliary functions from Debug Interface module
 ** See Copyright Notice in lua.h
 */
@@ -12,9 +12,9 @@
 #include "luadebug.h"
 
 
-void luaG_typeerror (lua_State *L, StkId o, const char *op);
+void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
 void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
-void luaG_aritherror (lua_State *L, StkId p1, TObject *p2);
+void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2);
 int luaG_getline (int *lineinfo, int pc, int refline, int *refi);
 void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
 int luaG_checkcode (const Proto *pt);

+ 6 - 6
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.218 2002/03/04 21:33:09 roberto Exp roberto $
+** $Id: lvm.c,v 1.219 2002/03/08 19:10:32 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -125,7 +125,7 @@ static void callTM (lua_State *L, const TObject *f,
 ** Receives the table at `t' and the key at `key'.
 ** leaves the result at `res'.
 */
-void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
+void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId res) {
   const TObject *tm;
   int loop = 0;
   init:
@@ -151,7 +151,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
     callTMres(L, tm, t, key, res);
   else {
     if (++loop == MAXTAGLOOP) luaD_error(L, "loop in gettable");
-    t = (StkId)tm;  /* ?? */
+    t = tm;
     goto init;  /* return luaV_gettable(L, tm, key, res); */
   }
 }
@@ -160,7 +160,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
 /*
 ** Receives table at `t', key at `key' and value at `val'.
 */
-void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
+void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) {
   const TObject *tm;
   int loop = 0;
   init:
@@ -181,7 +181,7 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
     callTM(L, tm, t, key, val);
   else {
     if (++loop == MAXTAGLOOP) luaD_error(L, "loop in settable");
-    t = (StkId)tm;  /* ?? */
+    t = tm;
     goto init;  /* luaV_settable(L, tm, key, val); */
   }
 }
@@ -198,7 +198,7 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
 }
 
 
-static void call_arith (lua_State *L, StkId p1, TObject *p2,
+static void call_arith (lua_State *L, StkId p1, const TObject *p2,
                         StkId res, TMS event) {
   if (!call_binTM(L, p1, p2, res, event))
     luaG_aritherror(L, p1, p2);

+ 3 - 3
lvm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.h,v 1.36 2002/02/07 17:24:05 roberto Exp roberto $
+** $Id: lvm.h,v 1.37 2002/03/04 21:33:09 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -21,8 +21,8 @@
 
 const TObject *luaV_tonumber (const TObject *obj, TObject *n);
 int luaV_tostring (lua_State *L, TObject *obj);
-void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res);
-void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val);
+void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId res);
+void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val);
 StkId luaV_execute (lua_State *L);
 int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
 void luaV_strconc (lua_State *L, int total, int last);