stop using transmute and document unsafe replacement code

This commit is contained in:
2025-04-27 15:08:14 -07:00
parent ba1c1ec8c6
commit 5f0ddc2f28
3 changed files with 21 additions and 6 deletions
lib
linear_ops
roblox_emulator
src
runner

@ -204,13 +204,19 @@ macro_rules! impl_matrix_named_fields_shape {
type Target=$struct_outer<Vector<$size_inner,T>>; type Target=$struct_outer<Vector<$size_inner,T>>;
#[inline] #[inline]
fn deref(&self)->&Self::Target{ fn deref(&self)->&Self::Target{
unsafe{core::mem::transmute(&self.array)} // This cast is valid because Matrix has #[repr(transparent)]
let ptr=&self.array as *const [[T;$size_inner];$size_outer] as *const Self::Target;
// SAFETY: this pointer is non-null because it comes from a reference
unsafe{&*ptr}
} }
} }
impl<T> core::ops::DerefMut for Matrix<$size_outer,$size_inner,T>{ impl<T> core::ops::DerefMut for Matrix<$size_outer,$size_inner,T>{
#[inline] #[inline]
fn deref_mut(&mut self)->&mut Self::Target{ fn deref_mut(&mut self)->&mut Self::Target{
unsafe{core::mem::transmute(&mut self.array)} // This cast is valid because Matrix has #[repr(transparent)]
let ptr=&mut self.array as *mut [[T;$size_inner];$size_outer] as *mut Self::Target;
// SAFETY: this pointer is non-null because it comes from a reference
unsafe{&mut*ptr}
} }
} }
} }

@ -330,13 +330,19 @@ macro_rules! impl_vector_named_fields {
type Target=$struct<T>; type Target=$struct<T>;
#[inline] #[inline]
fn deref(&self)->&Self::Target{ fn deref(&self)->&Self::Target{
unsafe{core::mem::transmute(&self.array)} // This cast is valid because Vector has #[repr(transparent)]
let ptr=&self.array as *const [T;$size] as *const Self::Target;
// SAFETY: this pointer is non-null because it comes from a reference
unsafe{&*ptr}
} }
} }
impl<T> core::ops::DerefMut for Vector<$size,T>{ impl<T> core::ops::DerefMut for Vector<$size,T>{
#[inline] #[inline]
fn deref_mut(&mut self)->&mut Self::Target{ fn deref_mut(&mut self)->&mut Self::Target{
unsafe{core::mem::transmute(&mut self.array)} // This cast is valid because Vector has #[repr(transparent)]
let ptr=&mut self.array as *mut [T;$size] as *mut Self::Target;
// SAFETY: this pointer is non-null because it comes from a reference
unsafe{&mut*ptr}
} }
} }
} }

@ -65,8 +65,11 @@ impl Runner{
globals.set("game",super::instance::Instance::new_unchecked(context.services.game)).map_err(Error::RustLua)?; globals.set("game",super::instance::Instance::new_unchecked(context.services.game)).map_err(Error::RustLua)?;
globals.set("workspace",super::instance::Instance::new_unchecked(context.services.workspace)).map_err(Error::RustLua)?; globals.set("workspace",super::instance::Instance::new_unchecked(context.services.workspace)).map_err(Error::RustLua)?;
} }
//this makes set_app_data shut up about the lifetime // SAFETY: This is not a &'static mut WeakDom,
self.lua.set_app_data::<crate::context::LuaAppData>(unsafe{core::mem::transmute(&mut context.dom)}); // but as long as Runnable<'a> holds the lifetime of &'a mut Context
// it is a valid unique reference.
let ptr=&mut context.dom as *mut rbx_dom_weak::WeakDom;
self.lua.set_app_data::<crate::context::LuaAppData>(unsafe{&mut*ptr});
#[cfg(feature="run-service")] #[cfg(feature="run-service")]
self.lua.set_app_data::<crate::scheduler::Scheduler>(crate::scheduler::Scheduler::default()); self.lua.set_app_data::<crate::scheduler::Scheduler>(crate::scheduler::Scheduler::default());
Ok(Runnable{ Ok(Runnable{