aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c11
-rw-r--r--lcode.c11
-rw-r--r--ldebug.c28
-rw-r--r--ldo.c28
-rw-r--r--lfunc.c100
-rw-r--r--lfunc.h11
-rw-r--r--lgc.c73
-rw-r--r--llimits.h7
-rw-r--r--lobject.h44
-rw-r--r--lopcodes.c8
-rw-r--r--lopcodes.h4
-rw-r--r--lparser.c147
-rw-r--r--lparser.h20
-rw-r--r--lstate.c6
-rw-r--r--lstate.h12
-rw-r--r--ltests.c6
-rw-r--r--lvm.c79
-rw-r--r--lvm.h4
18 files changed, 412 insertions, 187 deletions
diff --git a/lapi.c b/lapi.c
index 7c2f5d52..5c54c60c 100644
--- a/lapi.c
+++ b/lapi.c
@@ -248,7 +248,7 @@ LUA_API size_t lua_strlen (lua_State *L, int index) {
248 248
249LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) { 249LUA_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)->f.c; 251 return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->u.c.f;
252} 252}
253 253
254 254
@@ -310,9 +310,16 @@ LUA_API void lua_pushstring (lua_State *L, const l_char *s) {
310 310
311 311
312LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { 312LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
313 Closure *cl;
313 lua_lock(L); 314 lua_lock(L);
314 api_checknelems(L, n); 315 api_checknelems(L, n);
315 luaV_Cclosure(L, fn, n); 316 cl = luaF_newCclosure(L, n);
317 cl->u.c.f = fn;
318 L->top -= n;
319 while (n--)
320 setobj(&cl->u.c.upvalue[n], L->top+n);
321 setclvalue(L->top, cl);
322 incr_top;
316 lua_unlock(L); 323 lua_unlock(L);
317} 324}
318 325
diff --git a/lcode.c b/lcode.c
index d1b5355a..de26964b 100644
--- a/lcode.c
+++ b/lcode.c
@@ -273,6 +273,11 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
273 e->k = VNONRELOC; 273 e->k = VNONRELOC;
274 break; 274 break;
275 } 275 }
276 case VUPVAL: {
277 e->u.i.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.i.info, 0);
278 e->k = VRELOCABLE;
279 break;
280 }
276 case VGLOBAL: { 281 case VGLOBAL: {
277 e->u.i.info = luaK_codeABc(fs, OP_GETGLOBAL, 0, e->u.i.info); 282 e->u.i.info = luaK_codeABc(fs, OP_GETGLOBAL, 0, e->u.i.info);
278 e->k = VRELOCABLE; 283 e->k = VRELOCABLE;
@@ -437,6 +442,12 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
437 luaK_exp2reg(fs, exp, var->u.i.info); 442 luaK_exp2reg(fs, exp, var->u.i.info);
438 break; 443 break;
439 } 444 }
445 case VUPVAL: {
446 int e = luaK_exp2anyreg(fs, exp);
447 freereg(fs, e);
448 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.i.info, 0);
449 break;
450 }
440 case VGLOBAL: { 451 case VGLOBAL: {
441 int e = luaK_exp2anyreg(fs, exp); 452 int e = luaK_exp2anyreg(fs, exp);
442 freereg(fs, e); 453 freereg(fs, e);
diff --git a/ldebug.c b/ldebug.c
index 1f961ec1..57215028 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.86 2001/06/28 19:58:57 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.87 2001/07/03 17:01:34 roberto Exp $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -117,7 +117,7 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
117static int currentpc (CallInfo *ci) { 117static 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)->f.l->code) - 1; 120 return (*ci->pc - ci_func(ci)->u.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)->f.l->lineinfo; 130 int *lineinfo = ci_func(ci)->u.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
137static Proto *getluaproto (CallInfo *ci) { 137static Proto *getluaproto (CallInfo *ci) {
138 return (isLmark(ci) ? ci_func(ci)->f.l : NULL); 138 return (isLmark(ci) ? ci_func(ci)->u.l.p : NULL);
139} 139}
140 140
141 141
@@ -199,7 +199,7 @@ static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
199 ar->what = l_s("C"); 199 ar->what = l_s("C");
200 } 200 }
201 else 201 else
202 infoLproto(ar, cl->f.l); 202 infoLproto(ar, cl->u.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");
@@ -323,14 +323,15 @@ static int precheck (const Proto *pt) {
323} 323}
324 324
325 325
326static int checkopenop (Instruction i) { 326static int checkopenop (const Proto *pt, int pc) {
327 OpCode op = GET_OPCODE(i); 327 Instruction i = pt->code[pc+1];
328 switch (op) { 328 switch (GET_OPCODE(i)) {
329 case OP_CALL: 329 case OP_CALL:
330 case OP_RETURN: { 330 case OP_RETURN: {
331 check(GETARG_B(i) == NO_REG); 331 check(GETARG_B(i) == NO_REG);
332 return 1; 332 return 1;
333 } 333 }
334 case OP_CLOSE: return checkopenop(pt, pc+1);
334 case OP_SETLISTO: return 1; 335 case OP_SETLISTO: return 1;
335 default: return 0; /* invalid instruction after an open call */ 336 default: return 0; /* invalid instruction after an open call */
336 } 337 }
@@ -382,7 +383,8 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
382 last = pc; /* set registers from `a' to `b' */ 383 last = pc; /* set registers from `a' to `b' */
383 break; 384 break;
384 } 385 }
385 case OP_LOADUPVAL: { 386 case OP_GETUPVAL:
387 case OP_SETUPVAL: {
386 check(b < pt->nupvalues); 388 check(b < pt->nupvalues);
387 break; 389 break;
388 } 390 }
@@ -419,7 +421,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
419 checkreg(pt, a+b); 421 checkreg(pt, a+b);
420 } 422 }
421 if (c == NO_REG) { 423 if (c == NO_REG) {
422 check(checkopenop(pt->code[pc+1])); 424 check(checkopenop(pt, pc));
423 } 425 }
424 else if (c != 0) 426 else if (c != 0)
425 checkreg(pt, a+c-1); 427 checkreg(pt, a+c-1);
@@ -452,7 +454,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
452 } 454 }
453 case OP_CLOSURE: { 455 case OP_CLOSURE: {
454 check(b < pt->sizep); 456 check(b < pt->sizep);
455 checkreg(pt, a + pt->p[b]->nupvalues - 1); 457 check(pc + pt->p[b]->nupvalues < pt->sizecode);
456 break; 458 break;
457 } 459 }
458 default: break; 460 default: break;
@@ -472,7 +474,7 @@ int luaG_checkcode (const Proto *pt) {
472static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) { 474static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
473 CallInfo *ci = ci_stack(L, obj); 475 CallInfo *ci = ci_stack(L, obj);
474 if (isLmark(ci)) { /* an active Lua function? */ 476 if (isLmark(ci)) { /* an active Lua function? */
475 Proto *p = ci_func(ci)->f.l; 477 Proto *p = ci_func(ci)->u.l.p;
476 int pc = currentpc(ci); 478 int pc = currentpc(ci);
477 int stackpos = obj - ci->base; 479 int stackpos = obj - ci->base;
478 Instruction i; 480 Instruction i;
@@ -516,7 +518,7 @@ static const l_char *getfuncname (lua_State *L, CallInfo *ci,
516 if (ci == &L->basefunc || !isLmark(ci)) 518 if (ci == &L->basefunc || !isLmark(ci))
517 return NULL; /* not an active Lua function */ 519 return NULL; /* not an active Lua function */
518 else { 520 else {
519 Proto *p = ci_func(ci)->f.l; 521 Proto *p = ci_func(ci)->u.l.p;
520 int pc = currentpc(ci); 522 int pc = currentpc(ci);
521 Instruction i; 523 Instruction i;
522 if (pc == -1) return NULL; /* function is not activated */ 524 if (pc == -1) return NULL; /* function is not activated */
diff --git a/ldo.c b/ldo.c
index 92953d92..36e9cf7e 100644
--- a/ldo.c
+++ b/ldo.c
@@ -15,6 +15,7 @@
15 15
16#include "ldebug.h" 16#include "ldebug.h"
17#include "ldo.h" 17#include "ldo.h"
18#include "lfunc.h"
18#include "lgc.h" 19#include "lgc.h"
19#include "lmem.h" 20#include "lmem.h"
20#include "lobject.h" 21#include "lobject.h"
@@ -122,9 +123,9 @@ static StkId callCclosure (lua_State *L, const struct Closure *cl) {
122 int n; 123 int n;
123 luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */ 124 luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */
124 for (n=0; n<nup; n++) /* copy upvalues as extra arguments */ 125 for (n=0; n<nup; n++) /* copy upvalues as extra arguments */
125 setobj(L->top++, &cl->upvalue[n]); 126 setobj(L->top++, &cl->u.c.upvalue[n]);
126 lua_unlock(L); 127 lua_unlock(L);
127 n = (*cl->f.c)(L); /* do the actual call */ 128 n = (*cl->u.c.f)(L); /* do the actual call */
128 lua_lock(L); 129 lua_lock(L);
129 return L->top - n; /* return index of first result */ 130 return L->top - n; /* return index of first result */
130} 131}
@@ -209,7 +210,12 @@ struct SParser { /* data to `f_parser' */
209static void f_parser (lua_State *L, void *ud) { 210static void f_parser (lua_State *L, void *ud) {
210 struct SParser *p = cast(struct SParser *, ud); 211 struct SParser *p = cast(struct SParser *, ud);
211 Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z); 212 Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z);
212 luaV_Lclosure(L, tf, 0); 213 Closure *cl = luaF_newLclosure(L, 0);
214 cl->u.l.p = tf;
215 luaF_LConlist(L, cl);
216 setclvalue(L->top, cl);
217 incr_top;
218
213} 219}
214 220
215 221
@@ -286,6 +292,9 @@ struct lua_longjmp {
286 jmp_buf b; 292 jmp_buf b;
287 struct lua_longjmp *previous; 293 struct lua_longjmp *previous;
288 volatile int status; /* error code */ 294 volatile int status; /* error code */
295 CallInfo *ci; /* call info of active function that set protection */
296 StkId top; /* top stack when protection was set */
297 int allowhooks; /* `allowhook' state when protection was set */
289}; 298};
290 299
291 300
@@ -325,19 +334,20 @@ void luaD_breakrun (lua_State *L, int errcode) {
325 334
326 335
327int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { 336int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
328 CallInfo *oldci = L->ci;
329 StkId oldtop = L->top;
330 struct lua_longjmp lj; 337 struct lua_longjmp lj;
331 int allowhooks = L->allowhooks; 338 lj.ci = L->ci;
339 lj.top = L->top;
340 lj.allowhooks = L->allowhooks;
332 lj.status = 0; 341 lj.status = 0;
333 lj.previous = L->errorJmp; /* chain new error handler */ 342 lj.previous = L->errorJmp; /* chain new error handler */
334 L->errorJmp = &lj; 343 L->errorJmp = &lj;
335 if (setjmp(lj.b) == 0) 344 if (setjmp(lj.b) == 0)
336 (*f)(L, ud); 345 (*f)(L, ud);
337 else { /* an error occurred: restore the state */ 346 else { /* an error occurred: restore the state */
338 L->allowhooks = allowhooks; 347 luaF_close(L, lj.top); /* close eventual pending closures */
339 L->ci = oldci; 348 L->ci = lj.ci;
340 L->top = oldtop; 349 L->top = lj.top;
350 L->allowhooks = lj.allowhooks;
341 restore_stack_limit(L); 351 restore_stack_limit(L);
342 } 352 }
343 L->errorJmp = lj.previous; /* restore old error handler */ 353 L->errorJmp = lj.previous; /* restore old error handler */
diff --git a/lfunc.c b/lfunc.c
index cece5a1b..8c197499 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -12,15 +12,20 @@
12 12
13#include "lfunc.h" 13#include "lfunc.h"
14#include "lmem.h" 14#include "lmem.h"
15#include "lobject.h"
15#include "lstate.h" 16#include "lstate.h"
16 17
17 18
18#define sizeclosure(n) (cast(int, sizeof(Closure)) + \ 19#define sizeCclosure(n) (cast(int, sizeof(Closure)) + \
19 cast(int, sizeof(TObject)*((n)-1))) 20 cast(int, sizeof(TObject)*((n)-1)))
20 21
22#define sizeLclosure(n) (cast(int, sizeof(Closure)) + \
23 cast(int, sizeof(TObject *)*((n)-1)))
21 24
22Closure *luaF_newclosure (lua_State *L, int nelems) { 25
23 Closure *c = cast(Closure *, luaM_malloc(L, sizeclosure(nelems))); 26Closure *luaF_newCclosure (lua_State *L, int nelems) {
27 Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
28 c->isC = 1;
24 c->next = G(L)->rootcl; 29 c->next = G(L)->rootcl;
25 G(L)->rootcl = c; 30 G(L)->rootcl = c;
26 c->mark = c; 31 c->mark = c;
@@ -29,6 +34,90 @@ Closure *luaF_newclosure (lua_State *L, int nelems) {
29} 34}
30 35
31 36
37Closure *luaF_newLclosure (lua_State *L, int nelems) {
38 Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
39 c->isC = 0;
40 c->mark = c;
41 c->u.l.isopen = 0;
42 c->nupvalues = nelems;
43 return c;
44}
45
46
47/*
48** returns the open pointer in a closure that points higher into the stack
49*/
50static StkId uppoint (Closure *cl) {
51 StkId lp = NULL;
52 int i;
53 lua_assert(cl->u.l.isopen);
54 for (i=0; i<cl->nupvalues; i++) {
55 if (!luaF_isclosed(cl, i))
56 if (lp == NULL || cl->u.l.upvals[i] > lp)
57 lp = cl->u.l.upvals[i];
58 }
59 lua_assert(lp != NULL);
60 return lp;
61}
62
63
64void luaF_LConlist (lua_State *L, Closure *cl) {
65 lua_assert(!cl->isC);
66 if (cl->u.l.isopen == 0) { /* no more open entries? */
67 cl->next = G(L)->rootcl; /* insert in final list */
68 G(L)->rootcl = cl;
69 }
70 else { /* insert in list of open closures, ordered by decreasing uppoints */
71 StkId cli = uppoint(cl);
72 Closure **p = &L->opencl;
73 while (*p != NULL && uppoint(*p) > cli) p = &(*p)->next;
74 cl->next = *p;
75 *p = cl;
76 }
77}
78
79
80static int closeCl (lua_State *L, Closure *cl, StkId level) {
81 int got = 0; /* flag: 1 if some pointer in the closure was corrected */
82 int i;
83 for (i=0; i<cl->nupvalues; i++) {
84 StkId var;
85 if (!luaF_isclosed(cl, i) && (var=cl->u.l.upvals[i]) >= level) {
86 if (ttype(var) != LUA_TUPVAL) {
87 UpVal *v = luaM_new(L, UpVal);
88 v->val = *var;
89 v->marked = 0;
90 v->next = G(L)->rootupval;
91 G(L)->rootupval = v;
92 setupvalue(var, v);
93 }
94 cl->u.l.upvals[i] = cast(TObject *, vvalue(var));
95 luaF_closeentry(cl, i);
96 got = 1;
97 }
98 }
99 return got;
100}
101
102
103void luaF_close (lua_State *L, StkId level) {
104 Closure *affected = NULL; /* closures with open pointers >= level */
105 Closure *cl;
106 while ((cl=L->opencl) != NULL) {
107 if (!closeCl(L, cl, level)) break;
108 /* some pointer in `cl' changed; will re-insert it in original list */
109 L->opencl = cl->next; /* remove from original list */
110 cl->next = affected;
111 affected = cl; /* insert in affected list */
112 }
113 /* re-insert all affected closures in original list */
114 while ((cl=affected) != NULL) {
115 affected = cl->next;
116 luaF_LConlist(L, cl);
117 }
118}
119
120
32Proto *luaF_newproto (lua_State *L) { 121Proto *luaF_newproto (lua_State *L) {
33 Proto *f = luaM_new(L, Proto); 122 Proto *f = luaM_new(L, Proto);
34 f->k = NULL; 123 f->k = NULL;
@@ -60,12 +149,13 @@ void luaF_freeproto (lua_State *L, Proto *f) {
60 luaM_freearray(L, f->k, f->sizek, TObject); 149 luaM_freearray(L, f->k, f->sizek, TObject);
61 luaM_freearray(L, f->p, f->sizep, Proto *); 150 luaM_freearray(L, f->p, f->sizep, Proto *);
62 luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); 151 luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
63 luaM_freelem(L, f, Proto); 152 luaM_freelem(L, f);
64} 153}
65 154
66 155
67void luaF_freeclosure (lua_State *L, Closure *c) { 156void luaF_freeclosure (lua_State *L, Closure *c) {
68 luaM_free(L, c, sizeclosure(c->nupvalues)); 157 int size = (c->isC) ? sizeCclosure(c->nupvalues) : sizeLclosure(c->nupvalues);
158 luaM_free(L, c, size);
69} 159}
70 160
71 161
diff --git a/lfunc.h b/lfunc.h
index e5bcdca1..385767a2 100644
--- a/lfunc.h
+++ b/lfunc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.h,v 1.14 2000/12/28 12:55:41 roberto Exp roberto $ 2** $Id: lfunc.h,v 1.15 2001/02/23 17:17:25 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,9 +11,16 @@
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
14 18
15Proto *luaF_newproto (lua_State *L); 19Proto *luaF_newproto (lua_State *L);
16Closure *luaF_newclosure (lua_State *L, int nelems); 20Closure *luaF_newCclosure (lua_State *L, int nelems);
21Closure *luaF_newLclosure (lua_State *L, int nelems);
22void luaF_LConlist (lua_State *L, Closure *cl);
23void luaF_close (lua_State *L, StkId level);
17void luaF_freeproto (lua_State *L, Proto *f); 24void luaF_freeproto (lua_State *L, Proto *f);
18void luaF_freeclosure (lua_State *L, Closure *c); 25void luaF_freeclosure (lua_State *L, Closure *c);
19 26
diff --git a/lgc.c b/lgc.c
index 17373f9a..20d97cf2 100644
--- a/lgc.c
+++ b/lgc.c
@@ -7,6 +7,7 @@
7#define LUA_PRIVATE 7#define LUA_PRIVATE
8#include "lua.h" 8#include "lua.h"
9 9
10#include "ldebug.h"
10#include "ldo.h" 11#include "ldo.h"
11#include "lfunc.h" 12#include "lfunc.h"
12#include "lgc.h" 13#include "lgc.h"
@@ -45,15 +46,12 @@ static void protomark (Proto *f) {
45 for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */ 46 for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
46 strmark(f->locvars[i].varname); 47 strmark(f->locvars[i].varname);
47 } 48 }
49 lua_assert(luaG_checkcode(f));
48} 50}
49 51
50 52
51static void markclosure (GCState *st, Closure *cl) { 53static void markclosure (GCState *st, Closure *cl) {
52 if (!ismarked(cl)) { 54 if (!ismarked(cl)) {
53 if (!cl->isC) {
54 lua_assert(cl->nupvalues == cl->f.l->nupvalues);
55 protomark(cl->f.l);
56 }
57 cl->mark = st->cmark; /* chain it for later traversal */ 55 cl->mark = st->cmark; /* chain it for later traversal */
58 st->cmark = cl; 56 st->cmark = cl;
59 } 57 }
@@ -84,7 +82,10 @@ static void markobject (GCState *st, TObject *o) {
84 marktable(st, hvalue(o)); 82 marktable(st, hvalue(o));
85 break; 83 break;
86 } 84 }
87 default: break; /* numbers, etc */ 85 default: {
86 lua_assert(0 <= ttype(o) && ttype(o) <= LUA_TUPVAL);
87 break;
88 }
88 } 89 }
89} 90}
90 91
@@ -119,10 +120,26 @@ static void marktagmethods (global_State *G, GCState *st) {
119} 120}
120 121
121 122
122static void traverseclosure (GCState *st, Closure *f) { 123static void traverseclosure (GCState *st, Closure *cl) {
123 int i; 124 if (cl->isC) {
124 for (i=0; i<f->nupvalues; i++) /* mark its upvalues */ 125 int i;
125 markobject(st, &f->upvalue[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 }
126} 143}
127 144
128 145
@@ -164,9 +181,9 @@ static void markall (lua_State *L) {
164 marktable(&st, G(L)->weakregistry); 181 marktable(&st, G(L)->weakregistry);
165 for (;;) { /* mark tables and closures */ 182 for (;;) { /* mark tables and closures */
166 if (st.cmark) { 183 if (st.cmark) {
167 Closure *f = st.cmark; /* get first closure from list */ 184 Closure *cl = st.cmark; /* get first closure from list */
168 st.cmark = f->mark; /* remove it from list */ 185 st.cmark = cl->mark; /* remove it from list */
169 traverseclosure(&st, f); 186 traverseclosure(&st, cl);
170 } 187 }
171 else if (st.tmark) { 188 else if (st.tmark) {
172 Hash *h = st.tmark; /* get first table from list */ 189 Hash *h = st.tmark; /* get first table from list */
@@ -232,8 +249,7 @@ static void collectproto (lua_State *L) {
232} 249}
233 250
234 251
235static void collectclosure (lua_State *L) { 252static void collectclosure (lua_State *L, Closure **p) {
236 Closure **p = &G(L)->rootcl;
237 Closure *curr; 253 Closure *curr;
238 while ((curr = *p) != NULL) { 254 while ((curr = *p) != NULL) {
239 if (ismarked(curr)) { 255 if (ismarked(curr)) {
@@ -248,6 +264,16 @@ static void collectclosure (lua_State *L) {
248} 264}
249 265
250 266
267static void collectclosures (lua_State *L) {
268 lua_State *L1 = L;
269 do { /* for each thread */
270 collectclosure(L1, &L1->opencl);
271 L1 = L1->next;
272 } while (L1 != L);
273 collectclosure(L, &G(L)->rootcl);
274}
275
276
251static void collecttable (lua_State *L) { 277static void collecttable (lua_State *L) {
252 Hash **p = &G(L)->roottable; 278 Hash **p = &G(L)->roottable;
253 Hash *curr; 279 Hash *curr;
@@ -264,6 +290,22 @@ static void collecttable (lua_State *L) {
264} 290}
265 291
266 292
293static void collectupval (lua_State *L) {
294 UpVal **v = &G(L)->rootupval;
295 UpVal *curr;
296 while ((curr = *v) != NULL) {
297 if (curr->marked) {
298 curr->marked = 0;
299 v = &curr->next;
300 }
301 else {
302 *v = curr->next;
303 luaM_freelem(L, curr);
304 }
305 }
306}
307
308
267static void collectudata (lua_State *L, int keep) { 309static void collectudata (lua_State *L, int keep) {
268 Udata **p = &G(L)->rootudata; 310 Udata **p = &G(L)->rootudata;
269 Udata *curr; 311 Udata *curr;
@@ -370,7 +412,8 @@ void luaC_collect (lua_State *L, int all) {
370 collectstrings(L, all); 412 collectstrings(L, all);
371 collecttable(L); 413 collecttable(L);
372 collectproto(L); 414 collectproto(L);
373 collectclosure(L); 415 collectupval(L);
416 collectclosures(L);
374} 417}
375 418
376 419
diff --git a/llimits.h b/llimits.h
index dd210f20..40815404 100644
--- a/llimits.h
+++ b/llimits.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llimits.h,v 1.30 2001/06/05 20:01:09 roberto Exp roberto $ 2** $Id: llimits.h,v 1.31 2001/08/27 15:16:28 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,6 +51,9 @@ 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 */
52typedef long ls_nstr; 52typedef long ls_nstr;
53 53
54/* a bitmap with one bit for each upvalue used by a function */
55typedef unsigned long ls_bitup;
56
54 57
55/* chars used as small naturals (so that `char' is reserved for characteres) */ 58/* chars used as small naturals (so that `char' is reserved for characteres) */
56typedef unsigned char lu_byte; 59typedef unsigned char lu_byte;
@@ -108,7 +111,7 @@ typedef unsigned long Instruction;
108 111
109/* maximum number of upvalues */ 112/* maximum number of upvalues */
110#ifndef MAXUPVALUES 113#ifndef MAXUPVALUES
111#define MAXUPVALUES 32 /* arbitrary limit (<MAXSTACK) */ 114#define MAXUPVALUES (sizeof(ls_bitup)*CHAR_BIT)
112#endif 115#endif
113 116
114 117
diff --git a/lobject.h b/lobject.h
index 415f8080..6fa0ca92 100644
--- a/lobject.h
+++ b/lobject.h
@@ -27,15 +27,20 @@
27#endif 27#endif
28 28
29 29
30/* tags for values visible from Lua == first user-created tag */ 30/* tags for values visible from Lua */
31#define NUM_TAGS 6 31#define NUM_TAGS 6
32 32
33 33
34/* extra tag: used locally when moving an upvalue from the stack to the heap */
35#define LUA_TUPVAL 6
36
37
34typedef union { 38typedef union {
35 union TString *ts; 39 union TString *ts;
36 union Udata *u; 40 union Udata *u;
37 struct Closure *cl; 41 struct Closure *cl;
38 struct Hash *h; 42 struct Hash *h;
43 struct UpVal *v;
39 lua_Number n; /* LUA_TNUMBER */ 44 lua_Number n; /* LUA_TNUMBER */
40} Value; 45} Value;
41 46
@@ -53,6 +58,7 @@ typedef struct lua_TObject {
53#define uvalue(o) ((o)->value.u) 58#define uvalue(o) ((o)->value.u)
54#define clvalue(o) ((o)->value.cl) 59#define clvalue(o) ((o)->value.cl)
55#define hvalue(o) ((o)->value.h) 60#define hvalue(o) ((o)->value.h)
61#define vvalue(o) ((o)->value.v)
56 62
57 63
58/* Macros to set values */ 64/* Macros to set values */
@@ -75,6 +81,9 @@ typedef struct lua_TObject {
75 81
76#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) 82#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
77 83
84#define setupvalue(obj,x) \
85 { TObject *_o=(obj); _o->tt=LUA_TUPVAL; _o->value.v=(x); }
86
78#define setobj(obj1,obj2) \ 87#define setobj(obj1,obj2) \
79 { TObject *o1=(obj1); const TObject *o2=(obj2); \ 88 { TObject *o1=(obj1); const TObject *o2=(obj2); \
80 o1->tt=o2->tt; o1->value = o2->value; } 89 o1->tt=o2->tt; o1->value = o2->value; }
@@ -154,25 +163,48 @@ typedef struct LocVar {
154} LocVar; 163} LocVar;
155 164
156 165
166
167/*
168** Upvalues in the heap
169*/
170typedef struct UpVal {
171 TObject val;
172 struct UpVal *next;
173 int marked;
174} UpVal;
175
176
157/* 177/*
158** Closures 178** Closures
159*/ 179*/
160typedef struct Closure { 180typedef struct Closure {
161 int isC; /* 0 for Lua functions, 1 for C functions */ 181 int isC; /* 0 for Lua functions, 1 for C functions */
162 int nupvalues; 182 int nupvalues;
163 union {
164 lua_CFunction c; /* C functions */
165 struct Proto *l; /* Lua functions */
166 } f;
167 struct Closure *next; 183 struct Closure *next;
168 struct Closure *mark; /* marked closures (point to itself when not marked) */ 184 struct Closure *mark; /* marked closures (point to itself when not marked) */
169 TObject upvalue[1]; 185 union {
186 struct { /* C functions */
187 lua_CFunction f;
188 TObject upvalue[1];
189 } c;
190 struct { /* Lua functions */
191 struct Proto *p;
192 ls_bitup isopen; /* bitmap: bit==1 when upvals point to the stack */
193 TObject *upvals[1]; /* may point to the stack or to an UpVal */
194 } l;
195 } u;
170} Closure; 196} Closure;
171 197
172 198
173#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC) 199#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC)
174 200
175 201
202
203
204/*
205** Hash Tables
206*/
207
176typedef struct Node { 208typedef struct Node {
177 struct Node *next; /* for chaining */ 209 struct Node *next; /* for chaining */
178 TObject key; 210 TObject key;
diff --git a/lopcodes.c b/lopcodes.c
index 932ac073..9ad82d7a 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -20,10 +20,11 @@ const l_char *const luaP_opnames[] = {
20 l_s("LOADK"), 20 l_s("LOADK"),
21 l_s("LOADINT"), 21 l_s("LOADINT"),
22 l_s("LOADNIL"), 22 l_s("LOADNIL"),
23 l_s("LOADUPVAL"), 23 l_s("GETUPVAL"),
24 l_s("GETGLOBAL"), 24 l_s("GETGLOBAL"),
25 l_s("GETTABLE"), 25 l_s("GETTABLE"),
26 l_s("SETGLOBAL"), 26 l_s("SETGLOBAL"),
27 l_s("SETUPVAL"),
27 l_s("SETTABLE"), 28 l_s("SETTABLE"),
28 l_s("NEWTABLE"), 29 l_s("NEWTABLE"),
29 l_s("SELF"), 30 l_s("SELF"),
@@ -54,6 +55,7 @@ const l_char *const luaP_opnames[] = {
54 l_s("TFORLOOP"), 55 l_s("TFORLOOP"),
55 l_s("SETLIST"), 56 l_s("SETLIST"),
56 l_s("SETLISTO"), 57 l_s("SETLISTO"),
58 l_s("CLOSE"),
57 l_s("CLOSURE") 59 l_s("CLOSURE")
58}; 60};
59 61
@@ -69,10 +71,11 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
69 ,opmode(0,0,0,0, 1,1,iABc) /* OP_LOADK */ 71 ,opmode(0,0,0,0, 1,1,iABc) /* OP_LOADK */
70 ,opmode(0,0,0,0, 1,0,iAsBc) /* OP_LOADINT */ 72 ,opmode(0,0,0,0, 1,0,iAsBc) /* OP_LOADINT */
71 ,opmode(0,0,1,0, 1,0,iABC) /* OP_LOADNIL */ 73 ,opmode(0,0,1,0, 1,0,iABC) /* OP_LOADNIL */
72 ,opmode(0,0,0,0, 1,0,iABc) /* OP_LOADUPVAL */ 74 ,opmode(0,0,0,0, 1,0,iABC) /* OP_GETUPVAL */
73 ,opmode(0,0,0,0, 1,1,iABc) /* OP_GETGLOBAL */ 75 ,opmode(0,0,0,0, 1,1,iABc) /* OP_GETGLOBAL */
74 ,opmode(0,0,1,1, 1,0,iABC) /* OP_GETTABLE */ 76 ,opmode(0,0,1,1, 1,0,iABC) /* OP_GETTABLE */
75 ,opmode(0,0,0,0, 0,1,iABc) /* OP_SETGLOBAL */ 77 ,opmode(0,0,0,0, 0,1,iABc) /* OP_SETGLOBAL */
78 ,opmode(0,0,0,0, 0,0,iABC) /* OP_SETUPVAL */
76 ,opmode(0,0,1,1, 0,0,iABC) /* OP_SETTABLE */ 79 ,opmode(0,0,1,1, 0,0,iABC) /* OP_SETTABLE */
77 ,opmode(0,0,0,0, 1,0,iABc) /* OP_NEWTABLE */ 80 ,opmode(0,0,0,0, 1,0,iABc) /* OP_NEWTABLE */
78 ,opmode(0,0,1,1, 1,0,iABC) /* OP_SELF */ 81 ,opmode(0,0,1,1, 1,0,iABC) /* OP_SELF */
@@ -103,6 +106,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
103 ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_TFORLOOP */ 106 ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_TFORLOOP */
104 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLIST */ 107 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLIST */
105 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLISTO */ 108 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLISTO */
109 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */
106 ,opmode(0,0,0,0, 1,0,iABc) /* OP_CLOSURE */ 110 ,opmode(0,0,0,0, 1,0,iABc) /* OP_CLOSURE */
107}; 111};
108 112
diff --git a/lopcodes.h b/lopcodes.h
index f581dd1d..7492c462 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -131,12 +131,13 @@ OP_MOVE,/* A B R(A) := R(B) */
131OP_LOADK,/* A Bc R(A) := Kst(Bc) */ 131OP_LOADK,/* A Bc R(A) := Kst(Bc) */
132OP_LOADINT,/* A sBc R(A) := (Number)sBc */ 132OP_LOADINT,/* A sBc R(A) := (Number)sBc */
133OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ 133OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
134OP_LOADUPVAL,/* A Bc R(A) := UpValue[Bc] */ 134OP_GETUPVAL,/* A B R(A) := UpValue[B] */
135 135
136OP_GETGLOBAL,/* A Bc R(A) := Gbl[Kst(Bc)] */ 136OP_GETGLOBAL,/* A Bc R(A) := Gbl[Kst(Bc)] */
137OP_GETTABLE,/* A B C R(A) := R(B)[R/K(C)] */ 137OP_GETTABLE,/* A B C R(A) := R(B)[R/K(C)] */
138 138
139OP_SETGLOBAL,/* A Bc Gbl[Kst(Bc)] := R(A) */ 139OP_SETGLOBAL,/* A Bc Gbl[Kst(Bc)] := R(A) */
140OP_SETUPVAL,/* A B UpValue[B] := R(A) */
140OP_SETTABLE,/* A B C R(B)[R/K(C)] := R(A) */ 141OP_SETTABLE,/* A B C R(B)[R/K(C)] := R(A) */
141 142
142OP_NEWTABLE,/* A Bc R(A) := {} (size = Bc) */ 143OP_NEWTABLE,/* A Bc R(A) := {} (size = Bc) */
@@ -180,6 +181,7 @@ OP_TFORLOOP,/* A sBc */
180OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */ 181OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */
181OP_SETLISTO,/* A Bc */ 182OP_SETLISTO,/* A Bc */
182 183
184OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
183OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */ 185OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */
184} OpCode; 186} OpCode;
185 187
diff --git a/lparser.c b/lparser.c
index aa79a86a..725c2749 100644
--- a/lparser.c
+++ b/lparser.c
@@ -41,6 +41,7 @@ typedef struct Constdesc {
41typedef struct Breaklabel { 41typedef struct Breaklabel {
42 struct Breaklabel *previous; /* chain */ 42 struct Breaklabel *previous; /* chain */
43 int breaklist; /* list of jumps out of this loop */ 43 int breaklist; /* list of jumps out of this loop */
44 int nactloc; /* # of active local variables outside the breakable structure */
44} Breaklabel; 45} Breaklabel;
45 46
46 47
@@ -163,13 +164,29 @@ static void new_localvar (LexState *ls, TString *name, int n) {
163 164
164static void adjustlocalvars (LexState *ls, int nvars) { 165static void adjustlocalvars (LexState *ls, int nvars) {
165 FuncState *fs = ls->fs; 166 FuncState *fs = ls->fs;
166 while (nvars--) 167 while (nvars--) {
167 fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc; 168 fs->f->locvars[fs->actloc[fs->nactloc]].startpc = fs->pc;
169 resetbit(fs->wasup, fs->nactloc);
170 fs->nactloc++;
171 }
172}
173
174
175static void closelevel (LexState *ls, int level) {
176 FuncState *fs = ls->fs;
177 int i;
178 for (i=level; i<fs->nactloc; i++)
179 if (testbit(fs->wasup, i)) {
180 luaK_codeABC(fs, OP_CLOSE, level, 0, 0);
181 return;
182 }
183 return; /* nothing to close */
168} 184}
169 185
170 186
171static void removelocalvars (LexState *ls, int nvars) { 187static void removelocalvars (LexState *ls, int nvars) {
172 FuncState *fs = ls->fs; 188 FuncState *fs = ls->fs;
189 closelevel(ls, fs->nactloc - nvars);
173 while (nvars--) 190 while (nvars--)
174 fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc; 191 fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc;
175} 192}
@@ -180,68 +197,47 @@ static void new_localvarstr (LexState *ls, const l_char *name, int n) {
180} 197}
181 198
182 199
183static int search_local (LexState *ls, TString *n, expdesc *var) { 200static int indexupvalue (FuncState *fs, expdesc *v) {
184 FuncState *fs;
185 int level = 0;
186 for (fs=ls->fs; fs; fs=fs->prev) {
187 int i;
188 for (i=fs->nactloc-1; i >= 0; i--) {
189 if (n == fs->f->locvars[fs->actloc[i]].varname) {
190 init_exp(var, VLOCAL, i);
191 return level;
192 }
193 }
194 level++; /* `var' not found; check outer level */
195 }
196 init_exp(var, VGLOBAL, 0); /* not found in any level; must be global */
197 return -1;
198}
199
200
201static void singlevar (LexState *ls, TString *n, expdesc *var) {
202 int level = search_local(ls, n, var);
203 if (level >= 1) /* neither local (0) nor global (-1)? */
204 luaX_syntaxerror(ls, l_s("cannot access a variable in outer function"),
205 getstr(n));
206 else if (level == -1) /* global? */
207 var->u.i.info = luaK_stringk(ls->fs, n);
208}
209
210
211static int indexupvalue (LexState *ls, expdesc *v) {
212 FuncState *fs = ls->fs;
213 int i; 201 int i;
214 for (i=0; i<fs->f->nupvalues; i++) { 202 for (i=0; i<fs->f->nupvalues; i++) {
215 if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.i.info == v->u.i.info) 203 if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.i.info == v->u.i.info)
216 return i; 204 return i;
217 } 205 }
218 /* new one */ 206 /* new one */
219 luaX_checklimit(ls, fs->f->nupvalues+1, MAXUPVALUES, l_s("upvalues")); 207 luaX_checklimit(fs->ls, fs->f->nupvalues+1, MAXUPVALUES, l_s("upvalues"));
220 fs->upvalues[fs->f->nupvalues] = *v; 208 fs->upvalues[fs->f->nupvalues] = *v;
221 return fs->f->nupvalues++; 209 return fs->f->nupvalues++;
222} 210}
223 211
224 212
225static void codeupvalue (LexState *ls, expdesc *v, TString *n) { 213static void singlevar (FuncState *fs, TString *n, expdesc *var, int baselevel) {
226 FuncState *fs = ls->fs; 214 if (fs == NULL)
227 int level; 215 init_exp(var, VGLOBAL, 0); /* not local in any level; global variable */
228 level = search_local(ls, n, v); 216 else { /* look up at current level */
229 if (level == -1) { /* global? */ 217 int i;
230 if (fs->prev == NULL) 218 for (i=fs->nactloc-1; i >= 0; i--) {
231 luaX_syntaxerror(ls, l_s("cannot access an upvalue at top level"), 219 if (n == fs->f->locvars[fs->actloc[i]].varname) {
232 getstr(n)); 220 if (!baselevel)
233 v->u.i.info = luaK_stringk(fs->prev, n); 221 setbit(fs->wasup, i); /* will be upvalue in some other level */
234 } 222 init_exp(var, VLOCAL, i);
235 else if (level != 1) { 223 return;
236 luaX_syntaxerror(ls, 224 }
237 l_s("upvalue must be global or local to immediately outer function"), 225 }
238 getstr(n)); 226 /* not found at current level; try upper one */
227 singlevar(fs->prev, n, var, 0);
228 if (var->k == VGLOBAL) {
229 if (baselevel)
230 var->u.i.info = luaK_stringk(fs, n); /* info points to global name */
231 }
232 else { /* local variable in some upper level? */
233 var->u.i.info = indexupvalue(fs, var);
234 var->k = VUPVAL; /* upvalue in this level */
235 }
239 } 236 }
240 init_exp(v, VRELOCABLE,
241 luaK_codeABc(fs, OP_LOADUPVAL, 0, indexupvalue(ls, v)));
242} 237}
243 238
244 239
240
245static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { 241static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
246 FuncState *fs = ls->fs; 242 FuncState *fs = ls->fs;
247 int extra = nvars - nexps; 243 int extra = nvars - nexps;
@@ -278,6 +274,7 @@ static void code_params (LexState *ls, int nparams, short dots) {
278 274
279static void enterbreak (FuncState *fs, Breaklabel *bl) { 275static void enterbreak (FuncState *fs, Breaklabel *bl) {
280 bl->breaklist = NO_JUMP; 276 bl->breaklist = NO_JUMP;
277 bl->nactloc = fs->nactloc;
281 bl->previous = fs->bl; 278 bl->previous = fs->bl;
282 fs->bl = bl; 279 fs->bl = bl;
283} 280}
@@ -286,6 +283,7 @@ static void enterbreak (FuncState *fs, Breaklabel *bl) {
286static void leavebreak (FuncState *fs, Breaklabel *bl) { 283static void leavebreak (FuncState *fs, Breaklabel *bl) {
287 fs->bl = bl->previous; 284 fs->bl = bl->previous;
288 luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs)); 285 luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs));
286 lua_assert(bl->nactloc == fs->nactloc);
289} 287}
290 288
291 289
@@ -293,16 +291,14 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
293 FuncState *fs = ls->fs; 291 FuncState *fs = ls->fs;
294 Proto *f = fs->f; 292 Proto *f = fs->f;
295 int i; 293 int i;
296 int reg = fs->freereg;
297 for (i=0; i<func->f->nupvalues; i++)
298 luaK_exp2nextreg(fs, &func->upvalues[i]);
299 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, 294 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
300 MAXARG_Bc, l_s("constant table overflow")); 295 MAXARG_Bc, l_s("constant table overflow"));
301 f->p[fs->np++] = func->f; 296 f->p[fs->np++] = func->f;
302 fs->freereg = reg; /* CLOSURE will consume those values */ 297 init_exp(v, VRELOCABLE, luaK_codeABc(fs, OP_CLOSURE, 0, fs->np-1));
303 init_exp(v, VNONRELOC, reg); 298 for (i=0; i<func->f->nupvalues; i++) {
304 luaK_reserveregs(fs, 1); 299 luaK_exp2nextreg(fs, &func->upvalues[i]);
305 luaK_codeABc(fs, OP_CLOSURE, v->u.i.info, fs->np-1); 300 fs->freereg--; /* CLOSURE will use these values */
301 }
306} 302}
307 303
308 304
@@ -337,9 +333,9 @@ static void close_func (LexState *ls) {
337 lua_State *L = ls->L; 333 lua_State *L = ls->L;
338 FuncState *fs = ls->fs; 334 FuncState *fs = ls->fs;
339 Proto *f = fs->f; 335 Proto *f = fs->f;
336 removelocalvars(ls, fs->nactloc);
340 luaK_codeABC(fs, OP_RETURN, 0, 0, 0); /* final return */ 337 luaK_codeABC(fs, OP_RETURN, 0, 0, 0); /* final return */
341 luaK_getlabel(fs); /* close eventual list of pending jumps */ 338 luaK_getlabel(fs); /* close eventual list of pending jumps */
342 removelocalvars(ls, fs->nactloc);
343 lua_assert(G(L)->roottable == fs->h); 339 lua_assert(G(L)->roottable == fs->h);
344 G(L)->roottable = fs->h->next; 340 G(L)->roottable = fs->h->next;
345 luaH_free(L, fs->h); 341 luaH_free(L, fs->h);
@@ -644,16 +640,18 @@ static void primaryexp (LexState *ls, expdesc *v) {
644 return; 640 return;
645 } 641 }
646 case TK_NAME: { 642 case TK_NAME: {
647 singlevar(ls, str_checkname(ls), v); 643 singlevar(ls->fs, str_checkname(ls), v, 1);
648 next(ls); 644 next(ls);
649 return; 645 return;
650 } 646 }
651 case l_c('%'): { 647 case l_c('%'): { /* for compatibility only */
652 next(ls); /* skip `%' */ 648 next(ls); /* skip `%' */
653 codeupvalue(ls, v, str_checkname(ls)); 649 singlevar(ls->fs, str_checkname(ls), v, 1);
650 check_condition(ls, v->k == VUPVAL, l_s("global upvalues are deprecated"));
654 next(ls); 651 next(ls);
655 break; 652 return;
656 } 653 }
654
657 default: { 655 default: {
658 luaK_error(ls, l_s("unexpected symbol")); 656 luaK_error(ls, l_s("unexpected symbol"));
659 return; 657 return;
@@ -812,7 +810,7 @@ static void block (LexState *ls) {
812*/ 810*/
813struct LHS_assign { 811struct LHS_assign {
814 struct LHS_assign *prev; 812 struct LHS_assign *prev;
815 expdesc v; /* variable (global, local, or indexed) */ 813 expdesc v; /* variable (global, local, upvalue, or indexed) */
816}; 814};
817 815
818 816
@@ -847,9 +845,8 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
847 845
848static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { 846static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
849 expdesc e; 847 expdesc e;
850 check_condition(ls, lh->v.k == VLOCAL || lh->v.k == VGLOBAL || 848 check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
851 lh->v.k == VINDEXED, 849 l_s("syntax error!!"));
852 l_s("syntax error"));
853 if (ls->t.token == l_c(',')) { /* assignment -> `,' simpleexp assignment */ 850 if (ls->t.token == l_c(',')) { /* assignment -> `,' simpleexp assignment */
854 struct LHS_assign nv; 851 struct LHS_assign nv;
855 nv.prev = lh; 852 nv.prev = lh;
@@ -1054,7 +1051,7 @@ static void localstat (LexState *ls) {
1054static int funcname (LexState *ls, expdesc *v) { 1051static int funcname (LexState *ls, expdesc *v) {
1055 /* funcname -> NAME {field} [`:' NAME] */ 1052 /* funcname -> NAME {field} [`:' NAME] */
1056 int needself = 0; 1053 int needself = 0;
1057 singlevar(ls, str_checkname(ls), v); 1054 singlevar(ls->fs, str_checkname(ls), v, 1);
1058 next(ls); /* skip var name */ 1055 next(ls); /* skip var name */
1059 while (ls->t.token == l_c('.')) { 1056 while (ls->t.token == l_c('.')) {
1060 luaY_field(ls, v); 1057 luaY_field(ls, v);
@@ -1102,25 +1099,19 @@ static void retstat (LexState *ls) {
1102 if (block_follow(ls->t.token) || ls->t.token == l_c(';')) 1099 if (block_follow(ls->t.token) || ls->t.token == l_c(';'))
1103 first = nret = 0; /* return no values */ 1100 first = nret = 0; /* return no values */
1104 else { 1101 else {
1105 int n = explist1(ls, &e); /* optional return values */ 1102 explist1(ls, &e); /* optional return values */
1106 if (e.k == VCALL) { 1103 if (e.k == VCALL) {
1107 luaK_setcallreturns(fs, &e, LUA_MULTRET); 1104 luaK_setcallreturns(fs, &e, LUA_MULTRET);
1108 first = fs->nactloc; 1105 first = fs->nactloc;
1109 nret = NO_REG; /* return all values */ 1106 nret = NO_REG; /* return all values */
1110 } 1107 }
1111 else { 1108 else {
1112 if (n == 1) { /* only one value? */ 1109 luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
1113 luaK_exp2anyreg(fs, &e); 1110 first = fs->nactloc;
1114 first = e.u.i.info; 1111 nret = fs->freereg - first; /* return all `active' values */
1115 nret = 1; /* return only this value */
1116 }
1117 else {
1118 luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
1119 first = fs->nactloc;
1120 nret = fs->freereg - first; /* return all `active' values */
1121 }
1122 } 1112 }
1123 } 1113 }
1114 closelevel(ls, 0);
1124 luaK_codeABC(fs, OP_RETURN, first, nret, 0); 1115 luaK_codeABC(fs, OP_RETURN, first, nret, 0);
1125 fs->freereg = fs->nactloc; /* removes all temp values */ 1116 fs->freereg = fs->nactloc; /* removes all temp values */
1126} 1117}
@@ -1133,8 +1124,8 @@ static void breakstat (LexState *ls) {
1133 if (!bl) 1124 if (!bl)
1134 luaK_error(ls, l_s("no loop to break")); 1125 luaK_error(ls, l_s("no loop to break"));
1135 next(ls); /* skip BREAK */ 1126 next(ls); /* skip BREAK */
1127 closelevel(ls, bl->nactloc);
1136 luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); 1128 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
1137 /* correct stack for compiler and symbolic execution */
1138} 1129}
1139 1130
1140 1131
diff --git a/lparser.h b/lparser.h
index 22482ce2..2355b35d 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.33 2001/08/10 20:53:03 roberto Exp roberto $ 2** $Id: lparser.h,v 1.34 2001/08/27 15:16:28 roberto Exp $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -7,11 +7,24 @@
7#ifndef lparser_h 7#ifndef lparser_h
8#define lparser_h 8#define lparser_h
9 9
10#include "llimits.h"
10#include "lobject.h" 11#include "lobject.h"
11#include "ltable.h" 12#include "ltable.h"
12#include "lzio.h" 13#include "lzio.h"
13 14
14 15
16
17/* small implementation of bit arrays */
18
19#define BPW (CHAR_BIT*sizeof(unsigned int)) /* bits per word */
20
21#define words2bits(b) (((b)-1)/BPW + 1)
22
23#define setbit(a, b) ((a)[(b)/BPW] |= (1 << (b)%BPW))
24#define resetbit(a, b) ((a)[(b)/BPW] &= ~((1 << (b)%BPW)))
25#define testbit(a, b) ((a)[(b)/BPW] & (1 << (b)%BPW))
26
27
15/* 28/*
16** Expression descriptor 29** Expression descriptor
17*/ 30*/
@@ -21,8 +34,9 @@ typedef enum {
21 VNIL, 34 VNIL,
22 VNUMBER, /* n = value */ 35 VNUMBER, /* n = value */
23 VK, /* info = index of constant in `k' */ 36 VK, /* info = index of constant in `k' */
24 VGLOBAL, /* info = index of global name in `k' */
25 VLOCAL, /* info = local register */ 37 VLOCAL, /* info = local register */
38 VUPVAL, /* info = index of upvalue in `upvalues' */
39 VGLOBAL, /* info = index of global name in `k' */
26 VINDEXED, /* info = table register; aux = index register (or `k') */ 40 VINDEXED, /* info = table register; aux = index register (or `k') */
27 VRELOCABLE, /* info = instruction pc */ 41 VRELOCABLE, /* info = instruction pc */
28 VNONRELOC, /* info = result register */ 42 VNONRELOC, /* info = result register */
@@ -63,6 +77,8 @@ typedef struct FuncState {
63 struct Breaklabel *bl; /* chain of breakable blocks */ 77 struct Breaklabel *bl; /* chain of breakable blocks */
64 expdesc upvalues[MAXUPVALUES]; /* upvalues */ 78 expdesc upvalues[MAXUPVALUES]; /* upvalues */
65 int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */ 79 int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */
80 unsigned int wasup[words2bits(MAXLOCALS)]; /* bit array to mark whether a
81 local variable was used as upvalue at some level */
66} FuncState; 82} FuncState;
67 83
68 84
diff --git a/lstate.c b/lstate.c
index 456f1d6e..4b404b0b 100644
--- a/lstate.c
+++ b/lstate.c
@@ -58,6 +58,7 @@ static void f_luaopen (lua_State *L, void *ud) {
58 G(L)->rootcl = NULL; 58 G(L)->rootcl = NULL;
59 G(L)->roottable = NULL; 59 G(L)->roottable = NULL;
60 G(L)->rootudata = NULL; 60 G(L)->rootudata = NULL;
61 G(L)->rootupval = NULL;
61 G(L)->TMtable = NULL; 62 G(L)->TMtable = NULL;
62 G(L)->sizeTM = 0; 63 G(L)->sizeTM = 0;
63 G(L)->ntag = 0; 64 G(L)->ntag = 0;
@@ -91,6 +92,7 @@ LUA_API lua_State *lua_newthread (lua_State *OL, int stacksize) {
91 L->errorJmp = NULL; 92 L->errorJmp = NULL;
92 L->callhook = NULL; 93 L->callhook = NULL;
93 L->linehook = NULL; 94 L->linehook = NULL;
95 L->opencl = NULL;
94 L->allowhooks = 1; 96 L->allowhooks = 1;
95 L->next = L->previous = L; 97 L->next = L->previous = L;
96 so.stacksize = stacksize; 98 so.stacksize = stacksize;
@@ -122,10 +124,10 @@ static void close_state (lua_State *L, lua_State *OL) {
122 luaS_freeall(L); 124 luaS_freeall(L);
123 luaM_freearray(L, G(L)->TMtable, G(L)->sizeTM, struct TM); 125 luaM_freearray(L, G(L)->TMtable, G(L)->sizeTM, struct TM);
124 luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, l_char); 126 luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, l_char);
125 luaM_freelem(NULL, L->G, global_State); 127 luaM_freelem(NULL, L->G);
126 } 128 }
127 luaM_freearray(OL, L->stack, L->stacksize, TObject); 129 luaM_freearray(OL, L->stack, L->stacksize, TObject);
128 luaM_freelem(OL, L, lua_State); 130 luaM_freelem(OL, L);
129} 131}
130 132
131LUA_API void lua_close (lua_State *L) { 133LUA_API void lua_close (lua_State *L) {
diff --git a/lstate.h b/lstate.h
index cee07969..d6b5afd1 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.57 2001/06/06 18:00:19 roberto Exp roberto $ 2** $Id: lstate.h,v 1.58 2001/06/15 19:16:41 roberto Exp $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -56,10 +56,6 @@ typedef struct stringtable {
56typedef struct global_State { 56typedef struct global_State {
57 void *Mbuffer; /* global buffer */ 57 void *Mbuffer; /* global buffer */
58 size_t Mbuffsize; /* size of Mbuffer */ 58 size_t Mbuffsize; /* size of Mbuffer */
59 Proto *rootproto; /* list of all prototypes */
60 Closure *rootcl; /* list of all closures */
61 Hash *roottable; /* list of all tables */
62 Udata *rootudata; /* list of all userdata */
63 stringtable strt; /* hash table for strings */ 59 stringtable strt; /* hash table for strings */
64 Hash *type2tag; /* hash table from type names to tags */ 60 Hash *type2tag; /* hash table from type names to tags */
65 Hash *registry; /* (strong) registry table */ 61 Hash *registry; /* (strong) registry table */
@@ -69,6 +65,11 @@ typedef struct global_State {
69 int ntag; /* number of tags in TMtable */ 65 int ntag; /* number of tags in TMtable */
70 lu_mem GCthreshold; 66 lu_mem GCthreshold;
71 lu_mem nblocks; /* number of `bytes' currently allocated */ 67 lu_mem nblocks; /* number of `bytes' currently allocated */
68 Proto *rootproto; /* list of all prototypes */
69 Closure *rootcl; /* list of all closed closures */
70 Hash *roottable; /* list of all tables */
71 Udata *rootudata; /* list of all userdata */
72 UpVal *rootupval; /* list of all up values */
72} global_State; 73} global_State;
73 74
74 75
@@ -88,6 +89,7 @@ struct lua_State {
88 lua_Hook linehook; 89 lua_Hook linehook;
89 int allowhooks; 90 int allowhooks;
90 struct lua_longjmp *errorJmp; /* current error recover point */ 91 struct lua_longjmp *errorJmp; /* current error recover point */
92 Closure *opencl; /* list of closures still pointing to this stack */
91 lua_State *next; /* circular double linked list of states */ 93 lua_State *next; /* circular double linked list of states */
92 lua_State *previous; 94 lua_State *previous;
93 CallInfo basefunc; 95 CallInfo basefunc;
diff --git a/ltests.c b/ltests.c
index 35c6f027..a33a9638 100644
--- a/ltests.c
+++ b/ltests.c
@@ -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))->f.l; 168 p = clvalue(luaA_index(L, 1))->u.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))->f.l; 187 p = clvalue(luaA_index(L, 1))->u.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))->f.l; 205 p = clvalue(luaA_index(L, 1))->u.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;
diff --git a/lvm.c b/lvm.c
index b9d36938..1d16a7b5 100644
--- a/lvm.c
+++ b/lvm.c
@@ -64,8 +64,8 @@ int luaV_tostring (lua_State *L, TObject *obj) {
64 64
65static void traceexec (lua_State *L, lua_Hook linehook) { 65static void traceexec (lua_State *L, lua_Hook linehook) {
66 CallInfo *ci = L->ci; 66 CallInfo *ci = L->ci;
67 int *lineinfo = ci_func(ci)->f.l->lineinfo; 67 int *lineinfo = ci_func(ci)->u.l.p->lineinfo;
68 int pc = (*ci->pc - ci_func(ci)->f.l->code) - 1; 68 int pc = (*ci->pc - ci_func(ci)->u.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;
@@ -82,30 +82,6 @@ static void traceexec (lua_State *L, lua_Hook linehook) {
82} 82}
83 83
84 84
85static Closure *luaV_closure (lua_State *L, int nelems) {
86 Closure *c = luaF_newclosure(L, nelems);
87 L->top -= nelems;
88 while (nelems--)
89 setobj(&c->upvalue[nelems], L->top+nelems);
90 setclvalue(L->top, c);
91 incr_top;
92 return c;
93}
94
95
96void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems) {
97 Closure *cl = luaV_closure(L, nelems);
98 cl->f.c = c;
99 cl->isC = 1;
100}
101
102
103void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
104 Closure *cl = luaV_closure(L, nelems);
105 cl->f.l = l;
106 cl->isC = 0;
107}
108
109 85
110/* maximum stack used by a call to a tag method (func + args) */ 86/* maximum stack used by a call to a tag method (func + args) */
111#define MAXSTACK_TM 4 87#define MAXSTACK_TM 4
@@ -376,7 +352,7 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
376** Returns n such that the the results are between [n,top). 352** Returns n such that the the results are between [n,top).
377*/ 353*/
378StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { 354StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
379 const Proto *const tf = cl->f.l; 355 const Proto *const tf = cl->u.l.p;
380 const Instruction *pc; 356 const Instruction *pc;
381 lua_Hook linehook; 357 lua_Hook linehook;
382 if (tf->is_vararg) /* varargs? */ 358 if (tf->is_vararg) /* varargs? */
@@ -406,10 +382,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
406 setnvalue(ra, (lua_Number)GETARG_sBc(i)); 382 setnvalue(ra, (lua_Number)GETARG_sBc(i));
407 break; 383 break;
408 } 384 }
409 case OP_LOADUPVAL: {
410 setobj(ra, cl->upvalue+GETARG_Bc(i));
411 break;
412 }
413 case OP_LOADNIL: { 385 case OP_LOADNIL: {
414 TObject *rb = RB(i); 386 TObject *rb = RB(i);
415 do { 387 do {
@@ -417,6 +389,12 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
417 } while (rb >= ra); 389 } while (rb >= ra);
418 break; 390 break;
419 } 391 }
392 case OP_GETUPVAL: {
393 int b = GETARG_B(i);
394 lua_assert(luaF_isclosed(cl, b) || cl->u.l.upvals[b] < base);
395 setobj(ra, cl->u.l.upvals[b]);
396 break;
397 }
420 case OP_GETGLOBAL: { 398 case OP_GETGLOBAL: {
421 lua_assert(ttype(KBc(i)) == LUA_TSTRING); 399 lua_assert(ttype(KBc(i)) == LUA_TSTRING);
422 luaV_getglobal(L, tsvalue(KBc(i)), ra); 400 luaV_getglobal(L, tsvalue(KBc(i)), ra);
@@ -431,6 +409,12 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
431 luaV_setglobal(L, tsvalue(KBc(i)), ra); 409 luaV_setglobal(L, tsvalue(KBc(i)), ra);
432 break; 410 break;
433 } 411 }
412 case OP_SETUPVAL: {
413 int b = GETARG_B(i);
414 lua_assert(luaF_isclosed(cl, b) || cl->u.l.upvals[b] < base);
415 setobj(cl->u.l.upvals[b], ra);
416 break;
417 }
434 case OP_SETTABLE: { 418 case OP_SETTABLE: {
435 luaV_settable(L, RB(i), RKC(i), ra); 419 luaV_settable(L, RB(i), RKC(i), ra);
436 break; 420 break;
@@ -646,13 +630,34 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
646 luaH_setnum(L, h, bc+n, ra+n); 630 luaH_setnum(L, h, bc+n, ra+n);
647 break; 631 break;
648 } 632 }
633 case OP_CLOSE: {
634 luaF_close(L, ra);
635 break;
636 }
649 case OP_CLOSURE: { 637 case OP_CLOSURE: {
650 Proto *p = tf->p[GETARG_Bc(i)]; 638 Proto *p;
651 int nup = p->nupvalues; 639 Closure *ncl;
652 luaV_checkGC(L, ra+nup); 640 int nup, j;
653 L->top = ra+nup; 641 luaV_checkGC(L, L->top);
654 luaV_Lclosure(L, p, nup); 642 p = tf->p[GETARG_Bc(i)];
655 L->top = base + tf->maxstacksize; 643 nup = p->nupvalues;
644 ncl = luaF_newLclosure(L, nup);
645 ncl->u.l.p = p;
646 for (j=0; j<nup; j++, pc++) {
647 if (GET_OPCODE(*pc) == OP_GETUPVAL) {
648 int n = GETARG_B(*pc);
649 if (!luaF_isclosed(cl, n))
650 luaF_openentry(ncl, j);
651 ncl->u.l.upvals[j] = cl->u.l.upvals[n];
652 }
653 else {
654 lua_assert(GET_OPCODE(*pc) == OP_MOVE);
655 luaF_openentry(ncl, j);
656 ncl->u.l.upvals[j] = base + GETARG_B(*pc);
657 }
658 }
659 luaF_LConlist(L, ncl);
660 setclvalue(ra, ncl);
656 break; 661 break;
657 } 662 }
658 } 663 }
diff --git a/lvm.h b/lvm.h
index cbd47be4..de3fd45c 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.29 2001/02/07 18:13:49 roberto Exp roberto $ 2** $Id: lvm.h,v 1.30 2001/06/05 18:17:01 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*/
@@ -23,8 +23,6 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val);
23void luaV_getglobal (lua_State *L, TString *s, StkId res); 23void luaV_getglobal (lua_State *L, TString *s, StkId res);
24void luaV_setglobal (lua_State *L, TString *s, StkId val); 24void luaV_setglobal (lua_State *L, TString *s, StkId val);
25StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); 25StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
26void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
27void luaV_Lclosure (lua_State *L, Proto *l, int nelems);
28int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); 26int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
29void luaV_strconc (lua_State *L, int total, StkId top); 27void luaV_strconc (lua_State *L, int total, StkId top);
30 28