lua-users home
lua-l archive

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


> But I found something suspicious: luaF_close() is the only place
> where luaC_linkupval() is ever called. And both functions take care
> of the same write barrier (huh?). I think the isgray() part of
> luaC_linkupval() is never executed, since the upvalue can only be
> either black or white after the isgray() check in luaF_close.

This may explain the bug. I think the correct action is the one
from luaC_linkupval, not from luaF_close. If the GC is sweeping and
luaF_close is called, the upvalue will be marked as black. So, on the
next GC cycle, the object pointed by this upvalue won't be visited (if
it is pointed only by this upvalue and the upvalue doesn't change) and
so will be wrongly collected.

To test this theory, those with the bug could just remove the following
lines from luaF_close (lfunc.c:108):

      unlinkupval(uv);
      setobj(L, &uv->u.value, uv->v);
-     if (isgray(o)) {
-       gray2black(o);  /* closed upvalues are never gray */
-       luaC_barrier(L, uv, &uv->u.value);
-     }
      uv->v = &uv->u.value;  /* now current value lives here */
      luaC_linkupval(L, uv);  /* link upvalue into `gcroot' list */

-- Roberto