kyren / piccolo

An experimental stackless Lua VM implemented in pure Rust
Creative Commons Zero v1.0 Universal
1.62k stars 59 forks source link

UserData: add downcast_write_static #42

Closed jrobsonchase closed 4 months ago

jrobsonchase commented 4 months ago

Not 100% sure how useful this is, but it seemed like it was possible-yet-missing.

kyren commented 4 months ago

This method wasn't missing, it's just never required. You're not the first person to mention this to me, it's something that should be documented better but isn't (like everything in piccolo right now lol).

gc_arena::barrier::Write allows you to safely write garbage collected values by asserting that they've had the "write barrier" invoked, which is an essential part of the safety story of gc-arena. You can't safely mutate a value which may hold Gc pointers unless you do it through barrier::Write (or something that wraps it), because without the write barrier being invoked you may violate the color invariant of the garbage collector.

'static values cannot contain Gc pointers, so there are special rules for 'static types to make things easier. Cell<T> and RefCell<T> implement Collect only when T: 'static, giving you a "way out" of the whole write barrier system if your type is 'static. You never need to have a Write<T> when T: 'static because you don't even have to use wrapper types like gc_arena::lock::Lock (a wrapper around Cell) or gc_arena::lock::RefLock (a wrapper around RefCell), because you can just use Cell and RefCell directly.

Internal mutability for types which may hold Gc pointers is important to guard with write barriers (or require unsafe and a guarantee that the color invariant is upheld), but for types which cannot possibly hold Gc pointers, this is never necessary. If you know a type is 'static, then you must not ever need gc_arena::barrier::Write, so this method is simply not included on purpose.