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

This commit is contained in:
Roberto Ierusalimschy 2011-06-02 16:31:40 -03:00
parent 0214dab989
commit 3b44821334
10 changed files with 176 additions and 153 deletions

117
lapi.c
View File

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

View File

@ -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 ** Debug Interface
** See Copyright Notice in lua.h ** 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) { static int currentpc (CallInfo *ci) {
lua_assert(isLua(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) { 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) { 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) if (n >= ci->u.l.base - ci->func - nparams)
return NULL; /* no such vararg */ return NULL; /* no such vararg */
else { else {
@ -114,7 +114,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
return findvararg(ci, -n, pos); return findvararg(ci, -n, pos);
else { else {
base = ci->u.l.base; 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 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? */ if (!isLfunction(L->top - 1)) /* not a Lua function? */
name = NULL; name = NULL;
else /* consider live variables at function start (parameters) */ 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' */ else { /* active function; get information through 'ar' */
StkId pos = 0; /* to avoid warnings */ 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, static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
const char *what, const char **name) { const char *what, const char **name) {
if (ISK(c)) { /* is 'c' a constant? */ 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? */ if (ttisstring(kvalue)) { /* literal constant? */
*name = svalue(kvalue); /* it is its own name */ *name = svalue(kvalue); /* it is its own name */
return; 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, static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
const char **name) { const char **name) {
Proto *p = ci_func(ci)->l.p; Proto *p = ci_func(ci)->p;
const char *what = NULL; const char *what = NULL;
int lastpc = currentpc(ci); int lastpc = currentpc(ci);
int pc; 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)) if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous))
return NULL; /* calling function is not Lua (or is unknown) */ return NULL; /* calling function is not Lua (or is unknown) */
ci = ci->previous; /* calling function */ 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? */ 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)) { switch (GET_OPCODE(i)) {
case OP_CALL: case OP_CALL:
case OP_TAILCALL: case OP_TAILCALL:
@ -474,7 +474,7 @@ static int isinstack (CallInfo *ci, const TValue *o) {
static const char *getupvalname (CallInfo *ci, const TValue *o, static const char *getupvalname (CallInfo *ci, const TValue *o,
const char **name) { const char **name) {
LClosure *c = &ci_func(ci)->l; LClosure *c = ci_func(ci);
int i; int i;
for (i = 0; i < c->nupvalues; i++) { for (i = 0; i < c->nupvalues; i++) {
if (c->upvals[i]->v == o) { 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? */ if (isLua(ci)) { /* is Lua code? */
char buff[LUA_IDSIZE]; /* add file:line information */ char buff[LUA_IDSIZE]; /* add file:line information */
int line = currentline(ci); int line = currentline(ci);
TString *src = ci_func(ci)->l.p->source; TString *src = ci_func(ci)->p->source;
if (src) if (src)
luaO_chunkid(buff, getstr(src), LUA_IDSIZE); luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
else { /* no source available; use "?" instead */ else { /* no source available; use "?" instead */

View File

@ -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 ** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -17,6 +17,9 @@
#define resethookcount(L) (L->hookcount = L->basehookcount) #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, LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
const char *opname); const char *opname);

108
ldo.c
View File

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

View File

@ -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 ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -32,17 +32,25 @@
/* /*
** tags for Tagged Values have the following use of bits: ** tags for Tagged Values have the following use of bits:
** bits 0-3: actual tag (a LUA_T* value) ** bits 0-3: actual tag (a LUA_T* value)
** bit 4: variant bit (for functions, means a light C function) ** bits 4-5: variant bits
** bit 5: whether value is collectable ** bit 6: whether value is collectable
*/ */
/* Variant tag for light C functions */ /*
#define BIT_ISVARIANT (1 << 4) ** LUA_TFUNCTION variants:
#define LUA_TLCF (LUA_TFUNCTION | BIT_ISVARIANT) ** 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 */ /* Bit mark for collectable types */
#define BIT_ISCOLLECTABLE (1 << 5) #define BIT_ISCOLLECTABLE (1 << 6)
/* mark a tag as collectable */ /* mark a tag as collectable */
#define ctb(t) ((t) | BIT_ISCOLLECTABLE) #define ctb(t) ((t) | BIT_ISCOLLECTABLE)
@ -106,8 +114,8 @@ typedef struct lua_TValue {
/* raw type tag of a TValue */ /* raw type tag of a TValue */
#define rttype(o) ((o)->tt_) #define rttype(o) ((o)->tt_)
/* type tag of a TValue (bits 0-3 for tags + variant bit) */ /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
#define ttype(o) (rttype(o) & 0x1F) #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) */
@ -123,7 +131,9 @@ typedef struct lua_TValue {
#define ttisstring(o) checktag((o), ctb(LUA_TSTRING)) #define ttisstring(o) checktag((o), ctb(LUA_TSTRING))
#define ttistable(o) checktag((o), ctb(LUA_TTABLE)) #define ttistable(o) checktag((o), ctb(LUA_TTABLE))
#define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION) #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 ttislcf(o) checktag((o), LUA_TLCF)
#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) #define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA))
#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) #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 rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u)
#define uvalue(o) (&rawuvalue(o)->uv) #define uvalue(o) (&rawuvalue(o)->uv)
#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) #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 fvalue(o) check_exp(ttislcf(o), val_(o).f)
#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) #define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h)
#define bvalue(o) check_exp(ttisboolean(o), val_(o).b) #define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
@ -152,7 +164,7 @@ typedef struct lua_TValue {
/* Macros for internal tests */ /* 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) \ #define checkliveness(g,obj) \
lua_longassert(!iscollectable(obj) || \ lua_longassert(!iscollectable(obj) || \
@ -197,9 +209,14 @@ typedef struct lua_TValue {
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \ val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \
checkliveness(G(L),io); } checkliveness(G(L),io); }
#define setclvalue(L,obj,x) \ #define setclLvalue(L,obj,x) \
{ TValue *io=(obj); \ { TValue *io=(obj); \
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TFUNCTION)); \ 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_TCCL)); \
checkliveness(G(L),io); } checkliveness(G(L),io); }
#define sethvalue(L,obj,x) \ #define sethvalue(L,obj,x) \
@ -375,9 +392,9 @@ typedef union Closure {
} 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)
/* /*

View File

@ -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 ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -104,7 +104,6 @@ typedef struct CallInfo {
#define CIST_TAIL (1<<6) /* call was tail called */ #define CIST_TAIL (1<<6) /* call was tail called */
#define ci_func(ci) (clvalue((ci)->func))
#define isLua(ci) ((ci)->callstatus & CIST_LUA) #define isLua(ci) ((ci)->callstatus & CIST_LUA)

View File

@ -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) ** Lua tables (hash)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -468,7 +468,7 @@ const TValue *luaH_getstr (Table *t, TString *key) {
** main search function ** main search function
*/ */
const TValue *luaH_get (Table *t, const TValue *key) { const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) { switch (ttypenv(key)) {
case LUA_TNIL: return luaO_nilobject; case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
case LUA_TNUMBER: { case LUA_TNUMBER: {

View File

@ -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 ** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -291,7 +291,7 @@ static void checkclosure (global_State *g, Closure *cl) {
static int lua_checkpc (pCallInfo ci) { static int lua_checkpc (pCallInfo ci) {
if (!isLua(ci)) return 1; if (!isLua(ci)) return 1;
else { else {
Proto *p = ci_func(ci)->l.p; Proto *p = ci_func(ci)->p;
return p->code <= ci->u.l.savedpc && return p->code <= ci->u.l.savedpc &&
ci->u.l.savedpc <= p->code + p->sizecode; ci->u.l.savedpc <= p->code + p->sizecode;
} }

4
ltm.c
View File

@ -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 ** Tag methods
** See Copyright Notice in lua.h ** 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) { const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt; Table *mt;
switch (ttype(o)) { switch (ttypenv(o)) {
case LUA_TTABLE: case LUA_TTABLE:
mt = hvalue(o)->metatable; mt = hvalue(o)->metatable;
break; break;

13
lvm.c
View File

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