Browse Source

new ttypes to distinguish between C closures and Lua closures.

Roberto Ierusalimschy 26 năm trước cách đây
mục cha
commit
b1b0c219f5
15 tập tin đã thay đổi với 180 bổ sung147 xóa
  1. 36 45
      lapi.c
  2. 6 2
      lapi.h
  3. 3 3
      lbuiltin.c
  4. 14 9
      ldebug.c
  5. 40 31
      ldo.c
  6. 4 3
      lgc.c
  7. 18 10
      lobject.c
  8. 18 10
      lobject.h
  9. 3 3
      lparser.c
  10. 3 8
      lref.c
  11. 3 3
      ltable.c
  12. 12 1
      ltests.c
  13. 12 14
      ltm.c
  14. 2 2
      lundump.c
  15. 6 3
      lvm.c

+ 36 - 45
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.63 1999/12/06 12:03:45 roberto Exp roberto $
+** $Id: lapi.c,v 1.64 1999/12/14 18:31:20 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -30,19 +30,13 @@ const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
 
 
 
-lua_Type luaA_normalizedtype (const TObject *o) {
-  int t = ttype(o);
-  switch (t) {
-    case LUA_T_PMARK:
-      return LUA_T_PROTO;
-    case LUA_T_CMARK:
-      return LUA_T_CPROTO;
-    case LUA_T_CLMARK:
-      return LUA_T_CLOSURE;
-    default:
-      return t;
-  }
-}
+const lua_Type luaA_normtype[] = {  /* ORDER LUA_T */
+  LUA_T_USERDATA, LUA_T_NUMBER, LUA_T_STRING, LUA_T_ARRAY,
+  LUA_T_LPROTO, LUA_T_CPROTO, LUA_T_NIL,
+  LUA_T_LCLOSURE, LUA_T_CCLOSURE,
+  LUA_T_LCLOSURE, LUA_T_CCLOSURE,   /* LUA_T_LCLMARK, LUA_T_CCLMARK */
+  LUA_T_LPROTO, LUA_T_CPROTO        /* LUA_T_LMARK, LUA_T_CMARK */
+};
 
 
 void luaA_setnormalized (TObject *d, const TObject *s) {
@@ -52,7 +46,15 @@ void luaA_setnormalized (TObject *d, const TObject *s) {
 
 
 const TObject *luaA_protovalue (const TObject *o) {
-  return (luaA_normalizedtype(o) == LUA_T_CLOSURE) ?  protovalue(o) : o;
+  switch (luaA_normalizedtype(o)) {
+    case LUA_T_CCLOSURE:  case LUA_T_LCLOSURE:
+      return protovalue(o);
+    default:
+      LUA_ASSERT(L, luaA_normalizedtype(o) == LUA_T_LPROTO ||
+                    luaA_normalizedtype(o) == LUA_T_CPROTO,
+                    "invalid `function'");
+      return o;
+  }
 }
 
 
@@ -228,26 +230,32 @@ int lua_isnumber (lua_State *L, lua_Object o) {
 }
 
 int lua_isstring (lua_State *L, lua_Object o) {
-  int t = lua_tag(L, o);
-  return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
+  UNUSED(L);
+  return (o != LUA_NOOBJECT && (ttype(o) == LUA_T_STRING ||
+                                ttype(o) == LUA_T_NUMBER));
 }
 
 int lua_isfunction (lua_State *L, lua_Object o) {
-  int t = lua_tag(L, o);
-  return (t == LUA_T_PROTO) || (t == LUA_T_CPROTO);
+  return *lua_type(L, o) == 'f';
 }
 
 int lua_equal(lua_State *L, lua_Object o1, lua_Object o2) {
   UNUSED(L);
-  if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT) return (o1 == o2);
-  else return luaO_equalObj(o1, o2);
+  if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT)
+    return (o1 == o2);
+  else {
+    TObject obj1, obj2;
+    luaA_setnormalized(&obj1, o1);
+    luaA_setnormalized(&obj2, o2);
+    return luaO_equalObj(&obj1, &obj2);
+  }
 }
 
 
 double lua_getnumber (lua_State *L, lua_Object obj) {
   UNUSED(L);
-  if (obj == LUA_NOOBJECT) return 0.0;
-  if (tonumber(obj)) return 0.0;
+  if (obj == LUA_NOOBJECT  || tonumber(obj))
+     return 0.0;
   else return (nvalue(obj));
 }
 
