Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduced EngineRef and AsEngineRef trait #3378

Merged
merged 11 commits into from
Nov 30, 2022
2 changes: 1 addition & 1 deletion lib/api/src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ pub use wasmer_compiler_cranelift::{Cranelift, CraneliftOptLevel};
#[cfg(feature = "llvm")]
pub use wasmer_compiler_llvm::{LLVMOptLevel, LLVM};

pub use wasmer_compiler::Engine;
#[cfg(feature = "compiler")]
pub use wasmer_compiler::{Artifact, EngineBuilder};
pub use wasmer_compiler::{AsEngineRef, Engine, EngineRef};

/// Version number of this crate.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
Expand Down
40 changes: 24 additions & 16 deletions lib/api/src/sys/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::sync::Arc;
use thiserror::Error;
use wasmer_compiler::Artifact;
use wasmer_compiler::ArtifactCreate;
use wasmer_compiler::AsEngineRef;
#[cfg(feature = "wat")]
use wasmer_types::WasmError;
use wasmer_types::{
Expand Down Expand Up @@ -158,28 +159,38 @@ impl Module {
/// # Ok(())
/// # }
/// ```
/// # Example of loading a module using just an `Engine` and no `Store`
///
/// ```
/// # use wasmer::*;
/// #
/// # let compiler = Cranelift::default();
/// # let engine = EngineBuilder::new(compiler).engine();
///
/// let module = Module::from_file(&engine, "path/to/foo.wasm");
/// ```
#[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")]
let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| {
CompileError::Wasm(WasmError::Generic(format!(
"Error when converting wat: {}",
e
)))
})?;
Self::from_binary(store, bytes.as_ref())
Self::from_binary(engine, bytes.as_ref())
}

