diff options
-rw-r--r-- | lapi.c | 8 | ||||
-rw-r--r-- | ldebug.c | 18 | ||||
-rw-r--r-- | ldo.c | 15 | ||||
-rw-r--r-- | lfunc.c | 62 | ||||
-rw-r--r-- | lfunc.h | 7 | ||||
-rw-r--r-- | lgc.c | 78 | ||||
-rw-r--r-- | llimits.h | 9 | ||||
-rw-r--r-- | lobject.h | 54 | ||||
-rw-r--r-- | ltests.c | 8 | ||||
-rw-r--r-- | lvm.c | 30 | ||||
-rw-r--r-- | lvm.h | 4 |
11 files changed, 137 insertions, 156 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 1.149 2001/07/22 00:59:36 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.152 2001/09/07 17:39:10 roberto Exp $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -248,7 +248,7 @@ LUA_API size_t lua_strlen (lua_State *L, int index) { | |||
248 | 248 | ||
249 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) { | 249 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) { |
250 | StkId o = luaA_indexAcceptable(L, index); | 250 | StkId o = luaA_indexAcceptable(L, index); |
251 | return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->u.c.f; | 251 | return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f; |
252 | } | 252 | } |
253 | 253 | ||
254 | 254 | ||
@@ -314,10 +314,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | |||
314 | lua_lock(L); | 314 | lua_lock(L); |
315 | api_checknelems(L, n); | 315 | api_checknelems(L, n); |
316 | cl = luaF_newCclosure(L, n); | 316 | cl = luaF_newCclosure(L, n); |
317 | cl->u.c.f = fn; | 317 | cl->c.f = fn; |
318 | L->top -= n; | 318 | L->top -= n; |
319 | while (n--) | 319 | while (n--) |
320 | setobj(&cl->u.c.upvalue[n], L->top+n); | 320 | setobj(&cl->c.upvalue[n], L->top+n); |
321 | setclvalue(L->top, cl); | 321 | setclvalue(L->top, cl); |
322 | incr_top; | 322 | incr_top; |
323 | lua_unlock(L); | 323 | lua_unlock(L); |
@@ -33,7 +33,7 @@ static const l_char *getfuncname (lua_State *L, CallInfo *ci, | |||
33 | 33 | ||
34 | static int isLmark (CallInfo *ci) { | 34 | static int isLmark (CallInfo *ci) { |
35 | lua_assert(ci == NULL || ttype(ci->base - 1) == LUA_TFUNCTION); | 35 | lua_assert(ci == NULL || ttype(ci->base - 1) == LUA_TFUNCTION); |
36 | return (ci && ci->prev && !ci_func(ci)->isC); | 36 | return (ci && ci->prev && !ci_func(ci)->c.isC); |
37 | } | 37 | } |
38 | 38 | ||
39 | 39 | ||
@@ -117,7 +117,7 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { | |||
117 | static int currentpc (CallInfo *ci) { | 117 | static int currentpc (CallInfo *ci) { |
118 | lua_assert(isLmark(ci)); | 118 | lua_assert(isLmark(ci)); |
119 | if (ci->pc) | 119 | if (ci->pc) |
120 | return (*ci->pc - ci_func(ci)->u.l.p->code) - 1; | 120 | return (*ci->pc - ci_func(ci)->l.p->code) - 1; |
121 | else | 121 | else |
122 | return -1; /* function is not active */ | 122 | return -1; /* function is not active */ |
123 | } | 123 | } |
@@ -127,7 +127,7 @@ static int currentline (CallInfo *ci) { | |||
127 | if (!isLmark(ci)) | 127 | if (!isLmark(ci)) |
128 | return -1; /* only active lua functions have current-line information */ | 128 | return -1; /* only active lua functions have current-line information */ |
129 | else { | 129 | else { |
130 | int *lineinfo = ci_func(ci)->u.l.p->lineinfo; | 130 | int *lineinfo = ci_func(ci)->l.p->lineinfo; |
131 | return luaG_getline(lineinfo, currentpc(ci), 1, NULL); | 131 | return luaG_getline(lineinfo, currentpc(ci), 1, NULL); |
132 | } | 132 | } |
133 | } | 133 | } |
@@ -135,7 +135,7 @@ static int currentline (CallInfo *ci) { | |||
135 | 135 | ||
136 | 136 | ||
137 | static Proto *getluaproto (CallInfo *ci) { | 137 | static Proto *getluaproto (CallInfo *ci) { |
138 | return (isLmark(ci) ? ci_func(ci)->u.l.p : NULL); | 138 | return (isLmark(ci) ? ci_func(ci)->l.p : NULL); |
139 | } | 139 | } |
140 | 140 | ||
141 | 141 | ||
@@ -193,13 +193,13 @@ static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) { | |||
193 | luaD_error(L, l_s("value for `lua_getinfo' is not a function")); | 193 | luaD_error(L, l_s("value for `lua_getinfo' is not a function")); |
194 | cl = NULL; /* to avoid warnings */ | 194 | cl = NULL; /* to avoid warnings */ |
195 | } | 195 | } |
196 | if (cl->isC) { | 196 | if (cl->c.isC) { |
197 | ar->source = l_s("=C"); | 197 | ar->source = l_s("=C"); |
198 | ar->linedefined = -1; | 198 | ar->linedefined = -1; |
199 | ar->what = l_s("C"); | 199 | ar->what = l_s("C"); |
200 | } | 200 | } |
201 | else | 201 | else |
202 | infoLproto(ar, cl->u.l.p); | 202 | infoLproto(ar, cl->l.p); |
203 | luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); | 203 | luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); |
204 | if (ar->linedefined == 0) | 204 | if (ar->linedefined == 0) |
205 | ar->what = l_s("main"); | 205 | ar->what = l_s("main"); |
@@ -268,7 +268,7 @@ LUA_API int lua_getinfo (lua_State *L, const l_char *what, lua_Debug *ar) { | |||
268 | break; | 268 | break; |
269 | } | 269 | } |
270 | case l_c('u'): { | 270 | case l_c('u'): { |
271 | ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->nupvalues : 0; | 271 | ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->c.nupvalues : 0; |
272 | break; | 272 | break; |
273 | } | 273 | } |
274 | case l_c('n'): { | 274 | case l_c('n'): { |
@@ -473,7 +473,7 @@ int luaG_checkcode (const Proto *pt) { | |||
473 | static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) { | 473 | static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) { |
474 | CallInfo *ci = ci_stack(L, obj); | 474 | CallInfo *ci = ci_stack(L, obj); |
475 | if (isLmark(ci)) { /* an active Lua function? */ | 475 | if (isLmark(ci)) { /* an active Lua function? */ |
476 | Proto *p = ci_func(ci)->u.l.p; | 476 | Proto *p = ci_func(ci)->l.p; |
477 | int pc = currentpc(ci); | 477 | int pc = currentpc(ci); |
478 | int stackpos = obj - ci->base; | 478 | int stackpos = obj - ci->base; |
479 | Instruction i; | 479 | Instruction i; |
@@ -517,7 +517,7 @@ static const l_char *getfuncname (lua_State *L, CallInfo *ci, | |||
517 | if (ci == &L->basefunc || !isLmark(ci)) | 517 | if (ci == &L->basefunc || !isLmark(ci)) |
518 | return NULL; /* not an active Lua function */ | 518 | return NULL; /* not an active Lua function */ |
519 | else { | 519 | else { |
520 | Proto *p = ci_func(ci)->u.l.p; | 520 | Proto *p = ci_func(ci)->l.p; |
521 | int pc = currentpc(ci); | 521 | int pc = currentpc(ci); |
522 | Instruction i; | 522 | Instruction i; |
523 | if (pc == -1) return NULL; /* function is not activated */ | 523 | if (pc == -1) return NULL; /* function is not activated */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.140 2001/09/07 17:39:10 roberto Exp $ | 2 | ** $Id: ldo.c,v 1.141 2001/09/25 17:05:49 roberto Exp $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -118,14 +118,14 @@ static void luaD_callHook (lua_State *L, lua_Hook callhook, | |||
118 | } | 118 | } |
119 | 119 | ||
120 | 120 | ||
121 | static StkId callCclosure (lua_State *L, const struct Closure *cl) { | 121 | static StkId callCclosure (lua_State *L, const struct CClosure *cl) { |
122 | int nup = cl->nupvalues; /* number of upvalues */ | 122 | int nup = cl->nupvalues; /* number of upvalues */ |
123 | int n; | 123 | int n; |
124 | luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */ | 124 | luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */ |
125 | for (n=0; n<nup; n++) /* copy upvalues as extra arguments */ | 125 | for (n=0; n<nup; n++) /* copy upvalues as extra arguments */ |
126 | setobj(L->top++, &cl->u.c.upvalue[n]); | 126 | setobj(L->top++, &cl->upvalue[n]); |
127 | lua_unlock(L); | 127 | lua_unlock(L); |
128 | n = (*cl->u.c.f)(L); /* do the actual call */ | 128 | n = (*cl->f)(L); /* do the actual call */ |
129 | lua_lock(L); | 129 | lua_lock(L); |
130 | return L->top - n; /* return index of first result */ | 130 | return L->top - n; /* return index of first result */ |
131 | } | 131 | } |
@@ -155,8 +155,9 @@ void luaD_call (lua_State *L, StkId func) { | |||
155 | callhook = L->callhook; | 155 | callhook = L->callhook; |
156 | if (callhook) | 156 | if (callhook) |
157 | luaD_callHook(L, callhook, l_s("call")); | 157 | luaD_callHook(L, callhook, l_s("call")); |
158 | firstResult = (clvalue(func)->isC ? callCclosure(L, clvalue(func)) : | 158 | firstResult = (clvalue(func)->c.isC ? |
159 | luaV_execute(L, clvalue(func), func+1)); | 159 | callCclosure(L, &clvalue(func)->c) : |
160 | luaV_execute(L, &clvalue(func)->l, func+1)); | ||
160 | if (callhook) /* same hook that was active at entry */ | 161 | if (callhook) /* same hook that was active at entry */ |
161 | luaD_callHook(L, callhook, l_s("return")); | 162 | luaD_callHook(L, callhook, l_s("return")); |
162 | L->ci = ci.prev; /* unchain callinfo */ | 163 | L->ci = ci.prev; /* unchain callinfo */ |
@@ -213,7 +214,7 @@ static void f_parser (lua_State *L, void *ud) { | |||
213 | struct SParser *p = cast(struct SParser *, ud); | 214 | struct SParser *p = cast(struct SParser *, ud); |
214 | Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z); | 215 | Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z); |
215 | Closure *cl = luaF_newLclosure(L, 0); | 216 | Closure *cl = luaF_newLclosure(L, 0); |
216 | cl->u.l.p = tf; | 217 | cl->l.p = tf; |
217 | luaF_LConlist(L, cl); | 218 | luaF_LConlist(L, cl); |
218 | setclvalue(L->top, cl); | 219 | setclvalue(L->top, cl); |
219 | incr_top; | 220 | incr_top; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 1.45 2001/06/28 14:57:17 roberto Exp $ | 2 | ** $Id: lfunc.c,v 1.47 2001/09/07 17:39:10 roberto Exp $ |
3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -16,30 +16,29 @@ | |||
16 | #include "lstate.h" | 16 | #include "lstate.h" |
17 | 17 | ||
18 | 18 | ||
19 | #define sizeCclosure(n) (cast(int, sizeof(Closure)) + \ | 19 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ |
20 | cast(int, sizeof(TObject)*((n)-1))) | 20 | cast(int, sizeof(TObject)*((n)-1))) |
21 | 21 | ||
22 | #define sizeLclosure(n) (cast(int, sizeof(Closure)) + \ | 22 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ |
23 | cast(int, sizeof(TObject *)*((n)-1))) | 23 | cast(int, sizeof(LClosureEntry)*((n)-1))) |
24 | 24 | ||
25 | 25 | ||
26 | Closure *luaF_newCclosure (lua_State *L, int nelems) { | 26 | Closure *luaF_newCclosure (lua_State *L, int nelems) { |
27 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); | 27 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); |
28 | c->isC = 1; | 28 | c->c.isC = 1; |
29 | c->next = G(L)->rootcl; | 29 | c->c.next = G(L)->rootcl; |
30 | G(L)->rootcl = c; | 30 | G(L)->rootcl = c; |
31 | c->mark = c; | 31 | c->c.marked = 0; |
32 | c->nupvalues = nelems; | 32 | c->c.nupvalues = nelems; |
33 | return c; | 33 | return c; |
34 | } | 34 | } |
35 | 35 | ||
36 | 36 | ||
37 | Closure *luaF_newLclosure (lua_State *L, int nelems) { | 37 | Closure *luaF_newLclosure (lua_State *L, int nelems) { |
38 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); | 38 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); |
39 | c->isC = 0; | 39 | c->l.isC = 0; |
40 | c->mark = c; | 40 | c->l.marked = 0; |
41 | c->u.l.isopen = 0; | 41 | c->l.nupvalues = nelems; |
42 | c->nupvalues = nelems; | ||
43 | return c; | 42 | return c; |
44 | } | 43 | } |
45 | 44 | ||
@@ -47,42 +46,38 @@ Closure *luaF_newLclosure (lua_State *L, int nelems) { | |||
47 | /* | 46 | /* |
48 | ** returns the open pointer in a closure that points higher into the stack | 47 | ** returns the open pointer in a closure that points higher into the stack |
49 | */ | 48 | */ |
50 | static StkId uppoint (Closure *cl) { | 49 | static StkId uppoint (LClosure *cl) { |
51 | StkId lp = NULL; | 50 | StkId lp = NULL; |
52 | int i; | 51 | int i; |
53 | lua_assert(cl->u.l.isopen); | ||
54 | for (i=0; i<cl->nupvalues; i++) { | 52 | for (i=0; i<cl->nupvalues; i++) { |
55 | if (!luaF_isclosed(cl, i)) | 53 | if (cl->upvals[i].heap == NULL && (lp == NULL || cl->upvals[i].val > lp)) |
56 | if (lp == NULL || cl->u.l.upvals[i] > lp) | 54 | lp = cl->upvals[i].val; |
57 | lp = cl->u.l.upvals[i]; | ||
58 | } | 55 | } |
59 | lua_assert(lp != NULL); | ||
60 | return lp; | 56 | return lp; |
61 | } | 57 | } |
62 | 58 | ||
63 | 59 | ||
64 | void luaF_LConlist (lua_State *L, Closure *cl) { | 60 | void luaF_LConlist (lua_State *L, Closure *cl) { |
65 | lua_assert(!cl->isC); | 61 | StkId cli = uppoint(&cl->l); |
66 | if (cl->u.l.isopen == 0) { /* no more open entries? */ | 62 | if (cli == NULL) { /* no more open entries? */ |
67 | cl->next = G(L)->rootcl; /* insert in final list */ | 63 | cl->l.next = G(L)->rootcl; /* insert in final list */ |
68 | G(L)->rootcl = cl; | 64 | G(L)->rootcl = cl; |
69 | } | 65 | } |
70 | else { /* insert in list of open closures, ordered by decreasing uppoints */ | 66 | else { /* insert in list of open closures, ordered by decreasing uppoints */ |
71 | StkId cli = uppoint(cl); | ||
72 | Closure **p = &L->opencl; | 67 | Closure **p = &L->opencl; |
73 | while (*p != NULL && uppoint(*p) > cli) p = &(*p)->next; | 68 | while (*p != NULL && uppoint(&(*p)->l) > cli) p = &(*p)->l.next; |
74 | cl->next = *p; | 69 | cl->l.next = *p; |
75 | *p = cl; | 70 | *p = cl; |
76 | } | 71 | } |
77 | } | 72 | } |
78 | 73 | ||
79 | 74 | ||
80 | static int closeCl (lua_State *L, Closure *cl, StkId level) { | 75 | static int closeCl (lua_State *L, LClosure *cl, StkId level) { |
81 | int got = 0; /* flag: 1 if some pointer in the closure was corrected */ | 76 | int got = 0; /* flag: 1 if some pointer in the closure was corrected */ |
82 | int i; | 77 | int i; |
83 | for (i=0; i<cl->nupvalues; i++) { | 78 | for (i=0; i<cl->nupvalues; i++) { |
84 | StkId var; | 79 | StkId var; |
85 | if (!luaF_isclosed(cl, i) && (var=cl->u.l.upvals[i]) >= level) { | 80 | if (cl->upvals[i].heap == NULL && (var=cl->upvals[i].val) >= level) { |
86 | if (ttype(var) != LUA_TUPVAL) { | 81 | if (ttype(var) != LUA_TUPVAL) { |
87 | UpVal *v = luaM_new(L, UpVal); | 82 | UpVal *v = luaM_new(L, UpVal); |
88 | v->val = *var; | 83 | v->val = *var; |
@@ -91,8 +86,8 @@ static int closeCl (lua_State *L, Closure *cl, StkId level) { | |||
91 | G(L)->rootupval = v; | 86 | G(L)->rootupval = v; |
92 | setupvalue(var, v); | 87 | setupvalue(var, v); |
93 | } | 88 | } |
94 | cl->u.l.upvals[i] = cast(TObject *, vvalue(var)); | 89 | cl->upvals[i].heap = vvalue(var); |
95 | luaF_closeentry(cl, i); | 90 | cl->upvals[i].val = &vvalue(var)->val; |
96 | got = 1; | 91 | got = 1; |
97 | } | 92 | } |
98 | } | 93 | } |
@@ -104,15 +99,15 @@ void luaF_close (lua_State *L, StkId level) { | |||
104 | Closure *affected = NULL; /* closures with open pointers >= level */ | 99 | Closure *affected = NULL; /* closures with open pointers >= level */ |
105 | Closure *cl; | 100 | Closure *cl; |
106 | while ((cl=L->opencl) != NULL) { | 101 | while ((cl=L->opencl) != NULL) { |
107 | if (!closeCl(L, cl, level)) break; | 102 | if (!closeCl(L, cast(LClosure *, cl), level)) break; |
108 | /* some pointer in `cl' changed; will re-insert it in original list */ | 103 | /* some pointer in `cl' changed; will re-insert it in original list */ |
109 | L->opencl = cl->next; /* remove from original list */ | 104 | L->opencl = cl->l.next; /* remove from original list */ |
110 | cl->next = affected; | 105 | cl->l.next = affected; |
111 | affected = cl; /* insert in affected list */ | 106 | affected = cl; /* insert in affected list */ |
112 | } | 107 | } |
113 | /* re-insert all affected closures in original list */ | 108 | /* re-insert all affected closures in original list */ |
114 | while ((cl=affected) != NULL) { | 109 | while ((cl=affected) != NULL) { |
115 | affected = cl->next; | 110 | affected = cl->l.next; |
116 | luaF_LConlist(L, cl); | 111 | luaF_LConlist(L, cl); |
117 | } | 112 | } |
118 | } | 113 | } |
@@ -154,7 +149,8 @@ void luaF_freeproto (lua_State *L, Proto *f) { | |||
154 | 149 | ||
155 | 150 | ||
156 | void luaF_freeclosure (lua_State *L, Closure *c) { | 151 | void luaF_freeclosure (lua_State *L, Closure *c) { |
157 | int size = (c->isC) ? sizeCclosure(c->nupvalues) : sizeLclosure(c->nupvalues); | 152 | int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : |
153 | sizeLclosure(c->l.nupvalues); | ||
158 | luaM_free(L, c, size); | 154 | luaM_free(L, c, size); |
159 | } | 155 | } |
160 | 156 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.h,v 1.15 2001/02/23 17:17:25 roberto Exp $ | 2 | ** $Id: lfunc.h,v 1.16 2001/09/07 17:39:10 roberto Exp $ |
3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -11,11 +11,6 @@ | |||
11 | #include "lobject.h" | 11 | #include "lobject.h" |
12 | 12 | ||
13 | 13 | ||
14 | #define luaF_isclosed(c, i) (!((c)->u.l.isopen & (1 << (i)))) | ||
15 | #define luaF_openentry(c, i) ((c)->u.l.isopen |= (1 << (i))) | ||
16 | #define luaF_closeentry(c, i) ((c)->u.l.isopen &= ~(1 << (i))) | ||
17 | |||
18 | |||
19 | Proto *luaF_newproto (lua_State *L); | 14 | Proto *luaF_newproto (lua_State *L); |
20 | Closure *luaF_newCclosure (lua_State *L, int nelems); | 15 | Closure *luaF_newCclosure (lua_State *L, int nelems); |
21 | Closure *luaF_newLclosure (lua_State *L, int nelems); | 16 | Closure *luaF_newLclosure (lua_State *L, int nelems); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.109 2001/06/28 14:57:17 roberto Exp $ | 2 | ** $Id: lgc.c,v 1.111 2001/09/07 17:39:10 roberto Exp $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | typedef struct GCState { | 23 | typedef struct GCState { |
24 | Hash *tmark; /* list of marked tables to be visited */ | 24 | Hash *tmark; /* list of marked tables to be visited */ |
25 | Closure *cmark; /* list of marked closures to be visited */ | ||
26 | } GCState; | 25 | } GCState; |
27 | 26 | ||
28 | 27 | ||
@@ -32,6 +31,9 @@ typedef struct GCState { | |||
32 | 31 | ||
33 | 32 | ||
34 | 33 | ||
34 | static void markobject (GCState *st, TObject *o); | ||
35 | |||
36 | |||
35 | static void protomark (Proto *f) { | 37 | static void protomark (Proto *f) { |
36 | if (!f->marked) { | 38 | if (!f->marked) { |
37 | int i; | 39 | int i; |
@@ -51,9 +53,25 @@ static void protomark (Proto *f) { | |||
51 | 53 | ||
52 | 54 | ||
53 | static void markclosure (GCState *st, Closure *cl) { | 55 | static void markclosure (GCState *st, Closure *cl) { |
54 | if (!ismarked(cl)) { | 56 | if (!cl->c.marked) { |
55 | cl->mark = st->cmark; /* chain it for later traversal */ | 57 | cl->c.marked = 1; |
56 | st->cmark = cl; | 58 | if (cl->c.isC) { |
59 | int i; | ||
60 | for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ | ||
61 | markobject(st, &cl->c.upvalue[i]); | ||
62 | } | ||
63 | else { | ||
64 | int i; | ||
65 | lua_assert(cl->l.nupvalues == cl->l.p->nupvalues); | ||
66 | protomark(cl->l.p); | ||
67 | for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ | ||
68 | UpVal *u = cl->l.upvals[i].heap; | ||
69 | if (u && !u->marked) { | ||
70 | u->marked = 1; | ||
71 | markobject(st, &u->val); | ||
72 | } | ||
73 | } | ||
74 | } | ||
57 | } | 75 | } |
58 | } | 76 | } |
59 | 77 | ||
@@ -120,29 +138,6 @@ static void marktagmethods (global_State *G, GCState *st) { | |||
120 | } | 138 | } |
121 | 139 | ||
122 | 140 | ||
123 | static void traverseclosure (GCState *st, Closure *cl) { | ||
124 | if (cl->isC) { | ||
125 | int i; | ||
126 | for (i=0; i<cl->nupvalues; i++) /* mark its upvalues */ | ||
127 | markobject(st, &cl->u.c.upvalue[i]); | ||
128 | } | ||
129 | else { | ||
130 | int i; | ||
131 | lua_assert(cl->nupvalues == cl->u.l.p->nupvalues); | ||
132 | protomark(cl->u.l.p); | ||
133 | for (i=0; i<cl->nupvalues; i++) { /* mark its upvalues */ | ||
134 | if (luaF_isclosed(cl, i)) { | ||
135 | UpVal *u = cast(UpVal *, cl->u.l.upvals[i]); | ||
136 | if (!u->marked) { | ||
137 | u->marked = 1; | ||
138 | markobject(st, &u->val); | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | |||
145 | |||
146 | static void removekey (Node *n) { | 141 | static void removekey (Node *n) { |
147 | lua_assert(ttype(val(n)) == LUA_TNIL); | 142 | lua_assert(ttype(val(n)) == LUA_TNIL); |
148 | if (ttype(key(n)) != LUA_TNIL && ttype(key(n)) != LUA_TNUMBER) | 143 | if (ttype(key(n)) != LUA_TNIL && ttype(key(n)) != LUA_TNUMBER) |
@@ -172,25 +167,16 @@ static void traversetable (GCState *st, Hash *h) { | |||
172 | 167 | ||
173 | static void markall (lua_State *L) { | 168 | static void markall (lua_State *L) { |
174 | GCState st; | 169 | GCState st; |
175 | st.cmark = NULL; | ||
176 | st.tmark = NULL; | 170 | st.tmark = NULL; |
177 | marktagmethods(G(L), &st); /* mark tag methods */ | 171 | marktagmethods(G(L), &st); /* mark tag methods */ |
178 | markstacks(L, &st); /* mark all stacks */ | 172 | markstacks(L, &st); /* mark all stacks */ |
179 | marktable(&st, G(L)->type2tag); | 173 | marktable(&st, G(L)->type2tag); |
180 | marktable(&st, G(L)->registry); | 174 | marktable(&st, G(L)->registry); |
181 | marktable(&st, G(L)->weakregistry); | 175 | marktable(&st, G(L)->weakregistry); |
182 | for (;;) { /* mark tables and closures */ | 176 | while (st.tmark) { /* mark tables */ |
183 | if (st.cmark) { | 177 | Hash *h = st.tmark; /* get first table from list */ |
184 | Closure *cl = st.cmark; /* get first closure from list */ | 178 | st.tmark = h->mark; /* remove it from list */ |
185 | st.cmark = cl->mark; /* remove it from list */ | 179 | traversetable(&st, h); |
186 | traverseclosure(&st, cl); | ||
187 | } | ||
188 | else if (st.tmark) { | ||
189 | Hash *h = st.tmark; /* get first table from list */ | ||
190 | st.tmark = h->mark; /* remove it from list */ | ||
191 | traversetable(&st, h); | ||
192 | } | ||
193 | else break; /* nothing else to mark */ | ||
194 | } | 180 | } |
195 | } | 181 | } |
196 | 182 | ||
@@ -204,7 +190,7 @@ static int hasmark (const TObject *o) { | |||
204 | case LUA_TTABLE: | 190 | case LUA_TTABLE: |
205 | return ismarked(hvalue(o)); | 191 | return ismarked(hvalue(o)); |
206 | case LUA_TFUNCTION: | 192 | case LUA_TFUNCTION: |
207 | return ismarked(clvalue(o)); | 193 | return clvalue(o)->c.marked; |
208 | default: /* number, nil */ | 194 | default: /* number, nil */ |
209 | return 1; | 195 | return 1; |
210 | } | 196 | } |
@@ -252,12 +238,12 @@ static void collectproto (lua_State *L) { | |||
252 | static void collectclosure (lua_State *L, Closure **p) { | 238 | static void collectclosure (lua_State *L, Closure **p) { |
253 | Closure *curr; | 239 | Closure *curr; |
254 | while ((curr = *p) != NULL) { | 240 | while ((curr = *p) != NULL) { |
255 | if (ismarked(curr)) { | 241 | if (curr->c.marked) { |
256 | curr->mark = curr; /* unmark */ | 242 | curr->c.marked = 0; |
257 | p = &curr->next; | 243 | p = &curr->c.next; |
258 | } | 244 | } |
259 | else { | 245 | else { |
260 | *p = curr->next; | 246 | *p = curr->c.next; |
261 | luaF_freeclosure(L, curr); | 247 | luaF_freeclosure(L, curr); |
262 | } | 248 | } |
263 | } | 249 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llimits.h,v 1.31 2001/08/27 15:16:28 roberto Exp $ | 2 | ** $Id: llimits.h,v 1.32 2001/09/07 17:39:10 roberto Exp $ |
3 | ** Limits, basic types, and some other `installation-dependent' definitions | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -51,9 +51,6 @@ typedef unsigned long lu_mem; | |||
51 | /* an integer big enough to count the number of strings in use */ | 51 | /* an integer big enough to count the number of strings in use */ |
52 | typedef long ls_nstr; | 52 | typedef long ls_nstr; |
53 | 53 | ||
54 | /* a bitmap with one bit for each upvalue used by a function */ | ||
55 | typedef unsigned long ls_bitup; | ||
56 | |||
57 | 54 | ||
58 | /* chars used as small naturals (so that `char' is reserved for characteres) */ | 55 | /* chars used as small naturals (so that `char' is reserved for characteres) */ |
59 | typedef unsigned char lu_byte; | 56 | typedef unsigned char lu_byte; |
@@ -109,9 +106,9 @@ typedef unsigned long Instruction; | |||
109 | #endif | 106 | #endif |
110 | 107 | ||
111 | 108 | ||
112 | /* maximum number of upvalues */ | 109 | /* maximum number of upvalues per function */ |
113 | #ifndef MAXUPVALUES | 110 | #ifndef MAXUPVALUES |
114 | #define MAXUPVALUES (sizeof(ls_bitup)*CHAR_BIT) | 111 | #define MAXUPVALUES 32 |
115 | #endif | 112 | #endif |
116 | 113 | ||
117 | 114 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 1.112 2001/09/07 17:39:10 roberto Exp $ | 2 | ** $Id: lobject.h,v 1.113 2001/09/25 17:08:46 roberto Exp $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -38,7 +38,7 @@ | |||
38 | typedef union { | 38 | typedef union { |
39 | union TString *ts; | 39 | union TString *ts; |
40 | union Udata *u; | 40 | union Udata *u; |
41 | struct Closure *cl; | 41 | union Closure *cl; |
42 | struct Hash *h; | 42 | struct Hash *h; |
43 | struct UpVal *v; | 43 | struct UpVal *v; |
44 | lua_Number n; /* LUA_TNUMBER */ | 44 | lua_Number n; /* LUA_TNUMBER */ |
@@ -177,26 +177,38 @@ typedef struct UpVal { | |||
177 | /* | 177 | /* |
178 | ** Closures | 178 | ** Closures |
179 | */ | 179 | */ |
180 | typedef struct Closure { | 180 | |
181 | short isC; /* 0 for Lua functions, 1 for C functions */ | 181 | typedef struct CClosure { |
182 | short nupvalues; | 182 | lu_byte isC; /* 0 for Lua functions, 1 for C functions */ |
183 | struct Closure *next; | 183 | lu_byte nupvalues; |
184 | struct Closure *mark; /* marked closures (point to itself when not marked) */ | 184 | lu_byte marked; |
185 | union { | 185 | union Closure *next; |
186 | struct { /* C functions */ | 186 | lua_CFunction f; |
187 | lua_CFunction f; | 187 | TObject upvalue[1]; |
188 | TObject upvalue[1]; | 188 | } CClosure; |
189 | } c; | 189 | |
190 | struct { /* Lua functions */ | 190 | |
191 | struct Proto *p; | 191 | typedef struct LClosureEntry { |
192 | ls_bitup isopen; /* bitmap: bit==1 when upvals point to the stack */ | 192 | TObject *val; |
193 | TObject *upvals[1]; /* may point to the stack or to an UpVal */ | 193 | UpVal *heap; /* NULL when upvalue is still in the stack */ |
194 | } l; | 194 | } LClosureEntry; |
195 | } u; | 195 | |
196 | typedef struct LClosure { | ||
197 | lu_byte isC; | ||
198 | lu_byte nupvalues; | ||
199 | lu_byte marked; | ||
200 | union Closure *next; /* first four fields must be equal to CClosure!! */ | ||
201 | struct Proto *p; | ||
202 | LClosureEntry upvals[1]; | ||
203 | } LClosure; | ||
204 | |||
205 | typedef union Closure { | ||
206 | CClosure c; | ||
207 | LClosure l; | ||
196 | } Closure; | 208 | } Closure; |
197 | 209 | ||
198 | 210 | ||
199 | #define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC) | 211 | #define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) |
200 | 212 | ||
201 | 213 | ||
202 | 214 | ||
@@ -223,9 +235,7 @@ typedef struct Hash { | |||
223 | } Hash; | 235 | } Hash; |
224 | 236 | ||
225 | 237 | ||
226 | /* unmarked tables and closures are represented by pointing `mark' to | 238 | /* unmarked tables are represented by pointing `mark' to themselves */ |
227 | ** themselves | ||
228 | */ | ||
229 | #define ismarked(x) ((x)->mark != (x)) | 239 | #define ismarked(x) ((x)->mark != (x)) |
230 | 240 | ||
231 | 241 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 1.88 2001/07/12 18:11:58 roberto Exp $ | 2 | ** $Id: ltests.c,v 1.91 2001/09/07 17:39:10 roberto Exp $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -165,7 +165,7 @@ static int listcode (lua_State *L) { | |||
165 | Proto *p; | 165 | Proto *p; |
166 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), | 166 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), |
167 | 1, l_s("Lua function expected")); | 167 | 1, l_s("Lua function expected")); |
168 | p = clvalue(luaA_index(L, 1))->u.l.p; | 168 | p = clvalue(luaA_index(L, 1))->l.p; |
169 | lua_newtable(L); | 169 | lua_newtable(L); |
170 | setnameval(L, l_s("maxstack"), p->maxstacksize); | 170 | setnameval(L, l_s("maxstack"), p->maxstacksize); |
171 | setnameval(L, l_s("numparams"), p->numparams); | 171 | setnameval(L, l_s("numparams"), p->numparams); |
@@ -184,7 +184,7 @@ static int listk (lua_State *L) { | |||
184 | int i; | 184 | int i; |
185 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), | 185 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), |
186 | 1, l_s("Lua function expected")); | 186 | 1, l_s("Lua function expected")); |
187 | p = clvalue(luaA_index(L, 1))->u.l.p; | 187 | p = clvalue(luaA_index(L, 1))->l.p; |
188 | lua_newtable(L); | 188 | lua_newtable(L); |
189 | for (i=0; i<p->sizek; i++) { | 189 | for (i=0; i<p->sizek; i++) { |
190 | lua_pushnumber(L, i+1); | 190 | lua_pushnumber(L, i+1); |
@@ -202,7 +202,7 @@ static int listlocals (lua_State *L) { | |||
202 | const l_char *name; | 202 | const l_char *name; |
203 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), | 203 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), |
204 | 1, l_s("Lua function expected")); | 204 | 1, l_s("Lua function expected")); |
205 | p = clvalue(luaA_index(L, 1))->u.l.p; | 205 | p = clvalue(luaA_index(L, 1))->l.p; |
206 | while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) | 206 | while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) |
207 | lua_pushstring(L, name); | 207 | lua_pushstring(L, name); |
208 | return i-1; | 208 | return i-1; |
@@ -64,8 +64,8 @@ int luaV_tostring (lua_State *L, TObject *obj) { | |||
64 | 64 | ||
65 | static void traceexec (lua_State *L, lua_Hook linehook) { | 65 | static void traceexec (lua_State *L, lua_Hook linehook) { |
66 | CallInfo *ci = L->ci; | 66 | CallInfo *ci = L->ci; |
67 | int *lineinfo = ci_func(ci)->u.l.p->lineinfo; | 67 | int *lineinfo = ci_func(ci)->l.p->lineinfo; |
68 | int pc = (*ci->pc - ci_func(ci)->u.l.p->code) - 1; | 68 | int pc = (*ci->pc - ci_func(ci)->l.p->code) - 1; |
69 | int newline; | 69 | int newline; |
70 | if (pc == 0) { /* may be first time? */ | 70 | if (pc == 0) { /* may be first time? */ |
71 | ci->line = 1; | 71 | ci->line = 1; |
@@ -351,8 +351,8 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | |||
351 | ** Executes the given Lua function. Parameters are between [base,top). | 351 | ** Executes the given Lua function. Parameters are between [base,top). |
352 | ** Returns n such that the the results are between [n,top). | 352 | ** Returns n such that the the results are between [n,top). |
353 | */ | 353 | */ |
354 | StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | 354 | StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { |
355 | const Proto *const tf = cl->u.l.p; | 355 | const Proto *const tf = cl->p; |
356 | const Instruction *pc; | 356 | const Instruction *pc; |
357 | lua_Hook linehook; | 357 | lua_Hook linehook; |
358 | if (tf->is_vararg) /* varargs? */ | 358 | if (tf->is_vararg) /* varargs? */ |
@@ -391,8 +391,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
391 | } | 391 | } |
392 | case OP_GETUPVAL: { | 392 | case OP_GETUPVAL: { |
393 | int b = GETARG_B(i); | 393 | int b = GETARG_B(i); |
394 | lua_assert(luaF_isclosed(cl, b) || cl->u.l.upvals[b] < base); | 394 | lua_assert(cl->upvals[b].heap || cl->upvals[b].val < base); |
395 | setobj(ra, cl->u.l.upvals[b]); | 395 | setobj(ra, cl->upvals[b].val); |
396 | break; | 396 | break; |
397 | } | 397 | } |
398 | case OP_GETGLOBAL: { | 398 | case OP_GETGLOBAL: { |
@@ -411,8 +411,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
411 | } | 411 | } |
412 | case OP_SETUPVAL: { | 412 | case OP_SETUPVAL: { |
413 | int b = GETARG_B(i); | 413 | int b = GETARG_B(i); |
414 | lua_assert(luaF_isclosed(cl, b) || cl->u.l.upvals[b] < base); | 414 | lua_assert(cl->upvals[b].heap || cl->upvals[b].val < base); |
415 | setobj(cl->u.l.upvals[b], ra); | 415 | setobj(cl->upvals[b].val, ra); |
416 | break; | 416 | break; |
417 | } | 417 | } |
418 | case OP_SETTABLE: { | 418 | case OP_SETTABLE: { |
@@ -644,18 +644,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
644 | p = tf->p[GETARG_Bc(i)]; | 644 | p = tf->p[GETARG_Bc(i)]; |
645 | nup = p->nupvalues; | 645 | nup = p->nupvalues; |
646 | ncl = luaF_newLclosure(L, nup); | 646 | ncl = luaF_newLclosure(L, nup); |
647 | ncl->u.l.p = p; | 647 | ncl->l.p = p; |
648 | for (j=0; j<nup; j++, pc++) { | 648 | for (j=0; j<nup; j++, pc++) { |
649 | if (GET_OPCODE(*pc) == OP_GETUPVAL) { | 649 | if (GET_OPCODE(*pc) == OP_GETUPVAL) |
650 | int n = GETARG_B(*pc); | 650 | ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)]; |
651 | if (!luaF_isclosed(cl, n)) | ||
652 | luaF_openentry(ncl, j); | ||
653 | ncl->u.l.upvals[j] = cl->u.l.upvals[n]; | ||
654 | } | ||
655 | else { | 651 | else { |
656 | lua_assert(GET_OPCODE(*pc) == OP_MOVE); | 652 | lua_assert(GET_OPCODE(*pc) == OP_MOVE); |
657 | luaF_openentry(ncl, j); | 653 | ncl->l.upvals[j].heap = NULL; |
658 | ncl->u.l.upvals[j] = base + GETARG_B(*pc); | 654 | ncl->l.upvals[j].val = base + GETARG_B(*pc); |
659 | } | 655 | } |
660 | } | 656 | } |
661 | luaF_LConlist(L, ncl); | 657 | luaF_LConlist(L, ncl); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.h,v 1.30 2001/06/05 18:17:01 roberto Exp $ | 2 | ** $Id: lvm.h,v 1.31 2001/09/07 17:39:10 roberto Exp $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -22,7 +22,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res); | |||
22 | void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val); | 22 | void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val); |
23 | void luaV_getglobal (lua_State *L, TString *s, StkId res); | 23 | void luaV_getglobal (lua_State *L, TString *s, StkId res); |
24 | void luaV_setglobal (lua_State *L, TString *s, StkId val); | 24 | void luaV_setglobal (lua_State *L, TString *s, StkId val); |
25 | StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); | 25 | StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base); |
26 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); | 26 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); |
27 | void luaV_strconc (lua_State *L, int total, StkId top); | 27 | void luaV_strconc (lua_State *L, int total, StkId top); |
28 | 28 | ||