瀏覽代碼

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

Roberto Ierusalimschy 14 年之前
父節點
當前提交
3b44821334
共有 10 個文件被更改,包括 176 次插入153 次删除
  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);