/* Correct a list of gray objects. Return pointer to where rest of the list should be linked. Because this correction is done after sweeping, young objects might be turned white and still be in the list. They are only removed. 'TOUCHED1' objects are advanced to 'TOUCHED2' and remain on the list; Non-white threads also remain on the list; 'TOUCHED2' objects become regular old; they and anything else are removed from the list.  */
static GCObject** correctgraylist(GCObject **p)
/* Correct a list of gray objects. Return pointer to where rest of the list should be linked. Because this correction is done after sweeping, young objects might be turned white and still be in the list. They are only removed. 'TOUCHED1' objects are advanced to 'TOUCHED2' and remain on the list; Non-white threads also remain on the list; 'TOUCHED2' objects become regular old; they and anything else are removed from the list.  */
static GCObject** correctgraylist(GCObject **p)
{
    GCObject **next = getgclist(curr);
    if (iswhite(curr))
      goto remove;
    else if (getage(curr) == G_TOUCHED1) {
      lua_assert(isgray(curr));
      nw2black(curr);
      changeage(curr, G_TOUCHED1, G_TOUCHED2);
      goto remain;
    }
    else if (curr->tt == LUA_VTHREAD) {
      lua_assert(isgray(curr));
      goto remain;
    }
    else {
      lua_assert(isold(curr));
      if (getage(curr) == G_TOUCHED2)
        changeage(curr, G_TOUCHED2, G_OLD);
      nw2black(curr);
      goto remove;
    }
    remove: *p = *next; continue;
    remain: p = next; continue;
  }
  return p;
}