mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-17 01:28:44 +00:00
Removed Instance::new_no_memory_init, use custom LinearMemory with custom memory_init method to get the same result
This commit is contained in:
@@ -118,47 +118,7 @@ impl Instance {
|
|||||||
let imports = imports
|
let imports = imports
|
||||||
.imports_for_module(module)
|
.imports_for_module(module)
|
||||||
.map_err(InstantiationError::Link)?;
|
.map_err(InstantiationError::Link)?;
|
||||||
let mut handle = module.instantiate(store, &imports, true)?;
|
let mut handle = module.instantiate(store, &imports)?;
|
||||||
let exports = module
|
|
||||||
.exports()
|
|
||||||
.map(|export| {
|
|
||||||
let name = export.name().to_string();
|
|
||||||
let export = handle.lookup(&name).expect("export");
|
|
||||||
let extern_ = Extern::from_vm_extern(store, export);
|
|
||||||
(name, extern_)
|
|
||||||
})
|
|
||||||
.collect::<Exports>();
|
|
||||||
|
|
||||||
let instance = Self {
|
|
||||||
_handle: StoreHandle::new(store.objects_mut(), handle),
|
|
||||||
module: module.clone(),
|
|
||||||
exports,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(instance)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
/// Creates a new `Instance` from a WebAssembly [`Module`] and a
|
|
||||||
/// set of imports using [`Imports`] or the [`imports`] macro helper.
|
|
||||||
/// The instance memory will not be initialized
|
|
||||||
///
|
|
||||||
/// ## Errors
|
|
||||||
///
|
|
||||||
/// The function can return [`InstantiationError`]s.
|
|
||||||
///
|
|
||||||
/// Those are, as defined by the spec:
|
|
||||||
/// * Link errors that happen when plugging the imports into the instance
|
|
||||||
/// * Runtime errors that happen when running the module `start` function.
|
|
||||||
pub fn new_no_memory_init(
|
|
||||||
store: &mut impl AsStoreMut,
|
|
||||||
module: &Module,
|
|
||||||
imports: &Imports,
|
|
||||||
) -> Result<Self, InstantiationError> {
|
|
||||||
let imports = imports
|
|
||||||
.imports_for_module(module)
|
|
||||||
.map_err(InstantiationError::Link)?;
|
|
||||||
let mut handle = module.instantiate(store, &imports, false)?;
|
|
||||||
let exports = module
|
let exports = module
|
||||||
.exports()
|
.exports()
|
||||||
.map(|export| {
|
.map(|export| {
|
||||||
@@ -195,7 +155,7 @@ impl Instance {
|
|||||||
externs: &[Extern],
|
externs: &[Extern],
|
||||||
) -> Result<Self, InstantiationError> {
|
) -> Result<Self, InstantiationError> {
|
||||||
let imports = externs.to_vec();
|
let imports = externs.to_vec();
|
||||||
let mut handle = module.instantiate(store, &imports, true)?;
|
let mut handle = module.instantiate(store, &imports)?;
|
||||||
let exports = module
|
let exports = module
|
||||||
.exports()
|
.exports()
|
||||||
.map(|export| {
|
.map(|export| {
|
||||||
|
|||||||
@@ -343,7 +343,6 @@ impl Module {
|
|||||||
&self,
|
&self,
|
||||||
store: &mut impl AsStoreMut,
|
store: &mut impl AsStoreMut,
|
||||||
imports: &[crate::Extern],
|
imports: &[crate::Extern],
|
||||||
initialize_memory: bool,
|
|
||||||
) -> Result<InstanceHandle, InstantiationError> {
|
) -> Result<InstanceHandle, InstantiationError> {
|
||||||
// Ensure all imports come from the same context.
|
// Ensure all imports come from the same context.
|
||||||
for import in imports {
|
for import in imports {
|
||||||
@@ -371,7 +370,6 @@ impl Module {
|
|||||||
self.artifact.finish_instantiation(
|
self.artifact.finish_instantiation(
|
||||||
store.as_store_ref().signal_handler(),
|
store.as_store_ref().signal_handler(),
|
||||||
&mut instance_handle,
|
&mut instance_handle,
|
||||||
initialize_memory,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(instance_handle)
|
Ok(instance_handle)
|
||||||
|
|||||||
@@ -245,6 +245,13 @@ mod tests {
|
|||||||
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
|
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
|
||||||
None
|
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 {
|
impl From<VMTinyMemory> for wasmer_vm::VMMemory {
|
||||||
|
|||||||
@@ -398,7 +398,6 @@ impl Artifact {
|
|||||||
&self,
|
&self,
|
||||||
trap_handler: Option<*const TrapHandlerFn<'static>>,
|
trap_handler: Option<*const TrapHandlerFn<'static>>,
|
||||||
handle: &mut InstanceHandle,
|
handle: &mut InstanceHandle,
|
||||||
initialize_memory: bool,
|
|
||||||
) -> Result<(), InstantiationError> {
|
) -> Result<(), InstantiationError> {
|
||||||
let data_initializers = self
|
let data_initializers = self
|
||||||
.data_initializers()
|
.data_initializers()
|
||||||
@@ -409,7 +408,7 @@ impl Artifact {
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
handle
|
handle
|
||||||
.finish_instantiation(trap_handler, &data_initializers, initialize_memory)
|
.finish_instantiation(trap_handler, &data_initializers)
|
||||||
.map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))
|
.map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ impl Instance {
|
|||||||
unsafe { self.vmctx_plus_offset(self.offsets.vmctx_tables_begin()) }
|
unsafe { self.vmctx_plus_offset(self.offsets.vmctx_tables_begin()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
/// Get a locally defined or imported memory.
|
/// Get a locally defined or imported memory.
|
||||||
fn get_memory(&self, index: MemoryIndex) -> VMMemoryDefinition {
|
fn get_memory(&self, index: MemoryIndex) -> VMMemoryDefinition {
|
||||||
if let Some(local_index) = self.module.local_memory_index(index) {
|
if let Some(local_index) = self.module.local_memory_index(index) {
|
||||||
@@ -240,6 +241,21 @@ impl Instance {
|
|||||||
unsafe { self.vmctx_plus_offset(self.offsets.vmctx_memories_begin()) }
|
unsafe { self.vmctx_plus_offset(self.offsets.vmctx_memories_begin()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a locally defined or imported memory.
|
||||||
|
fn get_vmmemory(&self, index: MemoryIndex) -> &VMMemory {
|
||||||
|
if let Some(local_index) = self.module.local_memory_index(index) {
|
||||||
|
unsafe {
|
||||||
|
self.memories
|
||||||
|
.get(local_index)
|
||||||
|
.unwrap()
|
||||||
|
.get(self.context.as_ref().unwrap())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let import = self.imported_memory(index);
|
||||||
|
unsafe { import.handle.get(self.context.as_ref().unwrap()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the indexed `VMGlobalDefinition`.
|
/// Return the indexed `VMGlobalDefinition`.
|
||||||
fn global(&self, index: LocalGlobalIndex) -> VMGlobalDefinition {
|
fn global(&self, index: LocalGlobalIndex) -> VMGlobalDefinition {
|
||||||
unsafe { self.global_ptr(index).as_ref().clone() }
|
unsafe { self.global_ptr(index).as_ref().clone() }
|
||||||
@@ -701,29 +717,18 @@ impl Instance {
|
|||||||
) -> Result<(), Trap> {
|
) -> Result<(), Trap> {
|
||||||
// https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-memory-init
|
// https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-memory-init
|
||||||
|
|
||||||
let memory = self.get_memory(memory_index);
|
let memory = self.get_vmmemory(memory_index);
|
||||||
let passive_data = self.passive_data.borrow();
|
let passive_data = self.passive_data.borrow();
|
||||||
let data = passive_data.get(&data_index).map_or(&[][..], |d| &**d);
|
let data = passive_data.get(&data_index).map_or(&[][..], |d| &**d);
|
||||||
|
|
||||||
if src
|
if src
|
||||||
.checked_add(len)
|
.checked_add(len)
|
||||||
.map_or(true, |n| n as usize > data.len())
|
.map_or(true, |end| end as usize > data.len())
|
||||||
|| dst.checked_add(len).map_or(true, |m| {
|
|
||||||
usize::try_from(m).unwrap() > memory.current_length
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
|
return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
|
||||||
}
|
}
|
||||||
|
|
||||||
let src_slice = &data[src as usize..(src + len) as usize];
|
let src_slice = &data[src as usize..(src + len) as usize];
|
||||||
|
unsafe { memory.initialize_with_data(dst as usize, src_slice) }
|
||||||
unsafe {
|
|
||||||
let dst_start = memory.base.add(dst as usize);
|
|
||||||
let dst_slice = slice::from_raw_parts_mut(dst_start, len as usize);
|
|
||||||
dst_slice.copy_from_slice(src_slice);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drop the given data segment, truncating its length to zero.
|
/// Drop the given data segment, truncating its length to zero.
|
||||||
@@ -947,15 +952,12 @@ impl InstanceHandle {
|
|||||||
&mut self,
|
&mut self,
|
||||||
trap_handler: Option<*const TrapHandlerFn<'static>>,
|
trap_handler: Option<*const TrapHandlerFn<'static>>,
|
||||||
data_initializers: &[DataInitializer<'_>],
|
data_initializers: &[DataInitializer<'_>],
|
||||||
initialize_memory: bool,
|
|
||||||
) -> Result<(), Trap> {
|
) -> Result<(), Trap> {
|
||||||
let instance = self.instance_mut();
|
let instance = self.instance_mut();
|
||||||
|
|
||||||
// Apply the initializers.
|
// Apply the initializers.
|
||||||
initialize_tables(instance)?;
|
initialize_tables(instance)?;
|
||||||
if initialize_memory {
|
initialize_memories(instance, data_initializers)?;
|
||||||
initialize_memories(instance, data_initializers)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The WebAssembly spec specifies that the start function is
|
// The WebAssembly spec specifies that the start function is
|
||||||
// invoked automatically at instantiation time.
|
// invoked automatically at instantiation time.
|
||||||
@@ -1150,6 +1152,7 @@ fn get_memory_init_start(init: &DataInitializer<'_>, instance: &Instance) -> usi
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::mut_from_ref)]
|
#[allow(clippy::mut_from_ref)]
|
||||||
|
#[allow(dead_code)]
|
||||||
/// Return a byte-slice view of a memory's data.
|
/// Return a byte-slice view of a memory's data.
|
||||||
unsafe fn get_memory_slice<'instance>(
|
unsafe fn get_memory_slice<'instance>(
|
||||||
init: &DataInitializer<'_>,
|
init: &DataInitializer<'_>,
|
||||||
@@ -1245,21 +1248,11 @@ fn initialize_memories(
|
|||||||
data_initializers: &[DataInitializer<'_>],
|
data_initializers: &[DataInitializer<'_>],
|
||||||
) -> Result<(), Trap> {
|
) -> Result<(), Trap> {
|
||||||
for init in data_initializers {
|
for init in data_initializers {
|
||||||
let memory = instance.get_memory(init.location.memory_index);
|
let memory = instance.get_vmmemory(init.location.memory_index);
|
||||||
|
|
||||||
let start = get_memory_init_start(init, instance);
|
let start = get_memory_init_start(init, instance);
|
||||||
if start
|
|
||||||
.checked_add(init.data.len())
|
|
||||||
.map_or(true, |end| end > memory.current_length)
|
|
||||||
{
|
|
||||||
return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mem_slice = get_memory_slice(init, instance);
|
memory.initialize_with_data(start, init.data)?;
|
||||||
let end = start + init.data.len();
|
|
||||||
let to_init = &mut mem_slice[start..end];
|
|
||||||
to_init.copy_from_slice(init.data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
//!
|
//!
|
||||||
//! `Memory` is to WebAssembly linear memories what `Table` is to WebAssembly tables.
|
//! `Memory` is to WebAssembly linear memories what `Table` is to WebAssembly tables.
|
||||||
|
|
||||||
|
use crate::trap::{Trap, TrapCode};
|
||||||
use crate::{mmap::Mmap, store::MaybeInstanceOwned, vmcontext::VMMemoryDefinition};
|
use crate::{mmap::Mmap, store::MaybeInstanceOwned, vmcontext::VMMemoryDefinition};
|
||||||
use more_asserts::assert_ge;
|
use more_asserts::assert_ge;
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
use std::slice;
|
||||||
use wasmer_types::{Bytes, MemoryError, MemoryStyle, MemoryType, Pages};
|
use wasmer_types::{Bytes, MemoryError, MemoryStyle, MemoryType, Pages};
|
||||||
|
|
||||||
// The memory mapped area
|
// The memory mapped area
|
||||||
@@ -410,4 +412,22 @@ where
|
|||||||
|
|
||||||
/// Attempts to clone this memory (if its clonable)
|
/// Attempts to clone this memory (if its clonable)
|
||||||
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>>;
|
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>>;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
unsafe fn initialize_with_data(&self, start: usize, data: &[u8]) -> Result<(), Trap> {
|
||||||
|
let memory = self.vmmemory().as_ref();
|
||||||
|
if start
|
||||||
|
.checked_add(data.len())
|
||||||
|
.map_or(true, |end| end > memory.current_length)
|
||||||
|
{
|
||||||
|
return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mem_slice = slice::from_raw_parts_mut(memory.base, memory.current_length);
|
||||||
|
let end = start + data.len();
|
||||||
|
let to_init = &mut mem_slice[start..end];
|
||||||
|
to_init.copy_from_slice(data);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user