diff --git a/src/lj_gc.c b/src/lj_gc.c index 5750d0ef..bcef576b 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c @@ -251,8 +251,7 @@ static void gc_traverse_proto(global_State *g, GCproto *pt) } #endif /* 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. */ gc_markobj(g, proto_kgc(pt, i)); for (i = 0; i < (ptrdiff_t)pt->sizeuvname; i++) /* Mark upvalue names. */ diff --git a/src/lj_parse.c b/src/lj_parse.c index 54ff6974..ec355403 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -100,7 +100,6 @@ typedef struct UVMap { /* Per-function state. */ typedef struct FuncState { - GCproto *pt; /* Prototype object to be built. */ GCtab *kt; /* Hash table for constants. */ LexState *ls; /* Lexer state. */ lua_State *L; /* Lua state. */ @@ -1129,12 +1128,26 @@ static GCproto *fs_finish(LexState *ls, BCLine line) { lua_State *L = ls->L; FuncState *fs = ls->fs; - GCproto *pt = fs->pt; + GCproto *pt; /* Apply final fixups. */ var_remove(ls, 0); + lua_assert(fs->bl == NULL); 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_uv(fs, pt); @@ -1171,23 +1184,15 @@ static GCproto *fs_finish(LexState *ls, BCLine line) 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, setprotoV(L, L->top++, pt); ); - /* Remove VarInfo and FuncState. Pop const table and prototype. */ - lua_assert(fs->bl == NULL); - ls->vtop = fs->vbase; + L->top--; /* Pop prototype. */ + + L->top--; /* Pop table of constants. */ + ls->vtop = fs->vbase; /* Reset variable stack. */ ls->fs = fs->prev; - L->top -= 2; lua_assert(ls->fs != NULL || ls->token == TK_eof); /* Re-anchor last string token to avoid GC. */ 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) { 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->ls = ls; 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). */ settabV(L, L->top, fs->kt); incr_top(L); - setprotoV(L, L->top, pt); - incr_top(L); } /* -- Expressions --------------------------------------------------------- */