Browse Source

parser fully reentrant(!)

v5-2
Roberto Ierusalimschy 22 years ago
parent
commit
8332d5c8a5
  1. 6
      lapi.c
  2. 12
      lcode.c
  3. 22
      ldo.c
  4. 4
      ldo.h
  5. 27
      lgc.c
  6. 18
      llex.c
  7. 3
      llex.h
  8. 37
      lobject.h
  9. 46
      lparser.c
  10. 10
      lundump.c

6
lapi.c

@ -1,5 +1,5 @@
/* /*
** $Id: lapi.c,v 1.242 2003/08/25 19:51:54 roberto Exp roberto $ ** $Id: lapi.c,v 1.243 2003/08/25 20:00:50 roberto Exp roberto $
** Lua API ** Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -715,12 +715,10 @@ LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
const char *chunkname) { const char *chunkname) {
ZIO z; ZIO z;
int status; int status;
int c;
lua_lock(L); lua_lock(L);
if (!chunkname) chunkname = "?"; if (!chunkname) chunkname = "?";
luaZ_init(L, &z, reader, data); luaZ_init(L, &z, reader, data);
c = luaZ_lookahead(&z); status = luaD_protectedparser(L, &z, chunkname);
status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]), chunkname);
lua_unlock(L); lua_unlock(L);
return status; return status;
} }

12
lcode.c

@ -1,5 +1,5 @@
/* /*
** $Id: lcode.c,v 1.117 2003/04/03 13:35:34 roberto Exp roberto $ ** $Id: lcode.c,v 1.119 2003/08/27 20:58:52 roberto Exp $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -207,17 +207,19 @@ static void freeexp (FuncState *fs, expdesc *e) {
static int addk (FuncState *fs, TObject *k, TObject *v) { static int addk (FuncState *fs, TObject *k, TObject *v) {
const TObject *idx = luaH_get(fs->h, k); TObject *idx = luaH_set(fs->L, fs->h, k);
Proto *f = fs->f;
int oldsize = f->sizek;
if (ttisnumber(idx)) { if (ttisnumber(idx)) {
lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v)); lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
return cast(int, nvalue(idx)); return cast(int, nvalue(idx));
} }
else { /* constant not found; create a new entry */ else { /* constant not found; create a new entry */
Proto *f = fs->f; setnvalue(idx, cast(lua_Number, fs->nk));
luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
MAXARG_Bx, "constant table overflow"); MAXARG_Bx, "constant table overflow");
setobj2n(&f->k[fs->nk], v); while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk)); setobj(&f->k[fs->nk], v); /* write barrier */
return fs->nk++; return fs->nk++;
} }
} }

22
ldo.c

@ -1,5 +1,5 @@
/* /*
** $Id: ldo.c,v 1.222 2003/08/25 19:51:54 roberto Exp roberto $ ** $Id: ldo.c,v 1.223 2003/08/26 12:04:13 roberto Exp roberto $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -429,18 +429,17 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
struct SParser { /* data to `f_parser' */ struct SParser { /* data to `f_parser' */
ZIO *z; ZIO *z;
Mbuffer buff; /* buffer to be used by the scanner */ Mbuffer buff; /* buffer to be used by the scanner */
int bin;
const char *name; const char *name;
}; };
static void f_parser (lua_State *L, void *ud) { static void f_parser (lua_State *L, void *ud) {
struct SParser *p;
Proto *tf; Proto *tf;
Closure *cl; Closure *cl;
struct SParser *p = cast(struct SParser *, ud);
int c = luaZ_lookahead(p->z);
luaC_checkGC(L); luaC_checkGC(L);
p = cast(struct SParser *, ud); tf = (c == LUA_SIGNATURE[0]) ? luaU_undump(L, p->z, &p->buff, p->name) :
tf = p->bin ? luaU_undump(L, p->z, &p->buff, p->name) : luaY_parser(L, p->z, &p->buff, p->name);
luaY_parser(L, p->z, &p->buff, p->name);
cl = luaF_newLclosure(L, 0, gt(L)); cl = luaF_newLclosure(L, 0, gt(L));
cl->l.p = tf; cl->l.p = tf;
setclvalue(L->top, cl); setclvalue(L->top, cl);
@ -448,18 +447,13 @@ static void f_parser (lua_State *L, void *ud) {
} }
int luaD_protectedparser (lua_State *L, ZIO *z, int bin, const char *name) { int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
struct SParser p; struct SParser p;
int status; int status;
ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */ p.z = z; p.name = name;
p.z = z; p.bin = bin; p.name = name;
luaZ_initbuffer(L, &p.buff); luaZ_initbuffer(L, &p.buff);
status = luaD_rawrunprotected(L, f_parser, &p); status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
luaZ_freebuffer(L, &p.buff); luaZ_freebuffer(L, &p.buff);
if (status != 0) { /* error? */
StkId oldtop = restorestack(L, oldtopr);
seterrorobj(L, status, oldtop);
}
return status; return status;
} }

