Merge branch 'master' into fix-3197

This commit is contained in:
Felix Schütt
2022-10-11 11:48:56 +02:00
committed by GitHub
60 changed files with 14308 additions and 4499 deletions

View File

@@ -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

View File

@@ -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
///

View File

@@ -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 {

View File

@@ -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(())
}
}