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

refactor!: Memory API Modifications (try_clone/copy, duplicate_in_store) #3874

Merged
merged 1 commit into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 1 addition & 21 deletions lib/api/src/externals/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@ impl Memory {
self.0
.try_copy(&store)
.map(|new_memory| Self::new_from_existing(new_store, new_memory.into()))
.ok_or_else(|| {
MemoryError::Generic("memory is not clonable or could not be copied".to_string())
})
}

pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, vm_extern: VMExternMemory) -> Self {
Expand All @@ -152,7 +149,7 @@ impl Memory {
}

/// Attempts to clone this memory (if its clonable)
pub fn try_clone(&self, store: &impl AsStoreRef) -> Option<VMMemory> {
pub fn try_clone(&self, store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
self.0.try_clone(store)
}

Expand All @@ -172,23 +169,6 @@ impl Memory {
self.0
.try_clone(&store)
.map(|new_memory| Self::new_from_existing(new_store, new_memory))
.ok_or_else(|| MemoryError::Generic("memory is not clonable".to_string()))
}

/// Attempts to clone this memory (if its clonable) in a new store
/// (cloned memory will be shared between those that clone it)
#[deprecated = "use `share_in_store` or `copy_to_store` instead"]
pub fn duplicate_in_store(
&self,
store: &impl AsStoreRef,
new_store: &mut impl AsStoreMut,
) -> Option<Self> {
if !self.ty(store).shared {
// We should only be able to duplicate in a new store if the memory is shared
return None;
}
#[allow(deprecated)]
self.0.duplicate_in_store(store, new_store).map(Self)
}

/// To `VMExtern`.
Expand Down
18 changes: 4 additions & 14 deletions lib/api/src/js/externals/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,25 +142,15 @@ impl Memory {

/// Cloning memory will create another reference to the same memory that
/// can be put into a new store
pub fn try_clone(&self, _store: &impl AsStoreRef) -> Option<VMMemory> {
pub fn try_clone(&self, _store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
self.handle.try_clone()
}

/// Copying the memory will actually copy all the bytes in the memory to
/// a identical byte copy of the original that can be put into a new store
pub fn try_copy(&self, store: &impl AsStoreRef) -> Option<VMMemory> {
self.try_clone(store).and_then(|mut mem| mem.copy().ok())
}

#[deprecated = "use `try_clone` and `try_copy` instead"]
pub fn duplicate_in_store(
&self,
store: &impl AsStoreRef,
new_store: &mut impl AsStoreMut,
) -> Option<Self> {
self.try_clone(&store)
.and_then(|mut memory| memory.duplicate().ok())
.map(|new_memory| Self::new_from_existing(new_store, new_memory.into()))
pub fn try_copy(&self, store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
let mut cloned = self.try_clone(store)?;
cloned.copy()
}

pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
Expand Down
4 changes: 2 additions & 2 deletions lib/api/src/js/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ impl VMMemory {
}

/// Attempts to clone this memory (if its clonable)
pub(crate) fn try_clone(&self) -> Option<VMMemory> {
Some(self.clone())
pub(crate) fn try_clone(&self) -> Result<VMMemory, MemoryError> {
Ok(self.clone())
}

/// Copies this memory to a new memory
Expand Down
19 changes: 4 additions & 15 deletions lib/api/src/jsc/externals/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,26 +172,15 @@ impl Memory {

/// Cloning memory will create another reference to the same memory that
/// can be put into a new store
pub fn try_clone(&self, _store: &impl AsStoreRef) -> Option<VMMemory> {
pub fn try_clone(&self, _store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
self.handle.try_clone()
}

/// Copying the memory will actually copy all the bytes in the memory to
/// a identical byte copy of the original that can be put into a new store
pub fn try_copy(&self, store: &impl AsStoreRef) -> Option<VMMemory> {
self.try_clone(store)
.and_then(|mut mem| mem.copy(store).ok())
}

#[deprecated = "use `try_clone` and `try_copy` instead"]
pub fn duplicate_in_store(
&self,
store: &impl AsStoreRef,
new_store: &mut impl AsStoreMut,
) -> Option<Self> {
self.try_clone(&store)
.and_then(|mut memory| memory.duplicate(&store).ok())
.map(|new_memory| Self::new_from_existing(new_store, new_memory.into()))
pub fn try_copy(&self, store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
let mut cloned = self.try_clone(store)?;
cloned.copy(store)
}

pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
Expand Down
4 changes: 2 additions & 2 deletions lib/api/src/jsc/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ impl VMMemory {
}

/// Attempts to clone this memory (if its clonable)
pub(crate) fn try_clone(&self) -> Option<VMMemory> {
Some(self.clone())
pub(crate) fn try_clone(&self) -> Result<VMMemory, MemoryError> {
Ok(self.clone())
}

/// Copies this memory to a new memory
Expand Down
20 changes: 7 additions & 13 deletions lib/api/src/sys/externals/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,26 +65,20 @@ impl Memory {

/// Cloning memory will create another reference to the same memory that
/// can be put into a new store
pub fn try_clone(&self, store: &impl AsStoreRef) -> Option<VMMemory> {
pub fn try_clone(&self, store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
let mem = self.handle.get(store.as_store_ref().objects());
mem.try_clone().map(|mem| mem.into())
let cloned = mem.try_clone()?;
Ok(cloned.into())
}

/// Copying the memory will actually copy all the bytes in the memory to
/// a identical byte copy of the original that can be put into a new store
pub fn try_copy(&self, store: &impl AsStoreRef) -> Option<Box<dyn LinearMemory + 'static>> {
self.try_clone(store).and_then(|mut mem| mem.copy().ok())
}

#[deprecated = "use `try_clone` and `try_copy` instead"]
pub fn duplicate_in_store(
pub fn try_copy(
&self,
store: &impl AsStoreRef,
new_store: &mut impl AsStoreMut,
) -> Option<Self> {
self.try_clone(&store)
.and_then(|mut memory| memory.copy().ok())
.map(|new_memory| Self::new_from_existing(new_store, new_memory.into()))
) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
let mut mem = self.try_clone(store)?;
mem.copy()
}

/// To `VMExtern`.
Expand Down
6 changes: 4 additions & 2 deletions lib/api/src/sys/tunables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,10 @@ mod tests {
}
}

fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
None
fn try_clone(&self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
Err(MemoryError::InvalidMemory {
reason: "VMTinyMemory can not be cloned".to_string(),
})
}

fn copy(&mut self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
Expand Down
11 changes: 5 additions & 6 deletions lib/sys-utils/src/memory/fd_memory/memories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,8 @@ impl LinearMemory for VMOwnedMemory {
}

/// Owned memory can not be cloned (this will always return None)
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
tracing::warn!("trying to clone owned memory");
None
fn try_clone(&self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
Err(MemoryError::MemoryNotShared)
}

/// Copies this memory to a new memory
Expand Down Expand Up @@ -440,8 +439,8 @@ impl LinearMemory for VMSharedMemory {
}

/// Shared memory can always be cloned
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
Some(Box::new(self.clone()))
fn try_clone(&self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
Ok(Box::new(self.clone()))
}

/// Copies this memory to a new memory
Expand Down Expand Up @@ -515,7 +514,7 @@ impl LinearMemory for VMMemory {
}

/// Attempts to clone this memory (if its clonable)
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
fn try_clone(&self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
self.0.try_clone()
}

Expand Down
6 changes: 5 additions & 1 deletion lib/types/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub enum DeserializeError {

/// Error type describing things that can go wrong when operating on Wasm Memories.
#[derive(Error, Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum MemoryError {
/// Low level error with mmap.
#[error("Error when allocating memory: {0}")]
Expand All @@ -60,7 +61,7 @@ pub enum MemoryError {
/// The attempted amount to grow by in pages.
attempted_delta: Pages,
},
/// The operation would cause the size of the memory size exceed the maximum.
/// Invalid memory was provided.
#[error("The memory is invalid because {}", reason)]
InvalidMemory {
/// The reason why the provided memory is invalid.
Expand All @@ -82,6 +83,9 @@ pub enum MemoryError {
/// The number of pages requested as the maximum amount of memory.
max_allowed: Pages,
},
/// Returned when a shared memory is required, but the given memory is not shared.
#[error("The memory is not shared")]
MemoryNotShared,
/// A user defined error value, used for error cases not listed above.
#[error("A user-defined error occurred: {0}")]
Generic(String),
Expand Down
12 changes: 6 additions & 6 deletions lib/vm/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@ impl LinearMemory for VMOwnedMemory {
}

/// Owned memory can not be cloned (this will always return None)
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
None
fn try_clone(&self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
Err(MemoryError::MemoryNotShared)
}

/// Copies this memory to a new memory
Expand Down Expand Up @@ -429,8 +429,8 @@ impl LinearMemory for VMSharedMemory {
}

/// Shared memory can always be cloned
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
Some(Box::new(self.clone()))
fn try_clone(&self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
Ok(Box::new(self.clone()))
}

/// Copies this memory to a new memory
Expand Down Expand Up @@ -506,7 +506,7 @@ impl LinearMemory for VMMemory {
}

/// Attempts to clone this memory (if its clonable)
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
fn try_clone(&self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
self.0.try_clone()
}

Expand Down Expand Up @@ -637,7 +637,7 @@ where
fn vmmemory(&self) -> NonNull<VMMemoryDefinition>;

/// Attempts to clone this memory (if its clonable)
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>>;
fn try_clone(&self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError>;

#[doc(hidden)]
/// # Safety
Expand Down