mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-10 06:38:22 +00:00
Introduced EngineRef and AsEngineRef trait
This commit is contained in:
47
lib/api/src/js/engineref.rs
Normal file
47
lib/api/src/js/engineref.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
use crate::Tunables;
|
||||||
|
use wasmer_compiler::Engine;
|
||||||
|
|
||||||
|
/// A temporary handle to an [`Engine`] and [`Tunables`].
|
||||||
|
/// EngineRef can be used to build a [`Module`]
|
||||||
|
/// It can be created directly with an [`Engine`] and [`Tunables`]
|
||||||
|
/// Or from anything implementing [`AsEngineRef`]
|
||||||
|
/// like from [`Store`] typicaly
|
||||||
|
pub struct EngineRef<'a> {
|
||||||
|
/// The inner engine
|
||||||
|
pub(crate) inner: &'a Engine,
|
||||||
|
/// optionnal tunnables
|
||||||
|
pub(crate) tunables: &'a dyn Tunables,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> EngineRef<'a> {
|
||||||
|
/// Get inner [`Engine`]
|
||||||
|
pub fn engine(&self) -> &Engine {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
/// Get the [`Tunables`]
|
||||||
|
pub fn tunables(&self) -> &dyn Tunables {
|
||||||
|
self.tunables
|
||||||
|
}
|
||||||
|
/// Create an EngineRef from an Engine and Tunables
|
||||||
|
pub fn new(engine: &'a Engine, tunables: &'a dyn Tunables) -> Self {
|
||||||
|
EngineRef {
|
||||||
|
inner: engine,
|
||||||
|
tunables,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper trait for a value that is convertible to a [`EngineRef`].
|
||||||
|
pub trait AsEngineRef {
|
||||||
|
/// Returns a `EngineRef` pointing to the underlying context.
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for EngineRef<'_> {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: self.inner,
|
||||||
|
tunables: self.tunables,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ mod lib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod engineref;
|
||||||
pub(crate) mod error;
|
pub(crate) mod error;
|
||||||
mod export;
|
mod export;
|
||||||
mod exports;
|
mod exports;
|
||||||
@@ -43,6 +44,7 @@ mod types;
|
|||||||
mod value;
|
mod value;
|
||||||
mod wasm_bindgen_polyfill;
|
mod wasm_bindgen_polyfill;
|
||||||
|
|
||||||
|
pub use crate::js::engineref::{AsEngineRef, EngineRef};
|
||||||
pub use crate::js::error::{DeserializeError, InstantiationError, SerializeError};
|
pub use crate::js::error::{DeserializeError, InstantiationError, SerializeError};
|
||||||
pub use crate::js::export::Export;
|
pub use crate::js::export::Export;
|
||||||
pub use crate::js::exports::{ExportError, Exportable, Exports, ExportsIterator};
|
pub use crate::js::exports::{ExportError, Exportable, Exports, ExportsIterator};
|
||||||
|
|||||||
@@ -180,6 +180,42 @@ impl<T: AsStoreMut> AsStoreMut for &'_ mut T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for Store {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: &self.engine,
|
||||||
|
tunables: self.inner.tunables.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for &Store {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: &self.engine,
|
||||||
|
tunables: self.inner.tunables.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for StoreRef<'_> {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: &self.inner.engine,
|
||||||
|
tunables: self.inner.tunables.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for StoreMut<'_> {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: &self.inner.engine,
|
||||||
|
tunables: self.inner.tunables.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub use objects::*;
|
pub use objects::*;
|
||||||
|
|
||||||
mod objects {
|
mod objects {
|
||||||
|
|||||||
47
lib/api/src/sys/engineref.rs
Normal file
47
lib/api/src/sys/engineref.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
use crate::Tunables;
|
||||||
|
use wasmer_compiler::Engine;
|
||||||
|
|
||||||
|
/// A temporary handle to an [`Engine`] and [`Tunables`].
|
||||||
|
/// EngineRef can be used to build a [`Module`]
|
||||||
|
/// It can be created directly with an [`Engine`] and [`Tunables`]
|
||||||
|
/// Or from anything implementing [`AsEngineRef`]
|
||||||
|
/// like from [`Store`] typicaly
|
||||||
|
pub struct EngineRef<'a> {
|
||||||
|
/// The inner engine
|
||||||
|
pub(crate) inner: &'a Engine,
|
||||||
|
/// optionnal tunnables
|
||||||
|
pub(crate) tunables: &'a dyn Tunables,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> EngineRef<'a> {
|
||||||
|
/// Get inner [`Engine`]
|
||||||
|
pub fn engine(&self) -> &Engine {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
/// Get the [`Tunables`]
|
||||||
|
pub fn tunables(&self) -> &dyn Tunables {
|
||||||
|
self.tunables
|
||||||
|
}
|
||||||
|
/// Create an EngineRef from an Engine and Tunables
|
||||||
|
pub fn new(engine: &'a Engine, tunables: &'a dyn Tunables) -> Self {
|
||||||
|
EngineRef {
|
||||||
|
inner: engine,
|
||||||
|
tunables,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper trait for a value that is convertible to a [`EngineRef`].
|
||||||
|
pub trait AsEngineRef {
|
||||||
|
/// Returns a `EngineRef` pointing to the underlying context.
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for EngineRef<'_> {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: self.inner,
|
||||||
|
tunables: self.tunables,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
mod engineref;
|
||||||
mod exports;
|
mod exports;
|
||||||
mod extern_ref;
|
mod extern_ref;
|
||||||
mod externals;
|
mod externals;
|
||||||
@@ -13,6 +14,7 @@ mod store;
|
|||||||
mod tunables;
|
mod tunables;
|
||||||
mod value;
|
mod value;
|
||||||
|
|
||||||
|
pub use crate::sys::engineref::{AsEngineRef, EngineRef};
|
||||||
pub use crate::sys::exports::{ExportError, Exportable, Exports, ExportsIterator};
|
pub use crate::sys::exports::{ExportError, Exportable, Exports, ExportsIterator};
|
||||||
pub use crate::sys::extern_ref::ExternRef;
|
pub use crate::sys::extern_ref::ExternRef;
|
||||||
pub use crate::sys::externals::{
|
pub use crate::sys::externals::{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::sys::InstantiationError;
|
use crate::sys::InstantiationError;
|
||||||
|
use crate::AsEngineRef;
|
||||||
use crate::AsStoreMut;
|
use crate::AsStoreMut;
|
||||||
use crate::AsStoreRef;
|
use crate::AsStoreRef;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
@@ -159,7 +160,7 @@ impl Module {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
pub fn new(store: &impl AsStoreRef, bytes: impl AsRef<[u8]>) -> Result<Self, CompileError> {
|
pub fn new(engine: &impl AsEngineRef, bytes: impl AsRef<[u8]>) -> Result<Self, CompileError> {
|
||||||
#[cfg(feature = "wat")]
|
#[cfg(feature = "wat")]
|
||||||
let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| {
|
let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| {
|
||||||
CompileError::Wasm(WasmError::Generic(format!(
|
CompileError::Wasm(WasmError::Generic(format!(
|
||||||
@@ -167,19 +168,19 @@ impl Module {
|
|||||||
e
|
e
|
||||||
)))
|
)))
|
||||||
})?;
|
})?;
|
||||||
Self::from_binary(store, bytes.as_ref())
|
Self::from_binary(engine, bytes.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
/// Creates a new WebAssembly module from a file path.
|
/// Creates a new WebAssembly module from a file path.
|
||||||
pub fn from_file(
|
pub fn from_file(
|
||||||
store: &impl AsStoreRef,
|
engine: &impl AsEngineRef,
|
||||||
file: impl AsRef<Path>,
|
file: impl AsRef<Path>,
|
||||||
) -> Result<Self, IoCompileError> {
|
) -> Result<Self, IoCompileError> {
|
||||||
let file_ref = file.as_ref();
|
let file_ref = file.as_ref();
|
||||||
let canonical = file_ref.canonicalize()?;
|
let canonical = file_ref.canonicalize()?;
|
||||||
let wasm_bytes = std::fs::read(file_ref)?;
|
let wasm_bytes = std::fs::read(file_ref)?;
|
||||||
let mut module = Self::new(store, &wasm_bytes)?;
|
let mut module = Self::new(engine, &wasm_bytes)?;
|
||||||
// Set the module name to the absolute path of the filename.
|
// Set the module name to the absolute path of the filename.
|
||||||
// This is useful for debugging the stack traces.
|
// This is useful for debugging the stack traces.
|
||||||
let filename = canonical.as_path().to_str().unwrap();
|
let filename = canonical.as_path().to_str().unwrap();
|
||||||
@@ -193,9 +194,9 @@ impl Module {
|
|||||||
/// Opposed to [`Module::new`], this function is not compatible with
|
/// Opposed to [`Module::new`], this function is not compatible with
|
||||||
/// the WebAssembly text format (if the "wat" feature is enabled for
|
/// the WebAssembly text format (if the "wat" feature is enabled for
|
||||||
/// this crate).
|
/// this crate).
|
||||||
pub fn from_binary(store: &impl AsStoreRef, binary: &[u8]) -> Result<Self, CompileError> {
|
pub fn from_binary(engine: &impl AsEngineRef, binary: &[u8]) -> Result<Self, CompileError> {
|
||||||
Self::validate(store, binary)?;
|
Self::validate(engine, binary)?;
|
||||||
unsafe { Self::from_binary_unchecked(store, binary) }
|
unsafe { Self::from_binary_unchecked(engine, binary) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
@@ -207,10 +208,10 @@ impl Module {
|
|||||||
/// in environments where the WebAssembly modules are trusted and validated
|
/// in environments where the WebAssembly modules are trusted and validated
|
||||||
/// beforehand.
|
/// beforehand.
|
||||||
pub unsafe fn from_binary_unchecked(
|
pub unsafe fn from_binary_unchecked(
|
||||||
store: &impl AsStoreRef,
|
engine: &impl AsEngineRef,
|
||||||
binary: &[u8],
|
binary: &[u8],
|
||||||
) -> Result<Self, CompileError> {
|
) -> Result<Self, CompileError> {
|
||||||
let module = Self::compile(store, binary)?;
|
let module = Self::compile(engine, binary)?;
|
||||||
Ok(module)
|
Ok(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,16 +222,16 @@ impl Module {
|
|||||||
/// This validation is normally pretty fast and checks the enabled
|
/// This validation is normally pretty fast and checks the enabled
|
||||||
/// WebAssembly features in the Store Engine to assure deterministic
|
/// WebAssembly features in the Store Engine to assure deterministic
|
||||||
/// validation of the Module.
|
/// validation of the Module.
|
||||||
pub fn validate(store: &impl AsStoreRef, binary: &[u8]) -> Result<(), CompileError> {
|
pub fn validate(engine: &impl AsEngineRef, binary: &[u8]) -> Result<(), CompileError> {
|
||||||
store.as_store_ref().engine().validate(binary)
|
engine.as_engine_ref().engine().validate(binary)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
fn compile(store: &impl AsStoreRef, binary: &[u8]) -> Result<Self, CompileError> {
|
fn compile(engine: &impl AsEngineRef, binary: &[u8]) -> Result<Self, CompileError> {
|
||||||
let artifact = store
|
let artifact = engine
|
||||||
.as_store_ref()
|
.as_engine_ref()
|
||||||
.engine()
|
.engine()
|
||||||
.compile(binary, store.as_store_ref().tunables())?;
|
.compile(binary, engine.as_engine_ref().tunables())?;
|
||||||
Ok(Self::from_artifact(artifact))
|
Ok(Self::from_artifact(artifact))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::sys::engineref::{AsEngineRef, EngineRef};
|
||||||
use crate::sys::tunables::BaseTunables;
|
use crate::sys::tunables::BaseTunables;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
@@ -202,6 +203,42 @@ impl AsStoreMut for Store {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for Store {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: &self.engine,
|
||||||
|
tunables: self.inner.tunables.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for &Store {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: &self.engine,
|
||||||
|
tunables: self.inner.tunables.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for StoreRef<'_> {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: &self.inner.engine,
|
||||||
|
tunables: self.inner.tunables.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsEngineRef for StoreMut<'_> {
|
||||||
|
fn as_engine_ref(&self) -> EngineRef<'_> {
|
||||||
|
EngineRef {
|
||||||
|
inner: &self.inner.engine,
|
||||||
|
tunables: self.inner.tunables.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Store {
|
impl fmt::Debug for Store {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("Store").finish()
|
f.debug_struct("Store").finish()
|
||||||
|
|||||||
58
lib/types/src/basetunables.rs
Normal file
58
lib/types/src/basetunables.rs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
use crate::units::Pages;
|
||||||
|
use crate::compilation::target::{PointerWidth, Target};
|
||||||
|
|
||||||
|
/// Tunable parameters for WebAssembly compilation.
|
||||||
|
/// This is the reference implementation of the `Tunables` trait,
|
||||||
|
/// used by default.
|
||||||
|
///
|
||||||
|
/// You can use this as a template for creating a custom Tunables
|
||||||
|
/// implementation or use composition to wrap your Tunables around
|
||||||
|
/// this one. The later approach is demonstrated in the
|
||||||
|
/// tunables-limit-memory example.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BaseTunables {
|
||||||
|
/// For static heaps, the size in wasm pages of the heap protected by bounds checking.
|
||||||
|
pub static_memory_bound: Pages,
|
||||||
|
|
||||||
|
/// The size in bytes of the offset guard for static heaps.
|
||||||
|
pub static_memory_offset_guard_size: u64,
|
||||||
|
|
||||||
|
/// The size in bytes of the offset guard for dynamic heaps.
|
||||||
|
pub dynamic_memory_offset_guard_size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BaseTunables {
|
||||||
|
/// Get the `BaseTunables` for a specific Target
|
||||||
|
pub fn for_target(target: &Target) -> Self {
|
||||||
|
let triple = target.triple();
|
||||||
|
let pointer_width: PointerWidth = triple.pointer_width().unwrap();
|
||||||
|
let (static_memory_bound, static_memory_offset_guard_size): (Pages, u64) =
|
||||||
|
match pointer_width {
|
||||||
|
PointerWidth::U16 => (0x400.into(), 0x1000),
|
||||||
|
PointerWidth::U32 => (0x4000.into(), 0x1_0000),
|
||||||
|
// Static Memory Bound:
|
||||||
|
// Allocating 4 GiB of address space let us avoid the
|
||||||
|
// need for explicit bounds checks.
|
||||||
|
// Static Memory Guard size:
|
||||||
|
// Allocating 2 GiB of address space lets us translate wasm
|
||||||
|
// offsets into x86 offsets as aggressively as we can.
|
||||||
|
PointerWidth::U64 => (0x1_0000.into(), 0x8000_0000),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Allocate a small guard to optimize common cases but without
|
||||||
|
// wasting too much memory.
|
||||||
|
// The Windows memory manager seems more laxed than the other ones
|
||||||
|
// And a guard of just 1 page may not be enough is some borderline cases
|
||||||
|
// So using 2 pages for guard on this platform
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
let dynamic_memory_offset_guard_size: u64 = 0x2_0000;
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
let dynamic_memory_offset_guard_size: u64 = 0x1_0000;
|
||||||
|
|
||||||
|
Self {
|
||||||
|
static_memory_bound,
|
||||||
|
static_memory_offset_guard_size,
|
||||||
|
dynamic_memory_offset_guard_size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user