Przeglądaj źródła

object tag keeps variant bits too -> no need for 'isC' field in
Closures + more strick typing for closure variants

Roberto Ierusalimschy 13 lat temu
rodzic
commit
fd22ccd6d0
7 zmienionych plików z 88 dodań i 67 usunięć
  1. 8 5
      ldebug.c
  2. 3 12
      lfunc.c
  3. 1 2
      lfunc.h
  4. 41 23
      lgc.c
  5. 7 5
      lobject.h
  6. 5 2
      lstate.h
  7. 23 18
      ltests.c

+ 8 - 5
ldebug.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldebug.c,v 2.87 2011/10/07 20:45:19 roberto Exp roberto $
+** $Id: ldebug.c,v 2.88 2011/11/30 12:43:51 roberto Exp roberto $
 ** Debug Interface
 ** Debug Interface
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -30,6 +30,9 @@
 
 
 
 
 
 
+#define noLuaClosure(f)		((f) == NULL || (f)->c.tt == LUA_TCCL)
+
+
 static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
 static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
 
 
 
 
@@ -173,7 +176,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
 
 
 
 
 static void funcinfo (lua_Debug *ar, Closure *cl) {
 static void funcinfo (lua_Debug *ar, Closure *cl) {
-  if (cl == NULL || cl->c.isC) {
+  if (noLuaClosure(cl)) {
     ar->source = "=[C]";
     ar->source = "=[C]";
     ar->linedefined = -1;
     ar->linedefined = -1;
     ar->lastlinedefined = -1;
     ar->lastlinedefined = -1;
@@ -191,7 +194,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
 
 
 
 
 static void collectvalidlines (lua_State *L, Closure *f) {
 static void collectvalidlines (lua_State *L, Closure *f) {
-  if (f == NULL || f->c.isC) {
+  if (noLuaClosure(f)) {
     setnilvalue(L->top);
     setnilvalue(L->top);
     incr_top(L);
     incr_top(L);
   }
   }
@@ -210,7 +213,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
 
 
 
 
 static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
 static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
-                    Closure *f, CallInfo *ci) {
+                       Closure *f, CallInfo *ci) {
   int status = 1;
   int status = 1;
   for (; *what; what++) {
   for (; *what; what++) {
     switch (*what) {
     switch (*what) {
@@ -224,7 +227,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
       }
       }
       case 'u': {
       case 'u': {
         ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
         ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
-        if (f == NULL || f->c.isC) {
+        if (noLuaClosure(f)) {
           ar->isvararg = 1;
           ar->isvararg = 1;
           ar->nparams = 0;
           ar->nparams = 0;
         }
         }

+ 3 - 12
lfunc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lfunc.c,v 2.26 2010/06/10 21:27:09 roberto Exp roberto $
+** $Id: lfunc.c,v 2.27 2010/06/30 14:11:17 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -21,8 +21,7 @@
 
 
 
 
 Closure *luaF_newCclosure (lua_State *L, int n) {
 Closure *luaF_newCclosure (lua_State *L, int n) {
-  Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeCclosure(n), NULL, 0)->cl;
-  c->c.isC = 1;
+  Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl;
   c->c.nupvalues = cast_byte(n);
   c->c.nupvalues = cast_byte(n);
   return c;
   return c;
 }
 }
@@ -30,8 +29,7 @@ Closure *luaF_newCclosure (lua_State *L, int n) {
 
 
 Closure *luaF_newLclosure (lua_State *L, Proto *p) {
 Closure *luaF_newLclosure (lua_State *L, Proto *p) {
   int n = p->sizeupvalues;
   int n = p->sizeupvalues;
-  Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeLclosure(n), NULL, 0)->cl;
-  c->l.isC = 0;
+  Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl;
   c->l.p = p;
   c->l.p = p;
   c->l.nupvalues = cast_byte(n);
   c->l.nupvalues = cast_byte(n);
   while (n--) c->l.upvals[n] = NULL;
   while (n--) c->l.upvals[n] = NULL;
@@ -146,13 +144,6 @@ void luaF_freeproto (lua_State *L, Proto *f) {
 }
 }
 
 
 
 
-void luaF_freeclosure (lua_State *L, Closure *c) {
-  int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
-                          sizeLclosure(c->l.nupvalues);
-  luaM_freemem(L, c, size);
-}
-
-
 /*
 /*
 ** Look for n-th local variable at line `line' in function `func'.
 ** Look for n-th local variable at line `line' in function `func'.
 ** Returns NULL if not found.
 ** Returns NULL if not found.

+ 1 - 2
lfunc.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lfunc.h,v 2.5 2010/03/26 20:58:11 roberto Exp roberto $
+** $Id: lfunc.h,v 2.6 2010/06/04 13:06:15 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -25,7 +25,6 @@ LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
 LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
 LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
 LUAI_FUNC void luaF_close (lua_State *L, StkId level);
 LUAI_FUNC void luaF_close (lua_State *L, StkId level);
 LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
 LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
-LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
 LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
 LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
 LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
 LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
                                          int pc);
                                          int pc);

+ 41 - 23
lgc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.c,v 2.115 2011/11/28 17:25:48 roberto Exp roberto $
+** $Id: lgc.c,v 2.116 2011/12/02 13:18:41 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -217,7 +217,8 @@ void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
 GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list,
 GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list,
                        int offset) {
                        int offset) {
   global_State *g = G(L);
   global_State *g = G(L);
-  GCObject *o = obj2gco(cast(char *, luaM_newobject(L, tt, sz)) + offset);
+  char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz));
+  GCObject *o = obj2gco(raw + offset);
   if (list == NULL)
   if (list == NULL)
     list = &g->allgc;  /* standard list for collectable objects */
     list = &g->allgc;  /* standard list for collectable objects */
   gch(o)->marked = luaC_white(g);
   gch(o)->marked = luaC_white(g);
@@ -266,8 +267,13 @@ static void reallymarkobject (global_State *g, GCObject *o) {
         gray2black(o);  /* make it black */
         gray2black(o);  /* make it black */
       return;
       return;
     }
     }
-    case LUA_TFUNCTION: {
-      gco2cl(o)->c.gclist = g->gray;
+    case LUA_TLCL: {
+      gco2lcl(o)->gclist = g->gray;
+      g->gray = o;
+      break;
+    }
+    case LUA_TCCL: {
+      gco2ccl(o)->gclist = g->gray;
       g->gray = o;
       g->gray = o;
       break;
       break;
     }
     }
@@ -470,20 +476,20 @@ static int traverseproto (global_State *g, Proto *f) {
 }
 }
 
 
 
 
-static int traverseclosure (global_State *g, Closure *cl) {
-  if (cl->c.isC) {
-    int i;
-    for (i=0; i<cl->c.nupvalues; i++)  /* mark its upvalues */
-      markvalue(g, &cl->c.upvalue[i]);
-  }
-  else {
-    int i;
-    lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
-    markobject(g, cl->l.p);  /* mark its prototype */
-    for (i=0; i<cl->l.nupvalues; i++)  /* mark its upvalues */
-      markobject(g, cl->l.upvals[i]);
-  }
-  return TRAVCOST + cl->c.nupvalues;
+static int traverseCclosure (global_State *g, CClosure *cl) {
+  int i;
+  for (i = 0; i < cl->nupvalues; i++)  /* mark its upvalues */
+    markvalue(g, &cl->upvalue[i]);
+  return TRAVCOST + cl->nupvalues;
+}
+
+static int traverseLclosure (global_State *g, LClosure *cl) {
+  int i;
+  assert(cl->nupvalues == cl->p->sizeupvalues);
+  markobject(g, cl->p);  /* mark its prototype */
+  for (i = 0; i < cl->nupvalues; i++)  /* mark its upvalues */
+    markobject(g, cl->upvals[i]);
+  return TRAVCOST + cl->nupvalues;
 }
 }
 
 
 
 
@@ -517,10 +523,15 @@ static int propagatemark (global_State *g) {
       g->gray = h->gclist;
       g->gray = h->gclist;
       return traversetable(g, h);
       return traversetable(g, h);
     }
     }
-    case LUA_TFUNCTION: {
-      Closure *cl = gco2cl(o);
-      g->gray = cl->c.gclist;
-      return traverseclosure(g, cl);
+    case LUA_TLCL: {
+      LClosure *cl = gco2lcl(o);
+      g->gray = cl->gclist;
+      return traverseLclosure(g, cl);
+    }
+    case LUA_TCCL: {
+      CClosure *cl = gco2ccl(o);
+      g->gray = cl->gclist;
+      return traverseCclosure(g, cl);
     }
     }
     case LUA_TTHREAD: {
     case LUA_TTHREAD: {
       lua_State *th = gco2th(o);
       lua_State *th = gco2th(o);
@@ -640,7 +651,14 @@ static void clearvalues (GCObject *l, GCObject *f) {
 static void freeobj (lua_State *L, GCObject *o) {
 static void freeobj (lua_State *L, GCObject *o) {
   switch (gch(o)->tt) {
   switch (gch(o)->tt) {
     case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
     case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
-    case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
+    case LUA_TLCL: {
+      luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues));
+      break;
+    }
+    case LUA_TCCL: {
+      luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
+      break;
+    }
     case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
     case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
     case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
     case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
     case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
     case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;

+ 7 - 5
lobject.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lobject.h,v 2.63 2011/10/17 14:46:13 roberto Exp roberto $
+** $Id: lobject.h,v 2.64 2011/10/31 17:48:22 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -109,12 +109,14 @@ typedef struct lua_TValue TValue;
 /* raw type tag of a TValue */
 /* raw type tag of a TValue */
 #define rttype(o)	((o)->tt_)
 #define rttype(o)	((o)->tt_)
 
 
+/* tag with no variants (bits 0-3) */
+#define novariant(x)	((x) & 0x0F)
+
 /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
 /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
 #define ttype(o)	(rttype(o) & 0x3F)
 #define ttype(o)	(rttype(o) & 0x3F)
 
 
-
 /* type tag of a TValue with no variants (bits 0-3) */
 /* type tag of a TValue with no variants (bits 0-3) */
-#define ttypenv(o)	(rttype(o) & 0x0F)
+#define ttypenv(o)	(novariant(rttype(o)))
 
 
 
 
 /* Macros to test type */
 /* Macros to test type */
@@ -161,7 +163,7 @@ typedef struct lua_TValue TValue;
 
 
 
 
 /* Macros for internal tests */
 /* Macros for internal tests */
-#define righttt(obj)		(ttypenv(obj) == gcvalue(obj)->gch.tt)
+#define righttt(obj)		(ttype(obj) == gcvalue(obj)->gch.tt)
 
 
 #define checkliveness(g,obj) \
 #define checkliveness(g,obj) \
 	lua_longassert(!iscollectable(obj) || \
 	lua_longassert(!iscollectable(obj) || \
@@ -501,7 +503,7 @@ typedef struct UpVal {
 */
 */
 
 
 #define ClosureHeader \
 #define ClosureHeader \
-	CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist
+	CommonHeader; lu_byte nupvalues; GCObject *gclist
 
 
 typedef struct CClosure {
 typedef struct CClosure {
   ClosureHeader;
   ClosureHeader;

+ 5 - 2
lstate.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.h,v 2.73 2011/08/23 17:24:34 roberto Exp roberto $
+** $Id: lstate.h,v 2.74 2011/09/30 12:45:07 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -197,7 +197,10 @@ union GCObject {
 #define gco2ts(o)	(&rawgco2ts(o)->tsv)
 #define gco2ts(o)	(&rawgco2ts(o)->tsv)
 #define rawgco2u(o)	check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
 #define rawgco2u(o)	check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
 #define gco2u(o)	(&rawgco2u(o)->uv)
 #define gco2u(o)	(&rawgco2u(o)->uv)
-#define gco2cl(o)	check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
+#define gco2lcl(o)	check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l))
+#define gco2ccl(o)	check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c))
+#define gco2cl(o)  \
+	check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl))
 #define gco2t(o)	check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
 #define gco2t(o)	check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
 #define gco2p(o)	check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
 #define gco2p(o)	check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
 #define gco2uv(o)	check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
 #define gco2uv(o)	check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))

+ 23 - 18
ltests.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltests.c,v 2.123 2011/09/24 21:11:29 roberto Exp roberto $
+** $Id: ltests.c,v 2.124 2011/11/09 19:08:07 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -267,22 +267,23 @@ static void checkproto (global_State *g, Proto *f) {
 
 
 
 
 
 
-static void checkclosure (global_State *g, Closure *cl) {
+static void checkCclosure (global_State *g, CClosure *cl) {
   GCObject *clgc = obj2gco(cl);
   GCObject *clgc = obj2gco(cl);
-  if (cl->c.isC) {
-    int i;
-    for (i=0; i<cl->c.nupvalues; i++)
-      checkvalref(g, clgc, &cl->c.upvalue[i]);
-  }
-  else {
-    int i;
-    lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
-    checkobjref(g, clgc, cl->l.p);
-    for (i=0; i<cl->l.nupvalues; i++) {
-      if (cl->l.upvals[i]) {
-        lua_assert(cl->l.upvals[i]->tt == LUA_TUPVAL);
-        checkobjref(g, clgc, cl->l.upvals[i]);
-      }
+  int i;
+  for (i = 0; i < cl->nupvalues; i++)
+    checkvalref(g, clgc, &cl->upvalue[i]);
+}
+
+
+static void checkLclosure (global_State *g, LClosure *cl) {
+  GCObject *clgc = obj2gco(cl);
+  int i;
+  lua_assert(cl->nupvalues == cl->p->sizeupvalues);
+  checkobjref(g, clgc, cl->p);
+  for (i=0; i<cl->nupvalues; i++) {
+    if (cl->upvals[i]) {
+      lua_assert(cl->upvals[i]->tt == LUA_TUPVAL);
+      checkobjref(g, clgc, cl->upvals[i]);
     }
     }
   }
   }
 }
 }
@@ -347,8 +348,12 @@ static void checkobject (global_State *g, GCObject *o) {
         checkstack(g, gco2th(o));
         checkstack(g, gco2th(o));
         break;
         break;
       }
       }
-      case LUA_TFUNCTION: {
-        checkclosure(g, gco2cl(o));
+      case LUA_TLCL: {
+        checkLclosure(g, gco2lcl(o));
+        break;
+      }
+      case LUA_TCCL: {
+        checkCclosure(g, gco2ccl(o));
         break;
         break;
       }
       }
       case LUA_TPROTO: {
       case LUA_TPROTO: {