summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c4
-rw-r--r--ldebug.c11
-rw-r--r--ldo.c6
-rw-r--r--ldump.c17
-rw-r--r--lfunc.c9
-rw-r--r--lgc.c8
-rw-r--r--lobject.h16
-rw-r--r--lopcodes.h6
-rw-r--r--lparser.c39
-rw-r--r--lparser.h10
-rw-r--r--ltests.c9
-rw-r--r--luaconf.h9
-rw-r--r--lundump.c23
-rw-r--r--lvm.c28
14 files changed, 97 insertions, 98 deletions
diff --git a/lapi.c b/lapi.c
index c727cd6c..08a42516 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.90 2009/09/17 18:04:21 roberto Exp roberto $ 2** $Id: lapi.c,v 2.91 2009/09/21 12:09:52 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -1043,7 +1043,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val) {
1043 Proto *p = f->l.p; 1043 Proto *p = f->l.p;
1044 if (!(1 <= n && n <= p->sizeupvalues)) return NULL; 1044 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1045 *val = f->l.upvals[n-1]->v; 1045 *val = f->l.upvals[n-1]->v;
1046 return getstr(p->upvalues[n-1]); 1046 return getstr(p->upvalues[n-1].name);
1047 } 1047 }
1048} 1048}
1049 1049
diff --git a/ldebug.c b/ldebug.c
index 00ab2284..80d367cd 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.54 2009/09/23 20:33:05 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.55 2009/09/28 12:37:17 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -328,7 +328,8 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
328 case OP_GETUPVAL: { 328 case OP_GETUPVAL: {
329 if (reg == a) { 329 if (reg == a) {
330 int u = GETARG_B(i); /* upvalue index */ 330 int u = GETARG_B(i); /* upvalue index */
331 *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; 331 TString *tn = p->upvalues[u].name;
332 *name = tn ? getstr(tn) : "?";
332 what = "upvalue"; 333 what = "upvalue";
333 } 334 }
334 break; 335 break;
@@ -364,12 +365,6 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
364 pc += b; /* do the jump */ 365 pc += b; /* do the jump */
365 break; 366 break;
366 } 367 }
367 case OP_CLOSURE: {
368 int nup = p->p[GETARG_Bx(i)]->nups;
369 pc += nup; /* do not 'execute' pseudo-instructions */
370 lua_assert(pc <= lastpc);
371 break;
372 }
373 default: 368 default:
374 if (testAMode(op) && reg == a) what = NULL; 369 if (testAMode(op) && reg == a) what = NULL;
375 break; 370 break;
diff --git a/ldo.c b/ldo.c
index 913375b0..d3c9906d 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.66 2009/07/15 17:26:14 roberto Exp roberto $ 2** $Id: ldo.c,v 2.67 2009/09/14 14:30:39 roberto Exp roberto $
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*/
@@ -577,10 +577,10 @@ static void f_parser (lua_State *L, void *ud) {
577 : luaY_parser(L, p->z, &p->buff, p->name); 577 : luaY_parser(L, p->z, &p->buff, p->name);
578 setptvalue2s(L, L->top, tf); 578 setptvalue2s(L, L->top, tf);
579 incr_top(L); 579 incr_top(L);
580 cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); 580 cl = luaF_newLclosure(L, tf->sizeupvalues, hvalue(gt(L)));
581 cl->l.p = tf; 581 cl->l.p = tf;
582 setclvalue(L, L->top - 1, cl); 582 setclvalue(L, L->top - 1, cl);
583 for (i = 0; i < tf->nups; i++) /* initialize upvalues */ 583 for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */
584 cl->l.upvals[i] = luaF_newupval(L); 584 cl->l.upvals[i] = luaF_newupval(L);
585} 585}
586 586
diff --git a/ldump.c b/ldump.c
index e17c9363..e8337f03 100644
--- a/ldump.c
+++ b/ldump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldump.c,v 2.9 2006/09/11 14:07:24 roberto Exp roberto $ 2** $Id: ldump.c,v 2.10 2008/07/03 14:25:05 roberto Exp roberto $
3** save precompiled Lua chunks 3** save precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -108,6 +108,17 @@ static void DumpConstants(const Proto* f, DumpState* D)
108 for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D); 108 for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
109} 109}
110 110
111static void DumpUpvalues(const Proto* f, DumpState* D)
112{
113 int i,n=f->sizeupvalues;
114 DumpInt(n,D);
115 for (i=0; i<n; i++)
116 {
117 DumpChar(f->upvalues[i].instack, D);
118 DumpChar(f->upvalues[i].idx, D);
119 }
120}
121
111static void DumpDebug(const Proto* f, DumpState* D) 122static void DumpDebug(const Proto* f, DumpState* D)
112{ 123{
113 int i,n; 124 int i,n;
@@ -123,7 +134,7 @@ static void DumpDebug(const Proto* f, DumpState* D)
123 } 134 }
124 n= (D->strip) ? 0 : f->sizeupvalues; 135 n= (D->strip) ? 0 : f->sizeupvalues;
125 DumpInt(n,D); 136 DumpInt(n,D);
126 for (i=0; i<n; i++) DumpString(f->upvalues[i],D); 137 for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);
127} 138}
128 139
129static void DumpFunction(const Proto* f, const TString* p, DumpState* D) 140static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
@@ -131,12 +142,12 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
131 DumpString((f->source==p || D->strip) ? NULL : f->source,D); 142 DumpString((f->source==p || D->strip) ? NULL : f->source,D);
132 DumpInt(f->linedefined,D); 143 DumpInt(f->linedefined,D);
133 DumpInt(f->lastlinedefined,D); 144 DumpInt(f->lastlinedefined,D);
134 DumpChar(f->nups,D);
135 DumpChar(f->numparams,D); 145 DumpChar(f->numparams,D);
136 DumpChar(f->is_vararg,D); 146 DumpChar(f->is_vararg,D);
137 DumpChar(f->maxstacksize,D); 147 DumpChar(f->maxstacksize,D);
138 DumpCode(f,D); 148 DumpCode(f,D);
139 DumpConstants(f,D); 149 DumpConstants(f,D);
150 DumpUpvalues(f,D);
140 DumpDebug(f,D); 151 DumpDebug(f,D);
141} 152}
142 153
diff --git a/lfunc.c b/lfunc.c
index f4c35a2e..c6c63f2e 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 2.13 2007/02/07 17:48:52 roberto Exp roberto $ 2** $Id: lfunc.c,v 2.14 2009/04/17 14:40:13 roberto Exp roberto $
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*/
@@ -121,16 +121,15 @@ Proto *luaF_newproto (lua_State *L) {
121 f->sizep = 0; 121 f->sizep = 0;
122 f->code = NULL; 122 f->code = NULL;
123 f->sizecode = 0; 123 f->sizecode = 0;
124 f->lineinfo = NULL;
124 f->sizelineinfo = 0; 125 f->sizelineinfo = 0;
125 f->sizeupvalues = 0;
126 f->nups = 0;
127 f->upvalues = NULL; 126 f->upvalues = NULL;
127 f->sizeupvalues = 0;
128 f->numparams = 0; 128 f->numparams = 0;
129 f->is_vararg = 0; 129 f->is_vararg = 0;
130 f->maxstacksize = 0; 130 f->maxstacksize = 0;
131 f->lineinfo = NULL;
132 f->sizelocvars = 0;
133 f->locvars = NULL; 131 f->locvars = NULL;
132 f->sizelocvars = 0;
134 f->linedefined = 0; 133 f->linedefined = 0;
135 f->lastlinedefined = 0; 134 f->lastlinedefined = 0;
136 f->source = NULL; 135 f->source = NULL;
diff --git a/lgc.c b/lgc.c
index a3680f1e..06a5a249 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.55 2009/07/16 16:26:09 roberto Exp roberto $ 2** $Id: lgc.c,v 2.56 2009/09/28 13:50:34 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -349,8 +349,8 @@ static void traverseproto (global_State *g, Proto *f) {
349 for (i=0; i<f->sizek; i++) /* mark literals */ 349 for (i=0; i<f->sizek; i++) /* mark literals */
350 markvalue(g, &f->k[i]); 350 markvalue(g, &f->k[i]);
351 for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */ 351 for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
352 if (f->upvalues[i]) 352 if (f->upvalues[i].name)
353 stringmark(f->upvalues[i]); 353 stringmark(f->upvalues[i].name);
354 } 354 }
355 for (i=0; i<f->sizep; i++) /* mark nested protos */ 355 for (i=0; i<f->sizep; i++) /* mark nested protos */
356 markobject(g, f->p[i]); 356 markobject(g, f->p[i]);
@@ -371,7 +371,7 @@ static void traverseclosure (global_State *g, Closure *cl) {
371 } 371 }
372 else { 372 else {
373 int i; 373 int i;
374 lua_assert(cl->l.nupvalues == cl->l.p->nups); 374 lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
375 markobject(g, cl->l.p); 375 markobject(g, cl->l.p);
376 for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ 376 for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
377 markobject(g, cl->l.upvals[i]); 377 markobject(g, cl->l.upvals[i]);
diff --git a/lobject.h b/lobject.h
index 10eb363f..8b93f70a 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.27 2009/06/18 16:36:40 roberto Exp roberto $ 2** $Id: lobject.h,v 2.28 2009/07/15 18:37:19 roberto Exp roberto $
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*/
@@ -227,6 +227,15 @@ typedef union Udata {
227 227
228 228
229 229
230/*
231** Upvalues from a function prototype
232*/
233typedef struct Upvaldesc {
234 TString *name; /* upvalue name (for debug information) */
235 lu_byte instack;
236 lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
237} Upvaldesc;
238
230 239
231/* 240/*
232** Function Prototypes 241** Function Prototypes
@@ -238,9 +247,9 @@ typedef struct Proto {
238 struct Proto **p; /* functions defined inside the function */ 247 struct Proto **p; /* functions defined inside the function */
239 int *lineinfo; /* map from opcodes to source lines */ 248 int *lineinfo; /* map from opcodes to source lines */
240 struct LocVar *locvars; /* information about local variables */ 249 struct LocVar *locvars; /* information about local variables */
241 TString **upvalues; /* upvalue names */ 250 Upvaldesc *upvalues; /* upvalue information */
242 TString *source; 251 TString *source;
243 int sizeupvalues; 252 int sizeupvalues; /* size of 'upvalues' */
244 int sizek; /* size of `k' */ 253 int sizek; /* size of `k' */
245 int sizecode; 254 int sizecode;
246 int sizelineinfo; 255 int sizelineinfo;
@@ -249,7 +258,6 @@ typedef struct Proto {
249 int linedefined; 258 int linedefined;
250 int lastlinedefined; 259 int lastlinedefined;
251 GCObject *gclist; 260 GCObject *gclist;
252 lu_byte nups; /* number of upvalues */
253 lu_byte numparams; 261 lu_byte numparams;
254 lu_byte is_vararg; 262 lu_byte is_vararg;
255 lu_byte maxstacksize; 263 lu_byte maxstacksize;
diff --git a/lopcodes.h b/lopcodes.h
index 866c1641..41910d1b 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.129 2009/03/09 15:27:56 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.130 2009/09/23 20:33:05 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -251,10 +251,6 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
251 251
252 (*) All `skips' (pc++) assume that next instruction is a jump. 252 (*) All `skips' (pc++) assume that next instruction is a jump.
253 253
254 (*) The OP_CLOSURE instruction is followed by a sequence of
255 instructions coding the upvalues: OP_MOVE A B if upvalue is local B,
256 or OP_GETUPVAL A B if upvalue is enclosing upvalue B.
257
258===========================================================================*/ 254===========================================================================*/
259 255
260 256
diff --git a/lparser.c b/lparser.c
index 29fd747c..935526ce 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.65 2009/08/10 20:41:04 roberto Exp roberto $ 2** $Id: lparser.c,v 2.66 2009/09/23 20:14:00 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -188,23 +188,24 @@ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
188 int i; 188 int i;
189 Proto *f = fs->f; 189 Proto *f = fs->f;
190 int oldsize = f->sizeupvalues; 190 int oldsize = f->sizeupvalues;
191 for (i=0; i<f->nups; i++) { 191 int instk = (v->k == VLOCAL);
192 if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { 192 lua_assert(instk || v->k == VUPVAL);
193 lua_assert(f->upvalues[i] == name); 193 for (i=0; i<fs->nups; i++) {
194 if (f->upvalues[i].instack == instk && f->upvalues[i].idx == v->u.s.info) {
195 lua_assert(f->upvalues[i].name == name);
194 return i; 196 return i;
195 } 197 }
196 } 198 }
197 /* new one */ 199 /* new one */
198 luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); 200 luaY_checklimit(fs, fs->nups + 1, UCHAR_MAX, "upvalues");
199 luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, 201 luaM_growvector(fs->L, f->upvalues, fs->nups, f->sizeupvalues,
200 TString *, MAX_INT, "upvalues"); 202 Upvaldesc, UCHAR_MAX, "upvalues");
201 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; 203 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
202 f->upvalues[f->nups] = name; 204 f->upvalues[fs->nups].name = name;
203 luaC_objbarrier(fs->L, f, name); 205 luaC_objbarrier(fs->L, f, name);
204 lua_assert(v->k == VLOCAL || v->k == VUPVAL); 206 f->upvalues[fs->nups].instack = cast_byte(instk);
205 fs->upvalues[f->nups].k = cast_byte(v->k); 207 f->upvalues[fs->nups].idx = cast_byte(v->u.s.info);
206 fs->upvalues[f->nups].info = cast_byte(v->u.s.info); 208 return fs->nups++;
207 return f->nups++;
208} 209}
209 210
210 211
@@ -316,17 +317,12 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
316 FuncState *fs = ls->fs->prev; 317 FuncState *fs = ls->fs->prev;
317 Proto *f = fs->f; 318 Proto *f = fs->f;
318 int oldsize = f->sizep; 319 int oldsize = f->sizep;
319 int i;
320 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, 320 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
321 MAXARG_Bx, "functions"); 321 MAXARG_Bx, "functions");
322 while (oldsize < f->sizep) f->p[oldsize++] = NULL; 322 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
323 f->p[fs->np++] = func->f; 323 f->p[fs->np++] = func->f;
324 luaC_objbarrier(ls->L, f, func->f); 324 luaC_objbarrier(ls->L, f, func->f);
325 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); 325 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
326 for (i=0; i<func->f->nups; i++) {
327 OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
328 luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
329 }
330} 326}
331 327
332 328
@@ -343,6 +339,7 @@ static void open_func (LexState *ls, FuncState *fs) {
343 fs->freereg = 0; 339 fs->freereg = 0;
344 fs->nk = 0; 340 fs->nk = 0;
345 fs->np = 0; 341 fs->np = 0;
342 fs->nups = 0;
346 fs->nlocvars = 0; 343 fs->nlocvars = 0;
347 fs->nactvar = 0; 344 fs->nactvar = 0;
348 fs->bl = NULL; 345 fs->bl = NULL;
@@ -376,8 +373,8 @@ static void close_func (LexState *ls) {
376 f->sizep = fs->np; 373 f->sizep = fs->np;
377 luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); 374 luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
378 f->sizelocvars = fs->nlocvars; 375 f->sizelocvars = fs->nlocvars;
379 luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); 376 luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
380 f->sizeupvalues = f->nups; 377 f->sizeupvalues = fs->nups;
381 lua_assert(fs->bl == NULL); 378 lua_assert(fs->bl == NULL);
382 ls->fs = fs->prev; 379 ls->fs = fs->prev;
383 L->top -= 2; /* remove table and prototype from the stack */ 380 L->top -= 2; /* remove table and prototype from the stack */
@@ -402,7 +399,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
402 close_func(&lexstate); 399 close_func(&lexstate);
403 L->top--; 400 L->top--;
404 lua_assert(funcstate.prev == NULL); 401 lua_assert(funcstate.prev == NULL);
405 lua_assert(funcstate.f->nups == 0); 402 lua_assert(funcstate.nups == 0);
406 lua_assert(lexstate.fs == NULL); 403 lua_assert(lexstate.fs == NULL);
407 return funcstate.f; 404 return funcstate.f;
408} 405}
diff --git a/lparser.h b/lparser.h
index 0e06b1ad..5e1856e2 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.57 2006/03/09 18:14:31 roberto Exp roberto $ 2** $Id: lparser.h,v 1.58 2008/05/08 15:44:51 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -46,12 +46,6 @@ typedef struct expdesc {
46} expdesc; 46} expdesc;
47 47
48 48
49typedef struct upvaldesc {
50 lu_byte k;
51 lu_byte info;
52} upvaldesc;
53
54
55typedef struct vardesc { 49typedef struct vardesc {
56 unsigned short idx; 50 unsigned short idx;
57} vardesc; 51} vardesc;
@@ -76,7 +70,7 @@ typedef struct FuncState {
76 int np; /* number of elements in `p' */ 70 int np; /* number of elements in `p' */
77 short nlocvars; /* number of elements in `locvars' */ 71 short nlocvars; /* number of elements in `locvars' */
78 lu_byte nactvar; /* number of active local variables */ 72 lu_byte nactvar; /* number of active local variables */
79 upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ 73 lu_byte nups; /* number of upvalues */
80 vardesc actvar[LUAI_MAXVARS]; /* declared-variable stack */ 74 vardesc actvar[LUAI_MAXVARS]; /* declared-variable stack */
81} FuncState; 75} FuncState;
82 76
diff --git a/ltests.c b/ltests.c
index 0becc766..77677680 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.71 2009/09/14 14:30:39 roberto Exp roberto $ 2** $Id: ltests.c,v 2.72 2009/09/17 18:04:21 roberto Exp roberto $
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*/
@@ -248,8 +248,8 @@ static void checkproto (global_State *g, Proto *f) {
248 checkobjref(g, fgc, rawtsvalue(f->k+i)); 248 checkobjref(g, fgc, rawtsvalue(f->k+i));
249 } 249 }
250 for (i=0; i<f->sizeupvalues; i++) { 250 for (i=0; i<f->sizeupvalues; i++) {
251 if (f->upvalues[i]) 251 if (f->upvalues[i].name)
252 checkobjref(g, fgc, f->upvalues[i]); 252 checkobjref(g, fgc, f->upvalues[i].name);
253 } 253 }
254 for (i=0; i<f->sizep; i++) { 254 for (i=0; i<f->sizep; i++) {
255 if (f->p[i]) 255 if (f->p[i])
@@ -273,7 +273,7 @@ static void checkclosure (global_State *g, Closure *cl) {
273 } 273 }
274 else { 274 else {
275 int i; 275 int i;
276 lua_assert(cl->l.nupvalues == cl->l.p->nups); 276 lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
277 checkobjref(g, clgc, cl->l.p); 277 checkobjref(g, clgc, cl->l.p);
278 for (i=0; i<cl->l.nupvalues; i++) { 278 for (i=0; i<cl->l.nupvalues; i++) {
279 if (cl->l.upvals[i]) { 279 if (cl->l.upvals[i]) {
@@ -493,7 +493,6 @@ static int get_limits (lua_State *L) {
493 setnameval(L, "LFPF", LFIELDS_PER_FLUSH); 493 setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
494 setnameval(L, "MAXVARS", LUAI_MAXVARS); 494 setnameval(L, "MAXVARS", LUAI_MAXVARS);
495 setnameval(L, "MAXSTACK", MAXSTACK); 495 setnameval(L, "MAXSTACK", MAXSTACK);
496 setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES);
497 setnameval(L, "NUM_OPCODES", NUM_OPCODES); 496 setnameval(L, "NUM_OPCODES", NUM_OPCODES);
498 return 1; 497 return 1;
499} 498}
diff --git a/luaconf.h b/luaconf.h
index 1358633d..c18681dc 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: luaconf.h,v 1.108 2009/07/15 17:57:30 roberto Exp roberto $ 2** $Id: luaconf.h,v 1.109 2009/08/25 19:58:08 roberto Exp roberto $
3** Configuration file for Lua 3** Configuration file for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -462,13 +462,6 @@
462 462
463 463
464/* 464/*
465@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
466@* (must be smaller than 250).
467*/
468#define LUAI_MAXUPVALUES 60
469
470
471/*
472@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. 465@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
473*/ 466*/
474#define LUAL_BUFFERSIZE BUFSIZ 467#define LUAL_BUFFERSIZE BUFSIZ
diff --git a/lundump.c b/lundump.c
index bdebe74b..4ee11ac6 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 2.9 2008/04/07 18:44:23 roberto Exp roberto $ 2** $Id: lundump.c,v 2.10 2009/04/30 17:42:21 roberto Exp roberto $
3** load precompiled Lua chunks 3** load precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -133,6 +133,20 @@ static void LoadConstants(LoadState* S, Proto* f)
133 for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source); 133 for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
134} 134}
135 135
136static void LoadUpvalues(LoadState* S, Proto* f)
137{
138 int i,n;
139 n=LoadInt(S);
140 f->upvalues=luaM_newvector(S->L,n,Upvaldesc);
141 f->sizeupvalues=n;
142 for (i=0; i<n; i++) f->upvalues[i].name=NULL;
143 for (i=0; i<n; i++)
144 {
145 f->upvalues[i].instack=LoadChar(S);
146 f->upvalues[i].idx=LoadChar(S);
147 }
148}
149
136static void LoadDebug(LoadState* S, Proto* f) 150static void LoadDebug(LoadState* S, Proto* f)
137{ 151{
138 int i,n; 152 int i,n;
@@ -151,10 +165,7 @@ static void LoadDebug(LoadState* S, Proto* f)
151 f->locvars[i].endpc=LoadInt(S); 165 f->locvars[i].endpc=LoadInt(S);
152 } 166 }
153 n=LoadInt(S); 167 n=LoadInt(S);
154 f->upvalues=luaM_newvector(S->L,n,TString*); 168 for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
155 f->sizeupvalues=n;
156 for (i=0; i<n; i++) f->upvalues[i]=NULL;
157 for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
158} 169}
159 170
160static Proto* LoadFunction(LoadState* S, TString* p) 171static Proto* LoadFunction(LoadState* S, TString* p)
@@ -166,12 +177,12 @@ static Proto* LoadFunction(LoadState* S, TString* p)
166 f->source=LoadString(S); if (f->source==NULL) f->source=p; 177 f->source=LoadString(S); if (f->source==NULL) f->source=p;
167 f->linedefined=LoadInt(S); 178 f->linedefined=LoadInt(S);
168 f->lastlinedefined=LoadInt(S); 179 f->lastlinedefined=LoadInt(S);
169 f->nups=LoadByte(S);
170 f->numparams=LoadByte(S); 180 f->numparams=LoadByte(S);
171 f->is_vararg=LoadByte(S); 181 f->is_vararg=LoadByte(S);
172 f->maxstacksize=LoadByte(S); 182 f->maxstacksize=LoadByte(S);
173 LoadCode(S,f); 183 LoadCode(S,f);
174 LoadConstants(S,f); 184 LoadConstants(S,f);
185 LoadUpvalues(S,f);
175 LoadDebug(S,f); 186 LoadDebug(S,f);
176 S->L->top--; 187 S->L->top--;
177 G(S->L)->nCcalls--; 188 G(S->L)->nCcalls--;
diff --git a/lvm.c b/lvm.c
index f3a452de..7473d73b 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.96 2009/08/07 16:17:41 roberto Exp roberto $ 2** $Id: lvm.c,v 2.97 2009/09/23 20:33:05 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -773,22 +773,18 @@ void luaV_execute (lua_State *L) {
773 continue; 773 continue;
774 } 774 }
775 case OP_CLOSURE: { 775 case OP_CLOSURE: {
776 Proto *p; 776 Proto *p = cl->p->p[GETARG_Bx(i)]; /* prototype for new closure */
777 Closure *ncl; 777 int nup = p->sizeupvalues;
778 int nup, j; 778 Closure *ncl = luaF_newLclosure(L, nup, cl->env);
779 p = cl->p->p[GETARG_Bx(i)]; 779 Upvaldesc *uv = p->upvalues;
780 nup = p->nups; 780 int j;
781 ncl = luaF_newLclosure(L, nup, cl->env);
782 ncl->l.p = p; 781 ncl->l.p = p;
783 setclvalue(L, ra, ncl); 782 setclvalue(L, ra, ncl); /* anchor new closure in stack */
784 for (j=0; j<nup; j++) { 783 for (j = 0; j < nup; j++) { /* fill in upvalues */
785 Instruction u = *ci->u.l.savedpc++; 784 if (uv[j].instack) /* upvalue refers to local variable? */
786 if (GET_OPCODE(u) == OP_GETUPVAL) 785 ncl->l.upvals[j] = luaF_findupval(L, base + uv[j].idx);
787 ncl->l.upvals[j] = cl->upvals[GETARG_B(u)]; 786 else /* get upvalue from enclosing function */
788 else { 787 ncl->l.upvals[j] = cl->upvals[uv[j].idx];
789 lua_assert(GET_OPCODE(u) == OP_MOVE);
790 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(u));
791 }
792 } 788 }
793 Protect(luaC_checkGC(L)); 789 Protect(luaC_checkGC(L));
794 continue; 790 continue;