@@ -339,28 +347,11 @@ void lua_pushobject (lua_State *L, lua_Object o) {
 int lua_tag (lua_State *L, lua_Object o) {
   UNUSED(L);
   if (o == LUA_NOOBJECT)
-     return LUA_T_NIL;
-  else {
-    int t;
-    switch (t = ttype(o)) {
-      case LUA_T_USERDATA:
-        return o->value.ts->u.d.tag;
-      case LUA_T_ARRAY:
-        return o->value.a->htag;
-      case LUA_T_PMARK:
-        return LUA_T_PROTO;
-      case LUA_T_CMARK:
-        return LUA_T_CPROTO;
-      case LUA_T_CLOSURE: case LUA_T_CLMARK:
-        return o->value.cl->consts[0].ttype;
-#ifdef DEBUG
-      case LUA_T_LINE:
-        LUA_INTERNALERROR(L, "invalid type");
-#endif
-      default:
-        return t;
-    }
-  }
+    return LUA_T_NIL;
+  else if (ttype(o) == LUA_T_USERDATA)  /* to allow `old' tags (deprecated) */
+    return o->value.ts->u.d.tag;
+  else
+    return luaT_effectivetag(o);
 }
 
 

+ 6 - 2
lapi.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.h,v 1.10 1999/12/02 16:24:45 roberto Exp roberto $
+** $Id: lapi.h,v 1.11 1999/12/14 18:33:29 roberto Exp roberto $
 ** Auxiliary functions from Lua API
 ** See Copyright Notice in lua.h
 */
@@ -11,7 +11,11 @@
 #include "lobject.h"
 
 
-lua_Type luaA_normalizedtype (const TObject *o);
+extern const lua_Type luaA_normtype[];
+
+#define luaA_normalizedtype(o)	(luaA_normtype[-ttype(o)])
+
+
 void luaA_setnormalized (TObject *d, const TObject *s);
 void luaA_checkCparams (lua_State *L, int nParams);
 const TObject *luaA_protovalue (const TObject *o);

+ 3 - 3
lbuiltin.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbuiltin.c,v 1.85 1999/12/14 18:42:57 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.86 1999/12/20 13:10:38 roberto Exp roberto $
 ** Built-in functions
 ** See Copyright Notice in lua.h
 */
@@ -377,10 +377,10 @@ void luaB_tostring (lua_State *L) {
     case LUA_T_ARRAY:
       sprintf(buff, "table: %p", o->value.a);
       break;
-    case LUA_T_CLOSURE:
+    case LUA_T_LCLOSURE:  case LUA_T_CCLOSURE:
       sprintf(buff, "function: %p", o->value.cl);
       break;
-    case LUA_T_PROTO:
+    case LUA_T_LPROTO:
       sprintf(buff, "function: %p", o->value.tf);
       break;
     case LUA_T_CPROTO:

+ 14 - 9
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: ldebug.c,v 1.1 1999/12/14 18:31:20 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -42,10 +42,11 @@ int lua_setdebug (lua_State *L, int debug) {
 lua_Function lua_stackedfunction (lua_State *L, int level) {
   int i;
   for (i = (L->top-1)-L->stack; i>=0; i--) {
-    int t = L->stack[i].ttype;
-    if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
-      if (level-- == 0)
+    if (is_T_MARK(L->stack[i].ttype)) {
+      if (level == 0)
         return L->stack+i;
+      level--;
+    }
   }
   return LUA_NOOBJECT;
 }
@@ -53,8 +54,12 @@ lua_Function lua_stackedfunction (lua_State *L, int level) {
 
 int lua_nups (lua_State *L, lua_Function f) {
   UNUSED(L);
-  return (!f || luaA_normalizedtype(f) != LUA_T_CLOSURE) ? 0 :
-            f->value.cl->nelems;
+  switch (luaA_normalizedtype(f)) {
+    case LUA_T_LCLOSURE:  case LUA_T_CCLOSURE:
+      return f->value.cl->nelems;
+    default:
+      return 0;
+  }
 }
 
 
@@ -66,7 +71,7 @@ int lua_currentline (lua_State *L, lua_Function f) {
 lua_Object lua_getlocal (lua_State *L, lua_Function f, int local_number,
                          const char **name) {
   /* check whether `f' is a Lua function */
-  if (lua_tag(L, f) != LUA_T_PROTO)
+  if (lua_tag(L, f) != LUA_T_LPROTO)
     return LUA_NOOBJECT;
   else {
     TProtoFunc *fp = luaA_protovalue(f)->value.tf;
@@ -84,7 +89,7 @@ lua_Object lua_getlocal (lua_State *L, lua_Function f, int local_number,
 
 int lua_setlocal (lua_State *L, lua_Function f, int local_number) {
   /* check whether `f' is a Lua function */
-  if (lua_tag(L, f) != LUA_T_PROTO)
+  if (lua_tag(L, f) != LUA_T_LPROTO)
     return 0;
   else {
     TProtoFunc *fp = luaA_protovalue(f)->value.tf;
@@ -110,7 +115,7 @@ void lua_funcinfo (lua_State *L, lua_Object func,
     lua_error(L, "API error - `funcinfo' called with a non-function value");
   else {
     const TObject *f = luaA_protovalue(func);
-    if (luaA_normalizedtype(f) == LUA_T_PROTO) {
+    if (luaA_normalizedtype(f) == LUA_T_LPROTO) {
       *source = tfvalue(f)->source->str;
       *linedefined = tfvalue(f)->lineDefined;
     }

+ 40 - 31
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.58 1999/12/06 12:03:45 roberto Exp roberto $
+** $Id: ldo.c,v 1.59 1999/12/21 18:04:41 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -93,7 +93,8 @@ void luaD_adjusttop (lua_State *L, StkId base, int extra) {
 ** Open a hole inside the stack at `pos'
 */
 void luaD_openstack (lua_State *L, StkId pos) {
-  luaO_memup(pos+1, pos, (L->top-pos)*sizeof(TObject));
+  int i = L->top-pos; 
+  while (i--) pos[i+1] = pos[i];
   incr_top;
 }
 
@@ -122,15 +123,18 @@ static void luaD_callHook (lua_State *L, StkId func, lua_CHFunction callhook,
     if (isreturn)
       callhook(L, LUA_NOOBJECT, "(return)", 0);
     else {
-      if (ttype(func) == LUA_T_PROTO)
-        callhook(L, func, tfvalue(func)->source->str,
-                          tfvalue(func)->lineDefined);
-      else if (ttype(func) == LUA_T_CLOSURE &&
-               ttype(clvalue(func)->consts) == LUA_T_PROTO)
-        callhook(L, func, tfvalue(protovalue(func))->source->str,
-                          tfvalue(protovalue(func))->lineDefined);
-      else
-        callhook(L, func, "(C)", -1);
+      switch (ttype(func)) {
+        case LUA_T_LPROTO:
+          callhook(L, func, tfvalue(func)->source->str,
+                            tfvalue(func)->lineDefined);
+          break;
+        case LUA_T_LCLOSURE:
+          callhook(L, func, tfvalue(protovalue(func))->source->str,
+                            tfvalue(protovalue(func))->lineDefined);
+          break;
+        default:
+          callhook(L, func, "(C)", -1);
+      }
     }
     L->allowhooks = 1;
     L->top = old_top;
@@ -158,16 +162,16 @@ static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
 }
 
 
-static StkId callCclosure (lua_State *L, const struct Closure *cl,
-                           lua_CFunction f, StkId base) {
+static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
   int nup = cl->nelems;  /* number of upvalues */
+  int n = L->top-base;   /* number of arguments (to move up) */
   luaD_checkstack(L, nup);
   /* open space for upvalues as extra arguments */
-  luaO_memup(base+nup, base, (L->top-base)*sizeof(TObject));
-  /* copy upvalues into stack */
-  memcpy(base, cl->consts+1, nup*sizeof(TObject));
+  while (n--) *(base+nup+n) = *(base+n);
   L->top += nup;
-  return callC(L, f, base);
+  /* copy upvalues into stack */
+  while (nup--) *(base+nup) = cl->consts[nup+1];
+  return callC(L, fvalue(cl->consts), base);
 }
 
 
@@ -197,17 +201,20 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
       ttype(func) = LUA_T_CMARK;
       firstResult = callC(L, fvalue(func), func+1);
       break;
-    case LUA_T_PROTO:
-      ttype(func) = LUA_T_PMARK;
+    case LUA_T_LPROTO:
+      ttype(func) = LUA_T_LMARK;
       firstResult = luaV_execute(L, NULL, tfvalue(func), func+1);
       break;
-    case LUA_T_CLOSURE: {
+    case LUA_T_LCLOSURE: {
       Closure *c = clvalue(func);
-      TObject *proto = c->consts;
-      ttype(func) = LUA_T_CLMARK;
-      firstResult = (ttype(proto) == LUA_T_CPROTO) ?
-                       callCclosure(L, c, fvalue(proto), func+1) :
-                       luaV_execute(L, c, tfvalue(proto), func+1);
+      ttype(func) = LUA_T_LCLMARK;
+      firstResult = luaV_execute(L, c, tfvalue(c->consts), func+1);
+      break;
+    }
+    case LUA_T_CCLOSURE: {
+      Closure *c = clvalue(func);
+      ttype(func) = LUA_T_CCLMARK;
+      firstResult = callCclosure(L, c, func+1);
       break;
     }
     default: { /* `func' is not a function; check the `function' tag method */
@@ -226,16 +233,18 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
     nResults = L->top - firstResult;
   else
     luaD_adjusttop(L, firstResult, nResults);
-  /* move results to func (to erase parameters and function) */
-  luaO_memdown(func, firstResult, nResults*sizeof(TObject));
-  L->top = func+nResults;
+  /* move results to `func' (to erase parameters and function) */
+  while (nResults) {
+    *func++ = *(L->top - nResults);
+    nResults--;
+  }
+  L->top = func;
 }
 
 
 static void message (lua_State *L, const char *s) {
   const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value);
-  if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
-      ttype(em) == LUA_T_CLOSURE) {
+  if (*luaO_typename(em) == 'f') {
     *L->top = *em;
     incr_top;
     lua_pushstring(L, s);
@@ -313,7 +322,7 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
   L->errorJmp = oldErr;
   if (status) return 1;  /* error code */
   if (tf == NULL) return 2;  /* `natural' end */
-  L->top->ttype = LUA_T_PROTO;  /* push new function on the stack */
+  L->top->ttype = LUA_T_LPROTO;  /* push new function on the stack */
   L->top->value.tf = tf;
   incr_top;
   return 0;

+ 4 - 3
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.36 1999/12/14 18:31:20 roberto Exp roberto $
+** $Id: lgc.c,v 1.37 1999/12/21 18:04:41 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -100,10 +100,11 @@ static int markobject (lua_State *L, TObject *o) {
     case LUA_T_ARRAY:
       hashmark(L, avalue(o));
       break;
-    case LUA_T_CLOSURE:  case LUA_T_CLMARK:
+    case LUA_T_LCLOSURE:  case LUA_T_LCLMARK:
+    case LUA_T_CCLOSURE:  case LUA_T_CCLMARK:
       closuremark(L, o->value.cl);
       break;
-    case LUA_T_PROTO: case LUA_T_PMARK:
+    case LUA_T_LPROTO: case LUA_T_LMARK:
       protomark(L, o->value.tf);
       break;
     default: break;  /* numbers, cprotos, etc */

+ 18 - 10
lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 1.26 1999/11/26 18:59:20 roberto Exp roberto $
+** $Id: lobject.c,v 1.27 1999/12/14 18:31:20 roberto Exp roberto $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -14,8 +14,9 @@
 
 
 const char *const luaO_typenames[] = { /* ORDER LUA_T */
-    "userdata", "number", "string", "table", "function", "function",
-    "nil", "function", "mark", "mark", "mark", "line", NULL
+    "userdata", "number", "string", "table", "function", "function", "nil",
+    "function", "function", "function", "function", "function", "function",
+    "line", NULL
 };
 
 
@@ -34,13 +35,20 @@ unsigned long luaO_power2 (unsigned long n) {
 
 int luaO_equalval (const TObject *t1, const TObject *t2) {
   switch (ttype(t1)) {
-    case LUA_T_NIL: return 1;
-    case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
-    case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2);
-    case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
-    case LUA_T_PROTO: return tfvalue(t1)  == tfvalue(t2);
-    case LUA_T_CPROTO: return fvalue(t1)  == fvalue(t2);
-    case LUA_T_CLOSURE: return t1->value.cl == t2->value.cl;
+    case LUA_T_NIL:
+      return 1;
+    case LUA_T_NUMBER:
+      return nvalue(t1) == nvalue(t2);
+    case LUA_T_STRING: case LUA_T_USERDATA:
+      return svalue(t1) == svalue(t2);
+    case LUA_T_ARRAY: 
+      return avalue(t1) == avalue(t2);
+    case LUA_T_LPROTO:
+      return tfvalue(t1)  == tfvalue(t2);
+    case LUA_T_CPROTO:
+      return fvalue(t1)  == fvalue(t2);
+    case LUA_T_CCLOSURE: case LUA_T_LCLOSURE:
+      return t1->value.cl == t2->value.cl;
     default:
      LUA_INTERNALERROR(L, "invalid type");
      return 0; /* UNREACHABLE */

+ 18 - 10
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 1.39 1999/12/02 16:24:45 roberto Exp roberto $
+** $Id: lobject.h,v 1.40 1999/12/14 18:33:29 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -69,25 +69,33 @@ typedef enum {
   LUA_T_NUMBER   = -1,  /* fixed tag for numbers */
   LUA_T_STRING   = -2,  /* fixed tag for strings */
   LUA_T_ARRAY    = -3,  /* tag default for tables (or arrays) */
-  LUA_T_PROTO    = -4,  /* fixed tag for functions */
-  LUA_T_CPROTO   = -5,  /* fixed tag for Cfunctions */
+  LUA_T_LPROTO   = -4,  /* fixed tag for Lua functions */
+  LUA_T_CPROTO   = -5,  /* fixed tag for C functions */
   LUA_T_NIL      = -6,  /* last "pre-defined" tag */
-  LUA_T_CLOSURE  = -7,
-  LUA_T_CLMARK   = -8,  /* mark for closures */
-  LUA_T_PMARK    = -9,  /* mark for Lua prototypes */
-  LUA_T_CMARK    = -10, /* mark for C prototypes */
-  LUA_T_LINE     = -11
+  LUA_T_LCLOSURE  = -7, /* Lua closure */
+  LUA_T_CCLOSURE  = -8, /* C closure */
+  LUA_T_LCLMARK   = -9 ,/* mark for Lua closures */
+  LUA_T_CCLMARK   = -10,/* mark for C closures */
+  LUA_T_LMARK    = -11, /* mark for Lua prototypes */
+  LUA_T_CMARK    = -12, /* mark for C prototypes */
+  LUA_T_LINE     = -13
 } lua_Type;
 
 #define NUM_TAGS  7
 
+/*
+** chech whether t is a mark; ttypes are negative numbers, so the
+** comparisons look reversed.  (ORDER LUA_T)
+*/
+#define is_T_MARK(t)	(LUA_T_CMARK <= (t) && (t) <= LUA_T_LCLMARK)
+
 
 typedef union {
   lua_CFunction f;  /* LUA_T_CPROTO, LUA_T_CMARK */
   real n;  /* LUA_T_NUMBER */
   struct TaggedString *ts;  /* LUA_T_STRING, LUA_T_USERDATA */
-  struct TProtoFunc *tf;  /* LUA_T_PROTO, LUA_T_PMARK */
-  struct Closure *cl;  /* LUA_T_CLOSURE, LUA_T_CLMARK */
+  struct TProtoFunc *tf;  /* LUA_T_LPROTO, LUA_T_LMARK */
+  struct Closure *cl;  /* LUA_T_[CL]CLOSURE, LUA_T_[CL]CLMARK */
   struct Hash *a;  /* LUA_T_ARRAY */
   int i;  /* LUA_T_LINE */
 } Value;

+ 3 - 3
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.48 1999/12/21 17:31:28 roberto Exp roberto $
+** $Id: lparser.c,v 1.49 1999/12/22 16:58:36 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -547,7 +547,7 @@ static void func_onstack (LexState *ls, FuncState *func) {
   FuncState *fs = ls->fs;
   int i;
   int c = next_constant(ls, fs->f);
-  ttype(&fs->f->consts[c]) = LUA_T_PROTO;
+  ttype(&fs->f->consts[c]) = LUA_T_LPROTO;
   fs->f->consts[c].value.tf = func->f;
   if (func->nupvalues == 0)
     code_constant(ls, c);
@@ -580,7 +580,7 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
   code_byte(ls, 0);  /* to be filled with arg information */
   /* push function (to avoid GC) */
   tfvalue(L->top) = f;
-  ttype(L->top) = LUA_T_PROTO;
+  ttype(L->top) = LUA_T_LPROTO;
   incr_top;
 }
 

+ 3 - 8
lref.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lref.c,v 1.3 1999/11/22 13:12:07 roberto Exp roberto $
+** $Id: lref.c,v 1.4 1999/12/14 18:31:20 roberto Exp roberto $
 ** REF mechanism
 ** See Copyright Notice in lua.h
 */
@@ -85,15 +85,10 @@ static int ismarked (const TObject *o) {
       return o->value.ts->marked;
     case LUA_T_ARRAY:
       return o->value.a->marked;
-    case LUA_T_CLOSURE:
+    case LUA_T_LCLOSURE:  case LUA_T_CCLOSURE:
       return o->value.cl->marked;
-    case LUA_T_PROTO:
+    case LUA_T_LPROTO:
       return o->value.tf->marked;
-#ifdef DEBUG
-    case LUA_T_LINE: case LUA_T_CLMARK:
-    case LUA_T_CMARK: case LUA_T_PMARK:
-      LUA_INTERNALERROR(L, "invalid type");
-#endif
     default:  /* number or cproto */
       return 1;
   }

+ 3 - 3
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.31 1999/11/26 18:59:20 roberto Exp roberto $
+** $Id: ltable.c,v 1.32 1999/12/07 12:05:34 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -52,13 +52,13 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
     case LUA_T_ARRAY:
       h = IntPoint(L, avalue(key));
       break;
-    case LUA_T_PROTO:
+    case LUA_T_LPROTO:
       h = IntPoint(L, tfvalue(key));
       break;
     case LUA_T_CPROTO:
       h = IntPoint(L, fvalue(key));
       break;
-    case LUA_T_CLOSURE:
+    case LUA_T_LCLOSURE:  case LUA_T_CCLOSURE:
       h = IntPoint(L, clvalue(key));
       break;
     default:

+ 12 - 1
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbuiltin.c,v 1.83 1999/12/07 12:05:34 roberto Exp $
+** $Id: ltests.c,v 1.1 1999/12/14 18:31:20 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -17,6 +17,7 @@
 #include "lstring.h"
 #include "ltable.h"
 #include "lua.h"
+#include "luadebug.h"
 
 
 void luaB_opentests (lua_State *L);
@@ -195,6 +196,12 @@ static void testC (lua_State *L) {
     else if EQ("rawsettable") {
       lua_rawsettable(L);
     }
+    else if EQ("tag") {
+      lua_pushnumber(L, lua_tag(L, reg[getreg(L, &pc)]));
+    }
+    else if EQ("type") {
+      lua_pushstring(L, lua_type(L, reg[getreg(L, &pc)]));
+    }
     else if EQ("nextvar") {
       lua_pushstring(L, lua_nextvar(L, lua_getstring(L, reg[getreg(L, &pc)])));
     }
@@ -223,6 +230,10 @@ static void testC (lua_State *L) {
       int n = getreg(L, &pc);
       lua_settagmethod(L, (int)lua_getnumber(L, reg[n]), getname(&pc));
     }
+    else if EQ("getfunc") {
+      int n = getreg(L, &pc);
+      reg[n] = lua_stackedfunction(L, getnum(&pc));
+    }
     else if EQ("beginblock") {
       lua_beginblock(L);
     }

+ 12 - 14
ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.c,v 1.28 1999/10/04 17:51:04 roberto Exp roberto $
+** $Id: ltm.c,v 1.29 1999/11/22 13:12:07 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -42,7 +42,7 @@ static const char luaT_validevents[NUM_TAGS][IM_N] = {
 {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},  /* LUA_T_NUMBER */
 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},  /* LUA_T_STRING */
 {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},  /* LUA_T_ARRAY */
-{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  /* LUA_T_PROTO */
+{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  /* LUA_T_LPROTO */
 {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  /* LUA_T_CPROTO */
 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}   /* LUA_T_NIL */
 };
@@ -104,23 +104,21 @@ int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
 
 
 int luaT_effectivetag (const TObject *o) {
+  static const int realtag[] = {  /* ORDER LUA_T */
+    LUA_T_USERDATA, LUA_T_NUMBER, LUA_T_STRING, LUA_T_ARRAY,
+    LUA_T_LPROTO, LUA_T_CPROTO, LUA_T_NIL,
+    LUA_T_LPROTO, LUA_T_CPROTO,       /* LUA_T_LCLOSURE, LUA_T_CCLOSURE */
+    LUA_T_LPROTO, LUA_T_CPROTO,       /* LUA_T_LCLMARK, LUA_T_CCLMARK */
+    LUA_T_LPROTO, LUA_T_CPROTO        /* LUA_T_LMARK, LUA_T_CMARK */
+  };
   int t;
   switch (t = ttype(o)) {
-    case LUA_T_ARRAY:
-      return o->value.a->htag;
     case LUA_T_USERDATA: {
       int tag = o->value.ts->u.d.tag;
-      return (tag >= 0) ? LUA_T_USERDATA : tag;
+      return (tag >= 0) ? LUA_T_USERDATA : tag;  /* deprecated test */
     }
-    case LUA_T_CLOSURE:
-      return o->value.cl->consts[0].ttype;
-#ifdef DEBUG
-    case LUA_T_PMARK: case LUA_T_CMARK:
-    case LUA_T_CLMARK: case LUA_T_LINE:
-      LUA_INTERNALERROR(L, "invalid type");
-#endif
-    default:
-      return t;
+    case LUA_T_ARRAY:    return o->value.a->htag;
+    default:             return realtag[-t];
   }
 }
 

+ 2 - 2
lundump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lundump.c,v 1.24 1999/12/02 18:45:03 lhf Exp $
+** $Id: lundump.c,v 1.16 1999/12/02 19:11:51 roberto Exp roberto $
 ** load bytecodes from files
 ** See Copyright Notice in lua.h
 */
@@ -135,7 +135,7 @@ static void LoadConstants (lua_State* L, TProtoFunc* tf, ZIO* Z, int native)
    case LUA_T_STRING:
 	tsvalue(o)=LoadTString(L,Z);
 	break;
-   case LUA_T_PROTO:
+   case LUA_T_LPROTO:
 	tfvalue(o)=LoadFunction(L,Z,native);
 	break;
    case LUA_T_NIL:

+ 6 - 3
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.73 1999/12/14 18:31:20 roberto Exp roberto $
+** $Id: lvm.c,v 1.74 1999/12/21 18:04:41 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -86,8 +86,10 @@ void luaV_closure (lua_State *L, int nelems) {
     Closure *c = luaF_newclosure(L, nelems);
     c->consts[0] = *(L->top-1);
     L->top -= nelems;
-    memcpy(&c->consts[1], L->top-1, nelems*sizeof(TObject));
-    ttype(L->top-1) = LUA_T_CLOSURE;
+    while (nelems--)
+      c->consts[nelems+1] = *(L->top-1+nelems);
+    ttype(L->top-1) = (ttype(&c->consts[0]) == LUA_T_CPROTO) ?
+                        LUA_T_CCLOSURE : LUA_T_LCLOSURE;
     (L->top-1)->value.cl = c;
   }
 }
@@ -577,6 +579,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
         *top++ = consts[aux];
         L->top = top;
         aux = *pc++;  /* number of upvalues */
+        LUA_ASSERT(L, aux>0, "closure with no upvalues");
         luaV_closure(L, aux);
         luaC_checkGC(L);
         top -= aux;