mirror of
https://github.com/lua/lua.git
synced 2025-01-24 08:55:51 +08:00
object tag keeps variant bits too -> no need for 'isC' field in
Closures + more strick typing for closure variants
This commit is contained in:
parent
76eab106df
commit
fd22ccd6d0
13
ldebug.c
13
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
|
||||
** 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);
|
||||
|
||||
|
||||
@ -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) {
|
||||
if (cl == NULL || cl->c.isC) {
|
||||
if (noLuaClosure(cl)) {
|
||||
ar->source = "=[C]";
|
||||
ar->linedefined = -1;
|
||||
ar->lastlinedefined = -1;
|
||||
@ -191,7 +194,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
|
||||
|
||||
|
||||
static void collectvalidlines (lua_State *L, Closure *f) {
|
||||
if (f == NULL || f->c.isC) {
|
||||
if (noLuaClosure(f)) {
|
||||
setnilvalue(L->top);
|
||||
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,
|
||||
Closure *f, CallInfo *ci) {
|
||||
Closure *f, CallInfo *ci) {
|
||||
int status = 1;
|
||||
for (; *what; what++) {
|
||||
switch (*what) {
|
||||
@ -224,7 +227,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
||||
}
|
||||
case 'u': {
|
||||
ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
|
||||
if (f == NULL || f->c.isC) {
|
||||
if (noLuaClosure(f)) {
|
||||
ar->isvararg = 1;
|
||||
ar->nparams = 0;
|
||||
}
|
||||
|
15
lfunc.c
15
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
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -21,8 +21,7 @@
|
||||
|
||||
|
||||
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);
|
||||
return c;
|
||||
}
|
||||
@ -30,8 +29,7 @@ Closure *luaF_newCclosure (lua_State *L, int n) {
|
||||
|
||||
Closure *luaF_newLclosure (lua_State *L, Proto *p) {
|
||||
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.nupvalues = cast_byte(n);
|
||||
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'.
|
||||
** Returns NULL if not found.
|
||||
|
3
lfunc.h
3
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
|
||||
** 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 void luaF_close (lua_State *L, StkId level);
|
||||
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 const char *luaF_getlocalname (const Proto *func, int local_number,
|
||||
int pc);
|
||||
|
64
lgc.c
64
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
|
||||
** 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,
|
||||
int offset) {
|
||||
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)
|
||||
list = &g->allgc; /* standard list for collectable objects */
|
||||
gch(o)->marked = luaC_white(g);
|
||||
@ -266,8 +267,13 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
||||
gray2black(o); /* make it black */
|
||||
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;
|
||||
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;
|
||||
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: {
|
||||
lua_State *th = gco2th(o);
|
||||
@ -640,7 +651,14 @@ static void clearvalues (GCObject *l, GCObject *f) {
|
||||
static void freeobj (lua_State *L, GCObject *o) {
|
||||
switch (gch(o)->tt) {
|
||||
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_TTABLE: luaH_free(L, gco2t(o)); break;
|
||||
case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
|
||||
|
12
lobject.h
12
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
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -109,12 +109,14 @@ typedef struct lua_TValue TValue;
|
||||
/* raw type tag of a TValue */
|
||||
#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) */
|
||||
#define ttype(o) (rttype(o) & 0x3F)
|
||||
|
||||
|
||||
/* 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 */
|
||||
@ -161,7 +163,7 @@ typedef struct lua_TValue TValue;
|
||||
|
||||
|
||||
/* 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) \
|
||||
lua_longassert(!iscollectable(obj) || \
|
||||
@ -501,7 +503,7 @@ typedef struct UpVal {
|
||||
*/
|
||||
|
||||
#define ClosureHeader \
|
||||
CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist
|
||||
CommonHeader; lu_byte nupvalues; GCObject *gclist
|
||||
|
||||
typedef struct CClosure {
|
||||
ClosureHeader;
|
||||
|
7
lstate.h
7
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
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -197,7 +197,10 @@ union GCObject {
|
||||
#define gco2ts(o) (&rawgco2ts(o)->tsv)
|
||||
#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
|
||||
#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 gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
|
||||
#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
|
||||
|
41
ltests.c
41
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
|
||||
** 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);
|
||||
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));
|
||||
break;
|
||||
}
|
||||
case LUA_TFUNCTION: {
|
||||
checkclosure(g, gco2cl(o));
|
||||
case LUA_TLCL: {
|
||||
checkLclosure(g, gco2lcl(o));
|
||||
break;
|
||||
}
|
||||
case LUA_TCCL: {
|
||||
checkCclosure(g, gco2ccl(o));
|
||||
break;
|
||||
}
|
||||
case LUA_TPROTO: {
|
||||
|
Loading…
Reference in New Issue
Block a user