|
Here is the function from LDO.C
static int parse_file (lua_State *L, const char
*filename) {
ZIO z; int status; int bin; /* flag for file mode */ int c; /* look ahead char */ FILE *f = (filename == NULL) ? stdin : fopen(filename, "r"); if (f == NULL) return LUA_ERRFILE; /* unable to open file */ c = fgetc(f); ungetc(c, f); bin = (c == ID_CHUNK); if (bin && f != stdin) { f = freopen(filename, "rb", f); /* set binary mode */ if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */ } lua_pushstring(L, "@"); lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename); lua_concat(L, 2); filename = lua_tostring(L, -1); /* filename = '@'..filename */ ********* lua_pop(L, 1); /* OK: there is no GC during parser */ luaZ_Fopen(&z, f, filename); ########## status = protectedparser(L, &z, bin); if (f != stdin) fclose(f); status; } The * marked line makes an
assumption violated in the call marked #. <protectedparser>
*does* use GC and the <filename> string *does* get collected
sometimes. I have only seen this happen in version with
<lua-4.0-update.tar.gz> applied. But!... even pre-update version
has GC in <protectedparser>.
Simple solution is to comment the call to GC in
<protectedparser>. Another working solution is to create a reference for
<filename> in the function above and release it after # line. Has anybody
else seen this?
Here is the code for <protectedparser> with
GC code marked with @
static int protectedparser (lua_State *L, ZIO *z,
int bin) {
struct ParserS p; unsigned long old_blocks; int status; p.z = z; p.bin = bin; /* before parsing, give a (good) chance to GC */ @@@@@@@@@@ if (L->nblocks/8 >= L->GCthreshold/10) @@@@@@@@@@ luaC_collectgarbage(L); old_blocks = L->nblocks; status = luaD_runprotected(L, f_parser, &p); if (status == 0) { /* add new memory to threshold (as it probably will stay) */ L->GCthreshold += (L->nblocks - old_blocks); } else if (status == LUA_ERRRUN) /* an error occurred: correct error code */ status = LUA_ERRSYNTAX; return status; } AB
|