Skip to content
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 remaining issues identified by Miri #226

Merged
merged 6 commits into from
Sep 16, 2023

Conversation

Imberflur
Copy link
Contributor

@Imberflur Imberflur commented Feb 25, 2023

Addresses miri's complaints about vtable shenanigans in MetaTable implementation.

  • Before pointer casts and reads/deferences were used to extract/attach a vtable pointer as a usize (which includes operations that miri reports as UB). Now a function pointer is stored for each concrete type, this points to a function that knows the types involved and can thus leverage safe code to upcast a pointer from the concrete type to a trait object.
  • CastFrom trait now uses a single method that operates on pointers rather than two separate methods for &T and &mut T (this is so that we don't have to store a separate function pointer for each case). Safety requirements for implementing CastFrom having been modified (but can be trivially met by just returning the provided pointer (letting it be automatically coerced to a pointer to the trait object)).
  • MetaTable::register no longer requires an instance of the type being registered.
  • MetaTable::get_mut no longer converts a shared reference to an exclusive one (this was most likely UB).
  • MetaIter/MetaIterMut no longer cast aside the Ref/RefMut guard on each element (which would allow safe code to create aliasing references to items being yielded from these iterators). Instead, Ref::map and RefMut::map are used.
  • Converted meta iterators to use a loop rather than recursion for advancing past missing values from try_fetch_internal (not sure if this avoids impacting performance though...).

Misc changes:

  • Added crate-level deny for unsafe_op_in_unsafe_fn and added unsafe blocks where needed. This makes it easier to identify where unsafe operations are occuring and to document them.
  • Bump MSRV to 1.65.0, since we are already bumping it in specs to use GATs and it gives some convenient functions for working with pointers.
  • Remove unnecessary extern crates in benches/bench.rs (not needed in newer rust editions).

Update: This now adds a nightly feature which uses the unstable ptr_metadata feature for a more efficient implementation of the MetaTable.

implementation.

* Before pointer casts and reads/deferences were used to extract/attach
  a vtable pointer as a `usize` (which includes operations that miri
  reports as UB). Now a function pointer is stored for each concrete
  type, this points to a function that knows the types involved and can
  thus leverage safe code to upcast a pointer from the concrete type to
  a trait object.
* `CastFrom` trait now uses a single method that operates on pointers
  rather than two separate methods for `&T` and `&mut T` (this is so
  that we don't have to store a separate function pointer for each
  case). Safety requirements for implementing `CastFrom` having been
  modified (but can be trivially met by just returning the provided
  pointer (letting it be automatically coerced to a pointer to the trait
  object)).
* `MetaTable::register` no longer requires an instance of the type being
  registered.
* `MetaTable::get_mut` no longer converts a shared reference to an
  exclusive one (this was most likely UB).
* `MetaIter`/`MetaIterMut` no longer cast aside the `Ref`/`RefMut` guard
  on each element (which would allow safe code to create aliasing
  references to items being yielded from these iterators). Instead,
  `Ref::map` and `RefMut::map` are used.
* Converted meta iterators to use a loop rather than recursion for
  advancing past missing values from try_fetch_internal (not sure if
  this avoids impacting performance though...).

Misc changes:

* Added crate-level deny for `unsafe_op_in_unsafe_fn` and added unsafe
  blocks where needed. This makes it easier to identify where unsafe
  operations are occuring and to document them.
* Bump MSRV to 1.65.0, since we are already bumping it in specs to use
  GATs and it gives some convenient functions for working with pointers.
* Remove unnecessary `extern crate`s in benches/bench.rs (not needed in
  newer rust editions).
@Imberflur Imberflur merged commit 00a9b64 into amethyst:master Sep 16, 2023
@Imberflur Imberflur deleted the metatable-fix branch September 16, 2023 03:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants