瀏覽代碼

bug: luaD_protectedparser must protect its garbage collection too

Roberto Ierusalimschy 22 年之前
父節點
當前提交
e44e579dc1
共有 2 個文件被更改,包括 20 次插入15 次删除
  1. 6 0
      bugs
  2. 14 15
      ldo.c

+ 6 - 0
bugs

@@ -313,3 +313,9 @@ Fri Dec 20 09:53:19 UTC 2002
 >> `resume' was checking the wrong value for stack overflow
 (by Maik Zimmermann; since 5.0b)
 
+** ldo.c
+Thu Jan 23 11:29:06 UTC 2003
+>> error during garbage collection in luaD_protectedparser is not being
+>> protected
+(by Benoit Germain; since 5.0a)
+

+ 14 - 15
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.210 2002/12/04 17:28:27 roberto Exp roberto $
+** $Id: ldo.c,v 1.211 2002/12/04 17:38:31 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -415,35 +415,34 @@ struct SParser {  /* data to `f_parser' */
 };
 
 static void f_parser (lua_State *L, void *ud) {
+  lu_mem old_blocks;
+  Proto *tf;
+  Closure *cl;
   struct SParser *p = cast(struct SParser *, ud);
-  Proto *tf = p->bin ? luaU_undump(L, p->z, &p->buff) :
-                       luaY_parser(L, p->z, &p->buff);
-  Closure *cl = luaF_newLclosure(L, 0, gt(L));
+  /* before parsing, give a (good) chance to GC */
+  if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold)
+    luaC_collectgarbage(L);
+  old_blocks = G(L)->nblocks;
+  tf = p->bin ? luaU_undump(L, p->z, &p->buff) : luaY_parser(L, p->z, &p->buff);
+  cl = luaF_newLclosure(L, 0, gt(L));
   cl->l.p = tf;
   setclvalue(L->top, cl);
   incr_top(L);
+  /* add new memory to threshold (as it probably will stay) */
+  lua_assert(G(L)->nblocks >= old_blocks);
+  G(L)->GCthreshold += (G(L)->nblocks - old_blocks);
 }
 
 
 int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
   struct SParser p;
-  lu_mem old_blocks;
   int status;
   ptrdiff_t oldtopr = savestack(L, L->top);  /* save current top */
   p.z = z; p.bin = bin;
   luaZ_initbuffer(L, &p.buff);
-  /* before parsing, give a (good) chance to GC */
-  if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold)
-    luaC_collectgarbage(L);
-  old_blocks = G(L)->nblocks;
   status = luaD_rawrunprotected(L, f_parser, &p);
   luaZ_freebuffer(L, &p.buff);
-  if (status == 0) {
-    /* add new memory to threshold (as it probably will stay) */
-    lua_assert(G(L)->nblocks >= old_blocks);
-    G(L)->GCthreshold += (G(L)->nblocks - old_blocks);
-  }
-  else {  /* error */
+  if (status != 0) {  /* error */
     StkId oldtop = restorestack(L, oldtopr);
     seterrorobj(L, status, oldtop);
   }