4
ldo.h

@ -1,5 +1,5 @@
/* /*
** $Id: ldo.h,v 1.56 2002/12/04 17:29:32 roberto Exp roberto $ ** $Id: ldo.h,v 1.57 2003/08/25 19:51:54 roberto Exp roberto $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -42,7 +42,7 @@
typedef void (*Pfunc) (lua_State *L, void *ud); typedef void (*Pfunc) (lua_State *L, void *ud);
void luaD_resetprotection (lua_State *L); void luaD_resetprotection (lua_State *L);
int luaD_protectedparser (lua_State *L, ZIO *z, int bin, const char *name); int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
void luaD_callhook (lua_State *L, int event, int line); void luaD_callhook (lua_State *L, int event, int line);
StkId luaD_precall (lua_State *L, StkId func); StkId luaD_precall (lua_State *L, StkId func);
void luaD_call (lua_State *L, StkId func, int nResults); void luaD_call (lua_State *L, StkId func, int nResults);

27
lgc.c

@ -1,5 +1,5 @@
/* /*
** $Id: lgc.c,v 1.175 2003/07/16 20:49:02 roberto Exp roberto $ ** $Id: lgc.c,v 1.176 2003/07/29 19:25:37 roberto Exp roberto $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -176,20 +176,29 @@ static void traversetable (GCState *st, Table *h) {
} }
/*
** All marks are conditional because a GC may happen while the
** prototype is still being created
*/
static void traverseproto (GCState *st, Proto *f) { static void traverseproto (GCState *st, Proto *f) {
int i; int i;
stringmark(f->source); if (f->source) stringmark(f->source);
for (i=0; i<f->sizek; i++) { /* mark literal strings */ for (i=0; i<f->sizek; i++) { /* mark literal strings */
if (ttisstring(f->k+i)) if (ttisstring(f->k+i))
stringmark(tsvalue(f->k+i)); stringmark(tsvalue(f->k+i));
} }
for (i=0; i<f->sizeupvalues; i++) /* mark upvalue names */ for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
stringmark(f->upvalues[i]); if (f->upvalues[i])
for (i=0; i<f->sizep; i++) /* mark nested protos */ stringmark(f->upvalues[i]);
markvalue(st, f->p[i]); }
for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */ for (i=0; i<f->sizep; i++) { /* mark nested protos */
stringmark(f->locvars[i].varname); if (f->p[i])
lua_assert(luaG_checkcode(f)); markvalue(st, f->p[i]);
}
for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
if (f->locvars[i].varname)
stringmark(f->locvars[i].varname);
}
} }

18
llex.c

