mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-10 06:38:22 +00:00
265 lines
8.7 KiB
Rust
265 lines
8.7 KiB
Rust
pub use wasmer_compiler::BaseTunables;
|
|
|
|
// All BaseTunable definition now is in wasmer_compile crate
|
|
// Tests are still here
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::sys::TableType;
|
|
use std::cell::UnsafeCell;
|
|
use std::ptr::NonNull;
|
|
use wasmer_compiler::Tunables;
|
|
use wasmer_types::{MemoryType, Pages, WASM_PAGE_SIZE};
|
|
use wasmer_vm::{
|
|
LinearMemory, MemoryError, MemoryStyle, TableStyle, VMMemory, VMMemoryDefinition, VMTable,
|
|
VMTableDefinition,
|
|
};
|
|
|
|
#[test]
|
|
fn memory_style() {
|
|
let tunables = BaseTunables {
|
|
static_memory_bound: Pages(2048),
|
|
static_memory_offset_guard_size: 128,
|
|
dynamic_memory_offset_guard_size: 256,
|
|
};
|
|
|
|
// No maximum
|
|
let requested = MemoryType::new(3, None, true);
|
|
let style = tunables.memory_style(&requested);
|
|
match style {
|
|
MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256),
|
|
s => panic!("Unexpected memory style: {:?}", s),
|
|
}
|
|
|
|
// Large maximum
|
|
let requested = MemoryType::new(3, Some(5_000_000), true);
|
|
let style = tunables.memory_style(&requested);
|
|
match style {
|
|
MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256),
|
|
s => panic!("Unexpected memory style: {:?}", s),
|
|
}
|
|
|
|
// Small maximum
|
|
let requested = MemoryType::new(3, Some(16), true);
|
|
let style = tunables.memory_style(&requested);
|
|
match style {
|
|
MemoryStyle::Static {
|
|
bound,
|
|
offset_guard_size,
|
|
} => {
|
|
assert_eq!(bound, Pages(2048));
|
|
assert_eq!(offset_guard_size, 128);
|
|
}
|
|
s => panic!("Unexpected memory style: {:?}", s),
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct VMTinyMemory {
|
|
mem: Vec<u8>,
|
|
memory_definition: Option<UnsafeCell<VMMemoryDefinition>>,
|
|
}
|
|
|
|
unsafe impl Send for VMTinyMemory {}
|
|
unsafe impl Sync for VMTinyMemory {}
|
|
|
|
impl VMTinyMemory {
|
|
pub fn new() -> Result<Self, MemoryError> {
|
|
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(18u32),
|
|
maximum: Some(Pages::from(18u32)),
|
|
shared: false,
|
|
}
|
|
}
|
|
fn size(&self) -> Pages {
|
|
Pages::from(18u32)
|
|
}
|
|
fn style(&self) -> MemoryStyle {
|
|
MemoryStyle::Static {
|
|
bound: Pages::from(18u32),
|
|
offset_guard_size: 0,
|
|
}
|
|
}
|
|
fn grow(&mut self, delta: Pages) -> Result<Pages, MemoryError> {
|
|
Err(MemoryError::CouldNotGrow {
|
|
current: Pages::from(100u32),
|
|
attempted_delta: delta,
|
|
})
|
|
}
|
|
fn vmmemory(&self) -> NonNull<VMMemoryDefinition> {
|
|
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
|
|
}
|
|
fn fork(&mut self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
|
|
let mem = self.mem.clone();
|
|
Ok(Box::new(Self {
|
|
memory_definition: Some(UnsafeCell::new(VMMemoryDefinition {
|
|
base: mem.as_ptr() as _,
|
|
current_length: mem.len(),
|
|
})),
|
|
mem,
|
|
}))
|
|
}
|
|
/*
|
|
// 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 {
|
|
fn from(mem: VMTinyMemory) -> Self {
|
|
Self(Box::new(mem))
|
|
}
|
|
}
|
|
|
|
struct TinyTunables;
|
|
impl Tunables for TinyTunables {
|
|
fn memory_style(&self, _memory: &MemoryType) -> MemoryStyle {
|
|
MemoryStyle::Static {
|
|
bound: Pages::from(18u32),
|
|
offset_guard_size: 0,
|
|
}
|
|
}
|
|
|
|
/// Construct a `TableStyle` for the provided `TableType`
|
|
fn table_style(&self, _table: &TableType) -> TableStyle {
|
|
TableStyle::CallerChecksSignature
|
|
}
|
|
fn create_host_memory(
|
|
&self,
|
|
_ty: &MemoryType,
|
|
_style: &MemoryStyle,
|
|
) -> Result<VMMemory, MemoryError> {
|
|
let memory = VMTinyMemory::new().unwrap();
|
|
Ok(VMMemory::from_custom(memory))
|
|
}
|
|
unsafe fn create_vm_memory(
|
|
&self,
|
|
_ty: &MemoryType,
|
|
_style: &MemoryStyle,
|
|
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())
|
|
}
|
|
|
|
/// Create a table owned by the host given a [`TableType`] and a [`TableStyle`].
|
|
fn create_host_table(&self, ty: &TableType, style: &TableStyle) -> Result<VMTable, String> {
|
|
VMTable::new(ty, style)
|
|
}
|
|
|
|
/// Create a table owned by the VM given a [`TableType`] and a [`TableStyle`].
|
|
///
|
|
/// # Safety
|
|
/// - `vm_definition_location` must point to a valid location in VM memory.
|
|
unsafe fn create_vm_table(
|
|
&self,
|
|
ty: &TableType,
|
|
style: &TableStyle,
|
|
vm_definition_location: NonNull<VMTableDefinition>,
|
|
) -> Result<VMTable, String> {
|
|
VMTable::from_definition(ty, style, vm_definition_location)
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn check_linearmemory() {
|
|
let tunables = TinyTunables {};
|
|
let vmmemory = tunables.create_host_memory(
|
|
&MemoryType::new(1u32, Some(100u32), true),
|
|
&MemoryStyle::Static {
|
|
bound: Pages::from(18u32),
|
|
offset_guard_size: 0u64,
|
|
},
|
|
);
|
|
let mut vmmemory = vmmemory.unwrap();
|
|
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 {
|
|
current: Pages::from(100u32),
|
|
attempted_delta: Pages::from(0u32)
|
|
}
|
|
);
|
|
}
|
|
|
|
#[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(())
|
|
}
|
|
}
|