-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix unsound use of Rooted<T> with RootKind::Traceable #514
Conversation
9ef63c2
to
6365c75
Compare
9fa98bd
to
8c7ff63
Compare
Signed-off-by: Josh Matthews <[email protected]>
Signed-off-by: Josh Matthews <[email protected]>
…nts TraceableTrace. Signed-off-by: Josh Matthews <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Signed-off-by: Josh Matthews <[email protected]>
fn do_trace(&mut self, trc: *mut JSTracer) { | ||
unsafe { | ||
CallPropertyDescriptorTracer(trc, self); | ||
} | ||
unsafe fn do_trace(&mut self, trc: *mut JSTracer) { | ||
CallPropertyDescriptorTracer(trc, self); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually unsafe block in unsafe fn will be the only correct way in the future: https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html, but that is not yet relevant.
The existing implementation for
Rooted<T>
is correct for most JS types that are rooted, but there's one significant case that is broken.Rooted<T>
uses C++ template magic to change its base class depending on the type that it's templated over, and certain types that map toRootKind::Traceable
end up with a vtable that contains a custom tracing implementation, while other types do not have any such vtable.These template shenanigans are very likely the reason why we have a handwritten
Rooted<T>
definition, since bindgen is not able to handle this situation. This PR makes the following changes:Rooted<T>
which is zero-sized for types that do not have Traceable RootKind valueTraceableTrace
trait thatRooted<T>
's vtable delegates to, allowing implementers to write straightforward tracing implementations for their typesThese changes were verified by running the property_descriptor unit test with zealous GC enabled (ie. perform a GC every time there's an allocation) and the test no longer crashes after these changes are applied.