-
Notifications
You must be signed in to change notification settings - Fork 830
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 memory leak in host function envs #1865
Changes from 14 commits
1eaea6e
e43d9d2
4ec8c9e
ca4736c
476e8d1
6e95c50
99e0357
be3c381
ec4d6e6
bd01d6a
f798f34
27f7e7e
62d15fa
6a21169
8081aae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,12 +30,12 @@ impl From<ExportError> for HostEnvInitError { | |
/// ``` | ||
/// use wasmer::{WasmerEnv, LazyInit, Memory, NativeFunc}; | ||
/// | ||
/// #[derive(WasmerEnv)] | ||
/// #[derive(WasmerEnv, Clone)] | ||
/// pub struct MyEnvWithNoInstanceData { | ||
/// non_instance_data: u8, | ||
/// } | ||
/// | ||
/// #[derive(WasmerEnv)] | ||
/// #[derive(WasmerEnv, Clone)] | ||
/// pub struct MyEnvWithInstanceData { | ||
/// non_instance_data: u8, | ||
/// #[wasmer(export)] | ||
|
@@ -54,6 +54,7 @@ impl From<ExportError> for HostEnvInitError { | |
/// This trait can also be implemented manually: | ||
/// ``` | ||
/// # use wasmer::{WasmerEnv, LazyInit, Memory, Instance, HostEnvInitError}; | ||
/// #[derive(Clone)] | ||
/// pub struct MyEnv { | ||
/// memory: LazyInit<Memory>, | ||
/// } | ||
|
@@ -66,7 +67,7 @@ impl From<ExportError> for HostEnvInitError { | |
/// } | ||
/// } | ||
/// ``` | ||
pub trait WasmerEnv { | ||
pub trait WasmerEnv: Clone + Send { | ||
/// The function that Wasmer will call on your type to let it finish | ||
/// setting up the environment with data from the `Instance`. | ||
/// | ||
|
@@ -94,26 +95,26 @@ impl WasmerEnv for isize {} | |
impl WasmerEnv for char {} | ||
impl WasmerEnv for bool {} | ||
impl WasmerEnv for String {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicBool {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicI8 {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicU8 {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicI16 {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicU16 {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicI32 {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicU32 {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicI64 {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicUsize {} | ||
impl WasmerEnv for ::std::sync::atomic::AtomicIsize {} | ||
impl WasmerEnv for dyn ::std::any::Any {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicBool {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicI8 {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicU8 {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicI16 {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicU16 {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicI32 {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicU32 {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicI64 {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicUsize {} | ||
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicIsize {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why we need the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
These I'd be fine to remove them |
||
impl<T: WasmerEnv> WasmerEnv for Box<T> { | ||
fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> { | ||
(&mut **self).init_with_instance(instance) | ||
} | ||
} | ||
|
||
impl<T: WasmerEnv> WasmerEnv for &'static mut T { | ||
impl<T: WasmerEnv> WasmerEnv for ::std::sync::Arc<::std::sync::Mutex<T>> { | ||
fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> { | ||
(*self).init_with_instance(instance) | ||
let mut guard = self.lock().unwrap(); | ||
guard.init_with_instance(instance) | ||
} | ||
} | ||
|
||
|
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.
Why do we need to change the examples? The previous examples should work as is. Or am I missing something?
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.
Yeah, the previous examples were incorrect, we just didn't enforce it.
WasmerEnv
needs to beSend
andSync
becauseInstance
isSend
andSync
and we don't synchronize access to functions. So it's possible in safe Rust to get aNativeFunc
on multiple threads that points to the same underlying function. In order for theWasmerEnv
to be able to handle being used this way, it must be bothSend
andSync
. This shouldn't affect much, if any, real code. For example, WASI was not affected at all by this change. Emscripten was only affected because it was doing some weird stuff with pointers.