#[cfg(feature = "compiler")]
/// Creates a new WebAssembly module from a file path.
pub fn from_file(
store: &impl AsStoreRef,
engine: &impl AsEngineRef,
file: impl AsRef<Path>,
) -> Result<Self, IoCompileError> {
let file_ref = file.as_ref();
let canonical = file_ref.canonicalize()?;
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.
// This is useful for debugging the stack traces.
let filename = canonical.as_path().to_str().unwrap();
Expand All @@ -193,9 +204,9 @@ impl Module {
/// Opposed to [`Module::new`], this function is not compatible with
/// the WebAssembly text format (if the "wat" feature is enabled for
/// this crate).
pub fn from_binary(store: &impl AsStoreRef, binary: &[u8]) -> Result<Self, CompileError> {
Self::validate(store, binary)?;
unsafe { Self::from_binary_unchecked(store, binary) }
pub fn from_binary(engine: &impl AsEngineRef, binary: &[u8]) -> Result<Self, CompileError> {
Self::validate(engine, binary)?;
unsafe { Self::from_binary_unchecked(engine, binary) }
}

#[cfg(feature = "compiler")]
Expand All @@ -207,10 +218,10 @@ impl Module {
/// in environments where the WebAssembly modules are trusted and validated
/// beforehand.
pub unsafe fn from_binary_unchecked(
store: &impl AsStoreRef,
engine: &impl AsEngineRef,
binary: &[u8],
) -> Result<Self, CompileError> {
let module = Self::compile(store, binary)?;
let module = Self::compile(engine, binary)?;
Ok(module)
}

Expand All @@ -221,16 +232,13 @@ impl Module {
/// This validation is normally pretty fast and checks the enabled
/// WebAssembly features in the Store Engine to assure deterministic
/// validation of the Module.
pub fn validate(store: &impl AsStoreRef, binary: &[u8]) -> Result<(), CompileError> {
store.as_store_ref().engine().validate(binary)
pub fn validate(engine: &impl AsEngineRef, binary: &[u8]) -> Result<(), CompileError> {
engine.as_engine_ref().engine().validate(binary)
}

#[cfg(feature = "compiler")]
fn compile(store: &impl AsStoreRef, binary: &[u8]) -> Result<Self, CompileError> {
let artifact = store
.as_store_ref()
.engine()
.compile(binary, store.as_store_ref().tunables())?;
fn compile(engine: &impl AsEngineRef, binary: &[u8]) -> Result<Self, CompileError> {
let artifact = engine.as_engine_ref().engine().compile(binary)?;
Ok(Self::from_artifact(artifact))
}

Expand Down
75 changes: 47 additions & 28 deletions lib/api/src/sys/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::sys::tunables::BaseTunables;
use std::fmt;
use std::sync::{Arc, RwLock};
#[cfg(feature = "compiler")]
use wasmer_compiler::{Engine, EngineBuilder, Tunables};
use wasmer_compiler::{AsEngineRef, Engine, EngineBuilder, EngineRef, Tunables};
use wasmer_vm::{init_traps, TrapHandler, TrapHandlerFn};

use wasmer_vm::StoreObjects;
Expand All @@ -14,8 +14,6 @@ pub(crate) struct StoreInner {
pub(crate) objects: StoreObjects,
#[cfg(feature = "compiler")]
pub(crate) engine: Engine,
#[cfg(feature = "compiler")]
pub(crate) tunables: Box<dyn Tunables + Send + Sync>,
pub(crate) trap_handler: Option<Box<TrapHandlerFn<'static>>>,
}

Expand All @@ -25,10 +23,7 @@ pub(crate) struct StoreInner {
/// have been allocated during the lifetime of the abstract machine.
///
/// 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
#[cfg_attr(feature = "compiler", doc = "[`Tunables`]")]
#[cfg_attr(not(feature = "compiler"), doc = "`Tunables`")]
/// (that are used to create the memories, tables and globals).
/// the Wasm bytes into a valid module artifact).
///
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#store>
pub struct Store {
Expand All @@ -43,8 +38,20 @@ impl Store {
/// Creates a new `Store` with a specific [`Engine`].
pub fn new(engine: impl Into<Engine>) -> Self {
let engine = engine.into();
let target = engine.target().clone();
Self::new_with_tunables(engine, BaseTunables::for_target(&target))

// Make sure the signal handlers are installed.
// This is required for handling traps.
init_traps();

Self {
inner: Box::new(StoreInner {
objects: Default::default(),
engine: engine.cloned(),
trap_handler: None,
}),
engine: engine.cloned(),
trap_handler: Arc::new(RwLock::new(None)),
}
}

#[cfg(feature = "compiler")]
Expand All @@ -68,28 +75,16 @@ impl Store {
engine: impl Into<Engine>,
tunables: impl Tunables + Send + Sync + 'static,
) -> Self {
let engine = engine.into();
let mut engine = engine.into();
engine.set_tunables(tunables);

// Make sure the signal handlers are installed.
// This is required for handling traps.
init_traps();

Self {
inner: Box::new(StoreInner {
objects: Default::default(),
engine: engine.cloned(),
tunables: Box::new(tunables),
trap_handler: None,
}),
engine: engine.cloned(),
trap_handler: Arc::new(RwLock::new(None)),
}
Self::new(engine)
}

#[cfg(feature = "compiler")]
/// Returns the [`Tunables`].
pub fn tunables(&self) -> &dyn Tunables {
self.inner.tunables.as_ref()
self.engine.tunables()
}

#[cfg(feature = "compiler")]
Expand Down Expand Up @@ -202,6 +197,30 @@ impl AsStoreMut for Store {
}
}

impl AsEngineRef for Store {
fn as_engine_ref(&self) -> EngineRef<'_> {
EngineRef::new(&self.engine)
}
}

impl AsEngineRef for &Store {
fn as_engine_ref(&self) -> EngineRef<'_> {
EngineRef::new(&self.engine)
}
}

impl AsEngineRef for StoreRef<'_> {
fn as_engine_ref(&self) -> EngineRef<'_> {
EngineRef::new(&self.inner.engine)
}
}

impl AsEngineRef for StoreMut<'_> {
fn as_engine_ref(&self) -> EngineRef<'_> {
EngineRef::new(&self.inner.engine)
}
}

impl fmt::Debug for Store {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Store").finish()
Expand All @@ -221,7 +240,7 @@ impl<'a> StoreRef<'a> {
#[cfg(feature = "compiler")]
/// Returns the [`Tunables`].
pub fn tunables(&self) -> &dyn Tunables {
self.inner.tunables.as_ref()
self.inner.engine.tunables()
}

#[cfg(feature = "compiler")]
Expand Down Expand Up @@ -257,7 +276,7 @@ impl<'a> StoreMut<'a> {
/// Returns the [`Tunables`].
#[cfg(feature = "compiler")]
pub fn tunables(&self) -> &dyn Tunables {
self.inner.tunables.as_ref()
self.inner.engine.tunables()
}

/// Returns the [`Engine`].
Expand All @@ -276,7 +295,7 @@ impl<'a> StoreMut<'a> {

#[cfg(feature = "compiler")]
pub(crate) fn tunables_and_objects_mut(&mut self) -> (&dyn Tunables, &mut StoreObjects) {
(self.inner.tunables.as_ref(), &mut self.inner.objects)
(self.inner.engine.tunables(), &mut self.inner.objects)
}

pub(crate) fn as_raw(&self) -> *mut StoreInner {
Expand Down
Loading