Redesign of prototype generation, part 4: late creation of prototype.

This commit is contained in:
Mike Pall 2010-02-08 05:29:47 +01:00
parent 4424027844
commit f275a9d7ef
2 changed files with 20 additions and 20 deletions

View File

@ -251,7 +251,6 @@ static void gc_traverse_proto(global_State *g, GCproto *pt)
} }
#endif #endif
/* GC during prototype creation could cause NULL fields. */ /* GC during prototype creation could cause NULL fields. */
if (gcref(pt->chunkname))
gc_mark_str(proto_chunkname(pt)); gc_mark_str(proto_chunkname(pt));
for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) /* Mark collectable consts. */ for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) /* Mark collectable consts. */
gc_markobj(g, proto_kgc(pt, i)); gc_markobj(g, proto_kgc(pt, i));

View File

@ -100,7 +100,6 @@ typedef struct UVMap {
/* Per-function state. */ /* Per-function state. */
typedef struct FuncState { typedef struct FuncState {
GCproto *pt; /* Prototype object to be built. */
GCtab *kt; /* Hash table for constants. */ GCtab *kt; /* Hash table for constants. */
LexState *ls; /* Lexer state. */ LexState *ls; /* Lexer state. */
lua_State *L; /* Lua state. */ lua_State *L; /* Lua state. */
@ -1129,12 +1128,26 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
{ {
lua_State *L = ls->L; lua_State *L = ls->L;
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
GCproto *pt = fs->pt; GCproto *pt;
/* Apply final fixups. */ /* Apply final fixups. */
var_remove(ls, 0); var_remove(ls, 0);
lua_assert(fs->bl == NULL);
fs_fixup_ret(fs); fs_fixup_ret(fs);
/* Allocate prototype and initialize its fields. */
pt = lj_func_newproto(L);
setgcref(pt->chunkname, obj2gco(ls->chunkname));
pt->flags = fs->flags;
pt->numparams = fs->numparams;
pt->framesize = fs->framesize;
pt->linedefined = fs->linedefined;
pt->lastlinedefined = line;
/* Anchor prototype since allocation of the arrays may fail. */
setprotoV(L, L->top, pt);
incr_top(L);
fs_fixup_k(fs, pt); fs_fixup_k(fs, pt);
fs_fixup_uv(fs, pt); fs_fixup_uv(fs, pt);
@ -1171,23 +1184,15 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
pt->sizeuvname = n; pt->sizeuvname = n;
} }
/* Initialize prototype fields. */
setgcref(pt->chunkname, obj2gco(ls->chunkname));
pt->flags = fs->flags;
pt->numparams = fs->numparams;
pt->framesize = fs->framesize;
pt->linedefined = fs->linedefined;
pt->lastlinedefined = line;
lj_vmevent_send(L, BC, lj_vmevent_send(L, BC,
setprotoV(L, L->top++, pt); setprotoV(L, L->top++, pt);
); );
/* Remove VarInfo and FuncState. Pop const table and prototype. */ L->top--; /* Pop prototype. */
lua_assert(fs->bl == NULL);
ls->vtop = fs->vbase; L->top--; /* Pop table of constants. */
ls->vtop = fs->vbase; /* Reset variable stack. */
ls->fs = fs->prev; ls->fs = fs->prev;
L->top -= 2;
lua_assert(ls->fs != NULL || ls->token == TK_eof); lua_assert(ls->fs != NULL || ls->token == TK_eof);
/* Re-anchor last string token to avoid GC. */ /* Re-anchor last string token to avoid GC. */
if (ls->token == TK_name || ls->token == TK_string) { if (ls->token == TK_name || ls->token == TK_string) {
@ -1201,8 +1206,6 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
static void fs_init(LexState *ls, FuncState *fs) static void fs_init(LexState *ls, FuncState *fs)
{ {
lua_State *L = ls->L; lua_State *L = ls->L;
GCproto *pt = lj_func_newproto(L);
fs->pt = pt;
fs->prev = ls->fs; ls->fs = fs; /* Append to list. */ fs->prev = ls->fs; ls->fs = fs; /* Append to list. */
fs->ls = ls; fs->ls = ls;
fs->vbase = ls->vtop; fs->vbase = ls->vtop;
@ -1222,8 +1225,6 @@ static void fs_init(LexState *ls, FuncState *fs)
/* Anchor table of constants and prototype (to avoid being collected). */ /* Anchor table of constants and prototype (to avoid being collected). */
settabV(L, L->top, fs->kt); settabV(L, L->top, fs->kt);
incr_top(L); incr_top(L);
setprotoV(L, L->top, pt);
incr_top(L);
} }
/* -- Expressions --------------------------------------------------------- */ /* -- Expressions --------------------------------------------------------- */