diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-08-27 18:01:44 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-08-27 18:01:44 -0300 |
| commit | 8332d5c8a5059b85da1adaa3f0197d0f57afae81 (patch) | |
| tree | 8a2f59ff0803da3afbc7e8a409911c920d624e94 | |
| parent | 885961be1d8e3f703b54d1d19e6c63617cd2ed24 (diff) | |
| download | lua-8332d5c8a5059b85da1adaa3f0197d0f57afae81.tar.gz lua-8332d5c8a5059b85da1adaa3f0197d0f57afae81.tar.bz2 lua-8332d5c8a5059b85da1adaa3f0197d0f57afae81.zip | |
parser fully reentrant(!)
| -rw-r--r-- | lapi.c | 6 | ||||
| -rw-r--r-- | lcode.c | 12 | ||||
| -rw-r--r-- | ldo.c | 22 | ||||
| -rw-r--r-- | ldo.h | 4 | ||||
| -rw-r--r-- | lgc.c | 27 | ||||
| -rw-r--r-- | llex.c | 18 | ||||
| -rw-r--r-- | llex.h | 3 | ||||
| -rw-r--r-- | lobject.h | 37 | ||||
| -rw-r--r-- | lparser.c | 46 | ||||
| -rw-r--r-- | lundump.c | 10 |
10 files changed, 120 insertions, 65 deletions
| @@ -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 | } |
| @@ -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 | ||
| 209 | static int addk (FuncState *fs, TObject *k, TObject *v) { | 209 | static 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 | } |
| @@ -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, | |||
| 429 | struct SParser { /* data to `f_parser' */ | 429 | struct 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 | ||
| 436 | static void f_parser (lua_State *L, void *ud) { | 435 | static 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 | ||
| 451 | int luaD_protectedparser (lua_State *L, ZIO *z, int bin, const char *name) { | 450 | int 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 | ||
| @@ -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 @@ | |||
| 42 | typedef void (*Pfunc) (lua_State *L, void *ud); | 42 | typedef void (*Pfunc) (lua_State *L, void *ud); |
| 43 | 43 | ||
| 44 | void luaD_resetprotection (lua_State *L); | 44 | void luaD_resetprotection (lua_State *L); |
| 45 | int luaD_protectedparser (lua_State *L, ZIO *z, int bin, const char *name); | 45 | int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); |
| 46 | void luaD_callhook (lua_State *L, int event, int line); | 46 | void luaD_callhook (lua_State *L, int event, int line); |
| 47 | StkId luaD_precall (lua_State *L, StkId func); | 47 | StkId luaD_precall (lua_State *L, StkId func); |
| 48 | void luaD_call (lua_State *L, StkId func, int nResults); | 48 | void luaD_call (lua_State *L, StkId func, int nResults); |
| @@ -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 | */ | ||
| 179 | static void traverseproto (GCState *st, Proto *f) { | 183 | static 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 | ||
| @@ -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 | ||
| 114 | TString *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 | |||
| 114 | static void inclinenumber (LexState *LS) { | 124 | static 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; |
| @@ -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 | ||
| 66 | void luaX_init (lua_State *L); | 66 | void luaX_init (lua_State *L); |
| 67 | void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source); | 67 | void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source); |
| 68 | TString *luaX_newstring (LexState *LS, const char *str, size_t l); | ||
| 68 | int luaX_lex (LexState *LS, SemInfo *seminfo); | 69 | int luaX_lex (LexState *LS, SemInfo *seminfo); |
| 69 | void luaX_checklimit (LexState *ls, int val, int limit, const char *msg); | 70 | void luaX_checklimit (LexState *ls, int val, int limit, const char *msg); |
| 70 | void luaX_syntaxerror (LexState *ls, const char *s); | 71 | void luaX_syntaxerror (LexState *ls, const char *s); |
| @@ -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 */ |
| @@ -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 | ||
| 75 | static 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 | |||
| 74 | static void error_expected (LexState *ls, int token) { | 83 | static 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) { | |||
| 138 | static int luaI_registerlocalvar (LexState *ls, TString *varname) { | 147 | static 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 | ||
| 172 | static void new_localvarstr (LexState *ls, const char *name, int n) { | 183 | static 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 | ||
| 177 | static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { | 189 | static 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) { | |||
| 290 | static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { | 304 | static 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 | ||
| 305 | static void open_func (LexState *ls, FuncState *fs) { | 321 | static 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 | } |
| @@ -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 | ||
| 187 | static Proto* LoadFunction (LoadState* S, TString* p) | 192 | static 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 | ||
