aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c6
-rw-r--r--lcode.c12
-rw-r--r--ldo.c22
-rw-r--r--ldo.h4
-rw-r--r--lgc.c27
-rw-r--r--llex.c18
-rw-r--r--llex.h3
-rw-r--r--lobject.h37
-rw-r--r--lparser.c46
-rw-r--r--lundump.c10
10 files changed, 120 insertions, 65 deletions
diff --git a/lapi.c b/lapi.c
index 966f72ec..33eed2eb 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.242 2003/08/25 19:51:54 roberto Exp roberto $ 2** $Id: lapi.c,v 1.243 2003/08/25 20:00:50 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*/
@@ -715,12 +715,10 @@ LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
715 const char *chunkname) { 715 const char *chunkname) {
716 ZIO z; 716 ZIO z;
717 int status; 717 int status;
718 int c;
719 lua_lock(L); 718 lua_lock(L);
720 if (!chunkname) chunkname = "?"; 719 if (!chunkname) chunkname = "?";
721 luaZ_init(L, &z, reader, data); 720 luaZ_init(L, &z, reader, data);
722 c = luaZ_lookahead(&z); 721 status = luaD_protectedparser(L, &z, chunkname);
723 status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]), chunkname);
724 lua_unlock(L); 722 lua_unlock(L);
725 return status; 723 return status;
726} 724}
diff --git a/lcode.c b/lcode.c
index bb15a1cd..1f63a0d0 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.117 2003/04/03 13:35:34 roberto Exp roberto $ 2** $Id: lcode.c,v 1.119 2003/08/27 20:58:52 roberto Exp $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -207,17 +207,19 @@ static void freeexp (FuncState *fs, expdesc *e) {
207 207
208 208
209static int addk (FuncState *fs, TObject *k, TObject *v) { 209static int addk (FuncState *fs, TObject *k, TObject *v) {
210 const TObject *idx = luaH_get(fs->h, k); 210 TObject *idx = luaH_set(fs->L, fs->h, k);
211 Proto *f = fs->f;
212 int oldsize = f->sizek;
211 if (ttisnumber(idx)) { 213 if (ttisnumber(idx)) {
212 lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v)); 214 lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
213 return cast(int, nvalue(idx)); 215 return cast(int, nvalue(idx));
214 } 216 }
215 else { /* constant not found; create a new entry */ 217 else { /* constant not found; create a new entry */
216 Proto *f = fs->f; 218 setnvalue(idx, cast(lua_Number, fs->nk));
217 luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, 219 luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
218 MAXARG_Bx, "constant table overflow"); 220 MAXARG_Bx, "constant table overflow");
219 setobj2n(&f->k[fs->nk], v); 221 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
220 setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk)); 222 setobj(&f->k[fs->nk], v); /* write barrier */
221 return fs->nk++; 223 return fs->nk++;
222 } 224 }
223} 225}
diff --git a/ldo.c b/ldo.c
index 2b5dfdbf..bf244c91 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.222 2003/08/25 19:51:54 roberto Exp roberto $ 2** $Id: ldo.c,v 1.223 2003/08/26 12:04:13 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*/
@@ -429,18 +429,17 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
429struct SParser { /* data to `f_parser' */ 429struct SParser { /* data to `f_parser' */
430 ZIO *z; 430 ZIO *z;
431 Mbuffer buff; /* buffer to be used by the scanner */ 431 Mbuffer buff; /* buffer to be used by the scanner */
432 int bin;
433 const char *name; 432 const char *name;
434}; 433};
435 434
436static void f_parser (lua_State *L, void *ud) { 435static void f_parser (lua_State *L, void *ud) {
437 struct SParser *p;
438 Proto *tf; 436 Proto *tf;
439 Closure *cl; 437 Closure *cl;
438 struct SParser *p = cast(struct SParser *, ud);
439 int c = luaZ_lookahead(p->z);
440 luaC_checkGC(L); 440 luaC_checkGC(L);
441 p = cast(struct SParser *, ud); 441 tf = (c == LUA_SIGNATURE[0]) ? luaU_undump(L, p->z, &p->buff, p->name) :
442 tf = p->bin ? luaU_undump(L, p->z, &p->buff, p->name) : 442 luaY_parser(L, p->z, &p->buff, p->name);
443 luaY_parser(L, p->z, &p->buff, p->name);
444 cl = luaF_newLclosure(L, 0, gt(L)); 443 cl = luaF_newLclosure(L, 0, gt(L));
445 cl->l.p = tf; 444 cl->l.p = tf;
446 setclvalue(L->top, cl); 445 setclvalue(L->top, cl);
@@ -448,18 +447,13 @@ static void f_parser (lua_State *L, void *ud) {
448} 447}
449 448
450 449
451int luaD_protectedparser (lua_State *L, ZIO *z, int bin, const char *name) { 450int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
452 struct SParser p; 451 struct SParser p;
453 int status; 452 int status;
454 ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */ 453 p.z = z; p.name = name;
455 p.z = z; p.bin = bin; p.name = name;
456 luaZ_initbuffer(L, &p.buff); 454 luaZ_initbuffer(L, &p.buff);
457 status = luaD_rawrunprotected(L, f_parser, &p); 455 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
458 luaZ_freebuffer(L, &p.buff); 456 luaZ_freebuffer(L, &p.buff);
459 if (status != 0) { /* error? */
460 StkId oldtop = restorestack(L, oldtopr);
461 seterrorobj(L, status, oldtop);
462 }
463 return status; 457 return status;
464} 458}
465 459
diff --git a/ldo.h b/ldo.h
index af13516f..f3d528be 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 1.56 2002/12/04 17:29:32 roberto Exp roberto $ 2** $Id: ldo.h,v 1.57 2003/08/25 19:51:54 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*/
@@ -42,7 +42,7 @@
42typedef void (*Pfunc) (lua_State *L, void *ud); 42typedef void (*Pfunc) (lua_State *L, void *ud);
43 43
44void luaD_resetprotection (lua_State *L); 44void luaD_resetprotection (lua_State *L);
45int luaD_protectedparser (lua_State *L, ZIO *z, int bin, const char *name); 45int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
46void luaD_callhook (lua_State *L, int event, int line); 46void luaD_callhook (lua_State *L, int event, int line);
47StkId luaD_precall (lua_State *L, StkId func); 47StkId luaD_precall (lua_State *L, StkId func);
48void luaD_call (lua_State *L, StkId func, int nResults); 48void luaD_call (lua_State *L, StkId func, int nResults);
diff --git a/lgc.c b/lgc.c
index d5169fdc..1ec12f1d 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.175 2003/07/16 20:49:02 roberto Exp roberto $ 2** $Id: lgc.c,v 1.176 2003/07/29 19:25:37 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*/
@@ -176,20 +176,29 @@ static void traversetable (GCState *st, Table *h) {
176} 176}
177 177
178 178
179/*
180** All marks are conditional because a GC may happen while the
181** prototype is still being created
182*/
179static void traverseproto (GCState *st, Proto *f) { 183static void traverseproto (GCState *st, Proto *f) {
180 int i; 184 int i;
181 stringmark(f->source); 185 if (f->source) stringmark(f->source);
182 for (i=0; i<f->sizek; i++) { /* mark literal strings */ 186 for (i=0; i<f->sizek; i++) { /* mark literal strings */
183 if (ttisstring(f->k+i)) 187 if (ttisstring(f->k+i))
184 stringmark(tsvalue(f->k+i)); 188 stringmark(tsvalue(f->k+i));
185 } 189 }
186 for (i=0; i<f->sizeupvalues; i++) /* mark upvalue names */ 190 for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
187 stringmark(f->upvalues[i]); 191 if (f->upvalues[i])
188 for (i=0; i<f->sizep; i++) /* mark nested protos */ 192 stringmark(f->upvalues[i]);
189 markvalue(st, f->p[i]); 193 }
190 for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */ 194 for (i=0; i<f->sizep; i++) { /* mark nested protos */
191 stringmark(f->locvars[i].varname); 195 if (f->p[i])
192 lua_assert(luaG_checkcode(f)); 196 markvalue(st, f->p[i]);
197 }
198 for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
199 if (f->locvars[i].varname)
200 stringmark(f->locvars[i].varname);
201 }
193} 202}
194 203
195 204
diff --git a/llex.c b/llex.c
index 217194b6..e7b20a46 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 1.120 2003/05/15 12:20:24 roberto Exp roberto $ 2** $Id: llex.c,v 1.121 2003/08/21 14:16:43 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -111,6 +111,16 @@ static void luaX_lexerror (LexState *ls, const char *s, int token) {
111} 111}
112 112
113 113
114TString *luaX_newstring (LexState *LS, const char *str, size_t l) {
115 lua_State *L = LS->L;
116 TString *ts = luaS_newlstr(L, str, l);
117 TObject *o = luaH_setstr(L, LS->fs->h, ts); /* entry for `str' */
118 if (ttisnil(o))
119 setbvalue(o, 1); /* make sure `str' will not be collected */
120 return ts;
121}
122
123
114static void inclinenumber (LexState *LS) { 124static void inclinenumber (LexState *LS) {
115 int old = LS->current; 125 int old = LS->current;
116 lua_assert(nextIsNewline(LS)); 126 lua_assert(nextIsNewline(LS));
@@ -253,7 +263,7 @@ static void read_long_string (LexState *LS, SemInfo *seminfo) {
253 save_and_next(LS, l); /* skip the second `]' */ 263 save_and_next(LS, l); /* skip the second `]' */
254 save(LS, '\0', l); 264 save(LS, '\0', l);
255 if (seminfo) 265 if (seminfo)
256 seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 2, l - 5); 266 seminfo->ts = luaX_newstring(LS, luaZ_buffer(LS->buff) + 2, l - 5);
257} 267}
258 268
259 269
@@ -311,7 +321,7 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) {
311 } 321 }
312 save_and_next(LS, l); /* skip delimiter */ 322 save_and_next(LS, l); /* skip delimiter */
313 save(LS, '\0', l); 323 save(LS, '\0', l);
314 seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 1, l - 3); 324 seminfo->ts = luaX_newstring(LS, luaZ_buffer(LS->buff) + 1, l - 3);
315} 325}
316 326
317 327
@@ -401,7 +411,7 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) {
401 else if (isalpha(LS->current) || LS->current == '_') { 411 else if (isalpha(LS->current) || LS->current == '_') {
402 /* identifier or reserved word */ 412 /* identifier or reserved word */
403 size_t l = readname(LS); 413 size_t l = readname(LS);
404 TString *ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff), l); 414 TString *ts = luaX_newstring(LS, luaZ_buffer(LS->buff), l);
405 if (ts->tsv.reserved > 0) /* reserved word? */ 415 if (ts->tsv.reserved > 0) /* reserved word? */
406 return ts->tsv.reserved - 1 + FIRST_RESERVED; 416 return ts->tsv.reserved - 1 + FIRST_RESERVED;
407 seminfo->ts = ts; 417 seminfo->ts = ts;
diff --git a/llex.h b/llex.h
index 00c73c77..a97def0a 100644
--- a/llex.h
+++ b/llex.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.h,v 1.46 2002/11/22 16:35:20 roberto Exp roberto $ 2** $Id: llex.h,v 1.47 2003/02/28 17:19:47 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -65,6 +65,7 @@ typedef struct LexState {
65 65
66void luaX_init (lua_State *L); 66void luaX_init (lua_State *L);
67void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source); 67void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
68TString *luaX_newstring (LexState *LS, const char *str, size_t l);
68int luaX_lex (LexState *LS, SemInfo *seminfo); 69int luaX_lex (LexState *LS, SemInfo *seminfo);
69void luaX_checklimit (LexState *ls, int val, int limit, const char *msg); 70void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
70void luaX_syntaxerror (LexState *ls, const char *s); 71void luaX_syntaxerror (LexState *ls, const char *s);
diff --git a/lobject.h b/lobject.h
index 7488e2fe..86bc3601 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.159 2003/03/18 12:50:04 roberto Exp roberto $ 2** $Id: lobject.h,v 1.160 2003/04/28 19:26:16 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*/
@@ -92,44 +92,49 @@ typedef struct lua_TObject {
92#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) 92#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
93 93
94/* Macros to set values */ 94/* Macros to set values */
95#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
96
95#define setnvalue(obj,x) \ 97#define setnvalue(obj,x) \
96 { TObject *i_o=(obj); i_o->tt=LUA_TNUMBER; i_o->value.n=(x); } 98 { TObject *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
97 99
98#define chgnvalue(obj,x) \ 100#define chgnvalue(obj,x) \
99 check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x)) 101 check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x))
100 102
101#define setpvalue(obj,x) \ 103#define setpvalue(obj,x) \
102 { TObject *i_o=(obj); i_o->tt=LUA_TLIGHTUSERDATA; i_o->value.p=(x); } 104 { TObject *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
103 105
104#define setbvalue(obj,x) \ 106#define setbvalue(obj,x) \
105 { TObject *i_o=(obj); i_o->tt=LUA_TBOOLEAN; i_o->value.b=(x); } 107 { TObject *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
106 108
107#define setsvalue(obj,x) \ 109#define setsvalue(obj,x) \
108 { TObject *i_o=(obj); i_o->tt=LUA_TSTRING; \ 110 { TObject *i_o=(obj); \
109 i_o->value.gc=cast(GCObject *, (x)); \ 111 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
110 lua_assert(i_o->value.gc->gch.tt == LUA_TSTRING); } 112 lua_assert(i_o->value.gc->gch.tt == LUA_TSTRING); }
111 113
112#define setuvalue(obj,x) \ 114#define setuvalue(obj,x) \
113 { TObject *i_o=(obj); i_o->tt=LUA_TUSERDATA; \ 115 { TObject *i_o=(obj); \
114 i_o->value.gc=cast(GCObject *, (x)); \ 116 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
115 lua_assert(i_o->value.gc->gch.tt == LUA_TUSERDATA); } 117 lua_assert(i_o->value.gc->gch.tt == LUA_TUSERDATA); }
116 118
117#define setthvalue(obj,x) \ 119#define setthvalue(obj,x) \
118 { TObject *i_o=(obj); i_o->tt=LUA_TTHREAD; \ 120 { TObject *i_o=(obj); \
119 i_o->value.gc=cast(GCObject *, (x)); \ 121 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
120 lua_assert(i_o->value.gc->gch.tt == LUA_TTHREAD); } 122 lua_assert(i_o->value.gc->gch.tt == LUA_TTHREAD); }
121 123
122#define setclvalue(obj,x) \ 124#define setclvalue(obj,x) \
123 { TObject *i_o=(obj); i_o->tt=LUA_TFUNCTION; \ 125 { TObject *i_o=(obj); \
124 i_o->value.gc=cast(GCObject *, (x)); \ 126 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
125 lua_assert(i_o->value.gc->gch.tt == LUA_TFUNCTION); } 127 lua_assert(i_o->value.gc->gch.tt == LUA_TFUNCTION); }
126 128
127#define sethvalue(obj,x) \ 129#define sethvalue(obj,x) \
128 { TObject *i_o=(obj); i_o->tt=LUA_TTABLE; \ 130 { TObject *i_o=(obj); \
129 i_o->value.gc=cast(GCObject *, (x)); \ 131 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
130 lua_assert(i_o->value.gc->gch.tt == LUA_TTABLE); } 132 lua_assert(i_o->value.gc->gch.tt == LUA_TTABLE); }
131 133
132#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) 134#define setptvalue(obj,x) \
135 { TObject *i_o=(obj); \
136 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
137 lua_assert(i_o->value.gc->gch.tt == LUA_TPROTO); }
133 138
134 139
135 140
@@ -155,6 +160,8 @@ typedef struct lua_TObject {
155/* to stack (not from same stack) */ 160/* to stack (not from same stack) */
156#define setobj2s setobj 161#define setobj2s setobj
157#define setsvalue2s setsvalue 162#define setsvalue2s setsvalue
163#define sethvalue2s sethvalue
164#define setptvalue2s setptvalue
158/* from table to same table */ 165/* from table to same table */
159#define setobjt2t setobj 166#define setobjt2t setobj
160/* to table */ 167/* to table */
diff --git a/lparser.c b/lparser.c
index 1eb56401..633a5693 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.215 2003/07/29 18:51:00 roberto Exp roberto $ 2** $Id: lparser.c,v 1.216 2003/08/25 19:51:54 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*/
@@ -13,6 +13,7 @@
13 13
14#include "lcode.h" 14#include "lcode.h"
15#include "ldebug.h" 15#include "ldebug.h"
16#include "ldo.h"
16#include "lfunc.h" 17#include "lfunc.h"
17#include "llex.h" 18#include "llex.h"
18#include "lmem.h" 19#include "lmem.h"
@@ -71,6 +72,14 @@ static void lookahead (LexState *ls) {
71} 72}
72 73
73 74
75static void anchor_token (LexState *ls) {
76 if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
77 TString *ts = ls->t.seminfo.ts;
78 luaX_newstring(ls, getstr(ts), ts->tsv.len);
79 }
80}
81
82
74static void error_expected (LexState *ls, int token) { 83static void error_expected (LexState *ls, int token) {
75 luaX_syntaxerror(ls, 84 luaX_syntaxerror(ls,
76 luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token))); 85 luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token)));
@@ -138,9 +147,11 @@ static void checkname(LexState *ls, expdesc *e) {
138static int luaI_registerlocalvar (LexState *ls, TString *varname) { 147static int luaI_registerlocalvar (LexState *ls, TString *varname) {
139 FuncState *fs = ls->fs; 148 FuncState *fs = ls->fs;
140 Proto *f = fs->f; 149 Proto *f = fs->f;
150 int oldsize = f->sizelocvars;
141 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, 151 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
142 LocVar, USHRT_MAX, "too many local variables"); 152 LocVar, USHRT_MAX, "too many local variables");
143 f->locvars[fs->nlocvars].varname = varname; 153 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
154 f->locvars[fs->nlocvars].varname = varname; /* write barrier */
144 return fs->nlocvars++; 155 return fs->nlocvars++;
145} 156}
146 157
@@ -170,24 +181,27 @@ static void removevars (LexState *ls, int tolevel) {
170 181
171 182
172static void new_localvarstr (LexState *ls, const char *name, int n) { 183static void new_localvarstr (LexState *ls, const char *name, int n) {
173 new_localvar(ls, luaS_new(ls->L, name), n); 184 TString *ts = luaX_newstring(ls, name, strlen(name));
185 new_localvar(ls, ts, n);
174} 186}
175 187
176 188
177static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { 189static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
178 int i; 190 int i;
179 Proto *f = fs->f; 191 Proto *f = fs->f;
192 int oldsize = f->sizeupvalues;
180 for (i=0; i<f->nups; i++) { 193 for (i=0; i<f->nups; i++) {
181 if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) { 194 if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) {
182 lua_assert(fs->f->upvalues[i] == name); 195 lua_assert(f->upvalues[i] == name);
183 return i; 196 return i;
184 } 197 }
185 } 198 }
186 /* new one */ 199 /* new one */
187 luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues"); 200 luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues");
188 luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues, 201 luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
189 TString *, MAX_INT, ""); 202 TString *, MAX_INT, "");
190 fs->f->upvalues[f->nups] = name; 203 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
204 f->upvalues[f->nups] = name; /* write barrier */
191 lua_assert(v->k == VLOCAL || v->k == VUPVAL); 205 lua_assert(v->k == VLOCAL || v->k == VUPVAL);
192 fs->upvalues[f->nups].k = cast(lu_byte, v->k); 206 fs->upvalues[f->nups].k = cast(lu_byte, v->k);
193 fs->upvalues[f->nups].info = cast(lu_byte, v->info); 207 fs->upvalues[f->nups].info = cast(lu_byte, v->info);
@@ -290,10 +304,12 @@ static void leaveblock (FuncState *fs) {
290static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { 304static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
291 FuncState *fs = ls->fs; 305 FuncState *fs = ls->fs;
292 Proto *f = fs->f; 306 Proto *f = fs->f;
307 int oldsize = f->sizep;
293 int i; 308 int i;
294 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, 309 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
295 MAXARG_Bx, "constant table overflow"); 310 MAXARG_Bx, "constant table overflow");
296 f->p[fs->np++] = func->f; 311 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
312 f->p[fs->np++] = func->f; /* write barrier */
297 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); 313 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
298 for (i=0; i<func->f->nups; i++) { 314 for (i=0; i<func->f->nups; i++) {
299 OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; 315 OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
@@ -303,24 +319,30 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
303 319
304 320
305static void open_func (LexState *ls, FuncState *fs) { 321static void open_func (LexState *ls, FuncState *fs) {
322 lua_State *L = ls->L;
306 Proto *f = luaF_newproto(ls->L); 323 Proto *f = luaF_newproto(ls->L);
307 fs->f = f; 324 fs->f = f;
308 fs->prev = ls->fs; /* linked list of funcstates */ 325 fs->prev = ls->fs; /* linked list of funcstates */
309 fs->ls = ls; 326 fs->ls = ls;
310 fs->L = ls->L; 327 fs->L = L;
311 ls->fs = fs; 328 ls->fs = fs;
312 fs->pc = 0; 329 fs->pc = 0;
313 fs->lasttarget = 0; 330 fs->lasttarget = 0;
314 fs->jpc = NO_JUMP; 331 fs->jpc = NO_JUMP;
315 fs->freereg = 0; 332 fs->freereg = 0;
316 fs->nk = 0; 333 fs->nk = 0;
317 fs->h = luaH_new(ls->L, 0, 0);
318 fs->np = 0; 334 fs->np = 0;
319 fs->nlocvars = 0; 335 fs->nlocvars = 0;
320 fs->nactvar = 0; 336 fs->nactvar = 0;
321 fs->bl = NULL; 337 fs->bl = NULL;
322 f->source = ls->source; 338 f->source = ls->source;
323 f->maxstacksize = 2; /* registers 0/1 are always valid */ 339 f->maxstacksize = 2; /* registers 0/1 are always valid */
340 fs->h = luaH_new(L, 0, 0);
341 /* anchor table of constants and prototype (to avoid being collected) */
342 sethvalue2s(L->top, fs->h);
343 incr_top(L);
344 setptvalue2s(L->top, f);
345 incr_top(L);
324} 346}
325 347
326 348
@@ -345,6 +367,9 @@ static void close_func (LexState *ls) {
345 lua_assert(luaG_checkcode(f)); 367 lua_assert(luaG_checkcode(f));
346 lua_assert(fs->bl == NULL); 368 lua_assert(fs->bl == NULL);
347 ls->fs = fs->prev; 369 ls->fs = fs->prev;
370 L->top -= 2; /* remove table and prototype from the stack */
371 /* last token read was anchored in defunct function; must reanchor it */
372 if (fs) anchor_token(ls);
348} 373}
349 374
350 375
@@ -362,6 +387,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
362 lua_assert(funcstate.prev == NULL); 387 lua_assert(funcstate.prev == NULL);
363 lua_assert(funcstate.f->nups == 0); 388 lua_assert(funcstate.f->nups == 0);
364 lua_assert(lexstate.nestlevel == 0); 389 lua_assert(lexstate.nestlevel == 0);
390 lua_assert(lexstate.fs == NULL);
365 return funcstate.f; 391 return funcstate.f;
366} 392}
367 393
@@ -530,7 +556,7 @@ static void parlist (LexState *ls) {
530 case TK_DOTS: { /* param -> `...' */ 556 case TK_DOTS: { /* param -> `...' */
531 next(ls); 557 next(ls);
532 /* use `arg' as default name */ 558 /* use `arg' as default name */
533 new_localvar(ls, luaS_new(ls->L, "arg"), nparams++); 559 new_localvarstr(ls, "arg", nparams++);
534 f->is_vararg = 1; 560 f->is_vararg = 1;
535 break; 561 break;
536 } 562 }
diff --git a/lundump.c b/lundump.c
index 30f6f904..0777dc0f 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 1.62 2003/08/15 13:48:53 roberto Exp roberto $ 2** $Id: lundump.c,v 1.63 2003/08/25 19:51:54 roberto Exp roberto $
3** load pre-compiled Lua chunks 3** load pre-compiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -9,6 +9,7 @@
9#include "lua.h" 9#include "lua.h"
10 10
11#include "ldebug.h" 11#include "ldebug.h"
12#include "ldo.h"
12#include "lfunc.h" 13#include "lfunc.h"
13#include "lmem.h" 14#include "lmem.h"
14#include "lopcodes.h" 15#include "lopcodes.h"
@@ -122,6 +123,7 @@ static void LoadLocals (LoadState* S, Proto* f)
122 n=LoadInt(S); 123 n=LoadInt(S);
123 f->locvars=luaM_newvector(S->L,n,LocVar); 124 f->locvars=luaM_newvector(S->L,n,LocVar);
124 f->sizelocvars=n; 125 f->sizelocvars=n;
126 for (i=0; i<n; i++) f->locvars[i].varname=NULL;
125 for (i=0; i<n; i++) 127 for (i=0; i<n; i++)
126 { 128 {
127 f->locvars[i].varname=LoadString(S); 129 f->locvars[i].varname=LoadString(S);
@@ -147,6 +149,7 @@ static void LoadUpvalues (LoadState* S, Proto* f)
147 S->name,n,f->nups); 149 S->name,n,f->nups);
148 f->upvalues=luaM_newvector(S->L,n,TString*); 150 f->upvalues=luaM_newvector(S->L,n,TString*);
149 f->sizeupvalues=n; 151 f->sizeupvalues=n;
152 for (i=0; i<n; i++) f->upvalues[i]=NULL;
150 for (i=0; i<n; i++) f->upvalues[i]=LoadString(S); 153 for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
151} 154}
152 155
@@ -158,6 +161,7 @@ static void LoadConstants (LoadState* S, Proto* f)
158 n=LoadInt(S); 161 n=LoadInt(S);
159 f->k=luaM_newvector(S->L,n,TObject); 162 f->k=luaM_newvector(S->L,n,TObject);
160 f->sizek=n; 163 f->sizek=n;
164 for (i=0; i<n; i++) setnilvalue(&f->k[i]);
161 for (i=0; i<n; i++) 165 for (i=0; i<n; i++)
162 { 166 {
163 TObject* o=&f->k[i]; 167 TObject* o=&f->k[i];
@@ -181,12 +185,15 @@ static void LoadConstants (LoadState* S, Proto* f)
181 n=LoadInt(S); 185 n=LoadInt(S);
182 f->p=luaM_newvector(S->L,n,Proto*); 186 f->p=luaM_newvector(S->L,n,Proto*);
183 f->sizep=n; 187 f->sizep=n;
188 for (i=0; i<n; i++) f->p[i]=NULL;
184 for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source); 189 for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
185} 190}
186 191
187static Proto* LoadFunction (LoadState* S, TString* p) 192static Proto* LoadFunction (LoadState* S, TString* p)
188{ 193{
189 Proto* f=luaF_newproto(S->L); 194 Proto* f=luaF_newproto(S->L);
195 setptvalue2s(S->L->top, f);
196 incr_top(S->L);
190 f->source=LoadString(S); if (f->source==NULL) f->source=p; 197 f->source=LoadString(S); if (f->source==NULL) f->source=p;
191 f->lineDefined=LoadInt(S); 198 f->lineDefined=LoadInt(S);
192 f->nups=LoadByte(S); 199 f->nups=LoadByte(S);
@@ -201,6 +208,7 @@ static Proto* LoadFunction (LoadState* S, TString* p)
201#ifndef TRUST_BINARIES 208#ifndef TRUST_BINARIES
202 if (!luaG_checkcode(f)) luaG_runerror(S->L,"bad code in %s",S->name); 209 if (!luaG_checkcode(f)) luaG_runerror(S->L,"bad code in %s",S->name);
203#endif 210#endif
211 S->L->top--;
204 return f; 212 return f;
205} 213}
206 214