new definitions for closure structures
This commit is contained in:
8
lapi.c
8
lapi.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 1.149 2001/07/22 00:59:36 roberto Exp roberto $
|
** $Id: lapi.c,v 1.152 2001/09/07 17:39:10 roberto Exp $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -248,7 +248,7 @@ LUA_API size_t lua_strlen (lua_State *L, int index) {
|
|||||||
|
|
||||||
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
|
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
|
||||||
StkId o = luaA_indexAcceptable(L, index);
|
StkId o = luaA_indexAcceptable(L, index);
|
||||||
return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->u.c.f;
|
return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -314,10 +314,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
cl = luaF_newCclosure(L, n);
|
cl = luaF_newCclosure(L, n);
|
||||||
cl->u.c.f = fn;
|
cl->c.f = fn;
|
||||||
L->top -= n;
|
L->top -= n;
|
||||||
while (n--)
|
while (n--)
|
||||||
setobj(&cl->u.c.upvalue[n], L->top+n);
|
setobj(&cl->c.upvalue[n], L->top+n);
|
||||||
setclvalue(L->top, cl);
|
setclvalue(L->top, cl);
|
||||||
incr_top;
|
incr_top;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
|
|||||||
18
ldebug.c
18
ldebug.c
@@ -33,7 +33,7 @@ static const l_char *getfuncname (lua_State *L, CallInfo *ci,
|
|||||||
|
|
||||||
static int isLmark (CallInfo *ci) {
|
static int isLmark (CallInfo *ci) {
|
||||||
lua_assert(ci == NULL || ttype(ci->base - 1) == LUA_TFUNCTION);
|
lua_assert(ci == NULL || ttype(ci->base - 1) == LUA_TFUNCTION);
|
||||||
return (ci && ci->prev && !ci_func(ci)->isC);
|
return (ci && ci->prev && !ci_func(ci)->c.isC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
|
|||||||
static int currentpc (CallInfo *ci) {
|
static int currentpc (CallInfo *ci) {
|
||||||
lua_assert(isLmark(ci));
|
lua_assert(isLmark(ci));
|
||||||
if (ci->pc)
|
if (ci->pc)
|
||||||
return (*ci->pc - ci_func(ci)->u.l.p->code) - 1;
|
return (*ci->pc - ci_func(ci)->l.p->code) - 1;
|
||||||
else
|
else
|
||||||
return -1; /* function is not active */
|
return -1; /* function is not active */
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ static int currentline (CallInfo *ci) {
|
|||||||
if (!isLmark(ci))
|
if (!isLmark(ci))
|
||||||
return -1; /* only active lua functions have current-line information */
|
return -1; /* only active lua functions have current-line information */
|
||||||
else {
|
else {
|
||||||
int *lineinfo = ci_func(ci)->u.l.p->lineinfo;
|
int *lineinfo = ci_func(ci)->l.p->lineinfo;
|
||||||
return luaG_getline(lineinfo, currentpc(ci), 1, NULL);
|
return luaG_getline(lineinfo, currentpc(ci), 1, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ static int currentline (CallInfo *ci) {
|
|||||||
|
|
||||||
|
|
||||||
static Proto *getluaproto (CallInfo *ci) {
|
static Proto *getluaproto (CallInfo *ci) {
|
||||||
return (isLmark(ci) ? ci_func(ci)->u.l.p : NULL);
|
return (isLmark(ci) ? ci_func(ci)->l.p : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -193,13 +193,13 @@ static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
|
|||||||
luaD_error(L, l_s("value for `lua_getinfo' is not a function"));
|
luaD_error(L, l_s("value for `lua_getinfo' is not a function"));
|
||||||
cl = NULL; /* to avoid warnings */
|
cl = NULL; /* to avoid warnings */
|
||||||
}
|
}
|
||||||
if (cl->isC) {
|
if (cl->c.isC) {
|
||||||
ar->source = l_s("=C");
|
ar->source = l_s("=C");
|
||||||
ar->linedefined = -1;
|
ar->linedefined = -1;
|
||||||
ar->what = l_s("C");
|
ar->what = l_s("C");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
infoLproto(ar, cl->u.l.p);
|
infoLproto(ar, cl->l.p);
|
||||||
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
|
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
|
||||||
if (ar->linedefined == 0)
|
if (ar->linedefined == 0)
|
||||||
ar->what = l_s("main");
|
ar->what = l_s("main");
|
||||||
@@ -268,7 +268,7 @@ LUA_API int lua_getinfo (lua_State *L, const l_char *what, lua_Debug *ar) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case l_c('u'): {
|
case l_c('u'): {
|
||||||
ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->nupvalues : 0;
|
ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->c.nupvalues : 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case l_c('n'): {
|
case l_c('n'): {
|
||||||
@@ -473,7 +473,7 @@ int luaG_checkcode (const Proto *pt) {
|
|||||||
static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
|
static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
|
||||||
CallInfo *ci = ci_stack(L, obj);
|
CallInfo *ci = ci_stack(L, obj);
|
||||||
if (isLmark(ci)) { /* an active Lua function? */
|
if (isLmark(ci)) { /* an active Lua function? */
|
||||||
Proto *p = ci_func(ci)->u.l.p;
|
Proto *p = ci_func(ci)->l.p;
|
||||||
int pc = currentpc(ci);
|
int pc = currentpc(ci);
|
||||||
int stackpos = obj - ci->base;
|
int stackpos = obj - ci->base;
|
||||||
Instruction i;
|
Instruction i;
|
||||||
@@ -517,7 +517,7 @@ static const l_char *getfuncname (lua_State *L, CallInfo *ci,
|
|||||||
if (ci == &L->basefunc || !isLmark(ci))
|
if (ci == &L->basefunc || !isLmark(ci))
|
||||||
return NULL; /* not an active Lua function */
|
return NULL; /* not an active Lua function */
|
||||||
else {
|
else {
|
||||||
Proto *p = ci_func(ci)->u.l.p;
|
Proto *p = ci_func(ci)->l.p;
|
||||||
int pc = currentpc(ci);
|
int pc = currentpc(ci);
|
||||||
Instruction i;
|
Instruction i;
|
||||||
if (pc == -1) return NULL; /* function is not activated */
|
if (pc == -1) return NULL; /* function is not activated */
|
||||||
|
|||||||
15
ldo.c
15
ldo.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 1.140 2001/09/07 17:39:10 roberto Exp $
|
** $Id: ldo.c,v 1.141 2001/09/25 17:05:49 roberto Exp $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -118,14 +118,14 @@ static void luaD_callHook (lua_State *L, lua_Hook callhook,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static StkId callCclosure (lua_State *L, const struct Closure *cl) {
|
static StkId callCclosure (lua_State *L, const struct CClosure *cl) {
|
||||||
int nup = cl->nupvalues; /* number of upvalues */
|
int nup = cl->nupvalues; /* number of upvalues */
|
||||||
int n;
|
int n;
|
||||||
luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */
|
luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */
|
||||||
for (n=0; n<nup; n++) /* copy upvalues as extra arguments */
|
for (n=0; n<nup; n++) /* copy upvalues as extra arguments */
|
||||||
setobj(L->top++, &cl->u.c.upvalue[n]);
|
setobj(L->top++, &cl->upvalue[n]);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
n = (*cl->u.c.f)(L); /* do the actual call */
|
n = (*cl->f)(L); /* do the actual call */
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
return L->top - n; /* return index of first result */
|
return L->top - n; /* return index of first result */
|
||||||
}
|
}
|
||||||
@@ -155,8 +155,9 @@ void luaD_call (lua_State *L, StkId func) {
|
|||||||
callhook = L->callhook;
|
callhook = L->callhook;
|
||||||
if (callhook)
|
if (callhook)
|
||||||
luaD_callHook(L, callhook, l_s("call"));
|
luaD_callHook(L, callhook, l_s("call"));
|
||||||
firstResult = (clvalue(func)->isC ? callCclosure(L, clvalue(func)) :
|
firstResult = (clvalue(func)->c.isC ?
|
||||||
luaV_execute(L, clvalue(func), func+1));
|
callCclosure(L, &clvalue(func)->c) :
|
||||||
|
luaV_execute(L, &clvalue(func)->l, func+1));
|
||||||
if (callhook) /* same hook that was active at entry */
|
if (callhook) /* same hook that was active at entry */
|
||||||
luaD_callHook(L, callhook, l_s("return"));
|
luaD_callHook(L, callhook, l_s("return"));
|
||||||
L->ci = ci.prev; /* unchain callinfo */
|
L->ci = ci.prev; /* unchain callinfo */
|
||||||
@@ -213,7 +214,7 @@ static void f_parser (lua_State *L, void *ud) {
|
|||||||
struct SParser *p = cast(struct SParser *, ud);
|
struct SParser *p = cast(struct SParser *, ud);
|
||||||
Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z);
|
Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z);
|
||||||
Closure *cl = luaF_newLclosure(L, 0);
|
Closure *cl = luaF_newLclosure(L, 0);
|
||||||
cl->u.l.p = tf;
|
cl->l.p = tf;
|
||||||
luaF_LConlist(L, cl);
|
luaF_LConlist(L, cl);
|
||||||
setclvalue(L->top, cl);
|
setclvalue(L->top, cl);
|
||||||
incr_top;
|
incr_top;
|
||||||
|
|||||||
62
lfunc.c
62
lfunc.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lfunc.c,v 1.45 2001/06/28 14:57:17 roberto Exp $
|
** $Id: lfunc.c,v 1.47 2001/09/07 17:39:10 roberto Exp $
|
||||||
** Auxiliary functions to manipulate prototypes and closures
|
** Auxiliary functions to manipulate prototypes and closures
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -16,30 +16,29 @@
|
|||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
|
|
||||||
|
|
||||||
#define sizeCclosure(n) (cast(int, sizeof(Closure)) + \
|
#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
|
||||||
cast(int, sizeof(TObject)*((n)-1)))
|
cast(int, sizeof(TObject)*((n)-1)))
|
||||||
|
|
||||||
#define sizeLclosure(n) (cast(int, sizeof(Closure)) + \
|
#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
|
||||||
cast(int, sizeof(TObject *)*((n)-1)))
|
cast(int, sizeof(LClosureEntry)*((n)-1)))
|
||||||
|
|
||||||
|
|
||||||
Closure *luaF_newCclosure (lua_State *L, int nelems) {
|
Closure *luaF_newCclosure (lua_State *L, int nelems) {
|
||||||
Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
|
Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
|
||||||
c->isC = 1;
|
c->c.isC = 1;
|
||||||
c->next = G(L)->rootcl;
|
c->c.next = G(L)->rootcl;
|
||||||
G(L)->rootcl = c;
|
G(L)->rootcl = c;
|
||||||
c->mark = c;
|
c->c.marked = 0;
|
||||||
c->nupvalues = nelems;
|
c->c.nupvalues = nelems;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Closure *luaF_newLclosure (lua_State *L, int nelems) {
|
Closure *luaF_newLclosure (lua_State *L, int nelems) {
|
||||||
Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
|
Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
|
||||||
c->isC = 0;
|
c->l.isC = 0;
|
||||||
c->mark = c;
|
c->l.marked = 0;
|
||||||
c->u.l.isopen = 0;
|
c->l.nupvalues = nelems;
|
||||||
c->nupvalues = nelems;
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,42 +46,38 @@ Closure *luaF_newLclosure (lua_State *L, int nelems) {
|
|||||||
/*
|
/*
|
||||||
** returns the open pointer in a closure that points higher into the stack
|
** returns the open pointer in a closure that points higher into the stack
|
||||||
*/
|
*/
|
||||||
static StkId uppoint (Closure *cl) {
|
static StkId uppoint (LClosure *cl) {
|
||||||
StkId lp = NULL;
|
StkId lp = NULL;
|
||||||
int i;
|
int i;
|
||||||
lua_assert(cl->u.l.isopen);
|
|
||||||
for (i=0; i<cl->nupvalues; i++) {
|
for (i=0; i<cl->nupvalues; i++) {
|
||||||
if (!luaF_isclosed(cl, i))
|
if (cl->upvals[i].heap == NULL && (lp == NULL || cl->upvals[i].val > lp))
|
||||||
if (lp == NULL || cl->u.l.upvals[i] > lp)
|
lp = cl->upvals[i].val;
|
||||||
lp = cl->u.l.upvals[i];
|
|
||||||
}
|
}
|
||||||
lua_assert(lp != NULL);
|
|
||||||
return lp;
|
return lp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaF_LConlist (lua_State *L, Closure *cl) {
|
void luaF_LConlist (lua_State *L, Closure *cl) {
|
||||||
lua_assert(!cl->isC);
|
StkId cli = uppoint(&cl->l);
|
||||||
if (cl->u.l.isopen == 0) { /* no more open entries? */
|
if (cli == NULL) { /* no more open entries? */
|
||||||
cl->next = G(L)->rootcl; /* insert in final list */
|
cl->l.next = G(L)->rootcl; /* insert in final list */
|
||||||
G(L)->rootcl = cl;
|
G(L)->rootcl = cl;
|
||||||
}
|
}
|
||||||
else { /* insert in list of open closures, ordered by decreasing uppoints */
|
else { /* insert in list of open closures, ordered by decreasing uppoints */
|
||||||
StkId cli = uppoint(cl);
|
|
||||||
Closure **p = &L->opencl;
|
Closure **p = &L->opencl;
|
||||||
while (*p != NULL && uppoint(*p) > cli) p = &(*p)->next;
|
while (*p != NULL && uppoint(&(*p)->l) > cli) p = &(*p)->l.next;
|
||||||
cl->next = *p;
|
cl->l.next = *p;
|
||||||
*p = cl;
|
*p = cl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int closeCl (lua_State *L, Closure *cl, StkId level) {
|
static int closeCl (lua_State *L, LClosure *cl, StkId level) {
|
||||||
int got = 0; /* flag: 1 if some pointer in the closure was corrected */
|
int got = 0; /* flag: 1 if some pointer in the closure was corrected */
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<cl->nupvalues; i++) {
|
for (i=0; i<cl->nupvalues; i++) {
|
||||||
StkId var;
|
StkId var;
|
||||||
if (!luaF_isclosed(cl, i) && (var=cl->u.l.upvals[i]) >= level) {
|
if (cl->upvals[i].heap == NULL && (var=cl->upvals[i].val) >= level) {
|
||||||
if (ttype(var) != LUA_TUPVAL) {
|
if (ttype(var) != LUA_TUPVAL) {
|
||||||
UpVal *v = luaM_new(L, UpVal);
|
UpVal *v = luaM_new(L, UpVal);
|
||||||
v->val = *var;
|
v->val = *var;
|
||||||
@@ -91,8 +86,8 @@ static int closeCl (lua_State *L, Closure *cl, StkId level) {
|
|||||||
G(L)->rootupval = v;
|
G(L)->rootupval = v;
|
||||||
setupvalue(var, v);
|
setupvalue(var, v);
|
||||||
}
|
}
|
||||||
cl->u.l.upvals[i] = cast(TObject *, vvalue(var));
|
cl->upvals[i].heap = vvalue(var);
|
||||||
luaF_closeentry(cl, i);
|
cl->upvals[i].val = &vvalue(var)->val;
|
||||||
got = 1;
|
got = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,15 +99,15 @@ void luaF_close (lua_State *L, StkId level) {
|
|||||||
Closure *affected = NULL; /* closures with open pointers >= level */
|
Closure *affected = NULL; /* closures with open pointers >= level */
|
||||||
Closure *cl;
|
Closure *cl;
|
||||||
while ((cl=L->opencl) != NULL) {
|
while ((cl=L->opencl) != NULL) {
|
||||||
if (!closeCl(L, cl, level)) break;
|
if (!closeCl(L, cast(LClosure *, cl), level)) break;
|
||||||
/* some pointer in `cl' changed; will re-insert it in original list */
|
/* some pointer in `cl' changed; will re-insert it in original list */
|
||||||
L->opencl = cl->next; /* remove from original list */
|
L->opencl = cl->l.next; /* remove from original list */
|
||||||
cl->next = affected;
|
cl->l.next = affected;
|
||||||
affected = cl; /* insert in affected list */
|
affected = cl; /* insert in affected list */
|
||||||
}
|
}
|
||||||
/* re-insert all affected closures in original list */
|
/* re-insert all affected closures in original list */
|
||||||
while ((cl=affected) != NULL) {
|
while ((cl=affected) != NULL) {
|
||||||
affected = cl->next;
|
affected = cl->l.next;
|
||||||
luaF_LConlist(L, cl);
|
luaF_LConlist(L, cl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +149,8 @@ void luaF_freeproto (lua_State *L, Proto *f) {
|
|||||||
|
|
||||||
|
|
||||||
void luaF_freeclosure (lua_State *L, Closure *c) {
|
void luaF_freeclosure (lua_State *L, Closure *c) {
|
||||||
int size = (c->isC) ? sizeCclosure(c->nupvalues) : sizeLclosure(c->nupvalues);
|
int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
|
||||||
|
sizeLclosure(c->l.nupvalues);
|
||||||
luaM_free(L, c, size);
|
luaM_free(L, c, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
lfunc.h
7
lfunc.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lfunc.h,v 1.15 2001/02/23 17:17:25 roberto Exp $
|
** $Id: lfunc.h,v 1.16 2001/09/07 17:39:10 roberto Exp $
|
||||||
** Auxiliary functions to manipulate prototypes and closures
|
** Auxiliary functions to manipulate prototypes and closures
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -11,11 +11,6 @@
|
|||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
|
|
||||||
|
|
||||||
#define luaF_isclosed(c, i) (!((c)->u.l.isopen & (1 << (i))))
|
|
||||||
#define luaF_openentry(c, i) ((c)->u.l.isopen |= (1 << (i)))
|
|
||||||
#define luaF_closeentry(c, i) ((c)->u.l.isopen &= ~(1 << (i)))
|
|
||||||
|
|
||||||
|
|
||||||
Proto *luaF_newproto (lua_State *L);
|
Proto *luaF_newproto (lua_State *L);
|
||||||
Closure *luaF_newCclosure (lua_State *L, int nelems);
|
Closure *luaF_newCclosure (lua_State *L, int nelems);
|
||||||
Closure *luaF_newLclosure (lua_State *L, int nelems);
|
Closure *luaF_newLclosure (lua_State *L, int nelems);
|
||||||
|
|||||||
78
lgc.c
78
lgc.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 1.109 2001/06/28 14:57:17 roberto Exp $
|
** $Id: lgc.c,v 1.111 2001/09/07 17:39:10 roberto Exp $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
typedef struct GCState {
|
typedef struct GCState {
|
||||||
Hash *tmark; /* list of marked tables to be visited */
|
Hash *tmark; /* list of marked tables to be visited */
|
||||||
Closure *cmark; /* list of marked closures to be visited */
|
|
||||||
} GCState;
|
} GCState;
|
||||||
|
|
||||||
|
|
||||||
@@ -32,6 +31,9 @@ typedef struct GCState {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void markobject (GCState *st, TObject *o);
|
||||||
|
|
||||||
|
|
||||||
static void protomark (Proto *f) {
|
static void protomark (Proto *f) {
|
||||||
if (!f->marked) {
|
if (!f->marked) {
|
||||||
int i;
|
int i;
|
||||||
@@ -51,9 +53,25 @@ static void protomark (Proto *f) {
|
|||||||
|
|
||||||
|
|
||||||
static void markclosure (GCState *st, Closure *cl) {
|
static void markclosure (GCState *st, Closure *cl) {
|
||||||
if (!ismarked(cl)) {
|
if (!cl->c.marked) {
|
||||||
cl->mark = st->cmark; /* chain it for later traversal */
|
cl->c.marked = 1;
|
||||||
st->cmark = cl;
|
if (cl->c.isC) {
|
||||||
|
int i;
|
||||||
|
for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
|
||||||
|
markobject(st, &cl->c.upvalue[i]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
lua_assert(cl->l.nupvalues == cl->l.p->nupvalues);
|
||||||
|
protomark(cl->l.p);
|
||||||
|
for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
|
||||||
|
UpVal *u = cl->l.upvals[i].heap;
|
||||||
|
if (u && !u->marked) {
|
||||||
|
u->marked = 1;
|
||||||
|
markobject(st, &u->val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,29 +138,6 @@ static void marktagmethods (global_State *G, GCState *st) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void traverseclosure (GCState *st, Closure *cl) {
|
|
||||||
if (cl->isC) {
|
|
||||||
int i;
|
|
||||||
for (i=0; i<cl->nupvalues; i++) /* mark its upvalues */
|
|
||||||
markobject(st, &cl->u.c.upvalue[i]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int i;
|
|
||||||
lua_assert(cl->nupvalues == cl->u.l.p->nupvalues);
|
|
||||||
protomark(cl->u.l.p);
|
|
||||||
for (i=0; i<cl->nupvalues; i++) { /* mark its upvalues */
|
|
||||||
if (luaF_isclosed(cl, i)) {
|
|
||||||
UpVal *u = cast(UpVal *, cl->u.l.upvals[i]);
|
|
||||||
if (!u->marked) {
|
|
||||||
u->marked = 1;
|
|
||||||
markobject(st, &u->val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void removekey (Node *n) {
|
static void removekey (Node *n) {
|
||||||
lua_assert(ttype(val(n)) == LUA_TNIL);
|
lua_assert(ttype(val(n)) == LUA_TNIL);
|
||||||
if (ttype(key(n)) != LUA_TNIL && ttype(key(n)) != LUA_TNUMBER)
|
if (ttype(key(n)) != LUA_TNIL && ttype(key(n)) != LUA_TNUMBER)
|
||||||
@@ -172,25 +167,16 @@ static void traversetable (GCState *st, Hash *h) {
|
|||||||
|
|
||||||
static void markall (lua_State *L) {
|
static void markall (lua_State *L) {
|
||||||
GCState st;
|
GCState st;
|
||||||
st.cmark = NULL;
|
|
||||||
st.tmark = NULL;
|
st.tmark = NULL;
|
||||||
marktagmethods(G(L), &st); /* mark tag methods */
|
marktagmethods(G(L), &st); /* mark tag methods */
|
||||||
markstacks(L, &st); /* mark all stacks */
|
markstacks(L, &st); /* mark all stacks */
|
||||||
marktable(&st, G(L)->type2tag);
|
marktable(&st, G(L)->type2tag);
|
||||||
marktable(&st, G(L)->registry);
|
marktable(&st, G(L)->registry);
|
||||||
marktable(&st, G(L)->weakregistry);
|
marktable(&st, G(L)->weakregistry);
|
||||||
for (;;) { /* mark tables and closures */
|
while (st.tmark) { /* mark tables */
|
||||||
if (st.cmark) {
|
Hash *h = st.tmark; /* get first table from list */
|
||||||
Closure *cl = st.cmark; /* get first closure from list */
|
st.tmark = h->mark; /* remove it from list */
|
||||||
st.cmark = cl->mark; /* remove it from list */
|
traversetable(&st, h);
|
||||||
traverseclosure(&st, cl);
|
|
||||||
}
|
|
||||||
else if (st.tmark) {
|
|
||||||
Hash *h = st.tmark; /* get first table from list */
|
|
||||||
st.tmark = h->mark; /* remove it from list */
|
|
||||||
traversetable(&st, h);
|
|
||||||
}
|
|
||||||
else break; /* nothing else to mark */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +190,7 @@ static int hasmark (const TObject *o) {
|
|||||||
case LUA_TTABLE:
|
case LUA_TTABLE:
|
||||||
return ismarked(hvalue(o));
|
return ismarked(hvalue(o));
|
||||||
case LUA_TFUNCTION:
|
case LUA_TFUNCTION:
|
||||||
return ismarked(clvalue(o));
|
return clvalue(o)->c.marked;
|
||||||
default: /* number, nil */
|
default: /* number, nil */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -252,12 +238,12 @@ static void collectproto (lua_State *L) {
|
|||||||
static void collectclosure (lua_State *L, Closure **p) {
|
static void collectclosure (lua_State *L, Closure **p) {
|
||||||
Closure *curr;
|
Closure *curr;
|
||||||
while ((curr = *p) != NULL) {
|
while ((curr = *p) != NULL) {
|
||||||
if (ismarked(curr)) {
|
if (curr->c.marked) {
|
||||||
curr->mark = curr; /* unmark */
|
curr->c.marked = 0;
|
||||||
p = &curr->next;
|
p = &curr->c.next;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*p = curr->next;
|
*p = curr->c.next;
|
||||||
luaF_freeclosure(L, curr);
|
luaF_freeclosure(L, curr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llimits.h,v 1.31 2001/08/27 15:16:28 roberto Exp $
|
** $Id: llimits.h,v 1.32 2001/09/07 17:39:10 roberto Exp $
|
||||||
** Limits, basic types, and some other `installation-dependent' definitions
|
** Limits, basic types, and some other `installation-dependent' definitions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -51,9 +51,6 @@ typedef unsigned long lu_mem;
|
|||||||
/* an integer big enough to count the number of strings in use */
|
/* an integer big enough to count the number of strings in use */
|
||||||
typedef long ls_nstr;
|
typedef long ls_nstr;
|
||||||
|
|
||||||
/* a bitmap with one bit for each upvalue used by a function */
|
|
||||||
typedef unsigned long ls_bitup;
|
|
||||||
|
|
||||||
|
|
||||||
/* chars used as small naturals (so that `char' is reserved for characteres) */
|
/* chars used as small naturals (so that `char' is reserved for characteres) */
|
||||||
typedef unsigned char lu_byte;
|
typedef unsigned char lu_byte;
|
||||||
@@ -109,9 +106,9 @@ typedef unsigned long Instruction;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* maximum number of upvalues */
|
/* maximum number of upvalues per function */
|
||||||
#ifndef MAXUPVALUES
|
#ifndef MAXUPVALUES
|
||||||
#define MAXUPVALUES (sizeof(ls_bitup)*CHAR_BIT)
|
#define MAXUPVALUES 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
54
lobject.h
54
lobject.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 1.112 2001/09/07 17:39:10 roberto Exp $
|
** $Id: lobject.h,v 1.113 2001/09/25 17:08:46 roberto Exp $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
typedef union {
|
typedef union {
|
||||||
union TString *ts;
|
union TString *ts;
|
||||||
union Udata *u;
|
union Udata *u;
|
||||||
struct Closure *cl;
|
union Closure *cl;
|
||||||
struct Hash *h;
|
struct Hash *h;
|
||||||
struct UpVal *v;
|
struct UpVal *v;
|
||||||
lua_Number n; /* LUA_TNUMBER */
|
lua_Number n; /* LUA_TNUMBER */
|
||||||
@@ -177,26 +177,38 @@ typedef struct UpVal {
|
|||||||
/*
|
/*
|
||||||
** Closures
|
** Closures
|
||||||
*/
|
*/
|
||||||
typedef struct Closure {
|
|
||||||
short isC; /* 0 for Lua functions, 1 for C functions */
|
typedef struct CClosure {
|
||||||
short nupvalues;
|
lu_byte isC; /* 0 for Lua functions, 1 for C functions */
|
||||||
struct Closure *next;
|
lu_byte nupvalues;
|
||||||
struct Closure *mark; /* marked closures (point to itself when not marked) */
|
lu_byte marked;
|
||||||
union {
|
union Closure *next;
|
||||||
struct { /* C functions */
|
lua_CFunction f;
|
||||||
lua_CFunction f;
|
TObject upvalue[1];
|
||||||
TObject upvalue[1];
|
} CClosure;
|
||||||
} c;
|
|
||||||
struct { /* Lua functions */
|
|
||||||
struct Proto *p;
|
typedef struct LClosureEntry {
|
||||||
ls_bitup isopen; /* bitmap: bit==1 when upvals point to the stack */
|
TObject *val;
|
||||||
TObject *upvals[1]; /* may point to the stack or to an UpVal */
|
UpVal *heap; /* NULL when upvalue is still in the stack */
|
||||||
} l;
|
} LClosureEntry;
|
||||||
} u;
|
|
||||||
|
typedef struct LClosure {
|
||||||
|
lu_byte isC;
|
||||||
|
lu_byte nupvalues;
|
||||||
|
lu_byte marked;
|
||||||
|
union Closure *next; /* first four fields must be equal to CClosure!! */
|
||||||
|
struct Proto *p;
|
||||||
|
LClosureEntry upvals[1];
|
||||||
|
} LClosure;
|
||||||
|
|
||||||
|
typedef union Closure {
|
||||||
|
CClosure c;
|
||||||
|
LClosure l;
|
||||||
} Closure;
|
} Closure;
|
||||||
|
|
||||||
|
|
||||||
#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC)
|
#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -223,9 +235,7 @@ typedef struct Hash {
|
|||||||
} Hash;
|
} Hash;
|
||||||
|
|
||||||
|
|
||||||
/* unmarked tables and closures are represented by pointing `mark' to
|
/* unmarked tables are represented by pointing `mark' to themselves */
|
||||||
** themselves
|
|
||||||
*/
|
|
||||||
#define ismarked(x) ((x)->mark != (x))
|
#define ismarked(x) ((x)->mark != (x))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
8
ltests.c
8
ltests.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltests.c,v 1.88 2001/07/12 18:11:58 roberto Exp $
|
** $Id: ltests.c,v 1.91 2001/09/07 17:39:10 roberto Exp $
|
||||||
** 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
|
||||||
*/
|
*/
|
||||||
@@ -165,7 +165,7 @@ static int listcode (lua_State *L) {
|
|||||||
Proto *p;
|
Proto *p;
|
||||||
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
||||||
1, l_s("Lua function expected"));
|
1, l_s("Lua function expected"));
|
||||||
p = clvalue(luaA_index(L, 1))->u.l.p;
|
p = clvalue(luaA_index(L, 1))->l.p;
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
setnameval(L, l_s("maxstack"), p->maxstacksize);
|
setnameval(L, l_s("maxstack"), p->maxstacksize);
|
||||||
setnameval(L, l_s("numparams"), p->numparams);
|
setnameval(L, l_s("numparams"), p->numparams);
|
||||||
@@ -184,7 +184,7 @@ static int listk (lua_State *L) {
|
|||||||
int i;
|
int i;
|
||||||
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
||||||
1, l_s("Lua function expected"));
|
1, l_s("Lua function expected"));
|
||||||
p = clvalue(luaA_index(L, 1))->u.l.p;
|
p = clvalue(luaA_index(L, 1))->l.p;
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
for (i=0; i<p->sizek; i++) {
|
for (i=0; i<p->sizek; i++) {
|
||||||
lua_pushnumber(L, i+1);
|
lua_pushnumber(L, i+1);
|
||||||
@@ -202,7 +202,7 @@ static int listlocals (lua_State *L) {
|
|||||||
const l_char *name;
|
const l_char *name;
|
||||||
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
||||||
1, l_s("Lua function expected"));
|
1, l_s("Lua function expected"));
|
||||||
p = clvalue(luaA_index(L, 1))->u.l.p;
|
p = clvalue(luaA_index(L, 1))->l.p;
|
||||||
while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
|
while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
|
||||||
lua_pushstring(L, name);
|
lua_pushstring(L, name);
|
||||||
return i-1;
|
return i-1;
|
||||||
|
|||||||
30
lvm.c
30
lvm.c
@@ -64,8 +64,8 @@ int luaV_tostring (lua_State *L, TObject *obj) {
|
|||||||
|
|
||||||
static void traceexec (lua_State *L, lua_Hook linehook) {
|
static void traceexec (lua_State *L, lua_Hook linehook) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
int *lineinfo = ci_func(ci)->u.l.p->lineinfo;
|
int *lineinfo = ci_func(ci)->l.p->lineinfo;
|
||||||
int pc = (*ci->pc - ci_func(ci)->u.l.p->code) - 1;
|
int pc = (*ci->pc - ci_func(ci)->l.p->code) - 1;
|
||||||
int newline;
|
int newline;
|
||||||
if (pc == 0) { /* may be first time? */
|
if (pc == 0) { /* may be first time? */
|
||||||
ci->line = 1;
|
ci->line = 1;
|
||||||
@@ -351,8 +351,8 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
|
|||||||
** Executes the given Lua function. Parameters are between [base,top).
|
** Executes the given Lua function. Parameters are between [base,top).
|
||||||
** Returns n such that the the results are between [n,top).
|
** Returns n such that the the results are between [n,top).
|
||||||
*/
|
*/
|
||||||
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
|
StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
|
||||||
const Proto *const tf = cl->u.l.p;
|
const Proto *const tf = cl->p;
|
||||||
const Instruction *pc;
|
const Instruction *pc;
|
||||||
lua_Hook linehook;
|
lua_Hook linehook;
|
||||||
if (tf->is_vararg) /* varargs? */
|
if (tf->is_vararg) /* varargs? */
|
||||||
@@ -391,8 +391,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
|
|||||||
}
|
}
|
||||||
case OP_GETUPVAL: {
|
case OP_GETUPVAL: {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
lua_assert(luaF_isclosed(cl, b) || cl->u.l.upvals[b] < base);
|
lua_assert(cl->upvals[b].heap || cl->upvals[b].val < base);
|
||||||
setobj(ra, cl->u.l.upvals[b]);
|
setobj(ra, cl->upvals[b].val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_GETGLOBAL: {
|
case OP_GETGLOBAL: {
|
||||||
@@ -411,8 +411,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
|
|||||||
}
|
}
|
||||||
case OP_SETUPVAL: {
|
case OP_SETUPVAL: {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
lua_assert(luaF_isclosed(cl, b) || cl->u.l.upvals[b] < base);
|
lua_assert(cl->upvals[b].heap || cl->upvals[b].val < base);
|
||||||
setobj(cl->u.l.upvals[b], ra);
|
setobj(cl->upvals[b].val, ra);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_SETTABLE: {
|
case OP_SETTABLE: {
|
||||||
@@ -644,18 +644,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
|
|||||||
p = tf->p[GETARG_Bc(i)];
|
p = tf->p[GETARG_Bc(i)];
|
||||||
nup = p->nupvalues;
|
nup = p->nupvalues;
|
||||||
ncl = luaF_newLclosure(L, nup);
|
ncl = luaF_newLclosure(L, nup);
|
||||||
ncl->u.l.p = p;
|
ncl->l.p = p;
|
||||||
for (j=0; j<nup; j++, pc++) {
|
for (j=0; j<nup; j++, pc++) {
|
||||||
if (GET_OPCODE(*pc) == OP_GETUPVAL) {
|
if (GET_OPCODE(*pc) == OP_GETUPVAL)
|
||||||
int n = GETARG_B(*pc);
|
ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
|
||||||
if (!luaF_isclosed(cl, n))
|
|
||||||
luaF_openentry(ncl, j);
|
|
||||||
ncl->u.l.upvals[j] = cl->u.l.upvals[n];
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
lua_assert(GET_OPCODE(*pc) == OP_MOVE);
|
lua_assert(GET_OPCODE(*pc) == OP_MOVE);
|
||||||
luaF_openentry(ncl, j);
|
ncl->l.upvals[j].heap = NULL;
|
||||||
ncl->u.l.upvals[j] = base + GETARG_B(*pc);
|
ncl->l.upvals[j].val = base + GETARG_B(*pc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
luaF_LConlist(L, ncl);
|
luaF_LConlist(L, ncl);
|
||||||
|
|||||||
4
lvm.h
4
lvm.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.h,v 1.30 2001/06/05 18:17:01 roberto Exp $
|
** $Id: lvm.h,v 1.31 2001/09/07 17:39:10 roberto Exp $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -22,7 +22,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res);
|
|||||||
void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val);
|
void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val);
|
||||||
void luaV_getglobal (lua_State *L, TString *s, StkId res);
|
void luaV_getglobal (lua_State *L, TString *s, StkId res);
|
||||||
void luaV_setglobal (lua_State *L, TString *s, StkId val);
|
void luaV_setglobal (lua_State *L, TString *s, StkId val);
|
||||||
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
|
StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base);
|
||||||
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
|
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
|
||||||
void luaV_strconc (lua_State *L, int total, StkId top);
|
void luaV_strconc (lua_State *L, int total, StkId top);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user