Kaynağa Gözat

no more special cases for closures with 0 upvalues (performance is the same,
memory use a little higher, code much simpler).

Roberto Ierusalimschy 25 yıl önce
ebeveyn
işleme
a69356e9e0
16 değiştirilmiş dosya ile 128 ekleme ve 194 silme
  1. 5 18
      lapi.c
  2. 1 2
      lapi.h
  3. 1 7
      lbuiltin.c
  4. 10 18
      ldebug.c
  5. 23 40
      ldo.c
  6. 1 3
      ldo.h
  7. 3 2
      lfunc.c
  8. 7 8
      lgc.c
  9. 5 10
      lobject.c
  10. 29 32
      lobject.h
  11. 1 6
      lparser.c
  12. 2 4
      lref.c
  13. 1 7
      ltable.c
  14. 7 12
      ltm.c
  15. 28 22
      lvm.c
  16. 4 3
      lvm.h

+ 5 - 18
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.75 2000/03/20 19:14:54 roberto Exp roberto $
+** $Id: lapi.c,v 1.76 2000/03/27 20:10:21 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -30,17 +30,6 @@ const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
 
 
 
-
-const TObject *luaA_protovalue (const TObject *o) {
-  switch (ttype(o)) {
-    case TAG_CCLOSURE:  case TAG_LCLOSURE:
-      return protovalue(o);
-    default:
-      return o;
-  }
-}
-
-
 void luaA_checkCargs (lua_State *L, int nargs) {
   if (nargs > L->top-L->Cstack.base)
     luaL_verror(L, "Lua API error - "
@@ -210,7 +199,8 @@ int lua_isuserdata (lua_State *L, lua_Object o) {
 }
 
 int lua_iscfunction (lua_State *L, lua_Object o) {
-  return (lua_tag(L, o) == TAG_CPROTO);
+  UNUSED(L);
+  return (o != LUA_NOOBJECT) && (ttype(o) == TAG_CCLOSURE);
 }
 
 int lua_isnumber (lua_State *L, lua_Object o) {
@@ -266,7 +256,7 @@ void *lua_getuserdata (lua_State *L, lua_Object obj) {
 lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) {
   if (!lua_iscfunction(L, obj))
     return NULL;
-  else return fvalue(luaA_protovalue(obj));
+  else return clvalue(obj)->f.c;
 }
 
 
@@ -299,10 +289,7 @@ void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
   if (fn == NULL)
     lua_error(L, "Lua API error - attempt to push a NULL Cfunction");
   luaA_checkCargs(L, n);
-  ttype(L->top) = TAG_CPROTO;
-  fvalue(L->top) = fn;
-  incr_top;
-  luaV_closure(L, n);
+  luaV_Cclosure(L, fn, n);
   luaC_checkGC(L);
 }
 

+ 1 - 2
lapi.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.h,v 1.14 2000/03/03 14:58:26 roberto Exp roberto $
+** $Id: lapi.h,v 1.15 2000/03/10 18:37:44 roberto Exp roberto $
 ** Auxiliary functions from Lua API
 ** See Copyright Notice in lua.h
 */
@@ -12,7 +12,6 @@
 
 
 void luaA_checkCargs (lua_State *L, int nargs);
-const TObject *luaA_protovalue (const TObject *o);
 void luaA_pushobject (lua_State *L, const TObject *o);
 GlobalVar *luaA_nextvar (lua_State *L, TString *g);
 int luaA_next (lua_State *L, const Hash *t, int i);

+ 1 - 7
lbuiltin.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbuiltin.c,v 1.98 2000/03/27 20:08:02 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.99 2000/03/27 20:10:21 roberto Exp roberto $
 ** Built-in functions
 ** See Copyright Notice in lua.h
 */
@@ -386,12 +386,6 @@ void luaB_tostring (lua_State *L) {
     case TAG_LCLOSURE:  case TAG_CCLOSURE:
       sprintf(buff, "function: %p", o->value.cl);
       break;
-    case TAG_LPROTO:
-      sprintf(buff, "function: %p", o->value.tf);
-      break;
-    case TAG_CPROTO:
-      sprintf(buff, "function: %p", o->value.f);
-      break;
     case TAG_USERDATA:
       sprintf(buff, "userdata: %p(%d)", o->value.ts->u.d.value,
                                         o->value.ts->u.d.tag);

+ 10 - 18
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.12 2000/03/20 19:14:54 roberto Exp roberto $
+** $Id: ldebug.c,v 1.13 2000/03/27 20:10:21 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -24,10 +24,8 @@
 
 static const lua_Type normtype[] = {  /* ORDER LUA_T */
   TAG_USERDATA, TAG_NUMBER, TAG_STRING, TAG_TABLE,
-  TAG_LPROTO, TAG_CPROTO, TAG_NIL,
-  TAG_LCLOSURE, TAG_CCLOSURE,
-  TAG_LCLOSURE, TAG_CCLOSURE,   /* TAG_LCLMARK, TAG_CCLMARK */
-  TAG_LPROTO, TAG_CPROTO        /* TAG_LMARK, TAG_CMARK */
+  TAG_LCLOSURE, TAG_CCLOSURE, TAG_NIL,
+  TAG_LCLOSURE, TAG_CCLOSURE   /* TAG_LCLMARK, TAG_CCLMARK */
 };
 
 
@@ -104,11 +102,7 @@ static int lua_currentline (lua_State *L, StkId f) {
 
 
 static Proto *getluaproto (StkId f) {
-  if (ttype(f) == TAG_LMARK)
-    return f->value.tf;
-  else if (ttype(f) == TAG_LCLMARK)
-    return protovalue(f)->value.tf;
-  else return NULL;
+  return (ttype(f) == TAG_LCLMARK) ?  clvalue(f)->f.l : NULL;
 }
 
 
@@ -141,20 +135,18 @@ int lua_setlocal (lua_State *L, const lua_Dbgactreg *ar, lua_Dbglocvar *v) {
 static void lua_funcinfo (lua_Dbgactreg *ar) {
   StkId func = ar->_func;
   switch (ttype(func)) {
-    case TAG_LPROTO:  case TAG_LMARK:
-      ar->source = tfvalue(func)->source->str;
-      ar->linedefined = tfvalue(func)->lineDefined;
-      ar->what = "Lua";
-      break;
     case TAG_LCLOSURE:  case TAG_LCLMARK:
-      ar->source = tfvalue(protovalue(func))->source->str;
-      ar->linedefined = tfvalue(protovalue(func))->lineDefined;
+      ar->source = clvalue(func)->f.l->source->str;
+      ar->linedefined = clvalue(func)->f.l->lineDefined;
       ar->what = "Lua";
       break;
-    default:
+    case TAG_CCLOSURE:  case TAG_CCLMARK:
       ar->source = "(C)";
       ar->linedefined = -1;
       ar->what = "C";
+      break;
+    default:
+      LUA_INTERNALERROR(L, "invalid `func' value");
   }
   if (ar->linedefined == 0)
     ar->what = "main";

+ 23 - 40
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.68 2000/03/03 14:58:26 roberto Exp roberto $
+** $Id: ldo.c,v 1.69 2000/03/10 18:37:44 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -119,7 +119,7 @@ void luaD_lineHook (lua_State *L, StkId func, int line) {
 }
 
 
-void luaD_callHook (lua_State *L, StkId func, lua_Dbghook callhook,
+static void luaD_callHook (lua_State *L, StkId func, lua_Dbghook callhook,
                     const char *event) {
   if (L->allowhooks) {
     lua_Dbgactreg ar;
@@ -137,40 +137,31 @@ void luaD_callHook (lua_State *L, StkId func, lua_Dbghook callhook,
 }
 
 
-/*
-** Call a C function.
-** Cstack.num is the number of arguments; Cstack.lua2C points to the
-** first argument. Returns an index to the first result from C.
-*/
-static StkId callC (lua_State *L, 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 numarg = L->top-base;
   struct C_Lua_Stack oldCLS = L->Cstack;
   StkId firstResult;
-  int numarg = L->top - base;
+  if (nup > 0) {
+    int n = numarg;
+    luaD_checkstack(L, nup);
+    /* open space for upvalues as extra arguments */
+    while (n--) *(base+nup+n) = *(base+n);
+    L->top += nup;
+    numarg += nup;
+    /* copy upvalues into stack */
+    while (nup--) *(base+nup) = cl->consts[nup];
+  }
   L->Cstack.num = numarg;
   L->Cstack.lua2C = base;
   L->Cstack.base = L->top;
-  if (L->callhook)
-    luaD_callHook(L, base-1, L->callhook, "call");
-  (*f)(L);  /* do the actual call */
+  (*cl->f.c)(L);  /* do the actual call */
   firstResult = L->Cstack.base;
   L->Cstack = oldCLS;
   return firstResult;
 }
 
 
-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 */
-  while (n--) *(base+nup+n) = *(base+n);
-  L->top += nup;
-  /* copy upvalues into stack */
-  while (nup--) *(base+nup) = cl->consts[nup+1];
-  return callC(L, fvalue(cl->consts), base);
-}
-
-
 void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
   StkId base = L->top - nParams;
   luaD_openstack(L, base);
@@ -191,24 +182,18 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
   lua_Dbghook callhook = L->callhook;
   retry:  /* for `function' tag method */
   switch (ttype(func)) {
-    case TAG_CPROTO:
-      ttype(func) = TAG_CMARK;
-      firstResult = callC(L, fvalue(func), func+1);
-      break;
-    case TAG_LPROTO:
-      ttype(func) = TAG_LMARK;
-      firstResult = luaV_execute(L, NULL, tfvalue(func), func+1);
-      break;
     case TAG_LCLOSURE: {
-      Closure *c = clvalue(func);
       ttype(func) = TAG_LCLMARK;
-      firstResult = luaV_execute(L, c, tfvalue(c->consts), func+1);
+      if (callhook)
+        luaD_callHook(L, func, callhook, "call");
+      firstResult = luaV_execute(L, clvalue(func), func+1);
       break;
     }
     case TAG_CCLOSURE: {
-      Closure *c = clvalue(func);
       ttype(func) = TAG_CCLMARK;
-      firstResult = callCclosure(L, c, func+1);
+      if (callhook)
+        luaD_callHook(L, func, callhook, "call");
+      firstResult = callCclosure(L, clvalue(func), func+1);
       break;
     }
     default: { /* `func' is not a function; check the `function' tag method */
@@ -316,9 +301,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 = TAG_LPROTO;  /* push new function on the stack */
-  L->top->value.tf = tf;
-  incr_top;
+  luaV_Lclosure(L, tf, 0);
   return 0;
 }
 

+ 1 - 3
ldo.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 1.17 2000/01/19 12:00:45 roberto Exp roberto $
+** $Id: ldo.h,v 1.18 2000/03/24 17:26:08 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -22,8 +22,6 @@
 void luaD_init (lua_State *L, int stacksize);
 void luaD_adjusttop (lua_State *L, StkId base, int extra);
 void luaD_openstack (lua_State *L, StkId pos);
-void luaD_callHook (lua_State *L, StkId func, lua_Dbghook callhook,
-                    const char *event);
 void luaD_lineHook (lua_State *L, StkId func, int line);
 void luaD_call (lua_State *L, StkId func, int nResults);
 void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);

+ 3 - 2
lfunc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.c,v 1.19 2000/03/03 14:58:26 roberto Exp roberto $
+** $Id: lfunc.c,v 1.20 2000/03/10 18:37:44 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */
@@ -19,7 +19,8 @@
 
 
 Closure *luaF_newclosure (lua_State *L, int nelems) {
-  Closure *c = (Closure *)luaM_malloc(L, sizeof(Closure)+nelems*sizeof(TObject));
+  Closure *c = (Closure *)luaM_malloc(L, sizeof(Closure) +
+                                         sizeof(TObject)*(nelems-1));
   c->next = L->rootcl;
   L->rootcl = c;
   c->marked = 0;

+ 7 - 8
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.43 2000/03/27 20:08:02 roberto Exp roberto $
+** $Id: lgc.c,v 1.44 2000/03/27 20:10:21 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -43,9 +43,9 @@ static void protomark (lua_State *L, Proto *f) {
 
 static void closuremark (lua_State *L, Closure *f) {
   if (!f->marked) {
-    int i;
+    int i = f->nelems;
     f->marked = 1;
-    for (i=f->nelems; i>=0; i--)
+    while (i--)
       markobject(L, &f->consts[i]);
   }
 }
@@ -103,13 +103,12 @@ static int markobject (lua_State *L, TObject *o) {
       hashmark(L, avalue(o));
       break;
     case TAG_LCLOSURE:  case TAG_LCLMARK:
+      protomark(L, clvalue(o)->f.l);
+      /* go trhough */
     case TAG_CCLOSURE:  case TAG_CCLMARK:
-      closuremark(L, o->value.cl);
-      break;
-    case TAG_LPROTO: case TAG_LMARK:
-      protomark(L, o->value.tf);
+      closuremark(L, clvalue(o));
       break;
-    default: break;  /* numbers, cprotos, etc */
+    default: break;  /* numbers, etc */
   }
   return 0;
 }

+ 5 - 10
lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 1.33 2000/03/10 18:37:44 roberto Exp roberto $
+** $Id: lobject.c,v 1.34 2000/03/27 20:10:21 roberto Exp roberto $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -15,8 +15,7 @@
 
 const char *const luaO_typenames[] = { /* ORDER LUA_T */
     "userdata", "number", "string", "table", "function", "function", "nil",
-    "function", "function", "function", "function", "function", "function",
-    "line", NULL
+    "function", "function", "line"
 };
 
 
@@ -35,20 +34,16 @@ unsigned long luaO_power2 (unsigned long n) {
 
 int luaO_equalval (const TObject *t1, const TObject *t2) {
   switch (ttype(t1)) {
-    case TAG_NIL:
-      return 1;
     case TAG_NUMBER:
       return nvalue(t1) == nvalue(t2);
     case TAG_STRING: case TAG_USERDATA:
       return svalue(t1) == svalue(t2);
     case TAG_TABLE: 
       return avalue(t1) == avalue(t2);
-    case TAG_LPROTO:
-      return tfvalue(t1)  == tfvalue(t2);
-    case TAG_CPROTO:
-      return fvalue(t1)  == fvalue(t2);
     case TAG_CCLOSURE: case TAG_LCLOSURE:
-      return t1->value.cl == t2->value.cl;
+      return clvalue(t1) == clvalue(t2);
+    case TAG_NIL:
+      return 1;
     default:
      LUA_INTERNALERROR(L, "invalid type");
      return 0; /* UNREACHABLE */

+ 29 - 32
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 1.55 2000/03/24 19:49:23 roberto Exp roberto $
+** $Id: lobject.h,v 1.56 2000/03/27 20:10:21 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -23,7 +23,12 @@
 #endif
 
 
+#ifdef DEBUG
+/* to avoid warnings and make sure is is really unused */
+#define UNUSED(x)	(x=0, (void)x)
+#else
 #define UNUSED(x)	(void)x		/* to avoid warnings */
+#endif
 
 
 /*
@@ -36,17 +41,12 @@ typedef enum {
   TAG_NUMBER,	/* fixed tag for numbers */
   TAG_STRING,	/* fixed tag for strings */
   TAG_TABLE,	/* default tag for tables */
-  TAG_LPROTO,	/* fixed tag for Lua functions */
-  TAG_CPROTO,	/* fixed tag for C functions */
+  TAG_LCLOSURE,	/* fixed tag for Lua closures */
+  TAG_CCLOSURE,	/* fixed tag for C closures */
   TAG_NIL,	/* last "pre-defined" tag */
 
-  TAG_LCLOSURE,	/* Lua closure */
-  TAG_CCLOSURE,	/* C closure */
-
   TAG_LCLMARK,	/* mark for Lua closures */
   TAG_CCLMARK,	/* mark for C closures */
-  TAG_LMARK,	/* mark for Lua prototypes */
-  TAG_CMARK,	/* mark for C prototypes */
 
   TAG_LINE
 } lua_Type;
@@ -58,20 +58,27 @@ typedef enum {
 /*
 ** check whether `t' is a mark
 */
-#define is_T_MARK(t)	(TAG_LCLMARK <= (t) && (t) <= TAG_CMARK)
+#define is_T_MARK(t)	((t) == TAG_LCLMARK || (t) == TAG_CCLMARK)
 
 
 typedef union {
-  lua_CFunction f;              /* TAG_CPROTO, TAG_CMARK */
-  Number n;                       /* TAG_NUMBER */
-  struct TString *ts;      /* TAG_STRING, TAG_USERDATA */
-  struct Proto *tf;        /* TAG_LPROTO, TAG_LMARK */
-  struct Closure *cl;           /* TAG_[CL]CLOSURE, TAG_[CL]CLMARK */
-  struct Hash *a;               /* TAG_TABLE */
-  int i;                        /* TAG_LINE */
+  struct TString *ts;	/* TAG_STRING, TAG_USERDATA */
+  struct Closure *cl;	/* TAG_[CL]CLOSURE, TAG_[CL]CLMARK */
+  struct Hash *a;	/* TAG_TABLE */
+  Number n;		/* TAG_NUMBER */
+  int i;		/* TAG_LINE */
 } Value;
 
 
+/* Macros to access values */
+#define ttype(o)        ((o)->ttype)
+#define nvalue(o)       ((o)->value.n)
+#define svalue(o)       ((o)->value.ts->str)
+#define tsvalue(o)      ((o)->value.ts)
+#define clvalue(o)      ((o)->value.cl)
+#define avalue(o)       ((o)->value.a)
+
+
 typedef struct TObject {
   lua_Type ttype;
   Value value;
@@ -135,28 +142,18 @@ typedef struct LocVar {
 } LocVar;
 
 
-
-/* Macros to access structure members */
-#define ttype(o)        ((o)->ttype)
-#define nvalue(o)       ((o)->value.n)
-#define svalue(o)       ((o)->value.ts->str)
-#define tsvalue(o)      ((o)->value.ts)
-#define clvalue(o)      ((o)->value.cl)
-#define avalue(o)       ((o)->value.a)
-#define fvalue(o)       ((o)->value.f)
-#define tfvalue(o)	((o)->value.tf)
-
-#define protovalue(o)	((o)->value.cl->consts)
-
-
 /*
 ** Closures
 */
 typedef struct Closure {
   struct Closure *next;
   int marked;
-  int nelems;  /* not including the first one (always the prototype) */
-  TObject consts[1];  /* at least one for prototype */
+  union {
+    lua_CFunction c;  /* C functions */
+    struct Proto *l;  /* Lua functions */
+  } f;
+  int nelems;
+  TObject consts[1];
 } Closure;
 
 

+ 1 - 6
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.72 2000/03/24 12:17:53 roberto Exp roberto $
+** $Id: lparser.c,v 1.73 2000/03/24 17:26:08 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -345,10 +345,6 @@ static void init_state (LexState *ls, FuncState *fs, TString *source) {
   f->numparams = 0;  /* default for main chunk */
   f->is_vararg = 0;  /* default for main chunk */
   fs->nvars = (L->debug) ? 0 : -1;  /* flag no debug information? */
-  /* push function (to avoid GC) */
-  tfvalue(L->top) = f;
-  ttype(L->top) = TAG_LPROTO;
-  incr_top;
 }
 
 
@@ -366,7 +362,6 @@ static void close_func (LexState *ls) {
     luaM_reallocvector(L, f->locvars, fs->nvars, LocVar);
   }
   ls->fs = fs->prev;
-  L->top--;  /* pop function */
 }
 
 

+ 2 - 4
lref.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lref.c,v 1.9 2000/03/10 18:37:44 roberto Exp roberto $
+** $Id: lref.c,v 1.10 2000/03/27 20:10:21 roberto Exp roberto $
 ** reference mechanism
 ** See Copyright Notice in lua.h
 */
@@ -88,9 +88,7 @@ static int ismarked (const TObject *o) {
       return o->value.a->marked;
     case TAG_LCLOSURE:  case TAG_CCLOSURE:
       return o->value.cl->marked;
-    case TAG_LPROTO:
-      return o->value.tf->marked;
-    default:  /* number or cproto */
+    default:  /* number */
       return 1;
   }
 }

+ 1 - 7
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.36 2000/03/10 18:37:44 roberto Exp roberto $
+** $Id: ltable.c,v 1.37 2000/03/27 20:10:21 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -52,12 +52,6 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
     case TAG_TABLE:
       h = IntPoint(L, avalue(key));
       break;
-    case TAG_LPROTO:
-      h = IntPoint(L, tfvalue(key));
-      break;
-    case TAG_CPROTO:
-      h = IntPoint(L, fvalue(key));
-      break;
     case TAG_LCLOSURE:  case TAG_CCLOSURE:
       h = IntPoint(L, clvalue(key));
       break;

+ 7 - 12
ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.c,v 1.36 2000/03/27 20:08:02 roberto Exp roberto $
+** $Id: ltm.c,v 1.37 2000/03/27 20:10:21 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -47,8 +47,8 @@ static const char luaT_validevents[NUM_TAGS][IM_N] = {
   {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1},  /* TAG_NUMBER */
   {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},  /* TAG_STRING */
   {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},  /* TAG_TABLE */
-  {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  /* TAG_LPROTO */
-  {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  /* TAG_CPROTO */
+  {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  /* TAG_LCLOSURE */
+  {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  /* TAG_CCLOSURE */
   {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}   /* TAG_NIL */
 };
 
@@ -105,19 +105,14 @@ int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
 
 
 int luaT_effectivetag (lua_State *L, const TObject *o) {
-  static const int realtag[] = {  /* ORDER LUA_T */
-    TAG_USERDATA, TAG_NUMBER, TAG_STRING, TAG_TABLE,
-    TAG_LPROTO, TAG_CPROTO, TAG_NIL,
-    TAG_LPROTO, TAG_CPROTO,       /* TAG_LCLOSURE, TAG_CCLOSURE */
-  };
-  lua_Type t;
-  switch (t = ttype(o)) {
+  lua_Type t = ttype(o);
+  switch (t) {
     case TAG_USERDATA: {
       int tag = o->value.ts->u.d.tag;
       return (tag > L->last_tag) ? TAG_USERDATA : tag;  /* deprecated test */
     }
-    case TAG_TABLE:    return o->value.a->htag;
-    default:             return realtag[t];
+    case TAG_TABLE: return o->value.a->htag;
+    default: return t;
   }
 }
 

+ 28 - 22
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.96 2000/03/17 13:09:12 roberto Exp roberto $
+** $Id: lvm.c,v 1.97 2000/03/27 20:10:21 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -72,17 +72,27 @@ void luaV_setn (lua_State *L, Hash *t, int val) {
 }
 
 
-void luaV_closure (lua_State *L, int nelems) {
-  if (nelems > 0) {
-    Closure *c = luaF_newclosure(L, nelems);
-    c->consts[0] = *(L->top-1);
-    L->top -= nelems;
-    while (nelems--)
-      c->consts[nelems+1] = *(L->top-1+nelems);
-    ttype(L->top-1) = (ttype(&c->consts[0]) == TAG_CPROTO) ?
-                        TAG_CCLOSURE : TAG_LCLOSURE;
-    (L->top-1)->value.cl = c;
-  }
+static Closure *luaV_closure (lua_State *L, lua_Type t, int nelems) {
+  Closure *c = luaF_newclosure(L, nelems);
+  L->top -= nelems;
+  while (nelems--)
+    c->consts[nelems] = *(L->top+nelems);
+  ttype(L->top) = t;
+  clvalue(L->top) = c;
+  incr_top;
+  return c;
+}
+
+
+void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems) {
+  Closure *cl = luaV_closure(L, TAG_CCLOSURE, nelems);
+  cl->f.c = c;
+}
+
+
+void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
+  Closure *cl = luaV_closure(L, TAG_LCLOSURE, nelems);
+  cl->f.l = l;
 }
 
 
@@ -317,13 +327,11 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
 ** Executes the given Lua function. Parameters are between [base,top).
 ** Returns n such that the the results are between [n,top).
 */
-StkId luaV_execute (lua_State *L, const Closure *cl, const Proto *tf,
-                    register StkId base) {
+StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base) {
+  const Proto *tf = cl->f.l;
   register StkId top;  /* keep top local, for performance */
   register const Instruction *pc = tf->code;
   TString **kstr = tf->kstr;
-  if (L->callhook)
-    luaD_callHook(L, base-1, L->callhook, "call");
   luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
   if (tf->is_vararg) {  /* varargs? */
     adjust_varargs(L, base, tf->numparams);
@@ -392,7 +400,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const Proto *tf,
         break;
 
       case OP_PUSHUPVALUE:
-        *top++ = cl->consts[GETARG_U(i)+1];
+        *top++ = cl->consts[GETARG_U(i)];
         break;
 
       case OP_PUSHLOCAL:
@@ -604,11 +612,9 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const Proto *tf,
         break;
 
       case OP_CLOSURE:
-        ttype(top) = TAG_LPROTO;
-        tfvalue(top) = tf->kproto[GETARG_A(i)];
-        L->top = ++top;
-        luaV_closure(L, GETARG_B(i));
-        top -= GETARG_B(i);
+        L->top = top;
+        luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i));
+        top = L->top;
         luaC_checkGC(L);
         break;
 

+ 4 - 3
lvm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.h,v 1.18 2000/03/09 00:19:22 roberto Exp roberto $
+** $Id: lvm.h,v 1.19 2000/03/10 18:37:44 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -26,8 +26,9 @@ void luaV_settable (lua_State *L, StkId t, StkId top);
 void luaV_rawsettable (lua_State *L, StkId t);
 void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top);
 void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top);
-StkId luaV_execute (lua_State *L, const Closure *cl, const Proto *tf, StkId base);
-void luaV_closure (lua_State *L, int nelems);
+StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base);
+void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
+void luaV_Lclosure (lua_State *L, Proto *l, int nelems);
 int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top);
 
 #endif