diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2006-07-11 12:53:29 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2006-07-11 12:53:29 -0300 |
| commit | 3ca9af51a4f060cf2178901a67a21f8269af3224 (patch) | |
| tree | 4f1bb541280aa8b4960b16d0925eca60adb2b1a8 /lparser.c | |
| parent | c7b89dd28097296bbc14d9b47b4cea72514b2b76 (diff) | |
| download | lua-3ca9af51a4f060cf2178901a67a21f8269af3224.tar.gz lua-3ca9af51a4f060cf2178901a67a21f8269af3224.tar.bz2 lua-3ca9af51a4f060cf2178901a67a21f8269af3224.zip | |
emergency garbage collector (core forces a GC when allocation fails)
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 26 |
1 files changed, 16 insertions, 10 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.42 2006/06/05 15:57:59 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.43 2006/06/22 16:12:59 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 | */ |
| @@ -308,7 +308,7 @@ static void leaveblock (FuncState *fs) { | |||
| 308 | 308 | ||
| 309 | 309 | ||
| 310 | static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { | 310 | static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { |
| 311 | FuncState *fs = ls->fs; | 311 | FuncState *fs = ls->fs->prev; |
| 312 | Proto *f = fs->f; | 312 | Proto *f = fs->f; |
| 313 | int oldsize = f->sizep; | 313 | int oldsize = f->sizep; |
| 314 | int i; | 314 | int i; |
| @@ -327,8 +327,7 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { | |||
| 327 | 327 | ||
| 328 | static void open_func (LexState *ls, FuncState *fs) { | 328 | static void open_func (LexState *ls, FuncState *fs) { |
| 329 | lua_State *L = ls->L; | 329 | lua_State *L = ls->L; |
| 330 | Proto *f = luaF_newproto(L); | 330 | Proto *f; |
| 331 | fs->f = f; | ||
| 332 | fs->prev = ls->fs; /* linked list of funcstates */ | 331 | fs->prev = ls->fs; /* linked list of funcstates */ |
| 333 | fs->ls = ls; | 332 | fs->ls = ls; |
| 334 | fs->L = L; | 333 | fs->L = L; |
| @@ -342,12 +341,15 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
| 342 | fs->nlocvars = 0; | 341 | fs->nlocvars = 0; |
| 343 | fs->nactvar = 0; | 342 | fs->nactvar = 0; |
| 344 | fs->bl = NULL; | 343 | fs->bl = NULL; |
| 345 | f->source = ls->source; | 344 | fs->h = luaH_new(L); |
| 346 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | 345 | /* anchor table of constants (to avoid being collected) */ |
| 347 | fs->h = luaH_new(L, 0, 0); | ||
| 348 | /* anchor table of constants and prototype (to avoid being collected) */ | ||
| 349 | sethvalue2s(L, L->top, fs->h); | 346 | sethvalue2s(L, L->top, fs->h); |
| 350 | incr_top(L); | 347 | incr_top(L); |
| 348 | f = luaF_newproto(L); | ||
| 349 | fs->f = f; | ||
| 350 | f->source = ls->source; | ||
| 351 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | ||
| 352 | /* anchor prototype (to avoid being collected) */ | ||
| 351 | setptvalue2s(L, L->top, f); | 353 | setptvalue2s(L, L->top, f); |
| 352 | incr_top(L); | 354 | incr_top(L); |
| 353 | } | 355 | } |
| @@ -383,14 +385,18 @@ static void close_func (LexState *ls) { | |||
| 383 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { | 385 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { |
| 384 | struct LexState lexstate; | 386 | struct LexState lexstate; |
| 385 | struct FuncState funcstate; | 387 | struct FuncState funcstate; |
| 388 | TString *tname = luaS_new(L, name); | ||
| 389 | setsvalue2s(L, L->top, tname); /* protect name */ | ||
| 390 | incr_top(L); | ||
| 386 | lexstate.buff = buff; | 391 | lexstate.buff = buff; |
| 387 | luaX_setinput(L, &lexstate, z, luaS_new(L, name)); | 392 | luaX_setinput(L, &lexstate, z, tname); |
| 388 | open_func(&lexstate, &funcstate); | 393 | open_func(&lexstate, &funcstate); |
| 389 | funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ | 394 | funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ |
| 390 | luaX_next(&lexstate); /* read first token */ | 395 | luaX_next(&lexstate); /* read first token */ |
| 391 | chunk(&lexstate); | 396 | chunk(&lexstate); |
| 392 | check(&lexstate, TK_EOS); | 397 | check(&lexstate, TK_EOS); |
| 393 | close_func(&lexstate); | 398 | close_func(&lexstate); |
| 399 | L->top--; | ||
| 394 | lua_assert(funcstate.prev == NULL); | 400 | lua_assert(funcstate.prev == NULL); |
| 395 | lua_assert(funcstate.f->nups == 0); | 401 | lua_assert(funcstate.f->nups == 0); |
| 396 | lua_assert(lexstate.fs == NULL); | 402 | lua_assert(lexstate.fs == NULL); |
| @@ -588,8 +594,8 @@ static void body (LexState *ls, expdesc *e, int needself, int line) { | |||
| 588 | chunk(ls); | 594 | chunk(ls); |
| 589 | new_fs.f->lastlinedefined = ls->linenumber; | 595 | new_fs.f->lastlinedefined = ls->linenumber; |
| 590 | check_match(ls, TK_END, TK_FUNCTION, line); | 596 | check_match(ls, TK_END, TK_FUNCTION, line); |
| 591 | close_func(ls); | ||
| 592 | pushclosure(ls, &new_fs, e); | 597 | pushclosure(ls, &new_fs, e); |
| 598 | close_func(ls); | ||
| 593 | } | 599 | } |
| 594 | 600 | ||
| 595 | 601 | ||
