So in summary, it is the effectively fact that we call "setmetatable(o,mt)" on the object (o) passed in parameter to the finalizer that effectively changes its state (a bit in the object).
In my opinion, this is not the best way to handle it
- this requires a specific behavior of setmetatable: it inspects the metatatable to see if there's a __gc function in it, then sets the FINALIZEDBIT if it is so, then returns to the finalizer, which may still change the metatable after this.
- the only safe behavior would be that the finalizer **returns** an effective status. For now finalizer are functions that return nothing (or nil), they could return a non-nil value (probably non-false as well, e.g. true) to indicate its desire to indicate that the FINALIZEDBIT must be CLEARED on the object. A finalizer that does nothing (an empty function) would not return anything, so the GC can still safely look at the metadata at this time, see if it has a __gc function, and if not it will set the FINALIZEDBIT (allowing the object to be swept and freed).