lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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