@ -1,5 +1,5 @@
/* /*
** $Id: llex.c,v 1.120 2003/05/15 12:20:24 roberto Exp roberto $ ** $Id: llex.c,v 1.121 2003/08/21 14:16:43 roberto Exp roberto $
** Lexical Analyzer ** Lexical Analyzer
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -111,6 +111,16 @@ static void luaX_lexerror (LexState *ls, const char *s, int token) {
} }
TString *luaX_newstring (LexState *LS, const char *str, size_t l) {
lua_State *L = LS->L;
TString *ts = luaS_newlstr(L, str, l);
TObject *o = luaH_setstr(L, LS->fs->h, ts); /* entry for `str' */
if (ttisnil(o))
setbvalue(o, 1); /* make sure `str' will not be collected */
return ts;
}
static void inclinenumber (LexState *LS) { static void inclinenumber (LexState *LS) {
int old = LS->current; int old = LS->current;
lua_assert(nextIsNewline(LS)); lua_assert(nextIsNewline(LS));
@ -253,7 +263,7 @@ static void read_long_string (LexState *LS, SemInfo *seminfo) {
save_and_next(LS, l); /* skip the second `]' */ save_and_next(LS, l); /* skip the second `]' */
save(LS, '\0', l); save(LS, '\0', l);
if (seminfo) if (seminfo)
seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 2, l - 5); seminfo->ts = luaX_newstring(LS, luaZ_buffer(LS->buff) + 2, l - 5);
} }
@ -311,7 +321,7 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) {
} }
save_and_next(LS, l); /* skip delimiter */ save_and_next(LS, l); /* skip delimiter */
save(LS, '\0', l); save(LS, '\0', l);
seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 1, l - 3); seminfo->ts = luaX_newstring(LS, luaZ_buffer(LS->buff) + 1, l - 3);
} }
@ -401,7 +411,7 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) {
else if (isalpha(LS->current) || LS->current == '_') { else if (isalpha(LS->current) || LS->current == '_') {
/* identifier or reserved word */ /* identifier or reserved word */
size_t l = readname(LS); size_t l = readname(LS);
TString *ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff), l); TString *ts = luaX_newstring(LS, luaZ_buffer(LS->buff), l);
if (ts->tsv.reserved > 0) /* reserved word? */ if (ts->tsv.reserved > 0) /* reserved word? */
return ts->tsv.reserved - 1 + FIRST_RESERVED; return ts->tsv.reserved - 1 + FIRST_RESERVED;
seminfo->ts = ts; seminfo->ts = ts;

3
llex.h

@ -1,5 +1,5 @@
/* /*
** $Id: llex.h,v 1.46 2002/11/22 16:35:20 roberto Exp roberto $ ** $Id: llex.h,v 1.47 2003/02/28 17:19:47 roberto Exp roberto $
** Lexical Analyzer ** Lexical Analyzer
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -65,6 +65,7 @@ typedef struct LexState {
void luaX_init (lua_State *L); void luaX_init (lua_State *L);
void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source); void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
TString *luaX_newstring (LexState *LS, const char *str, size_t l);
int luaX_lex (LexState *LS, SemInfo *seminfo); int luaX_lex (LexState *LS, SemInfo *seminfo);
void luaX_checklimit (LexState *ls, int val, int limit, const char *msg); void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
void luaX_syntaxerror (LexState *ls, const char *s); void luaX_syntaxerror (LexState *ls, const char *s);

37
lobject.h

@ -1,5 +1,5 @@
/* /*
** $Id: lobject.h,v 1.159 2003/03/18 12:50:04 roberto Exp roberto $ ** $Id: lobject.h,v 1.160 2003/04/28 19:26:16 roberto Exp roberto $
** Type definitions for Lua objects ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -92,44 +92,49 @@ typedef struct lua_TObject {
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
/* Macros to set values */ /* Macros to set values */
#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
#define setnvalue(obj,x) \ #define setnvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TNUMBER; i_o->value.n=(x); } { TObject *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
#define chgnvalue(obj,x) \ #define chgnvalue(obj,x) \
check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x)) check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x))
#define setpvalue(obj,x) \ #define setpvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TLIGHTUSERDATA; i_o->value.p=(x); } { TObject *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
#define setbvalue(obj,x) \ #define setbvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TBOOLEAN; i_o->value.b=(x); } { TObject *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
#define setsvalue(obj,x) \ #define setsvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TSTRING; \ { TObject *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
lua_assert(i_o->value.gc->gch.tt == LUA_TSTRING); } lua_assert(i_o->value.gc->gch.tt == LUA_TSTRING); }
#define setuvalue(obj,x) \ #define setuvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TUSERDATA; \ { TObject *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
lua_assert(i_o->value.gc->gch.tt == LUA_TUSERDATA); } lua_assert(i_o->value.gc->gch.tt == LUA_TUSERDATA); }
#define setthvalue(obj,x) \ #define setthvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TTHREAD; \ { TObject *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
lua_assert(i_o->value.gc->gch.tt == LUA_TTHREAD); } lua_assert(i_o->value.gc->gch.tt == LUA_TTHREAD); }
#define setclvalue(obj,x) \ #define setclvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TFUNCTION; \ { TObject *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
lua_assert(i_o->value.gc->gch.tt == LUA_TFUNCTION); } lua_assert(i_o->value.gc->gch.tt == LUA_TFUNCTION); }
#define sethvalue(obj,x) \ #define sethvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TTABLE; \ { TObject *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
lua_assert(i_o->value.gc->gch.tt == LUA_TTABLE); } lua_assert(i_o->value.gc->gch.tt == LUA_TTABLE); }
#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) #define setptvalue(obj,x) \
{ TObject *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
lua_assert(i_o->value.gc->gch.tt == LUA_TPROTO); }
@ -155,6 +160,8 @@ typedef struct lua_TObject {
/* to stack (not from same stack) */ /* to stack (not from same stack) */
#define setobj2s setobj #define setobj2s setobj
#define setsvalue2s setsvalue #define setsvalue2s setsvalue
#define sethvalue2s sethvalue
#define setptvalue2s setptvalue
/* from table to same table */ /* from table to same table */
#define setobjt2t setobj #define setobjt2t setobj
/* to table */ /* to table */

46
lparser.c

@ -1,5 +1,5 @@
/* /*
** $Id: lparser.c,v 1.215 2003/07/29 18:51:00 roberto Exp roberto $ ** $Id: lparser.c,v 1.216 2003/08/25 19:51:54 roberto Exp roberto $
** Lua Parser ** Lua Parser
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -13,6 +13,7 @@
#include "lcode.h" #include "lcode.h"
#include "ldebug.h" #include "ldebug.h"
#include "ldo.h"
#include "lfunc.h" #include "lfunc.h"
#include "llex.h" #include "llex.h"
#include "lmem.h" #include "lmem.h"
@ -71,6 +72,14 @@ static void lookahead (LexState *ls) {
} }
static void anchor_token (LexState *ls) {
if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
TString *ts = ls->t.seminfo.ts;
luaX_newstring(ls, getstr(ts), ts->tsv.len);
}
}
static void error_expected (LexState *ls, int token) { static void error_expected (LexState *ls, int token) {
luaX_syntaxerror(ls, luaX_syntaxerror(ls,
luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token))); luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token)));
@ -138,9 +147,11 @@ static void checkname(LexState *ls, expdesc *e) {
static int luaI_registerlocalvar (LexState *ls, TString *varname) { static int luaI_registerlocalvar (LexState *ls, TString *varname) {
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
Proto *f = fs->f; Proto *f = fs->f;
int oldsize = f->sizelocvars;
luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
LocVar, USHRT_MAX, "too many local variables"); LocVar, USHRT_MAX, "too many local variables");
f->locvars[fs->nlocvars].varname = varname; while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
f->locvars[fs->nlocvars].varname = varname; /* write barrier */
return fs->nlocvars++; return fs->nlocvars++;
} }
@ -170,24 +181,27 @@ static void removevars (LexState *ls, int tolevel) {
static void new_localvarstr (LexState *ls, const char *name, int n) { static void new_localvarstr (LexState *ls, const char *name, int n) {
new_localvar(ls, luaS_new(ls->L, name), n); TString *ts = luaX_newstring(ls, name, strlen(name));
new_localvar(ls, ts, n);
} }
static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
int i; int i;
Proto *f = fs->f; Proto *f = fs->f;
int oldsize = f->sizeupvalues;
for (i=0; i<f->nups; i++) { for (i=0; i<f->nups; i++) {
if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) { if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) {
lua_assert(fs->f->upvalues[i] == name); lua_assert(f->upvalues[i] == name);
return i; return i;
} }
} }
/* new one */ /* new one */
luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues"); luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues");
luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues, luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
TString *, MAX_INT, ""); TString *, MAX_INT, "");
fs->f->upvalues[f->nups] = name; while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
f->upvalues[f->nups] = name; /* write barrier */
lua_assert(v->k == VLOCAL || v->k == VUPVAL); lua_assert(v->k == VLOCAL || v->k == VUPVAL);
fs->upvalues[f->nups].k = cast(lu_byte, v->k); fs->upvalues[f->nups].k = cast(lu_byte, v->k);
fs->upvalues[f->nups].info = cast(lu_byte, v->info); fs->upvalues[f->nups].info = cast(lu_byte, v->info);
@ -290,10 +304,12 @@ static void leaveblock (FuncState *fs) {
static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
Proto *f = fs->f; Proto *f = fs->f;
int oldsize = f->sizep;
int i; int i;
luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
MAXARG_Bx, "constant table overflow"); MAXARG_Bx, "constant table overflow");
f->p[fs->np++] = func->f; while (oldsize < f->sizep) f->p[oldsize++] = NULL;
f->p[fs->np++] = func->f; /* write barrier */
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
for (i=0; i<func->f->nups; i++) { for (i=0; i<func->f->nups; i++) {
OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
@ -303,24 +319,30 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
static void open_func (LexState *ls, FuncState *fs) { static void open_func (LexState *ls, FuncState *fs) {
lua_State *L = ls->L;
Proto *f = luaF_newproto(ls->L); Proto *f = luaF_newproto(ls->L);
fs->f = f; fs->f = f;
fs->prev = ls->fs; /* linked list of funcstates */ fs->prev = ls->fs; /* linked list of funcstates */
fs->ls = ls; fs->ls = ls;
fs->L = ls->L; fs->L = L;
ls->fs = fs; ls->fs = fs;
fs->pc = 0; fs->pc = 0;
fs->lasttarget = 0; fs->lasttarget = 0;
fs->jpc = NO_JUMP; fs->jpc = NO_JUMP;
fs->freereg = 0; fs->freereg = 0;
fs->nk = 0; fs->nk = 0;
fs->h = luaH_new(ls->L, 0, 0);
fs->np = 0; fs->np = 0;
fs->nlocvars = 0; fs->nlocvars = 0;
fs->nactvar = 0; fs->nactvar = 0;
fs->bl = NULL; fs->bl = NULL;
f->source = ls->source; f->source = ls->source;
f->maxstacksize = 2; /* registers 0/1 are always valid */ f->maxstacksize = 2; /* registers 0/1 are always valid */
fs->h = luaH_new(L, 0, 0);
/* anchor table of constants and prototype (to avoid being collected) */
sethvalue2s(L->top, fs->h);
incr_top(L);
setptvalue2s(L->top, f);
incr_top(L);
} }
@ -345,6 +367,9 @@ static void close_func (LexState *ls) {
lua_assert(luaG_checkcode(f)); lua_assert(luaG_checkcode(f));
lua_assert(fs->bl == NULL); lua_assert(fs->bl == NULL);
ls->fs = fs->prev; ls->fs = fs->prev;
L->top -= 2; /* remove table and prototype from the stack */
/* last token read was anchored in defunct function; must reanchor it */
if (fs) anchor_token(ls);
} }
@ -362,6 +387,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
lua_assert(funcstate.prev == NULL); lua_assert(funcstate.prev == NULL);
lua_assert(funcstate.f->nups == 0); lua_assert(funcstate.f->nups == 0);
lua_assert(lexstate.nestlevel == 0); lua_assert(lexstate.nestlevel == 0);
lua_assert(lexstate.fs == NULL);
return funcstate.f; return funcstate.f;
} }
@ -530,7 +556,7 @@ static void parlist (LexState *ls) {
case TK_DOTS: { /* param -> `...' */ case TK_DOTS: { /* param -> `...' */
next(ls); next(ls);
/* use `arg' as default name */ /* use `arg' as default name */
new_localvar(ls, luaS_new(ls->L, "arg"), nparams++); new_localvarstr(ls, "arg", nparams++);
f->is_vararg = 1; f->is_vararg = 1;
break; break;
} }

10
lundump.c

@ -1,5 +1,5 @@
/* /*
** $Id: lundump.c,v 1.62 2003/08/15 13:48:53 roberto Exp roberto $ ** $Id: lundump.c,v 1.63 2003/08/25 19:51:54 roberto Exp roberto $
** load pre-compiled Lua chunks ** load pre-compiled Lua chunks
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -9,6 +9,7 @@
#include "lua.h" #include "lua.h"
#include "ldebug.h" #include "ldebug.h"
#include "ldo.h"
#include "lfunc.h" #include "lfunc.h"
#include "lmem.h" #include "lmem.h"
#include "lopcodes.h" #include "lopcodes.h"
@ -122,6 +123,7 @@ static void LoadLocals (LoadState* S, Proto* f)
n=LoadInt(S); n=LoadInt(S);
f->locvars=luaM_newvector(S->L,n,LocVar); f->locvars=luaM_newvector(S->L,n,LocVar);
f->sizelocvars=n; f->sizelocvars=n;
for (i=0; i<n; i++) f->locvars[i].varname=NULL;
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
f->locvars[i].varname=LoadString(S); f->locvars[i].varname=LoadString(S);
@ -147,6 +149,7 @@ static void LoadUpvalues (LoadState* S, Proto* f)
S->name,n,f->nups); S->name,n,f->nups);
f->upvalues=luaM_newvector(S->L,n,TString*); f->upvalues=luaM_newvector(S->L,n,TString*);
f->sizeupvalues=n; f->sizeupvalues=n;
for (i=0; i<n; i++) f->upvalues[i]=NULL;
for (i=0; i<n; i++) f->upvalues[i]=LoadString(S); for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
} }
@ -158,6 +161,7 @@ static void LoadConstants (LoadState* S, Proto* f)
n=LoadInt(S); n=LoadInt(S);
f->k=luaM_newvector(S->L,n,TObject); f->k=luaM_newvector(S->L,n,TObject);
f->sizek=n; f->sizek=n;
for (i=0; i<n; i++) setnilvalue(&f->k[i]);
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
TObject* o=&f->k[i]; TObject* o=&f->k[i];
@ -181,12 +185,15 @@ static void LoadConstants (LoadState* S, Proto* f)
n=LoadInt(S); n=LoadInt(S);
f->p=luaM_newvector(S->L,n,Proto*); f->p=luaM_newvector(S->L,n,Proto*);
f->sizep=n; f->sizep=n;
for (i=0; i<n; i++) f->p[i]=NULL;
for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source); for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
} }
static Proto* LoadFunction (LoadState* S, TString* p) static Proto* LoadFunction (LoadState* S, TString* p)
{ {
Proto* f=luaF_newproto(S->L); Proto* f=luaF_newproto(S->L);
setptvalue2s(S->L->top, f);
incr_top(S->L);
f->source=LoadString(S); if (f->source==NULL) f->source=p; f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->lineDefined=LoadInt(S); f->lineDefined=LoadInt(S);
f->nups=LoadByte(S); f->nups=LoadByte(S);
@ -201,6 +208,7 @@ static Proto* LoadFunction (LoadState* S, TString* p)
#ifndef TRUST_BINARIES #ifndef TRUST_BINARIES
if (!luaG_checkcode(f)) luaG_runerror(S->L,"bad code in %s",S->name); if (!luaG_checkcode(f)) luaG_runerror(S->L,"bad code in %s",S->name);
#endif #endif
S->L->top--;
return f; return f;
} }

Loading…
Cancel
Save