Browse Source

stricter control (using tag variants) over closure kinds (Lua x C)

Roberto Ierusalimschy 14 năm trước cách đây
mục cha
commit
3b44821334
10 tập tin đã thay đổi với 176 bổ sung153 xóa
  1. 61 56
      lapi.c
  2. 12 12
      ldebug.c
  3. 4 1
      ldebug.h
  4. 54 54
      ldo.c
  5. 32 15
      lobject.h
  6. 1 2
      lstate.h
  7. 2 2
      ltable.c
  8. 2 2
      ltests.c
  9. 2 2
      ltm.c
  10. 6 7
      lvm.c

+ 61 - 56
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.146 2011/05/31 18:24:36 roberto Exp roberto $
+** $Id: lapi.c,v 2.147 2011/05/31 18:27:56 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -59,9 +59,9 @@ static TValue *index2addr (lua_State *L, int idx) {
     if (ttislcf(ci->func))  /* light C function? */
       return cast(TValue *, luaO_nilobject);  /* it has no upvalues */
     else {
-      Closure *func = clvalue(ci->func);
-      return (idx <= func->c.nupvalues)
-             ? &func->c.upvalue[idx-1]
+      CClosure *func = clCvalue(ci->func);
+      return (idx <= func->nupvalues)
+             ? &func->upvalue[idx-1]
              : cast(TValue *, luaO_nilobject);
     }
   }
@@ -195,10 +195,8 @@ static void moveto (lua_State *L, TValue *fr, int idx) {
   TValue *to = index2addr(L, idx);
   api_checkvalidindex(L, to);
   setobj(L, to, fr);
-  if (idx < LUA_REGISTRYINDEX) {  /* function upvalue? */
-    lua_assert(ttisclosure(L->ci->func));
-    luaC_barrier(L, clvalue(L->ci->func), fr);
-  }
+  if (idx < LUA_REGISTRYINDEX)  /* function upvalue? */
+    luaC_barrier(L, clCvalue(L->ci->func), fr);
   /* LUA_REGISTRYINDEX does not need gc barrier
      (collector revisits it before finishing collection) */
 }
