mirror of
https://github.com/mii443/wasmer.git
synced 2025-09-02 07:29:21 +00:00
Remove Engine trait
This commit is contained in:
20
Makefile
20
Makefile
@ -9,22 +9,22 @@ SHELL=/usr/bin/env bash
|
|||||||
|
|
||||||
# The matrix is the product of the following columns:
|
# The matrix is the product of the following columns:
|
||||||
#
|
#
|
||||||
# |------------|-----------|----------|--------------|-------|
|
# |------------|----------|--------------|-------|
|
||||||
# | Compiler ⨯ Engine ⨯ Platform ⨯ Architecture ⨯ libc |
|
# | Compiler ⨯ Platform ⨯ Architecture ⨯ libc |
|
||||||
# |------------|-----------|----------|--------------|-------|
|
# |------------|----------|--------------|-------|
|
||||||
# | Cranelift | Universal | Linux | amd64 | glibc |
|
# | Cranelift | Linux | amd64 | glibc |
|
||||||
# | LLVM | | Darwin | aarch64 | musl |
|
# | LLVM | Darwin | aarch64 | musl |
|
||||||
# | Singlepass | | Windows | | |
|
# | Singlepass | Windows | | |
|
||||||
# |------------|-----------|----------|--------------|-------|
|
# |------------|----------|--------------|-------|
|
||||||
#
|
#
|
||||||
# Here is what works and what doesn't:
|
# Here is what works and what doesn't:
|
||||||
#
|
#
|
||||||
# * Cranelift with the Universal engine works everywhere,
|
# * Cranelift works everywhere,
|
||||||
#
|
#
|
||||||
# * LLVM with the Universal engine works on Linux+Darwin/`amd64`,
|
# * LLVM works on Linux+Darwin/`amd64`,
|
||||||
# but it doesn't work on */`aarch64` or Windows/*.
|
# but it doesn't work on */`aarch64` or Windows/*.
|
||||||
#
|
#
|
||||||
# * Singlepass with the Universal engine works on Linux+Darwin/`amd64`, but
|
# * Singlepass works on Linux+Darwin/`amd64`, but
|
||||||
# it doesn't work on */`aarch64` or Windows/*.
|
# it doesn't work on */`aarch64` or Windows/*.
|
||||||
#
|
#
|
||||||
# * Windows isn't tested on `aarch64`, that's why we consider it's not
|
# * Windows isn't tested on `aarch64`, that's why we consider it's not
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target};
|
use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target};
|
||||||
use wasm_smith::{Config, ConfiguredModule};
|
use wasm_smith::{Config, ConfiguredModule};
|
||||||
use wasmer::{CompilerConfig, Engine, Module, Store};
|
use wasmer::{CompilerConfig, Module, Store, UniversalEngine};
|
||||||
use wasmer_compiler::Universal;
|
use wasmer_compiler::Universal;
|
||||||
use wasmer_compiler_cranelift::Cranelift;
|
use wasmer_compiler_cranelift::Cranelift;
|
||||||
use wasmer_compiler_llvm::LLVM;
|
use wasmer_compiler_llvm::LLVM;
|
||||||
@ -23,8 +23,8 @@ impl Config for NoImportsConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_and_compare(name: &str, engine: impl Engine, wasm: &[u8]) {
|
fn compile_and_compare(name: &str, engine: UniversalEngine, wasm: &[u8]) {
|
||||||
let mut store = Store::new_with_engine(&engine);
|
let store = Store::new_with_engine(&engine);
|
||||||
|
|
||||||
// compile for first time
|
// compile for first time
|
||||||
let module = Module::new(&store, wasm).unwrap();
|
let module = Module::new(&store, wasm).unwrap();
|
||||||
|
@ -36,7 +36,7 @@ pub use target_lexicon::{Architecture, CallingConvention, OperatingSystem, Tripl
|
|||||||
pub use wasmer_compiler::{
|
pub use wasmer_compiler::{
|
||||||
wasmparser, CompilerConfig, FunctionMiddleware, MiddlewareReaderState, ModuleMiddleware,
|
wasmparser, CompilerConfig, FunctionMiddleware, MiddlewareReaderState, ModuleMiddleware,
|
||||||
};
|
};
|
||||||
pub use wasmer_compiler::{Engine, Features, FrameInfo, LinkError, RuntimeError, Tunables};
|
pub use wasmer_compiler::{Features, FrameInfo, LinkError, RuntimeError, Tunables};
|
||||||
pub use wasmer_derive::ValueType;
|
pub use wasmer_derive::ValueType;
|
||||||
pub use wasmer_types::is_wasm;
|
pub use wasmer_types::is_wasm;
|
||||||
pub use wasmer_types::{
|
pub use wasmer_types::{
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
use crate::sys::tunables::BaseTunables;
|
use crate::sys::tunables::BaseTunables;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, RwLock};
|
||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
use wasmer_compiler::CompilerConfig;
|
use wasmer_compiler::CompilerConfig;
|
||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
use wasmer_compiler::Universal;
|
use wasmer_compiler::{Tunables, Universal, UniversalEngine};
|
||||||
use wasmer_compiler::{Engine, Tunables};
|
use wasmer_vm::{init_traps, TrapHandler, TrapHandlerFn};
|
||||||
use wasmer_vm::{init_traps, TrapHandlerFn};
|
|
||||||
|
|
||||||
use wasmer_vm::StoreObjects;
|
use wasmer_vm::StoreObjects;
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ use wasmer_vm::StoreObjects;
|
|||||||
/// wrap the actual context in a box.
|
/// wrap the actual context in a box.
|
||||||
pub(crate) struct StoreInner {
|
pub(crate) struct StoreInner {
|
||||||
pub(crate) objects: StoreObjects,
|
pub(crate) objects: StoreObjects,
|
||||||
pub(crate) engine: Arc<dyn Engine + Send + Sync>,
|
pub(crate) engine: Arc<UniversalEngine>,
|
||||||
pub(crate) tunables: Box<dyn Tunables + Send + Sync>,
|
pub(crate) tunables: Box<dyn Tunables + Send + Sync>,
|
||||||
pub(crate) trap_handler: Option<Box<TrapHandlerFn<'static>>>,
|
pub(crate) trap_handler: Option<Box<TrapHandlerFn<'static>>>,
|
||||||
}
|
}
|
||||||
@ -32,6 +31,8 @@ pub(crate) struct StoreInner {
|
|||||||
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#store>
|
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#store>
|
||||||
pub struct Store {
|
pub struct Store {
|
||||||
pub(crate) inner: Box<StoreInner>,
|
pub(crate) inner: Box<StoreInner>,
|
||||||
|
engine: Arc<UniversalEngine>,
|
||||||
|
trap_handler: Arc<RwLock<Option<Box<TrapHandlerFn<'static>>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Store {
|
impl Store {
|
||||||
@ -43,10 +44,7 @@ impl Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `Store` with a specific [`Engine`].
|
/// Creates a new `Store` with a specific [`Engine`].
|
||||||
pub fn new_with_engine<E>(engine: &E) -> Self
|
pub fn new_with_engine(engine: &UniversalEngine) -> Self {
|
||||||
where
|
|
||||||
E: Engine + ?Sized,
|
|
||||||
{
|
|
||||||
Self::new_with_tunables(engine, BaseTunables::for_target(engine.target()))
|
Self::new_with_tunables(engine, BaseTunables::for_target(engine.target()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +54,10 @@ impl Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `Store` with a specific [`Engine`] and [`Tunables`].
|
/// Creates a new `Store` with a specific [`Engine`] and [`Tunables`].
|
||||||
pub fn new_with_tunables<E>(engine: &E, tunables: impl Tunables + Send + Sync + 'static) -> Self
|
pub fn new_with_tunables(
|
||||||
where
|
engine: &UniversalEngine,
|
||||||
E: Engine + ?Sized,
|
tunables: impl Tunables + Send + Sync + 'static,
|
||||||
{
|
) -> Self {
|
||||||
// Make sure the signal handlers are installed.
|
// Make sure the signal handlers are installed.
|
||||||
// This is required for handling traps.
|
// This is required for handling traps.
|
||||||
init_traps();
|
init_traps();
|
||||||
@ -71,6 +69,41 @@ impl Store {
|
|||||||
tunables: Box::new(tunables),
|
tunables: Box::new(tunables),
|
||||||
trap_handler: None,
|
trap_handler: None,
|
||||||
}),
|
}),
|
||||||
|
engine: engine.cloned(),
|
||||||
|
trap_handler: Arc::new(RwLock::new(None)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the [`Tunables`].
|
||||||
|
pub fn tunables(&self) -> &dyn Tunables {
|
||||||
|
self.inner.tunables.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the [`Engine`].
|
||||||
|
pub fn engine(&self) -> &Arc<UniversalEngine> {
|
||||||
|
&self.engine
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks whether two stores are identical. A store is considered
|
||||||
|
/// equal to another store if both have the same engine. The
|
||||||
|
/// tunables are excluded from the logic.
|
||||||
|
pub fn same(a: &Self, b: &Self) -> bool {
|
||||||
|
a.engine.id() == b.engine.id()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Store {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
Self::same(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl TrapHandler for Store {
|
||||||
|
fn custom_trap_handler(&self, call: &dyn Fn(&TrapHandlerFn) -> bool) -> bool {
|
||||||
|
if let Some(handler) = self.trap_handler.read().unwrap().as_ref() {
|
||||||
|
call(handler)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +142,7 @@ impl Default for Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unreachable_code, unused_mut)]
|
#[allow(unreachable_code, unused_mut)]
|
||||||
fn get_engine(mut config: impl CompilerConfig + 'static) -> impl Engine + Send + Sync {
|
fn get_engine(mut config: impl CompilerConfig + 'static) -> UniversalEngine {
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "default-universal")] {
|
if #[cfg(feature = "default-universal")] {
|
||||||
wasmer_compiler::Universal::new(config)
|
wasmer_compiler::Universal::new(config)
|
||||||
@ -165,7 +198,7 @@ impl<'a> StoreRef<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`Engine`].
|
/// Returns the [`Engine`].
|
||||||
pub fn engine(&self) -> &Arc<dyn Engine + Send + Sync> {
|
pub fn engine(&self) -> &Arc<UniversalEngine> {
|
||||||
&self.inner.engine
|
&self.inner.engine
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +231,7 @@ impl<'a> StoreMut<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`Engine`].
|
/// Returns the [`Engine`].
|
||||||
pub fn engine(&self) -> &Arc<dyn Engine + Send + Sync> {
|
pub fn engine(&self) -> &Arc<UniversalEngine> {
|
||||||
&self.inner.engine
|
&self.inner.engine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,9 +12,8 @@ use super::unstable::target_lexicon::wasmer_target_t;
|
|||||||
use crate::error::update_last_error;
|
use crate::error::update_last_error;
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasmer_api::Engine;
|
|
||||||
#[cfg(feature = "universal")]
|
#[cfg(feature = "universal")]
|
||||||
use wasmer_compiler::Universal;
|
use wasmer_compiler::{Universal, UniversalEngine};
|
||||||
|
|
||||||
/// Kind of compilers that can be used by the engines.
|
/// Kind of compilers that can be used by the engines.
|
||||||
///
|
///
|
||||||
@ -263,7 +262,7 @@ pub extern "C" fn wasm_config_set_engine(config: &mut wasm_config_t, engine: was
|
|||||||
/// cbindgen:ignore
|
/// cbindgen:ignore
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct wasm_engine_t {
|
pub struct wasm_engine_t {
|
||||||
pub(crate) inner: Arc<dyn Engine + Send + Sync>,
|
pub(crate) inner: Arc<UniversalEngine>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
@ -296,7 +295,7 @@ cfg_if! {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
|
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
|
||||||
let compiler_config: Box<dyn CompilerConfig> = get_default_compiler_config();
|
let compiler_config: Box<dyn CompilerConfig> = get_default_compiler_config();
|
||||||
let engine: Arc<dyn Engine + Send + Sync> = Arc::new(Universal::new(compiler_config).engine());
|
let engine: Arc<UniversalEngine> = Arc::new(Universal::new(compiler_config).engine());
|
||||||
Box::new(wasm_engine_t { inner: engine })
|
Box::new(wasm_engine_t { inner: engine })
|
||||||
}
|
}
|
||||||
} else if #[cfg(feature = "universal")] {
|
} else if #[cfg(feature = "universal")] {
|
||||||
@ -309,7 +308,7 @@ cfg_if! {
|
|||||||
/// cbindgen:ignore
|
/// cbindgen:ignore
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
|
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
|
||||||
let engine: Arc<dyn Engine + Send + Sync> = Arc::new(Universal::headless().engine());
|
let engine: Arc<UniversalEngine> = Arc::new(Universal::headless().engine());
|
||||||
Box::new(wasm_engine_t { inner: engine })
|
Box::new(wasm_engine_t { inner: engine })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -419,10 +418,11 @@ pub extern "C" fn wasm_engine_new_with_config(
|
|||||||
compiler_config.canonicalize_nans(true);
|
compiler_config.canonicalize_nans(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let inner: Arc<dyn Engine + Send + Sync> = match config.engine {
|
#[cfg(not(feature = "universal"))]
|
||||||
wasmer_engine_t::UNIVERSAL => {
|
return return_with_error("Wasmer has not been compiled with the `universal` feature.");
|
||||||
cfg_if! {
|
#[cfg(feature = "universal")]
|
||||||
if #[cfg(feature = "universal")] {
|
let inner: Arc<UniversalEngine> =
|
||||||
|
{
|
||||||
let mut builder = Universal::new(compiler_config);
|
let mut builder = Universal::new(compiler_config);
|
||||||
|
|
||||||
if let Some(target) = config.target {
|
if let Some(target) = config.target {
|
||||||
@ -434,16 +434,10 @@ pub extern "C" fn wasm_engine_new_with_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Arc::new(builder.engine())
|
Arc::new(builder.engine())
|
||||||
} else {
|
|
||||||
return return_with_error("Wasmer has not been compiled with the `universal` feature.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
Some(Box::new(wasm_engine_t { inner }))
|
Some(Box::new(wasm_engine_t { inner }))
|
||||||
} else {
|
} else {
|
||||||
let inner: Arc<dyn Engine + Send + Sync> = match config.engine {
|
let inner: Arc<UniversalEngine> =
|
||||||
wasmer_engine_t::UNIVERSAL => {
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(feature = "universal")] {
|
if #[cfg(feature = "universal")] {
|
||||||
let mut builder = Universal::headless();
|
let mut builder = Universal::headless();
|
||||||
@ -460,8 +454,6 @@ pub extern "C" fn wasm_engine_new_with_config(
|
|||||||
} else {
|
} else {
|
||||||
return return_with_error("Wasmer has not been compiled with the `universal` feature.");
|
return return_with_error("Wasmer has not been compiled with the `universal` feature.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
Some(Box::new(wasm_engine_t { inner }))
|
Some(Box::new(wasm_engine_t { inner }))
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::store::{EngineType, StoreOptions};
|
use crate::store::StoreOptions;
|
||||||
use crate::warning;
|
use crate::warning;
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
@ -39,15 +39,8 @@ impl Compile {
|
|||||||
.context(format!("failed to compile `{}`", self.path.display()))
|
.context(format!("failed to compile `{}`", self.path.display()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_recommend_extension(
|
pub(crate) fn get_recommend_extension(target_triple: &Triple) -> Result<&'static str> {
|
||||||
engine_type: &EngineType,
|
Ok(wasmer_compiler::UniversalArtifactBuild::get_default_extension(target_triple))
|
||||||
target_triple: &Triple,
|
|
||||||
) -> Result<&'static str> {
|
|
||||||
Ok(match engine_type {
|
|
||||||
EngineType::Universal => {
|
|
||||||
wasmer_compiler::UniversalArtifactBuild::get_default_extension(target_triple)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inner_execute(&self) -> Result<()> {
|
fn inner_execute(&self) -> Result<()> {
|
||||||
@ -66,14 +59,13 @@ impl Compile {
|
|||||||
Target::new(target_triple.clone(), features)
|
Target::new(target_triple.clone(), features)
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let (mut engine, engine_type, compiler_type) =
|
let (mut engine, compiler_type) = self.store.get_engine_for_target(target.clone())?;
|
||||||
self.store.get_engine_for_target(target.clone())?;
|
|
||||||
let output_filename = self
|
let output_filename = self
|
||||||
.output
|
.output
|
||||||
.file_stem()
|
.file_stem()
|
||||||
.map(|osstr| osstr.to_string_lossy().to_string())
|
.map(|osstr| osstr.to_string_lossy().to_string())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let recommended_extension = Self::get_recommend_extension(&engine_type, target.triple())?;
|
let recommended_extension = Self::get_recommend_extension(target.triple())?;
|
||||||
match self.output.extension() {
|
match self.output.extension() {
|
||||||
Some(ext) => {
|
Some(ext) => {
|
||||||
if ext != recommended_extension {
|
if ext != recommended_extension {
|
||||||
@ -86,7 +78,6 @@ impl Compile {
|
|||||||
}
|
}
|
||||||
let tunables = self.store.get_tunables_for_target(&target)?;
|
let tunables = self.store.get_tunables_for_target(&target)?;
|
||||||
|
|
||||||
println!("Engine: {}", engine_type.to_string());
|
|
||||||
println!("Compiler: {}", compiler_type.to_string());
|
println!("Compiler: {}", compiler_type.to_string());
|
||||||
println!("Target: {}", target.triple());
|
println!("Target: {}", target.triple());
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ impl Validate {
|
|||||||
Triple::from_str("x86_64-linux-gnu").unwrap(),
|
Triple::from_str("x86_64-linux-gnu").unwrap(),
|
||||||
CpuFeature::SSE2 | CpuFeature::AVX,
|
CpuFeature::SSE2 | CpuFeature::AVX,
|
||||||
);
|
);
|
||||||
let (engine, _engine_type, _compiler_type) = self.store.get_engine_for_target(target)?;
|
let (engine, _compiler_type) = self.store.get_engine_for_target(target)?;
|
||||||
let module_contents = std::fs::read(&self.path)?;
|
let module_contents = std::fs::read(&self.path)?;
|
||||||
if !is_wasm(&module_contents) {
|
if !is_wasm(&module_contents) {
|
||||||
bail!("`wasmer validate` only validates WebAssembly files");
|
bail!("`wasmer validate` only validates WebAssembly files");
|
||||||
|
@ -172,14 +172,10 @@ impl CompilerOptions {
|
|||||||
&self,
|
&self,
|
||||||
target: Target,
|
target: Target,
|
||||||
compiler_config: Box<dyn CompilerConfig>,
|
compiler_config: Box<dyn CompilerConfig>,
|
||||||
engine_type: EngineType,
|
|
||||||
) -> Result<UniversalEngineBuilder> {
|
) -> Result<UniversalEngineBuilder> {
|
||||||
let features = self.get_features(compiler_config.default_features_for_target(&target))?;
|
let features = self.get_features(compiler_config.default_features_for_target(&target))?;
|
||||||
let engine: UniversalEngineBuilder = match engine_type {
|
let engine: UniversalEngineBuilder =
|
||||||
EngineType::Universal => {
|
UniversalEngineBuilder::new(Some(compiler_config.compiler()), features);
|
||||||
UniversalEngineBuilder::new(Some(compiler_config.compiler()), features)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(engine)
|
Ok(engine)
|
||||||
}
|
}
|
||||||
@ -361,48 +357,23 @@ impl ToString for CompilerType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The engine used for the store
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
|
||||||
pub enum EngineType {
|
|
||||||
/// Universal Engine
|
|
||||||
Universal,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToString for EngineType {
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
match self {
|
|
||||||
Self::Universal => "universal".to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StoreOptions {
|
impl StoreOptions {
|
||||||
/// Get a UniversalEngineBulder for the Target
|
/// Get a UniversalEngineBulder for the Target
|
||||||
pub fn get_engine_for_target(
|
pub fn get_engine_for_target(
|
||||||
&self,
|
&self,
|
||||||
target: Target,
|
target: Target,
|
||||||
) -> Result<(UniversalEngineBuilder, EngineType, CompilerType)> {
|
) -> Result<(UniversalEngineBuilder, CompilerType)> {
|
||||||
let (compiler_config, compiler_type) = self.compiler.get_compiler_config()?;
|
let (compiler_config, compiler_type) = self.compiler.get_compiler_config()?;
|
||||||
let (engine, engine_type) = self.get_engine_with_compiler(target, compiler_config)?;
|
let engine = self.get_engine_with_compiler(target, compiler_config)?;
|
||||||
Ok((engine, engine_type, compiler_type))
|
Ok((engine, compiler_type))
|
||||||
}
|
|
||||||
|
|
||||||
/// Get default EngineType
|
|
||||||
pub fn get_engine(&self) -> Result<EngineType> {
|
|
||||||
Ok(EngineType::Universal)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_engine_with_compiler(
|
fn get_engine_with_compiler(
|
||||||
&self,
|
&self,
|
||||||
target: Target,
|
target: Target,
|
||||||
compiler_config: Box<dyn CompilerConfig>,
|
compiler_config: Box<dyn CompilerConfig>,
|
||||||
) -> Result<(UniversalEngineBuilder, EngineType)> {
|
) -> Result<UniversalEngineBuilder> {
|
||||||
let engine_type = self.get_engine()?;
|
self.compiler.get_engine_by_type(target, compiler_config)
|
||||||
let engine = self
|
|
||||||
.compiler
|
|
||||||
.get_engine_by_type(target, compiler_config, engine_type)?;
|
|
||||||
|
|
||||||
Ok((engine, engine_type))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get (Subset)Tunables for the Target
|
/// Get (Subset)Tunables for the Target
|
||||||
|
@ -112,9 +112,9 @@ impl CompilerOptions {
|
|||||||
&self,
|
&self,
|
||||||
target: Target,
|
target: Target,
|
||||||
compiler_config: Box<dyn CompilerConfig>,
|
compiler_config: Box<dyn CompilerConfig>,
|
||||||
) -> Result<Box<dyn Engine + Send + Sync>> {
|
) -> Result<Box<UniversalEngine>> {
|
||||||
let features = self.get_features(compiler_config.default_features_for_target(&target))?;
|
let features = self.get_features(compiler_config.default_features_for_target(&target))?;
|
||||||
let engine: Box<dyn Engine + Send + Sync> = Box::new(
|
let engine: Box<UniversalEngine> = Box::new(
|
||||||
wasmer_compiler::Universal::new(compiler_config)
|
wasmer_compiler::Universal::new(compiler_config)
|
||||||
.features(features)
|
.features(features)
|
||||||
.target(target)
|
.target(target)
|
||||||
@ -321,7 +321,7 @@ impl StoreOptions {
|
|||||||
&self,
|
&self,
|
||||||
target: Target,
|
target: Target,
|
||||||
compiler_config: Box<dyn CompilerConfig>,
|
compiler_config: Box<dyn CompilerConfig>,
|
||||||
) -> Result<Box<dyn Engine + Send + Sync>> {
|
) -> Result<Box<UniversalEngine>> {
|
||||||
let engine = self.compiler.get_engine(target, compiler_config)?;
|
let engine = self.compiler.get_engine(target, compiler_config)?;
|
||||||
|
|
||||||
Ok(engine)
|
Ok(engine)
|
||||||
@ -331,8 +331,8 @@ impl StoreOptions {
|
|||||||
// If we don't have a compiler, but we have an engine
|
// If we don't have a compiler, but we have an engine
|
||||||
#[cfg(not(feature = "compiler"))]
|
#[cfg(not(feature = "compiler"))]
|
||||||
impl StoreOptions {
|
impl StoreOptions {
|
||||||
fn get_engine_headless(&self) -> Result<Arc<dyn Engine + Send + Sync>> {
|
fn get_engine_headless(&self) -> Result<Arc<UniversalEngine>> {
|
||||||
let engine: Arc<dyn Engine + Send + Sync> =
|
let engine: Arc<UniversalEngine> =
|
||||||
Arc::new(wasmer_compiler::Universal::headless().engine());
|
Arc::new(wasmer_compiler::Universal::headless().engine());
|
||||||
Ok(engine)
|
Ok(engine)
|
||||||
}
|
}
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
//! Engine trait and associated types.
|
|
||||||
|
|
||||||
use crate::engine::tunables::Tunables;
|
|
||||||
use crate::UniversalArtifact;
|
|
||||||
use memmap2::Mmap;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
|
||||||
use std::sync::Arc;
|
|
||||||
use wasmer_types::{CompileError, DeserializeError, FunctionType, Target};
|
|
||||||
use wasmer_vm::VMSharedSignatureIndex;
|
|
||||||
|
|
||||||
/// A unimplemented Wasmer `Engine`.
|
|
||||||
///
|
|
||||||
/// This trait is used by implementors to implement custom engines
|
|
||||||
/// such as: Universal or Native.
|
|
||||||
///
|
|
||||||
/// The product that an `Engine` produces and consumes is the [`Artifact`].
|
|
||||||
pub trait Engine {
|
|
||||||
/// Gets the target
|
|
||||||
fn target(&self) -> &Target;
|
|
||||||
|
|
||||||
/// Register a signature
|
|
||||||
fn register_signature(&self, func_type: &FunctionType) -> VMSharedSignatureIndex;
|
|
||||||
|
|
||||||
/// Lookup a signature
|
|
||||||
fn lookup_signature(&self, sig: VMSharedSignatureIndex) -> Option<FunctionType>;
|
|
||||||
|
|
||||||
/// Validates a WebAssembly module
|
|
||||||
fn validate(&self, binary: &[u8]) -> Result<(), CompileError>;
|
|
||||||
|
|
||||||
/// Compile a WebAssembly binary
|
|
||||||
fn compile(
|
|
||||||
&self,
|
|
||||||
binary: &[u8],
|
|
||||||
tunables: &dyn Tunables,
|
|
||||||
) -> Result<Arc<UniversalArtifact>, CompileError>;
|
|
||||||
|
|
||||||
/// Deserializes a WebAssembly module
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The serialized content must represent a serialized WebAssembly module.
|
|
||||||
unsafe fn deserialize(&self, bytes: &[u8]) -> Result<Arc<UniversalArtifact>, DeserializeError>;
|
|
||||||
|
|
||||||
/// Deserializes a WebAssembly module from a path
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The file's content must represent a serialized WebAssembly module.
|
|
||||||
unsafe fn deserialize_from_file(
|
|
||||||
&self,
|
|
||||||
file_ref: &Path,
|
|
||||||
) -> Result<Arc<UniversalArtifact>, DeserializeError> {
|
|
||||||
let file = std::fs::File::open(file_ref)?;
|
|
||||||
let mmap = Mmap::map(&file)?;
|
|
||||||
self.deserialize(&mmap)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A unique identifier for this object.
|
|
||||||
///
|
|
||||||
/// This exists to allow us to compare two Engines for equality. Otherwise,
|
|
||||||
/// comparing two trait objects unsafely relies on implementation details
|
|
||||||
/// of trait representation.
|
|
||||||
fn id(&self) -> &EngineId;
|
|
||||||
|
|
||||||
/// Clone the engine
|
|
||||||
fn cloned(&self) -> Arc<dyn Engine + Send + Sync>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
/// A unique identifier for an Engine.
|
|
||||||
pub struct EngineId {
|
|
||||||
id: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EngineId {
|
|
||||||
/// Format this identifier as a string.
|
|
||||||
pub fn id(&self) -> String {
|
|
||||||
format!("{}", &self.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for EngineId {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for EngineId {
|
|
||||||
fn default() -> Self {
|
|
||||||
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
|
|
||||||
Self {
|
|
||||||
id: NEXT_ID.fetch_add(1, SeqCst),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
//! Generic Engine abstraction for Wasmer Engines.
|
//! The Wasmer Engine.
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
mod inner;
|
|
||||||
mod resolver;
|
mod resolver;
|
||||||
mod trap;
|
mod trap;
|
||||||
mod tunables;
|
mod tunables;
|
||||||
@ -10,7 +9,6 @@ mod tunables;
|
|||||||
mod universal;
|
mod universal;
|
||||||
|
|
||||||
pub use self::error::{InstantiationError, LinkError};
|
pub use self::error::{InstantiationError, LinkError};
|
||||||
pub use self::inner::{Engine, EngineId};
|
|
||||||
pub use self::resolver::resolve_imports;
|
pub use self::resolver::resolve_imports;
|
||||||
pub use self::trap::*;
|
pub use self::trap::*;
|
||||||
pub use self::tunables::Tunables;
|
pub use self::tunables::Tunables;
|
||||||
|
@ -5,13 +5,13 @@ use super::engine::{UniversalEngine, UniversalEngineInner};
|
|||||||
use crate::engine::universal::link::link_module;
|
use crate::engine::universal::link::link_module;
|
||||||
use crate::ArtifactCreate;
|
use crate::ArtifactCreate;
|
||||||
use crate::Features;
|
use crate::Features;
|
||||||
|
#[cfg(feature = "universal_engine")]
|
||||||
|
use crate::ModuleEnvironment;
|
||||||
use crate::UniversalArtifactBuild;
|
use crate::UniversalArtifactBuild;
|
||||||
use crate::{
|
use crate::{
|
||||||
register_frame_info, resolve_imports, FunctionExtent, GlobalFrameInfoRegistration,
|
register_frame_info, resolve_imports, FunctionExtent, GlobalFrameInfoRegistration,
|
||||||
InstantiationError, MetadataHeader, RuntimeError, Tunables,
|
InstantiationError, MetadataHeader, RuntimeError, Tunables,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "universal_engine")]
|
|
||||||
use crate::{Engine, ModuleEnvironment};
|
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
@ -4,7 +4,10 @@
|
|||||||
use crate::Compiler;
|
use crate::Compiler;
|
||||||
use crate::UniversalEngineBuilder;
|
use crate::UniversalEngineBuilder;
|
||||||
use crate::{CodeMemory, UniversalArtifact};
|
use crate::{CodeMemory, UniversalArtifact};
|
||||||
use crate::{Engine, EngineId, FunctionExtent, Tunables};
|
use crate::{FunctionExtent, Tunables};
|
||||||
|
use memmap2::Mmap;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use wasmer_types::entity::PrimaryMap;
|
use wasmer_types::entity::PrimaryMap;
|
||||||
use wasmer_types::FunctionBody;
|
use wasmer_types::FunctionBody;
|
||||||
@ -74,34 +77,32 @@ impl UniversalEngine {
|
|||||||
pub(crate) fn inner_mut(&self) -> std::sync::MutexGuard<'_, UniversalEngineInner> {
|
pub(crate) fn inner_mut(&self) -> std::sync::MutexGuard<'_, UniversalEngineInner> {
|
||||||
self.inner.lock().unwrap()
|
self.inner.lock().unwrap()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Engine for UniversalEngine {
|
/// Gets the target
|
||||||
/// The target
|
pub fn target(&self) -> &Target {
|
||||||
fn target(&self) -> &Target {
|
|
||||||
&self.target
|
&self.target
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a signature
|
/// Register a signature
|
||||||
fn register_signature(&self, func_type: &FunctionType) -> VMSharedSignatureIndex {
|
pub fn register_signature(&self, func_type: &FunctionType) -> VMSharedSignatureIndex {
|
||||||
let compiler = self.inner();
|
let compiler = self.inner();
|
||||||
compiler.signatures().register(func_type)
|
compiler.signatures().register(func_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lookup a signature
|
/// Lookup a signature
|
||||||
fn lookup_signature(&self, sig: VMSharedSignatureIndex) -> Option<FunctionType> {
|
pub fn lookup_signature(&self, sig: VMSharedSignatureIndex) -> Option<FunctionType> {
|
||||||
let compiler = self.inner();
|
let compiler = self.inner();
|
||||||
compiler.signatures().lookup(sig)
|
compiler.signatures().lookup(sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validates a WebAssembly module
|
/// Validates a WebAssembly module
|
||||||
fn validate(&self, binary: &[u8]) -> Result<(), CompileError> {
|
pub fn validate(&self, binary: &[u8]) -> Result<(), CompileError> {
|
||||||
self.inner().validate(binary)
|
self.inner().validate(binary)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile a WebAssembly binary
|
/// Compile a WebAssembly binary
|
||||||
#[cfg(feature = "universal_engine")]
|
#[cfg(feature = "universal_engine")]
|
||||||
fn compile(
|
pub fn compile(
|
||||||
&self,
|
&self,
|
||||||
binary: &[u8],
|
binary: &[u8],
|
||||||
tunables: &dyn Tunables,
|
tunables: &dyn Tunables,
|
||||||
@ -111,7 +112,7 @@ impl Engine for UniversalEngine {
|
|||||||
|
|
||||||
/// Compile a WebAssembly binary
|
/// Compile a WebAssembly binary
|
||||||
#[cfg(not(feature = "universal_engine"))]
|
#[cfg(not(feature = "universal_engine"))]
|
||||||
fn compile(
|
pub fn compile(
|
||||||
&self,
|
&self,
|
||||||
_binary: &[u8],
|
_binary: &[u8],
|
||||||
_tunables: &dyn Tunables,
|
_tunables: &dyn Tunables,
|
||||||
@ -123,15 +124,42 @@ impl Engine for UniversalEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes a WebAssembly module
|
/// Deserializes a WebAssembly module
|
||||||
unsafe fn deserialize(&self, bytes: &[u8]) -> Result<Arc<UniversalArtifact>, DeserializeError> {
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The serialized content must represent a serialized WebAssembly module.
|
||||||
|
pub unsafe fn deserialize(
|
||||||
|
&self,
|
||||||
|
bytes: &[u8],
|
||||||
|
) -> Result<Arc<UniversalArtifact>, DeserializeError> {
|
||||||
Ok(Arc::new(UniversalArtifact::deserialize(self, bytes)?))
|
Ok(Arc::new(UniversalArtifact::deserialize(self, bytes)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id(&self) -> &EngineId {
|
/// Deserializes a WebAssembly module from a path
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The file's content must represent a serialized WebAssembly module.
|
||||||
|
pub unsafe fn deserialize_from_file(
|
||||||
|
&self,
|
||||||
|
file_ref: &Path,
|
||||||
|
) -> Result<Arc<UniversalArtifact>, DeserializeError> {
|
||||||
|
let file = std::fs::File::open(file_ref)?;
|
||||||
|
let mmap = Mmap::map(&file)?;
|
||||||
|
self.deserialize(&mmap)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A unique identifier for this object.
|
||||||
|
///
|
||||||
|
/// This exists to allow us to compare two Engines for equality. Otherwise,
|
||||||
|
/// comparing two trait objects unsafely relies on implementation details
|
||||||
|
/// of trait representation.
|
||||||
|
pub fn id(&self) -> &EngineId {
|
||||||
&self.engine_id
|
&self.engine_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cloned(&self) -> Arc<dyn Engine + Send + Sync> {
|
/// Clone the engine
|
||||||
|
pub fn cloned(&self) -> Arc<Self> {
|
||||||
Arc::new(self.clone())
|
Arc::new(self.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,3 +313,32 @@ impl UniversalEngineInner {
|
|||||||
&self.signatures
|
&self.signatures
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
/// A unique identifier for an Engine.
|
||||||
|
pub struct EngineId {
|
||||||
|
id: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EngineId {
|
||||||
|
/// Format this identifier as a string.
|
||||||
|
pub fn id(&self) -> String {
|
||||||
|
format!("{}", &self.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for EngineId {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for EngineId {
|
||||||
|
fn default() -> Self {
|
||||||
|
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
Self {
|
||||||
|
id: NEXT_ID.fetch_add(1, SeqCst),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasmer::{CompilerConfig, Engine, Features, ModuleMiddleware, Store};
|
use wasmer::{CompilerConfig, Features, ModuleMiddleware, Store};
|
||||||
|
use wasmer_compiler::UniversalEngine;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Compiler {
|
pub enum Compiler {
|
||||||
@ -49,7 +50,7 @@ impl Config {
|
|||||||
Store::new_with_engine(&*engine)
|
Store::new_with_engine(&*engine)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn engine(&self, compiler_config: Box<dyn CompilerConfig>) -> Box<dyn Engine> {
|
pub fn engine(&self, compiler_config: Box<dyn CompilerConfig>) -> Box<UniversalEngine> {
|
||||||
let mut engine = wasmer_compiler::Universal::new(compiler_config);
|
let mut engine = wasmer_compiler::Universal::new(compiler_config);
|
||||||
if let Some(ref features) = self.features {
|
if let Some(ref features) = self.features {
|
||||||
engine = engine.features(features.clone())
|
engine = engine.features(features.clone())
|
||||||
@ -57,7 +58,7 @@ impl Config {
|
|||||||
Box::new(engine.engine())
|
Box::new(engine.engine())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn engine_headless(&self) -> Box<dyn Engine> {
|
pub fn engine_headless(&self) -> Box<UniversalEngine> {
|
||||||
Box::new(wasmer_compiler::Universal::headless().engine())
|
Box::new(wasmer_compiler::Universal::headless().engine())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ impl Ignores {
|
|||||||
arch = Some(alias.to_string());
|
arch = Some(alias.to_string());
|
||||||
}
|
}
|
||||||
// Engines
|
// Engines
|
||||||
"universal" => {
|
"universal" | "engine" => {
|
||||||
engine = Some(alias.to_string());
|
engine = Some(alias.to_string());
|
||||||
}
|
}
|
||||||
// Compilers
|
// Compilers
|
||||||
|
Reference in New Issue
Block a user