mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-10 06:38:22 +00:00
Merge branch 'master' into fix-3197
This commit is contained in:
29
lib/api/src/js/externals/memory_view.rs
vendored
29
lib/api/src/js/externals/memory_view.rs
vendored
@@ -58,6 +58,35 @@ impl<'a> MemoryView<'a> {
|
||||
self.size
|
||||
}
|
||||
|
||||
// TODO: do we want a proper implementation here instead?
|
||||
/// Retrieve a slice of the memory contents.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Until the returned slice is dropped, it is undefined behaviour to
|
||||
/// modify the memory contents in any way including by calling a wasm
|
||||
/// function that writes to the memory or by resizing the memory.
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn data_unchecked(&self) -> &[u8] {
|
||||
unimplemented!("direct data pointer access is not possible in JavaScript");
|
||||
}
|
||||
|
||||
// TODO: do we want a proper implementation here instead?
|
||||
/// Retrieve a mutable slice of the memory contents.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This method provides interior mutability without an UnsafeCell. Until
|
||||
/// the returned value is dropped, it is undefined behaviour to read or
|
||||
/// write to the pointed-to memory in any way except through this slice,
|
||||
/// including by calling a wasm function that reads the memory contents or
|
||||
/// by resizing this Memory.
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn data_unchecked_mut(&self) -> &mut [u8] {
|
||||
unimplemented!("direct data pointer access is not possible in JavaScript");
|
||||
}
|
||||
|
||||
/// Returns the size (in [`Pages`]) of the `Memory`.
|
||||
///
|
||||
/// # Example
|
||||
|
||||
@@ -234,7 +234,9 @@ impl Module {
|
||||
}
|
||||
|
||||
/// Serializes a module into a binary representation that the `Engine`
|
||||
/// can later process via [`Module::deserialize`].
|
||||
/// can later process via
|
||||
#[cfg_attr(feature = "compiler", doc = "[`Module::deserialize`].")]
|
||||
#[cfg_attr(not(feature = "compiler"), doc = "`Module::deserialize`.")]
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
@@ -252,7 +254,9 @@ impl Module {
|
||||
}
|
||||
|
||||
/// Serializes a module into a file that the `Engine`
|
||||
/// can later process via [`Module::deserialize_from_file`].
|
||||
/// can later process via
|
||||
#[cfg_attr(feature = "compiler", doc = "[`Module::deserialize_from_file`].")]
|
||||
#[cfg_attr(not(feature = "compiler"), doc = "`Module::deserialize_from_file`.")]
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
|
||||
@@ -26,7 +26,9 @@ pub(crate) struct StoreInner {
|
||||
///
|
||||
/// The `Store` holds the engine (that is —amongst many things— used to compile
|
||||
/// the Wasm bytes into a valid module artifact), in addition to the
|
||||
/// [`Tunables`] (that are used to create the memories, tables and globals).
|
||||
#[cfg_attr(feature = "compiler", doc = "[`Tunables`]")]
|
||||
#[cfg_attr(not(feature = "compiler"), doc = "`Tunables`")]
|
||||
/// (that are used to create the memories, tables and globals).
|
||||
///
|
||||
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#store>
|
||||
pub struct Store {
|
||||
|
||||
@@ -178,11 +178,12 @@ mod tests {
|
||||
use std::cell::UnsafeCell;
|
||||
use std::ptr::NonNull;
|
||||
use wasmer_types::{MemoryError, MemoryStyle, MemoryType, Pages, WASM_PAGE_SIZE};
|
||||
use wasmer_vm::{LinearMemory, MaybeInstanceOwned};
|
||||
use wasmer_vm::LinearMemory;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct VMTinyMemory {
|
||||
mem: [u8; WASM_PAGE_SIZE],
|
||||
mem: Vec<u8>,
|
||||
memory_definition: Option<UnsafeCell<VMMemoryDefinition>>,
|
||||
}
|
||||
|
||||
unsafe impl Send for VMTinyMemory {}
|
||||
@@ -190,26 +191,35 @@ mod tests {
|
||||
|
||||
impl VMTinyMemory {
|
||||
pub fn new() -> Result<Self, MemoryError> {
|
||||
Ok(VMTinyMemory {
|
||||
mem: [0; WASM_PAGE_SIZE],
|
||||
})
|
||||
let sz = 18 * WASM_PAGE_SIZE;
|
||||
let mut memory = Vec::new();
|
||||
memory.resize(sz, 0);
|
||||
let mut ret = VMTinyMemory {
|
||||
mem: memory,
|
||||
memory_definition: None,
|
||||
};
|
||||
ret.memory_definition = Some(UnsafeCell::new(VMMemoryDefinition {
|
||||
base: ret.mem.as_ptr() as _,
|
||||
current_length: sz,
|
||||
}));
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
impl LinearMemory for VMTinyMemory {
|
||||
fn ty(&self) -> MemoryType {
|
||||
MemoryType {
|
||||
minimum: Pages::from(1u32),
|
||||
maximum: Some(Pages::from(1u32)),
|
||||
minimum: Pages::from(18u32),
|
||||
maximum: Some(Pages::from(18u32)),
|
||||
shared: false,
|
||||
}
|
||||
}
|
||||
fn size(&self) -> Pages {
|
||||
Pages::from(1u32)
|
||||
Pages::from(18u32)
|
||||
}
|
||||
fn style(&self) -> MemoryStyle {
|
||||
MemoryStyle::Static {
|
||||
bound: Pages::from(1u32),
|
||||
bound: Pages::from(18u32),
|
||||
offset_guard_size: 0,
|
||||
}
|
||||
}
|
||||
@@ -220,15 +230,28 @@ mod tests {
|
||||
})
|
||||
}
|
||||
fn vmmemory(&self) -> NonNull<VMMemoryDefinition> {
|
||||
MaybeInstanceOwned::Host(Box::new(UnsafeCell::new(VMMemoryDefinition {
|
||||
base: self.mem.as_ptr() as _,
|
||||
current_length: WASM_PAGE_SIZE,
|
||||
})))
|
||||
.as_ptr()
|
||||
unsafe {
|
||||
NonNull::new(
|
||||
self.memory_definition
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get()
|
||||
.as_mut()
|
||||
.unwrap() as _,
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
|
||||
None
|
||||
}
|
||||
/*
|
||||
// this code allow custom memory to be ignoring init_memory
|
||||
use wasmer_vm::Trap;
|
||||
unsafe fn initialize_with_data(&self, _start: usize, _data: &[u8]) -> Result<(), Trap> {
|
||||
Ok(())
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
impl From<VMTinyMemory> for wasmer_vm::VMMemory {
|
||||
@@ -241,7 +264,7 @@ mod tests {
|
||||
impl Tunables for TinyTunables {
|
||||
fn memory_style(&self, _memory: &MemoryType) -> MemoryStyle {
|
||||
MemoryStyle::Static {
|
||||
bound: Pages::from(1u32),
|
||||
bound: Pages::from(18u32),
|
||||
offset_guard_size: 0,
|
||||
}
|
||||
}
|
||||
@@ -262,9 +285,16 @@ mod tests {
|
||||
&self,
|
||||
_ty: &MemoryType,
|
||||
_style: &MemoryStyle,
|
||||
_vm_definition_location: NonNull<VMMemoryDefinition>,
|
||||
vm_definition_location: NonNull<VMMemoryDefinition>,
|
||||
) -> Result<VMMemory, MemoryError> {
|
||||
let memory = VMTinyMemory::new().unwrap();
|
||||
// now, it's important to update vm_definition_location with the memory information!
|
||||
let mut ptr = vm_definition_location;
|
||||
let md = ptr.as_mut();
|
||||
let unsafecell = memory.memory_definition.as_ref().unwrap();
|
||||
let def = unsafecell.get().as_ref().unwrap();
|
||||
md.base = def.base;
|
||||
md.current_length = def.current_length;
|
||||
Ok(memory.into())
|
||||
}
|
||||
|
||||
@@ -293,13 +323,13 @@ mod tests {
|
||||
let vmmemory = tunables.create_host_memory(
|
||||
&MemoryType::new(1u32, Some(100u32), true),
|
||||
&MemoryStyle::Static {
|
||||
bound: Pages::from(1u32),
|
||||
bound: Pages::from(18u32),
|
||||
offset_guard_size: 0u64,
|
||||
},
|
||||
);
|
||||
let mut vmmemory = vmmemory.unwrap();
|
||||
assert!(vmmemory.grow(Pages::from(2u32)).is_err());
|
||||
assert_eq!(vmmemory.size(), Pages::from(1u32));
|
||||
assert!(vmmemory.grow(Pages::from(50u32)).is_err());
|
||||
assert_eq!(vmmemory.size(), Pages::from(18u32));
|
||||
assert_eq!(
|
||||
vmmemory.grow(Pages::from(0u32)).err().unwrap(),
|
||||
MemoryError::CouldNotGrow {
|
||||
@@ -308,4 +338,42 @@ mod tests {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_customtunables() -> Result<(), Box<dyn std::error::Error>> {
|
||||
use crate::{imports, wat2wasm, Instance, Memory, Module, Store};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
|
||||
let wasm_bytes = wat2wasm(
|
||||
br#"(module
|
||||
(memory (;0;) 18)
|
||||
(global (;0;) (mut i32) i32.const 1048576)
|
||||
(export "memory" (memory 0))
|
||||
(data (;0;) (i32.const 1048576) "*\00\00\00")
|
||||
)"#,
|
||||
)?;
|
||||
let compiler = Cranelift::default();
|
||||
|
||||
let tunables = TinyTunables {};
|
||||
let mut store = Store::new_with_tunables(compiler, tunables);
|
||||
//let mut store = Store::new(compiler);
|
||||
let module = Module::new(&store, wasm_bytes)?;
|
||||
let import_object = imports! {};
|
||||
let instance = Instance::new(&mut store, &module, &import_object)?;
|
||||
|
||||
let mut memories: Vec<Memory> = instance
|
||||
.exports
|
||||
.iter()
|
||||
.memories()
|
||||
.map(|pair| pair.1.clone())
|
||||
.collect();
|
||||
assert_eq!(memories.len(), 1);
|
||||
let first_memory = memories.pop().unwrap();
|
||||
assert_eq!(first_memory.ty(&store).maximum.unwrap(), Pages(18));
|
||||
let view = first_memory.view(&store);
|
||||
let x = unsafe { view.data_unchecked_mut() }[0];
|
||||
assert_eq!(x, 0);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user