@@ -251,7 +249,7 @@ LUA_API const char *lua_typename (lua_State *L, int t) {
 
 LUA_API int lua_iscfunction (lua_State *L, int idx) {
   StkId o = index2addr(L, idx);
-  return (ttislcf(o) || (ttisclosure(o) && clvalue(o)->c.isC));
+  return (ttislcf(o) || (ttisCclosure(o)));
 }
 
 
@@ -398,7 +396,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
 
 LUA_API size_t lua_rawlen (lua_State *L, int idx) {
   StkId o = index2addr(L, idx);
-  switch (ttype(o)) {
+  switch (ttypenv(o)) {
     case LUA_TSTRING: return tsvalue(o)->len;
     case LUA_TUSERDATA: return uvalue(o)->len;
     case LUA_TTABLE: return luaH_getn(hvalue(o));
@@ -410,15 +408,15 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) {
 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
   StkId o = index2addr(L, idx);
   if (ttislcf(o)) return fvalue(o);
-  else if (ttisclosure(o) && clvalue(o)->c.isC)
-    return clvalue(o)->c.f;
+  else if (ttisCclosure(o))
+    return clCvalue(o)->f;
   else return NULL;  /* not a C function */
 }
 
 
 LUA_API void *lua_touserdata (lua_State *L, int idx) {
   StkId o = index2addr(L, idx);
-  switch (ttype(o)) {
+  switch (ttypenv(o)) {
     case LUA_TUSERDATA: return (rawuvalue(o) + 1);
     case LUA_TLIGHTUSERDATA: return pvalue(o);
     default: return NULL;
@@ -436,7 +434,8 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
   StkId o = index2addr(L, idx);
   switch (ttype(o)) {
     case LUA_TTABLE: return hvalue(o);
-    case LUA_TFUNCTION: return clvalue(o);
+    case LUA_TLCL: return clLvalue(o);
+    case LUA_TCCL: return clCvalue(o);
     case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
     case LUA_TTHREAD: return thvalue(o);
     case LUA_TUSERDATA:
@@ -556,7 +555,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
     L->top -= n;
     while (n--)
       setobj2n(L, &cl->c.upvalue[n], L->top + n);
-    setclvalue(L, L->top, cl);
+    setclCvalue(L, L->top, cl);
   }
   api_incr_top(L);
   lua_unlock(L);
@@ -656,7 +655,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
   int res;
   lua_lock(L);
   obj = index2addr(L, objindex);
-  switch (ttype(obj)) {
+  switch (ttypenv(obj)) {
     case LUA_TTABLE:
       mt = hvalue(obj)->metatable;
       break;
@@ -763,7 +762,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
     api_check(L, ttistable(L->top - 1), "table expected");
     mt = hvalue(L->top - 1);
   }
-  switch (ttype(obj)) {
+  switch (ttypenv(obj)) {
     case LUA_TTABLE: {
       hvalue(obj)->metatable = mt;
       if (mt)
@@ -921,15 +920,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
   luaZ_init(L, &z, reader, data);
   status = luaD_protectedparser(L, &z, chunkname);
   if (status == LUA_OK) {  /* no errors? */
-    Closure *f = clvalue(L->top - 1);  /* get newly created function */
-    lua_assert(!f->c.isC);
-    if (f->l.nupvalues == 1) {  /* does it have one upvalue? */
+    LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
+    if (f->nupvalues == 1) {  /* does it have one upvalue? */
       /* get global table from registry */
       Table *reg = hvalue(&G(L)->l_registry);
       const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
       /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
-      setobj(L, f->l.upvals[0]->v, gt);
-      luaC_barrier(L, f->l.upvals[0], gt);
+      setobj(L, f->upvals[0]->v, gt);
+      luaC_barrier(L, f->upvals[0], gt);
     }
   }
   lua_unlock(L);
@@ -1131,25 +1129,27 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
 
 static const char *aux_upvalue (StkId fi, int n, TValue **val,
                                 GCObject **owner) {
-  Closure *f;
-  if (!ttisclosure(fi)) return NULL;
-  f = clvalue(fi);
-  if (f->c.isC) {
-    if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
-    *val = &f->c.upvalue[n-1];
-    if (owner) *owner = obj2gco(f);
-    return "";
-  }
-  else {
-    const char *name;
-    Proto *p = f->l.p;
-    if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
-    *val = f->l.upvals[n-1]->v;
-    if (owner) *owner = obj2gco(f->l.upvals[n - 1]);
-    name = getstr(p->upvalues[n-1].name);
-    if (name == NULL)  /* no debug information? */
-      name = "";
-    return name;
+  switch (ttype(fi)) {
+    case LUA_TCCL: {  /* C closure */
+      CClosure *f = clCvalue(fi);
+      if (!(1 <= n && n <= f->nupvalues)) return NULL;
+      *val = &f->upvalue[n-1];
+      if (owner) *owner = obj2gco(f);
+      return "";
+    }
+    case LUA_TLCL: {  /* Lua closure */
+      LClosure *f = clLvalue(fi);
+      const char *name;
+      Proto *p = f->p;
+      if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
+      *val = f->upvals[n-1]->v;
+      if (owner) *owner = obj2gco(f->upvals[n - 1]);
+      name = getstr(p->upvalues[n-1].name);
+      if (name == NULL)  /* no debug information? */
+        name = "";
+      return name;
+    }
+    default: return NULL;  /* not a closure */
   }
 }
 
@@ -1187,34 +1187,39 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
 }
 
 
-static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) {
-  Closure *f;
+static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
+  LClosure *f;
   StkId fi = index2addr(L, fidx);
-  api_check(L, ttisclosure(fi), "Lua function expected");
-  f = clvalue(fi);
-  api_check(L, !f->c.isC, "Lua function expected");
-  api_check(L, (1 <= n && n <= f->l.p->sizeupvalues), "invalid upvalue index");
+  api_check(L, ttisLclosure(fi), "Lua function expected");
+  f = clLvalue(fi);
+  api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
   if (pf) *pf = f;
-  return &f->l.upvals[n - 1];  /* get its upvalue pointer */
+  return &f->upvals[n - 1];  /* get its upvalue pointer */
 }
 
 
 LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
-  Closure *f;
   StkId fi = index2addr(L, fidx);
-  api_check(L, ttisclosure(fi), "function expected");
-  f = clvalue(fi);
-  if (f->c.isC) {
-    api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index");
-    return &f->c.upvalue[n - 1];
+  switch (ttype(fi)) {
+    case LUA_TLCL: {  /* lua closure */
+      return *getupvalref(L, fidx, n, NULL);
+    }
+    case LUA_TCCL: {  /* C closure */
+      CClosure *f = clCvalue(fi);
+      api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
+      return &f->upvalue[n - 1];
+    }
+    default: {
+      api_check(L, 0, "closure expected");
+      return NULL;
+    }
   }
-  else return *getupvalref(L, fidx, n, NULL);
 }
 
 
 LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
                                             int fidx2, int n2) {
-  Closure *f1;
+  LClosure *f1;
   UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
   UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
   *up1 = *up2;

+ 12 - 12
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.80 2011/04/19 16:22:13 roberto Exp roberto $
+** $Id: ldebug.c,v 2.81 2011/04/28 14:00:11 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -35,12 +35,12 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
 
 static int currentpc (CallInfo *ci) {
   lua_assert(isLua(ci));
-  return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
+  return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
 }
 
 
 static int currentline (CallInfo *ci) {
-  return getfuncline(ci_func(ci)->l.p, currentpc(ci));
+  return getfuncline(ci_func(ci)->p, currentpc(ci));
 }
 
 
@@ -95,7 +95,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
 
 
 static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
-  int nparams = clvalue(ci->func)->l.p->numparams;
+  int nparams = clLvalue(ci->func)->p->numparams;
   if (n >= ci->u.l.base - ci->func - nparams)
     return NULL;  /* no such vararg */
   else {
@@ -114,7 +114,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
       return findvararg(ci, -n, pos);
     else {
       base = ci->u.l.base;
-      name = luaF_getlocalname(ci_func(ci)->l.p, n, currentpc(ci));
+      name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
     }
   }
   else
@@ -138,7 +138,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
     if (!isLfunction(L->top - 1))  /* not a Lua function? */
       name = NULL;
     else  /* consider live variables at function start (parameters) */
-      name = luaF_getlocalname(clvalue(L->top - 1)->l.p, n, 0);
+      name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
   }
   else {  /* active function; get information through 'ar' */
     StkId pos = 0;  /* to avoid warnings */
@@ -294,7 +294,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
 static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
                    const char *what, const char **name) {
   if (ISK(c)) {  /* is 'c' a constant? */
-    TValue *kvalue = &ci_func(ci)->l.p->k[INDEXK(c)];
+    TValue *kvalue = &ci_func(ci)->p->k[INDEXK(c)];
     if (ttisstring(kvalue)) {  /* literal constant? */
       *name = svalue(kvalue);  /* it is its own name */
       return;
@@ -315,7 +315,7 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
 
 static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
                                const char **name) {
-  Proto *p = ci_func(ci)->l.p;
+  Proto *p = ci_func(ci)->p;
   const char *what = NULL;
   int lastpc = currentpc(ci);
   int pc;
@@ -421,9 +421,9 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
   if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous))
     return NULL;  /* calling function is not Lua (or is unknown) */
   ci = ci->previous;  /* calling function */
-  i = ci_func(ci)->l.p->code[currentpc(ci)];
+  i = ci_func(ci)->p->code[currentpc(ci)];
   if (GET_OPCODE(i) == OP_EXTRAARG)  /* extra argument? */
-    i = ci_func(ci)->l.p->code[currentpc(ci) - 1];  /* get 'real' instruction */
+    i = ci_func(ci)->p->code[currentpc(ci) - 1];  /* get 'real' instruction */
   switch (GET_OPCODE(i)) {
     case OP_CALL:
     case OP_TAILCALL:
@@ -474,7 +474,7 @@ static int isinstack (CallInfo *ci, const TValue *o) {
 
 static const char *getupvalname (CallInfo *ci, const TValue *o,
                                const char **name) {
-  LClosure *c = &ci_func(ci)->l;
+  LClosure *c = ci_func(ci);
   int i;
   for (i = 0; i < c->nupvalues; i++) {
     if (c->upvals[i]->v == o) {
@@ -535,7 +535,7 @@ static void addinfo (lua_State *L, const char *msg) {
   if (isLua(ci)) {  /* is Lua code? */
     char buff[LUA_IDSIZE];  /* add file:line information */
     int line = currentline(ci);
-    TString *src = ci_func(ci)->l.p->source;
+    TString *src = ci_func(ci)->p->source;
     if (src)
       luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
     else {  /* no source available; use "?" instead */

+ 4 - 1
ldebug.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.h,v 2.4 2009/04/30 17:42:21 roberto Exp roberto $
+** $Id: ldebug.h,v 2.5 2009/06/10 16:57:53 roberto Exp roberto $
 ** Auxiliary functions from Debug Interface module
 ** See Copyright Notice in lua.h
 */
@@ -17,6 +17,9 @@
 
 #define resethookcount(L)	(L->hookcount = L->basehookcount)
 
+/* Active Lua function (given call info) */
+#define ci_func(ci)		(clLvalue((ci)->func))
+
 
 LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
                                              const char *opname);

+ 54 - 54
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.93 2011/02/23 13:13:10 roberto Exp roberto $
+** $Id: ldo.c,v 2.94 2011/05/30 16:36:38 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -293,59 +293,59 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
 ** returns true if function has been executed (C function)
 */
 int luaD_precall (lua_State *L, StkId func, int nresults) {
-  Closure *cl;
   lua_CFunction f;
-  ptrdiff_t funcr;
-  if (!ttisfunction(func)) /* `func' is not a function? */
-    func = tryfuncTM(L, func);  /* check the `function' tag method */
-  funcr = savestack(L, func);
-  if (ttislcf(func) || (cl = clvalue(func), cl->c.isC)) {  /* C function? */
-    CallInfo *ci;
-    int n;
-    f = (ttislcf(func) ? fvalue(func) : cl->c.f);
-    luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
-    ci = next_ci(L);  /* now 'enter' new function */
-    ci->nresults = nresults;
-    ci->func = restorestack(L, funcr);
-    ci->top = L->top + LUA_MINSTACK;
-    lua_assert(ci->top <= L->stack_last);
-    ci->callstatus = 0;
-    if (L->hookmask & LUA_MASKCALL)
-      luaD_hook(L, LUA_HOOKCALL, -1);
-    lua_unlock(L);
-    n = (*f)(L);  /* do the actual call */
-    lua_lock(L);
-    api_checknelems(L, n);
-    luaD_poscall(L, L->top - n);
-    return 1;
-  }
-  else {  /* Lua function: prepare its call */
-    CallInfo *ci;
-    int nparams, nargs;
-    StkId base;
-    Proto *p = cl->l.p;
-    luaD_checkstack(L, p->maxstacksize);
-    func = restorestack(L, funcr);
-    nargs = cast_int(L->top - func) - 1;  /* number of real arguments */
-    nparams = p->numparams;  /* number of expected parameters */
-    for (; nargs < nparams; nargs++)
-      setnilvalue(L->top++);  /* complete missing arguments */
-    if (!p->is_vararg)  /* no varargs? */
-      base = func + 1;
-    else  /* vararg function */
-      base = adjust_varargs(L, p, nargs);
-    ci = next_ci(L);  /* now 'enter' new function */
-    ci->nresults = nresults;
-    ci->func = func;
-    ci->u.l.base = base;
-    ci->top = base + p->maxstacksize;
-    lua_assert(ci->top <= L->stack_last);
-    ci->u.l.savedpc = p->code;  /* starting point */
-    ci->callstatus = CIST_LUA;
-    L->top = ci->top;
-    if (L->hookmask & LUA_MASKCALL)
-      callhook(L, ci);
-    return 0;
+  CallInfo *ci;
+  int n;  /* number of arguments (Lua) or returns (C) */
+  ptrdiff_t funcr = savestack(L, func);
+  switch (ttype(func)) {
+    case LUA_TLCF:  /* light C function */
+      f = fvalue(func);
+      goto Cfunc;
+    case LUA_TCCL: {  /* C closure */
+      f = clCvalue(func)->f;
+     Cfunc:
+      luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
+      ci = next_ci(L);  /* now 'enter' new function */
+      ci->nresults = nresults;
+      ci->func = restorestack(L, funcr);
+      ci->top = L->top + LUA_MINSTACK;
+      lua_assert(ci->top <= L->stack_last);
+      ci->callstatus = 0;
+      if (L->hookmask & LUA_MASKCALL)
+        luaD_hook(L, LUA_HOOKCALL, -1);
+      lua_unlock(L);
+      n = (*f)(L);  /* do the actual call */
+      lua_lock(L);
+      api_checknelems(L, n);
+      luaD_poscall(L, L->top - n);
+      return 1;
+    }
+    case LUA_TLCL: {  /* Lua function: prepare its call */
+      StkId base;
+      Proto *p = clLvalue(func)->p;
+      luaD_checkstack(L, p->maxstacksize);
+      func = restorestack(L, funcr);
+      n = cast_int(L->top - func) - 1;  /* number of real arguments */
+      for (; n < p->numparams; n++)
+        setnilvalue(L->top++);  /* complete missing arguments */
+      base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n);
+      ci = next_ci(L);  /* now 'enter' new function */
+      ci->nresults = nresults;
+      ci->func = func;
+      ci->u.l.base = base;
+      ci->top = base + p->maxstacksize;
+      lua_assert(ci->top <= L->stack_last);
+      ci->u.l.savedpc = p->code;  /* starting point */
+      ci->callstatus = CIST_LUA;
+      L->top = ci->top;
+      if (L->hookmask & LUA_MASKCALL)
+        callhook(L, ci);
+      return 0;
+    }
+    default: {  /* not a function */
+      func = tryfuncTM(L, func);  /* retry with 'function' tag method */
+      return luaD_precall(L, func, nresults);
+    }
   }
 }
 
@@ -626,7 +626,7 @@ static void f_parser (lua_State *L, void *ud) {
   setptvalue2s(L, L->top, tf);
   incr_top(L);
   cl = luaF_newLclosure(L, tf);
-  setclvalue(L, L->top - 1, cl);
+  setclLvalue(L, L->top - 1, cl);
   for (i = 0; i < tf->sizeupvalues; i++)  /* initialize upvalues */
     cl->l.upvals[i] = luaF_newupval(L);
 }

+ 32 - 15
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 2.55 2011/05/31 18:24:36 roberto Exp roberto $
+** $Id: lobject.h,v 2.56 2011/05/31 19:15:01 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -32,17 +32,25 @@
 /*
 ** tags for Tagged Values have the following use of bits:
 ** bits 0-3: actual tag (a LUA_T* value)
-** bit 4: variant bit (for functions, means a light C function)
-** bit 5: whether value is collectable
+** bits 4-5: variant bits
+** bit 6: whether value is collectable
 */
 
-/* Variant tag for light C functions */
-#define BIT_ISVARIANT	(1 << 4)
-#define LUA_TLCF	(LUA_TFUNCTION | BIT_ISVARIANT)
+/*
+** LUA_TFUNCTION variants:
+** 0 - Lua function
+** 1 - light C function
+** 2 - regular C function (closure)
+*/
+
+/* Variant tags for functions */
+#define LUA_TLCL	(LUA_TFUNCTION | (0 << 4))  /* Lua closure */
+#define LUA_TLCF	(LUA_TFUNCTION | (1 << 4))  /* light C function */
+#define LUA_TCCL	(LUA_TFUNCTION | (2 << 4))  /* C closure */
 
 
 /* Bit mark for collectable types */
-#define BIT_ISCOLLECTABLE	(1 << 5)
+#define BIT_ISCOLLECTABLE	(1 << 6)
 
 /* mark a tag as collectable */
 #define ctb(t)			((t) | BIT_ISCOLLECTABLE)
@@ -106,8 +114,8 @@ typedef struct lua_TValue {
 /* raw type tag of a TValue */
 #define rttype(o)	((o)->tt_)
 
-/* type tag of a TValue (bits 0-3 for tags + variant bit) */
-#define ttype(o)	(rttype(o) & 0x1F)
+/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
+#define ttype(o)	(rttype(o) & 0x3F)
 
 
 /* type tag of a TValue with no variants (bits 0-3) */
@@ -123,7 +131,9 @@ typedef struct lua_TValue {
 #define ttisstring(o)		checktag((o), ctb(LUA_TSTRING))
 #define ttistable(o)		checktag((o), ctb(LUA_TTABLE))
 #define ttisfunction(o)		(ttypenv(o) == LUA_TFUNCTION)
-#define ttisclosure(o)		checktag((o), ctb(LUA_TFUNCTION))
+#define ttisclosure(o)		((rttype(o) & 0x1F) == LUA_TFUNCTION)
+#define ttisCclosure(o)		checktag((o), ctb(LUA_TCCL))
+#define ttisLclosure(o)		checktag((o), ctb(LUA_TLCL))
 #define ttislcf(o)		checktag((o), LUA_TLCF)
 #define ttisuserdata(o)		checktag((o), ctb(LUA_TUSERDATA))
 #define ttisthread(o)		checktag((o), ctb(LUA_TTHREAD))
@@ -140,6 +150,8 @@ typedef struct lua_TValue {
 #define rawuvalue(o)	check_exp(ttisuserdata(o), &val_(o).gc->u)
 #define uvalue(o)	(&rawuvalue(o)->uv)
 #define clvalue(o)	check_exp(ttisclosure(o), &val_(o).gc->cl)
+#define clLvalue(o)	check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
+#define clCvalue(o)	check_exp(ttisCclosure(o), &val_(o).gc->cl.c)
 #define fvalue(o)	check_exp(ttislcf(o), val_(o).f)
 #define hvalue(o)	check_exp(ttistable(o), &val_(o).gc->h)
 #define bvalue(o)	check_exp(ttisboolean(o), val_(o).b)
@@ -152,7 +164,7 @@ typedef struct lua_TValue {
 
 
 /* Macros for internal tests */
-#define righttt(obj)		(ttype(obj) == gcvalue(obj)->gch.tt)
+#define righttt(obj)		(ttypenv(obj) == gcvalue(obj)->gch.tt)
 
 #define checkliveness(g,obj) \
   lua_longassert(!iscollectable(obj) || \
@@ -197,9 +209,14 @@ typedef struct lua_TValue {
     val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \
     checkliveness(G(L),io); }
 
-#define setclvalue(L,obj,x) \
+#define setclLvalue(L,obj,x) \
+  { TValue *io=(obj); \
+    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \
+    checkliveness(G(L),io); }
+
+#define setclCvalue(L,obj,x) \
   { TValue *io=(obj); \
-    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TFUNCTION)); \
+    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \
     checkliveness(G(L),io); }
 
 #define sethvalue(L,obj,x) \
@@ -375,9 +392,9 @@ typedef union Closure {
 } Closure;
 
 
-#define isLfunction(o)	(ttisclosure(o) && !clvalue(o)->c.isC)
+#define isLfunction(o)	ttisLclosure(o)
 
-#define getproto(o)	(clvalue(o)->l.p)
+#define getproto(o)	(clLvalue(o)->p)
 
 
 /*

+ 1 - 2
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.70 2010/12/20 18:17:46 roberto Exp roberto $
+** $Id: lstate.h,v 2.71 2010/12/20 19:40:07 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -104,7 +104,6 @@ typedef struct CallInfo {
 #define CIST_TAIL	(1<<6)	/* call was tail called */
 
 
-#define ci_func(ci)	(clvalue((ci)->func))
 #define isLua(ci)	((ci)->callstatus & CIST_LUA)
 
 

+ 2 - 2
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 2.56 2011/05/31 18:24:36 roberto Exp roberto $
+** $Id: ltable.c,v 2.57 2011/05/31 18:27:56 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -468,7 +468,7 @@ const TValue *luaH_getstr (Table *t, TString *key) {
 ** main search function
 */
 const TValue *luaH_get (Table *t, const TValue *key) {
-  switch (ttype(key)) {
+  switch (ttypenv(key)) {
     case LUA_TNIL: return luaO_nilobject;
     case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
     case LUA_TNUMBER: {

+ 2 - 2
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.117 2011/05/05 16:18:53 roberto Exp roberto $
+** $Id: ltests.c,v 2.118 2011/05/25 14:12:28 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -291,7 +291,7 @@ static void checkclosure (global_State *g, Closure *cl) {
 static int lua_checkpc (pCallInfo ci) {
   if (!isLua(ci)) return 1;
   else {
-    Proto *p = ci_func(ci)->l.p;
+    Proto *p = ci_func(ci)->p;
     return p->code <= ci->u.l.savedpc &&
            ci->u.l.savedpc <= p->code + p->sizecode;
   }

+ 2 - 2
ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.c,v 2.12 2010/04/13 20:48:12 roberto Exp roberto $
+** $Id: ltm.c,v 2.13 2011/02/28 17:32:10 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -62,7 +62,7 @@ const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
 
 const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
   Table *mt;
-  switch (ttype(o)) {
+  switch (ttypenv(o)) {
     case LUA_TTABLE:
       mt = hvalue(o)->metatable;
       break;

+ 6 - 7
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.138 2011/05/31 18:24:36 roberto Exp roberto $
+** $Id: lvm.c,v 2.139 2011/05/31 18:27:56 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -65,7 +65,7 @@ static void traceexec (lua_State *L) {
     luaD_hook(L, LUA_HOOKCOUNT, -1);
   }
   if (mask & LUA_MASKLINE) {
-    Proto *p = ci_func(ci)->l.p;
+    Proto *p = ci_func(ci)->p;
     int npc = pcRel(ci->u.l.savedpc, p);
     int newline = getfuncline(p, npc);
     if (npc == 0 ||  /* call linehook when enter a new function, */
@@ -315,7 +315,7 @@ void luaV_concat (lua_State *L, int total) {
 
 void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
   const TValue *tm;
-  switch (ttype(rb)) {
+  switch (ttypenv(rb)) {
     case LUA_TTABLE: {
       Table *h = hvalue(rb);
       tm = fasttm(L, h->metatable, TM_LEN);
@@ -385,7 +385,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
   Upvaldesc *uv = p->upvalues;
   int i;
   Closure *ncl = luaF_newLclosure(L, p);
-  setclvalue(L, ra, ncl);  /* anchor new closure in stack */
+  setclLvalue(L, ra, ncl);  /* anchor new closure in stack */
   for (i = 0; i < nup; i++) {  /* fill in its upvalues */
     if (uv[i].instack)  /* upvalue refers to local variable? */
       ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);
@@ -512,9 +512,8 @@ void luaV_execute (lua_State *L) {
   TValue *k;
   StkId base;
  newframe:  /* reentry point when frame changes (call/return) */
-  lua_assert(isLua(ci));
   lua_assert(ci == L->ci);
-  cl = &clvalue(ci->func)->l;
+  cl = clLvalue(ci->func);
   k = cl->p->k;
   base = ci->u.l.base;
   /* main loop of interpreter */
@@ -819,7 +818,7 @@ void luaV_execute (lua_State *L) {
         if (ncl == NULL)  /* no match? */
           pushclosure(L, p, cl->upvals, base, ra);  /* create a new one */
         else
-          setclvalue(L, ra, ncl);  /* push cashed closure */
+          setclLvalue(L, ra, ncl);  /* push cashed closure */
         checkGC(L,
           L->top = ra + 1;  /* limit of live values */
           luaC_step(L);