mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-10 22:58:18 +00:00
Split Artifact to have ArtifactCreate that handles only the creation part, not the run part
This commit is contained in:
19
Cargo.lock
generated
19
Cargo.lock
generated
@@ -2765,6 +2765,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
"wasmer-artifact",
|
||||
"wasmer-compiler",
|
||||
"wasmer-compiler-cranelift",
|
||||
"wasmer-compiler-llvm",
|
||||
@@ -2780,6 +2781,17 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-artifact"
|
||||
version = "2.2.1"
|
||||
dependencies = [
|
||||
"enumset",
|
||||
"loupe",
|
||||
"thiserror",
|
||||
"wasmer-compiler",
|
||||
"wasmer-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-bin-fuzz"
|
||||
version = "0.0.0"
|
||||
@@ -2858,6 +2870,7 @@ dependencies = [
|
||||
"tempfile",
|
||||
"unix_mode",
|
||||
"wasmer",
|
||||
"wasmer-artifact",
|
||||
"wasmer-cache",
|
||||
"wasmer-compiler",
|
||||
"wasmer-compiler-cranelift",
|
||||
@@ -2996,6 +3009,7 @@ dependencies = [
|
||||
"serde_bytes",
|
||||
"target-lexicon 0.12.3",
|
||||
"thiserror",
|
||||
"wasmer-artifact",
|
||||
"wasmer-compiler",
|
||||
"wasmer-types",
|
||||
"wasmer-vm",
|
||||
@@ -3010,6 +3024,7 @@ dependencies = [
|
||||
"loupe",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"wasmer-artifact",
|
||||
"wasmer-compiler",
|
||||
"wasmer-engine",
|
||||
"wasmer-types",
|
||||
@@ -3031,6 +3046,7 @@ dependencies = [
|
||||
"serde",
|
||||
"tempfile",
|
||||
"tracing",
|
||||
"wasmer-artifact",
|
||||
"wasmer-compiler",
|
||||
"wasmer-engine",
|
||||
"wasmer-object",
|
||||
@@ -3052,6 +3068,7 @@ dependencies = [
|
||||
"serde",
|
||||
"tempfile",
|
||||
"tracing",
|
||||
"wasmer-artifact",
|
||||
"wasmer-compiler",
|
||||
"wasmer-engine",
|
||||
"wasmer-object",
|
||||
@@ -3070,6 +3087,7 @@ dependencies = [
|
||||
"loupe",
|
||||
"region",
|
||||
"rkyv",
|
||||
"wasmer-artifact",
|
||||
"wasmer-compiler",
|
||||
"wasmer-engine",
|
||||
"wasmer-types",
|
||||
@@ -3156,6 +3174,7 @@ dependencies = [
|
||||
"scopeguard",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"wasmer-artifact",
|
||||
"wasmer-types",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@@ -22,6 +22,7 @@ edition = "2018"
|
||||
# Shared dependencies.
|
||||
[dependencies]
|
||||
# - Mandatory shared dependencies.
|
||||
wasmer-artifact = { path = "../artifact", version = "=2.2.1" }
|
||||
indexmap = { version = "1.6", features = ["serde-1"] }
|
||||
cfg-if = "1.0"
|
||||
thiserror = "1.0"
|
||||
|
||||
22
lib/artifact/Cargo.toml
Normal file
22
lib/artifact/Cargo.toml
Normal file
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "wasmer-artifact"
|
||||
version = "2.2.1"
|
||||
description = "Wasmer Artifact abstraction"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly", "engine"]
|
||||
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
repository = "https://github.com/wasmerio/wasmer"
|
||||
license = "MIT OR Apache-2.0 WITH LLVM-exception "
|
||||
readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../types", version = "=2.2.1" }
|
||||
wasmer-compiler = { path = "../compiler", version = "=2.2.1" }
|
||||
loupe = "0.1"
|
||||
thiserror = "1.0"
|
||||
enumset = "1.0"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
|
||||
20
lib/artifact/README.md
Normal file
20
lib/artifact/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# `wasmer-artifact` [](https://github.com/wasmerio/wasmer/actions?query=workflow%3Abuild) [](https://slack.wasmer.io) [](https://github.com/wasmerio/wasmer/blob/master/LICENSE)
|
||||
|
||||
|
||||
This crate is the general abstraction for creating Artifacts in Wasmer.
|
||||
|
||||
### Acknowledgments
|
||||
|
||||
This project borrowed some of the code of the trap implementation from
|
||||
the [`wasmtime-api`], the code since then has evolved significantly.
|
||||
|
||||
Please check [Wasmer `ATTRIBUTIONS`] to further see licenses and other
|
||||
attributions of the project.
|
||||
|
||||
|
||||
[`wasmer-engine-universal`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-universal
|
||||
[`wasmer-engine-dylib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-dylib
|
||||
[`wasmer-engine-staticlib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-staticlib
|
||||
[`wasmer-engine-dummy`]: https://github.com/wasmerio/wasmer/tree/master/tests/lib/engine-dummy
|
||||
[`wasmtime-api`]: https://crates.io/crates/wasmtime
|
||||
[Wasmer `ATTRIBUTIONS`]: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md
|
||||
166
lib/artifact/src/artifact.rs
Normal file
166
lib/artifact/src/artifact.rs
Normal file
@@ -0,0 +1,166 @@
|
||||
use crate::{DeserializeError, SerializeError};
|
||||
use enumset::EnumSet;
|
||||
use loupe::MemoryUsage;
|
||||
use std::any::Any;
|
||||
use std::convert::TryInto;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::{fs, mem};
|
||||
use wasmer_compiler::{CpuFeature, Features};
|
||||
use wasmer_types::entity::PrimaryMap;
|
||||
use wasmer_types::{
|
||||
MemoryIndex, MemoryStyle, ModuleInfo, OwnedDataInitializer, TableIndex, TableStyle,
|
||||
};
|
||||
|
||||
/// An `Artifact` is the product that the `Engine`
|
||||
/// implementation produce and use.
|
||||
///
|
||||
/// The `Artifact` contains the compiled data for a given
|
||||
/// module as well as extra information needed to run the
|
||||
/// module at runtime, such as [`ModuleInfo`] and [`Features`].
|
||||
pub trait ArtifactCreate: Send + Sync + Upcastable + MemoryUsage {
|
||||
/// Return a reference-counted pointer to the module
|
||||
fn module(&self) -> Arc<ModuleInfo>;
|
||||
|
||||
/// Return a pointer to a module.
|
||||
fn module_ref(&self) -> &ModuleInfo;
|
||||
|
||||
/// Gets a mutable reference to the info.
|
||||
///
|
||||
/// Note: this will return `None` if the module is already instantiated.
|
||||
fn module_mut(&mut self) -> Option<&mut ModuleInfo>;
|
||||
|
||||
/// Register thie `Artifact` stack frame information into the global scope.
|
||||
///
|
||||
/// This is required to ensure that any traps can be properly symbolicated.
|
||||
fn register_frame_info(&self);
|
||||
|
||||
/// Returns the features for this Artifact
|
||||
fn features(&self) -> &Features;
|
||||
|
||||
/// Returns the CPU features for this Artifact
|
||||
fn cpu_features(&self) -> EnumSet<CpuFeature>;
|
||||
|
||||
/// Returns the memory styles associated with this `Artifact`.
|
||||
fn memory_styles(&self) -> &PrimaryMap<MemoryIndex, MemoryStyle>;
|
||||
|
||||
/// Returns the table plans associated with this `Artifact`.
|
||||
fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle>;
|
||||
|
||||
/// Returns data initializers to pass to `InstanceHandle::initialize`
|
||||
fn data_initializers(&self) -> &[OwnedDataInitializer];
|
||||
|
||||
/// Serializes an artifact into bytes
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError>;
|
||||
|
||||
/// Serializes an artifact into a file path
|
||||
fn serialize_to_file(&self, path: &Path) -> Result<(), SerializeError> {
|
||||
let serialized = self.serialize()?;
|
||||
fs::write(&path, serialized)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of `Upcastable` taken from https://users.rust-lang.org/t/why-does-downcasting-not-work-for-subtraits/33286/7 .
|
||||
/// Trait needed to get downcasting of `Engine`s to work.
|
||||
pub trait Upcastable {
|
||||
/// upcast ref
|
||||
fn upcast_any_ref(&'_ self) -> &'_ dyn Any;
|
||||
/// upcast mut ref
|
||||
fn upcast_any_mut(&'_ mut self) -> &'_ mut dyn Any;
|
||||
/// upcast boxed dyn
|
||||
fn upcast_any_box(self: Box<Self>) -> Box<dyn Any>;
|
||||
}
|
||||
|
||||
impl<T: Any + Send + Sync + 'static> Upcastable for T {
|
||||
#[inline]
|
||||
fn upcast_any_ref(&'_ self) -> &'_ dyn Any {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn upcast_any_mut(&'_ mut self) -> &'_ mut dyn Any {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn upcast_any_box(self: Box<Self>) -> Box<dyn Any> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl dyn ArtifactCreate + 'static {
|
||||
/// Try to downcast the artifact into a given type.
|
||||
#[inline]
|
||||
pub fn downcast_ref<T: 'static>(&'_ self) -> Option<&'_ T> {
|
||||
self.upcast_any_ref().downcast_ref::<T>()
|
||||
}
|
||||
|
||||
/// Try to downcast the artifact into a given type mutably.
|
||||
#[inline]
|
||||
pub fn downcast_mut<T: 'static>(&'_ mut self) -> Option<&'_ mut T> {
|
||||
self.upcast_any_mut().downcast_mut::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata header which holds an ABI version and the length of the remaining
|
||||
/// metadata.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct MetadataHeader {
|
||||
magic: [u8; 8],
|
||||
version: u32,
|
||||
len: u32,
|
||||
}
|
||||
|
||||
impl MetadataHeader {
|
||||
/// Current ABI version. Increment this any time breaking changes are made
|
||||
/// to the format of the serialized data.
|
||||
const CURRENT_VERSION: u32 = 1;
|
||||
|
||||
/// Magic number to identify wasmer metadata.
|
||||
const MAGIC: [u8; 8] = *b"WASMER\0\0";
|
||||
|
||||
/// Length of the metadata header.
|
||||
pub const LEN: usize = 16;
|
||||
|
||||
/// Alignment of the metadata.
|
||||
pub const ALIGN: usize = 16;
|
||||
|
||||
/// Creates a new header for metadata of the given length.
|
||||
pub fn new(len: usize) -> [u8; 16] {
|
||||
let header = MetadataHeader {
|
||||
magic: Self::MAGIC,
|
||||
version: Self::CURRENT_VERSION,
|
||||
len: len.try_into().expect("metadata exceeds maximum length"),
|
||||
};
|
||||
unsafe { mem::transmute(header) }
|
||||
}
|
||||
|
||||
/// Parses the header and returns the length of the metadata following it.
|
||||
pub fn parse(bytes: &[u8]) -> Result<usize, DeserializeError> {
|
||||
if bytes.as_ptr() as usize % 16 != 0 {
|
||||
return Err(DeserializeError::CorruptedBinary(
|
||||
"misaligned metadata".to_string(),
|
||||
));
|
||||
}
|
||||
let bytes: [u8; 16] = bytes
|
||||
.get(..16)
|
||||
.ok_or_else(|| {
|
||||
DeserializeError::CorruptedBinary("invalid metadata header".to_string())
|
||||
})?
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let header: MetadataHeader = unsafe { mem::transmute(bytes) };
|
||||
if header.magic != Self::MAGIC {
|
||||
return Err(DeserializeError::Incompatible(
|
||||
"The provided bytes were not serialized by Wasmer".to_string(),
|
||||
));
|
||||
}
|
||||
if header.version != Self::CURRENT_VERSION {
|
||||
return Err(DeserializeError::Incompatible(
|
||||
"The provided bytes were serialized by an incompatible version of Wasmer"
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
Ok(header.len as usize)
|
||||
}
|
||||
}
|
||||
66
lib/artifact/src/error.rs
Normal file
66
lib/artifact/src/error.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
//! The WebAssembly possible errors
|
||||
use std::io;
|
||||
use thiserror::Error;
|
||||
use wasmer_compiler::CompileError;
|
||||
use wasmer_types::ExternType;
|
||||
|
||||
/// The Serialize error can occur when serializing a
|
||||
/// compiled Module into a binary.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum SerializeError {
|
||||
/// An IO error
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
/// A generic serialization error
|
||||
#[error("{0}")]
|
||||
Generic(String),
|
||||
}
|
||||
|
||||
/// The Deserialize error can occur when loading a
|
||||
/// compiled Module from a binary.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum DeserializeError {
|
||||
/// An IO error
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
/// A generic deserialization error
|
||||
#[error("{0}")]
|
||||
Generic(String),
|
||||
/// Incompatible serialized binary
|
||||
#[error("incompatible binary: {0}")]
|
||||
Incompatible(String),
|
||||
/// The provided binary is corrupted
|
||||
#[error("corrupted binary: {0}")]
|
||||
CorruptedBinary(String),
|
||||
/// The binary was valid, but we got an error when
|
||||
/// trying to allocate the required resources.
|
||||
#[error(transparent)]
|
||||
Compiler(CompileError),
|
||||
}
|
||||
|
||||
/// An ImportError.
|
||||
///
|
||||
/// Note: this error is not standard to WebAssembly, but it's
|
||||
/// useful to determine the import issue on the API side.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ImportError {
|
||||
/// Incompatible Import Type.
|
||||
/// This error occurs when the import types mismatch.
|
||||
#[error("incompatible import type. Expected {0:?} but received {1:?}")]
|
||||
IncompatibleType(ExternType, ExternType),
|
||||
|
||||
/// Unknown Import.
|
||||
/// This error occurs when an import was expected but not provided.
|
||||
#[error("unknown import. Expected {0:?}")]
|
||||
UnknownImport(ExternType),
|
||||
}
|
||||
|
||||
/// An error while preinstantiating a module.
|
||||
///
|
||||
#[derive(Error, Debug)]
|
||||
pub enum PreInstantiationError {
|
||||
/// The module was compiled with a CPU feature that is not available on
|
||||
/// the current host.
|
||||
#[error("module compiled with CPU feature that is missing from host")]
|
||||
CpuFeature(String),
|
||||
}
|
||||
17
lib/artifact/src/funcbody.rs
Normal file
17
lib/artifact/src/funcbody.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
/// A placeholder byte-sized type which is just used to provide some amount of type
|
||||
/// safety when dealing with pointers to JIT-compiled function bodies. Note that it's
|
||||
/// deliberately not Copy, as we shouldn't be carelessly copying function body bytes
|
||||
/// around.
|
||||
#[repr(C)]
|
||||
pub struct VMFunctionBody(u8);
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_vmfunction_body {
|
||||
use super::VMFunctionBody;
|
||||
use std::mem::size_of;
|
||||
|
||||
#[test]
|
||||
fn check_vmfunction_body_offsets() {
|
||||
assert_eq!(size_of::<VMFunctionBody>(), 1);
|
||||
}
|
||||
}
|
||||
55
lib/artifact/src/lib.rs
Normal file
55
lib/artifact/src/lib.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
//! Generic Artifact abstraction for Wasmer Engines.
|
||||
|
||||
#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
|
||||
#![warn(unused_import_braces)]
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(clippy::new_without_default, clippy::new_without_default)
|
||||
)]
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
warn(
|
||||
clippy::float_arithmetic,
|
||||
clippy::mut_mut,
|
||||
clippy::nonminimal_bool,
|
||||
clippy::option_map_unwrap_or,
|
||||
clippy::option_map_unwrap_or_else,
|
||||
clippy::print_stdout,
|
||||
clippy::unicode_not_nfc,
|
||||
clippy::use_self
|
||||
)
|
||||
)]
|
||||
|
||||
mod artifact;
|
||||
mod error;
|
||||
mod funcbody;
|
||||
|
||||
pub use crate::artifact::{ArtifactCreate, MetadataHeader, Upcastable};
|
||||
pub use crate::error::{DeserializeError, ImportError, PreInstantiationError, SerializeError};
|
||||
pub use crate::funcbody::VMFunctionBody;
|
||||
use loupe::MemoryUsage;
|
||||
|
||||
/// Version number of this crate.
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
/// A safe wrapper around `VMFunctionBody`.
|
||||
#[derive(Clone, Copy, Debug, MemoryUsage)]
|
||||
#[repr(transparent)]
|
||||
pub struct FunctionBodyPtr(pub *const VMFunctionBody);
|
||||
|
||||
impl std::ops::Deref for FunctionBodyPtr {
|
||||
type Target = *const VMFunctionBody;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// The VMFunctionBody that this points to is opaque, so there's no data to
|
||||
/// read or write through this pointer. This is essentially a usize.
|
||||
unsafe impl Send for FunctionBodyPtr {}
|
||||
/// # Safety
|
||||
/// The VMFunctionBody that this points to is opaque, so there's no data to
|
||||
/// read or write through this pointer. This is essentially a usize.
|
||||
unsafe impl Sync for FunctionBodyPtr {}
|
||||
@@ -24,6 +24,7 @@ doc = false
|
||||
required-features = ["headless"]
|
||||
|
||||
[dependencies]
|
||||
wasmer-artifact = { version = "=2.2.1", path = "../artifact" }
|
||||
wasmer-compiler = { version = "=2.2.1", path = "../compiler" }
|
||||
wasmer-compiler-singlepass = { version = "=2.2.1", path = "../compiler-singlepass", optional = true }
|
||||
wasmer-engine = { version = "=2.2.1", path = "../engine" }
|
||||
|
||||
@@ -11,6 +11,7 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-artifact = { path = "../artifact", version = "=2.2.1" }
|
||||
wasmer-types = { path = "../types", version = "=2.2.1" }
|
||||
wasmer-compiler = { path = "../compiler", version = "=2.2.1" }
|
||||
wasmer-vm = { path = "../vm", version = "=2.2.1", features = ["enable-rkyv"] }
|
||||
|
||||
@@ -19,6 +19,7 @@ use tempfile::NamedTempFile;
|
||||
use tracing::log::error;
|
||||
#[cfg(feature = "compiler")]
|
||||
use tracing::trace;
|
||||
use wasmer_artifact::ArtifactCreate;
|
||||
use wasmer_compiler::{
|
||||
Architecture, CompileError, CompiledFunctionFrameInfo, CpuFeature, Features,
|
||||
FunctionAddressMap, OperatingSystem, Symbol, SymbolRegistry, Triple,
|
||||
@@ -678,7 +679,7 @@ impl DylibArtifact {
|
||||
}
|
||||
}
|
||||
|
||||
impl Artifact for DylibArtifact {
|
||||
impl ArtifactCreate for DylibArtifact {
|
||||
fn module(&self) -> Arc<ModuleInfo> {
|
||||
self.metadata.compile_info.module.clone()
|
||||
}
|
||||
@@ -841,30 +842,6 @@ impl Artifact for DylibArtifact {
|
||||
&self.metadata.compile_info.table_styles
|
||||
}
|
||||
|
||||
fn finished_functions(&self) -> &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr> {
|
||||
&self.finished_functions
|
||||
}
|
||||
|
||||
fn finished_function_call_trampolines(&self) -> &BoxedSlice<SignatureIndex, VMTrampoline> {
|
||||
&self.finished_function_call_trampolines
|
||||
}
|
||||
|
||||
fn finished_dynamic_function_trampolines(&self) -> &BoxedSlice<FunctionIndex, FunctionBodyPtr> {
|
||||
&self.finished_dynamic_function_trampolines
|
||||
}
|
||||
|
||||
fn signatures(&self) -> &BoxedSlice<SignatureIndex, VMSharedSignatureIndex> {
|
||||
&self.signatures
|
||||
}
|
||||
|
||||
fn func_data_registry(&self) -> &FuncDataRegistry {
|
||||
&self.func_data_registry
|
||||
}
|
||||
|
||||
fn preinstantiate(&self) -> Result<(), InstantiationError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Serialize a `DylibArtifact`.
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
Ok(std::fs::read(&self.dylib_path)?)
|
||||
@@ -908,3 +885,28 @@ impl Artifact for DylibArtifact {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Artifact for DylibArtifact {
|
||||
fn finished_functions(&self) -> &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr> {
|
||||
&self.finished_functions
|
||||
}
|
||||
|
||||
fn finished_function_call_trampolines(&self) -> &BoxedSlice<SignatureIndex, VMTrampoline> {
|
||||
&self.finished_function_call_trampolines
|
||||
}
|
||||
|
||||
fn finished_dynamic_function_trampolines(&self) -> &BoxedSlice<FunctionIndex, FunctionBodyPtr> {
|
||||
&self.finished_dynamic_function_trampolines
|
||||
}
|
||||
|
||||
fn signatures(&self) -> &BoxedSlice<SignatureIndex, VMSharedSignatureIndex> {
|
||||
&self.signatures
|
||||
}
|
||||
|
||||
fn func_data_registry(&self) -> &FuncDataRegistry {
|
||||
&self.func_data_registry
|
||||
}
|
||||
|
||||
fn preinstantiate(&self) -> Result<(), InstantiationError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-artifact = { path = "../artifact", version = "=2.2.1" }
|
||||
wasmer-types = { path = "../types", version = "=2.2.1" }
|
||||
wasmer-compiler = { path = "../compiler", version = "=2.2.1" }
|
||||
wasmer-vm = { path = "../vm", version = "=2.2.1" }
|
||||
|
||||
@@ -9,6 +9,7 @@ use std::collections::BTreeMap;
|
||||
use std::error::Error;
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
use wasmer_artifact::ArtifactCreate;
|
||||
use wasmer_compiler::{
|
||||
CompileError, CpuFeature, Features, OperatingSystem, SymbolRegistry, Triple,
|
||||
};
|
||||
@@ -436,7 +437,7 @@ impl StaticlibArtifact {
|
||||
}
|
||||
}
|
||||
|
||||
impl Artifact for StaticlibArtifact {
|
||||
impl ArtifactCreate for StaticlibArtifact {
|
||||
fn module(&self) -> Arc<ModuleInfo> {
|
||||
self.metadata.compile_info.module.clone()
|
||||
}
|
||||
@@ -473,6 +474,12 @@ impl Artifact for StaticlibArtifact {
|
||||
&self.metadata.compile_info.table_styles
|
||||
}
|
||||
|
||||
/// Serialize a StaticlibArtifact
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
Ok(self.module_bytes.clone())
|
||||
}
|
||||
}
|
||||
impl Artifact for StaticlibArtifact {
|
||||
fn finished_functions(&self) -> &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr> {
|
||||
&self.finished_functions
|
||||
}
|
||||
@@ -492,7 +499,6 @@ impl Artifact for StaticlibArtifact {
|
||||
fn func_data_registry(&self) -> &FuncDataRegistry {
|
||||
&self.func_data_registry
|
||||
}
|
||||
|
||||
fn preinstantiate(&self) -> Result<(), InstantiationError> {
|
||||
if self.is_compiled {
|
||||
panic!(
|
||||
@@ -502,9 +508,4 @@ impl Artifact for StaticlibArtifact {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Serialize a StaticlibArtifact
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
Ok(self.module_bytes.clone())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-artifact = { path = "../artifact", version = "=2.2.1" }
|
||||
wasmer-types = { path = "../types", version = "=2.2.1", features = [
|
||||
"enable-rkyv",
|
||||
] }
|
||||
@@ -21,7 +22,6 @@ wasmer-compiler = { path = "../compiler", version = "=2.2.1", features = [
|
||||
wasmer-vm = { path = "../vm", version = "=2.2.1", features = ["enable-rkyv"] }
|
||||
wasmer-engine = { path = "../engine", version = "=2.2.1" }
|
||||
# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" }
|
||||
region = { version = "3.0" }
|
||||
cfg-if = "1.0"
|
||||
leb128 = "0.2"
|
||||
rkyv = "0.7.20"
|
||||
@@ -29,6 +29,9 @@ loupe = "0.1"
|
||||
enumset = "1.0"
|
||||
enum-iterator = "0.7.0"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
region = { version = "3.0" }
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winapi = { version = "0.3", features = ["winnt", "impl-default"] }
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ use enumset::EnumSet;
|
||||
use loupe::MemoryUsage;
|
||||
use std::mem;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use wasmer_artifact::ArtifactCreate;
|
||||
use wasmer_compiler::{CompileError, CpuFeature, Features, Triple};
|
||||
#[cfg(feature = "compiler")]
|
||||
use wasmer_compiler::{CompileModuleInfo, ModuleEnvironment, ModuleMiddlewareChain};
|
||||
@@ -267,7 +268,7 @@ impl UniversalArtifact {
|
||||
}
|
||||
}
|
||||
|
||||
impl Artifact for UniversalArtifact {
|
||||
impl ArtifactCreate for UniversalArtifact {
|
||||
fn module(&self) -> Arc<ModuleInfo> {
|
||||
self.serializable.compile_info.module.clone()
|
||||
}
|
||||
@@ -324,6 +325,19 @@ impl Artifact for UniversalArtifact {
|
||||
&self.serializable.compile_info.table_styles
|
||||
}
|
||||
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
let serialized_data = self.serializable.serialize()?;
|
||||
assert!(mem::align_of::<SerializableModule>() <= MetadataHeader::ALIGN);
|
||||
|
||||
let mut metadata_binary = vec![];
|
||||
metadata_binary.extend(Self::MAGIC_HEADER);
|
||||
metadata_binary.extend(MetadataHeader::new(serialized_data.len()));
|
||||
metadata_binary.extend(serialized_data);
|
||||
Ok(metadata_binary)
|
||||
}
|
||||
}
|
||||
|
||||
impl Artifact for UniversalArtifact {
|
||||
fn finished_functions(&self) -> &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr> {
|
||||
&self.finished_functions
|
||||
}
|
||||
@@ -343,14 +357,4 @@ impl Artifact for UniversalArtifact {
|
||||
fn func_data_registry(&self) -> &FuncDataRegistry {
|
||||
&self.func_data_registry
|
||||
}
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
let serialized_data = self.serializable.serialize()?;
|
||||
assert!(mem::align_of::<SerializableModule>() <= MetadataHeader::ALIGN);
|
||||
|
||||
let mut metadata_binary = vec![];
|
||||
metadata_binary.extend(Self::MAGIC_HEADER);
|
||||
metadata_binary.extend(MetadataHeader::new(serialized_data.len()));
|
||||
metadata_binary.extend(serialized_data);
|
||||
Ok(metadata_binary)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../types", version = "=2.2.1" }
|
||||
wasmer-compiler = { path = "../compiler", version = "=2.2.1" }
|
||||
wasmer-artifact = { path = "../artifact", version = "=2.2.1" }
|
||||
target-lexicon = { version = "0.12.2", default-features = false }
|
||||
# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" }
|
||||
backtrace = "0.3"
|
||||
|
||||
@@ -1,63 +1,26 @@
|
||||
use crate::{
|
||||
resolve_imports, DeserializeError, InstantiationError, Resolver, RuntimeError, SerializeError,
|
||||
Tunables,
|
||||
};
|
||||
use enumset::EnumSet;
|
||||
use crate::{resolve_imports, InstantiationError, Resolver, RuntimeError, Tunables};
|
||||
use loupe::MemoryUsage;
|
||||
use std::any::Any;
|
||||
use std::convert::TryInto;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::{fs, mem};
|
||||
use wasmer_compiler::{CpuFeature, Features};
|
||||
use wasmer_types::entity::{BoxedSlice, PrimaryMap};
|
||||
use wasmer_types::{
|
||||
DataInitializer, FunctionIndex, LocalFunctionIndex, MemoryIndex, ModuleInfo,
|
||||
OwnedDataInitializer, SignatureIndex, TableIndex,
|
||||
};
|
||||
pub use wasmer_artifact::MetadataHeader;
|
||||
use wasmer_artifact::{ArtifactCreate, Upcastable};
|
||||
use wasmer_compiler::CpuFeature;
|
||||
use wasmer_types::entity::BoxedSlice;
|
||||
use wasmer_types::{DataInitializer, FunctionIndex, LocalFunctionIndex, SignatureIndex};
|
||||
use wasmer_vm::{
|
||||
FuncDataRegistry, FunctionBodyPtr, InstanceAllocator, InstanceHandle, MemoryStyle, TableStyle,
|
||||
TrapHandler, VMSharedSignatureIndex, VMTrampoline,
|
||||
FuncDataRegistry, FunctionBodyPtr, InstanceAllocator, InstanceHandle, TrapHandler,
|
||||
VMSharedSignatureIndex, VMTrampoline,
|
||||
};
|
||||
|
||||
/// An `Artifact` is the product that the `Engine`
|
||||
/// implementation produce and use.
|
||||
///
|
||||
/// The `Artifact` contains the compiled data for a given
|
||||
/// module as well as extra information needed to run the
|
||||
|
||||
/// An `Artifact` is the product that the `Engine`
|
||||
/// implementation produce and use.
|
||||
///
|
||||
/// The `ArtifactRun` contains the extra information needed to run the
|
||||
/// module at runtime, such as [`ModuleInfo`] and [`Features`].
|
||||
pub trait Artifact: Send + Sync + Upcastable + MemoryUsage {
|
||||
/// Return a reference-counted pointer to the module
|
||||
fn module(&self) -> Arc<ModuleInfo>;
|
||||
|
||||
/// Return a pointer to a module.
|
||||
fn module_ref(&self) -> &ModuleInfo;
|
||||
|
||||
/// Gets a mutable reference to the info.
|
||||
///
|
||||
/// Note: this will return `None` if the module is already instantiated.
|
||||
fn module_mut(&mut self) -> Option<&mut ModuleInfo>;
|
||||
|
||||
/// Register thie `Artifact` stack frame information into the global scope.
|
||||
///
|
||||
/// This is required to ensure that any traps can be properly symbolicated.
|
||||
fn register_frame_info(&self);
|
||||
|
||||
/// Returns the features for this Artifact
|
||||
fn features(&self) -> &Features;
|
||||
|
||||
/// Returns the CPU features for this Artifact
|
||||
fn cpu_features(&self) -> EnumSet<CpuFeature>;
|
||||
|
||||
/// Returns the memory styles associated with this `Artifact`.
|
||||
fn memory_styles(&self) -> &PrimaryMap<MemoryIndex, MemoryStyle>;
|
||||
|
||||
/// Returns the table plans associated with this `Artifact`.
|
||||
fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle>;
|
||||
|
||||
/// Returns data initializers to pass to `InstanceHandle::initialize`
|
||||
fn data_initializers(&self) -> &[OwnedDataInitializer];
|
||||
|
||||
pub trait Artifact: Send + Sync + Upcastable + MemoryUsage + ArtifactCreate {
|
||||
/// Returns the functions allocated in memory or this `Artifact`
|
||||
/// ready to be run.
|
||||
fn finished_functions(&self) -> &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>;
|
||||
@@ -76,21 +39,10 @@ pub trait Artifact: Send + Sync + Upcastable + MemoryUsage {
|
||||
/// Get the func data registry
|
||||
fn func_data_registry(&self) -> &FuncDataRegistry;
|
||||
|
||||
/// Serializes an artifact into bytes
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError>;
|
||||
|
||||
/// Serializes an artifact into a file path
|
||||
fn serialize_to_file(&self, path: &Path) -> Result<(), SerializeError> {
|
||||
let serialized = self.serialize()?;
|
||||
fs::write(&path, serialized)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Do preinstantiation logic that is executed before instantiating
|
||||
fn preinstantiate(&self) -> Result<(), InstantiationError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Crate an `Instance` from this `Artifact`.
|
||||
///
|
||||
/// # Safety
|
||||
@@ -168,7 +120,6 @@ pub trait Artifact: Send + Sync + Upcastable + MemoryUsage {
|
||||
.map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))?;
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
/// Finishes the instantiation of a just created `InstanceHandle`.
|
||||
///
|
||||
/// # Safety
|
||||
@@ -193,29 +144,6 @@ pub trait Artifact: Send + Sync + Upcastable + MemoryUsage {
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of `Upcastable` taken from https://users.rust-lang.org/t/why-does-downcasting-not-work-for-subtraits/33286/7 .
|
||||
/// Trait needed to get downcasting of `Engine`s to work.
|
||||
pub trait Upcastable {
|
||||
fn upcast_any_ref(&'_ self) -> &'_ dyn Any;
|
||||
fn upcast_any_mut(&'_ mut self) -> &'_ mut dyn Any;
|
||||
fn upcast_any_box(self: Box<Self>) -> Box<dyn Any>;
|
||||
}
|
||||
|
||||
impl<T: Any + Send + Sync + 'static> Upcastable for T {
|
||||
#[inline]
|
||||
fn upcast_any_ref(&'_ self) -> &'_ dyn Any {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn upcast_any_mut(&'_ mut self) -> &'_ mut dyn Any {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn upcast_any_box(self: Box<Self>) -> Box<dyn Any> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl dyn Artifact + 'static {
|
||||
/// Try to downcast the artifact into a given type.
|
||||
#[inline]
|
||||
@@ -229,67 +157,3 @@ impl dyn Artifact + 'static {
|
||||
self.upcast_any_mut().downcast_mut::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata header which holds an ABI version and the length of the remaining
|
||||
/// metadata.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct MetadataHeader {
|
||||
magic: [u8; 8],
|
||||
version: u32,
|
||||
len: u32,
|
||||
}
|
||||
|
||||
impl MetadataHeader {
|
||||
/// Current ABI version. Increment this any time breaking changes are made
|
||||
/// to the format of the serialized data.
|
||||
const CURRENT_VERSION: u32 = 1;
|
||||
|
||||
/// Magic number to identify wasmer metadata.
|
||||
const MAGIC: [u8; 8] = *b"WASMER\0\0";
|
||||
|
||||
/// Length of the metadata header.
|
||||
pub const LEN: usize = 16;
|
||||
|
||||
/// Alignment of the metadata.
|
||||
pub const ALIGN: usize = 16;
|
||||
|
||||
/// Creates a new header for metadata of the given length.
|
||||
pub fn new(len: usize) -> [u8; 16] {
|
||||
let header = MetadataHeader {
|
||||
magic: Self::MAGIC,
|
||||
version: Self::CURRENT_VERSION,
|
||||
len: len.try_into().expect("metadata exceeds maximum length"),
|
||||
};
|
||||
unsafe { mem::transmute(header) }
|
||||
}
|
||||
|
||||
/// Parses the header and returns the length of the metadata following it.
|
||||
pub fn parse(bytes: &[u8]) -> Result<usize, DeserializeError> {
|
||||
if bytes.as_ptr() as usize % 16 != 0 {
|
||||
return Err(DeserializeError::CorruptedBinary(
|
||||
"misaligned metadata".to_string(),
|
||||
));
|
||||
}
|
||||
let bytes: [u8; 16] = bytes
|
||||
.get(..16)
|
||||
.ok_or_else(|| {
|
||||
DeserializeError::CorruptedBinary("invalid metadata header".to_string())
|
||||
})?
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let header: MetadataHeader = unsafe { mem::transmute(bytes) };
|
||||
if header.magic != Self::MAGIC {
|
||||
return Err(DeserializeError::Incompatible(
|
||||
"The provided bytes were not serialized by Wasmer".to_string(),
|
||||
));
|
||||
}
|
||||
if header.version != Self::CURRENT_VERSION {
|
||||
return Err(DeserializeError::Incompatible(
|
||||
"The provided bytes were serialized by an incompatible version of Wasmer"
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
Ok(header.len as usize)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,60 +1,7 @@
|
||||
//! The WebAssembly possible errors
|
||||
use crate::trap::RuntimeError;
|
||||
use std::io;
|
||||
use thiserror::Error;
|
||||
use wasmer_compiler::CompileError;
|
||||
use wasmer_types::ExternType;
|
||||
|
||||
/// The Serialize error can occur when serializing a
|
||||
/// compiled Module into a binary.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum SerializeError {
|
||||
/// An IO error
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
/// A generic serialization error
|
||||
#[error("{0}")]
|
||||
Generic(String),
|
||||
}
|
||||
|
||||
/// The Deserialize error can occur when loading a
|
||||
/// compiled Module from a binary.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum DeserializeError {
|
||||
/// An IO error
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
/// A generic deserialization error
|
||||
#[error("{0}")]
|
||||
Generic(String),
|
||||
/// Incompatible serialized binary
|
||||
#[error("incompatible binary: {0}")]
|
||||
Incompatible(String),
|
||||
/// The provided binary is corrupted
|
||||
#[error("corrupted binary: {0}")]
|
||||
CorruptedBinary(String),
|
||||
/// The binary was valid, but we got an error when
|
||||
/// trying to allocate the required resources.
|
||||
#[error(transparent)]
|
||||
Compiler(CompileError),
|
||||
}
|
||||
|
||||
/// An ImportError.
|
||||
///
|
||||
/// Note: this error is not standard to WebAssembly, but it's
|
||||
/// useful to determine the import issue on the API side.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ImportError {
|
||||
/// Incompatible Import Type.
|
||||
/// This error occurs when the import types mismatch.
|
||||
#[error("incompatible import type. Expected {0:?} but received {1:?}")]
|
||||
IncompatibleType(ExternType, ExternType),
|
||||
|
||||
/// Unknown Import.
|
||||
/// This error occurs when an import was expected but not provided.
|
||||
#[error("unknown import. Expected {0:?}")]
|
||||
UnknownImport(ExternType),
|
||||
}
|
||||
pub use wasmer_artifact::{DeserializeError, ImportError, SerializeError};
|
||||
|
||||
/// The WebAssembly.LinkError object indicates an error during
|
||||
/// module instantiation (besides traps from the start function).
|
||||
|
||||
@@ -31,11 +31,9 @@ mod resolver;
|
||||
mod trap;
|
||||
mod tunables;
|
||||
|
||||
pub use crate::artifact::{Artifact, MetadataHeader};
|
||||
pub use crate::artifact::Artifact;
|
||||
pub use crate::engine::{Engine, EngineId};
|
||||
pub use crate::error::{
|
||||
DeserializeError, ImportError, InstantiationError, LinkError, SerializeError,
|
||||
};
|
||||
pub use crate::error::{InstantiationError, LinkError};
|
||||
pub use crate::export::{Export, ExportFunction, ExportFunctionMetadata};
|
||||
pub use crate::resolver::{
|
||||
resolve_imports, ChainableNamedResolver, NamedResolver, NamedResolverChain, NullResolver,
|
||||
@@ -43,6 +41,8 @@ pub use crate::resolver::{
|
||||
};
|
||||
pub use crate::trap::*;
|
||||
pub use crate::tunables::Tunables;
|
||||
pub use wasmer_artifact::{ArtifactCreate, MetadataHeader};
|
||||
pub use wasmer_artifact::{DeserializeError, ImportError, SerializeError};
|
||||
|
||||
/// Version number of this crate.
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
@@ -2,6 +2,7 @@ use enum_iterator::IntoEnumIterator;
|
||||
use loupe::MemoryUsage;
|
||||
#[cfg(feature = "enable-rkyv")]
|
||||
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
|
||||
#[cfg(feature = "enable-serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
@@ -12,9 +13,8 @@ use std::fmt;
|
||||
feature = "enable-rkyv",
|
||||
derive(RkyvSerialize, RkyvDeserialize, Archive)
|
||||
)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, MemoryUsage, IntoEnumIterator,
|
||||
)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, MemoryUsage, IntoEnumIterator)]
|
||||
pub enum LibCall {
|
||||
/// ceil.f32
|
||||
CeilF32,
|
||||
|
||||
@@ -2,6 +2,7 @@ use crate::Pages;
|
||||
use loupe::MemoryUsage;
|
||||
#[cfg(feature = "enable-rkyv")]
|
||||
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
|
||||
#[cfg(feature = "enable-serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -48,11 +49,12 @@ pub enum MemoryError {
|
||||
}
|
||||
|
||||
/// Implementation styles for WebAssembly linear memory.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, MemoryUsage)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, MemoryUsage)]
|
||||
#[cfg_attr(
|
||||
feature = "enable-rkyv",
|
||||
derive(RkyvSerialize, RkyvDeserialize, Archive)
|
||||
)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum MemoryStyle {
|
||||
/// The actual memory can be resized and moved.
|
||||
Dynamic {
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
use loupe::MemoryUsage;
|
||||
#[cfg(feature = "enable-rkyv")]
|
||||
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
|
||||
#[cfg(feature = "enable-serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Implementation styles for WebAssembly tables.
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, MemoryUsage)]
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq, MemoryUsage)]
|
||||
#[cfg_attr(
|
||||
feature = "enable-rkyv",
|
||||
derive(RkyvSerialize, RkyvDeserialize, Archive)
|
||||
)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum TableStyle {
|
||||
/// Signatures are stored in the table and checked in the caller.
|
||||
CallerChecksSignature,
|
||||
|
||||
@@ -9,6 +9,7 @@ use core::str::FromStr;
|
||||
use loupe::MemoryUsage;
|
||||
#[cfg(feature = "enable-rkyv")]
|
||||
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
|
||||
#[cfg(feature = "enable-serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::error::Error;
|
||||
use thiserror::Error;
|
||||
@@ -16,11 +17,12 @@ use thiserror::Error;
|
||||
/// A trap code describing the reason for a trap.
|
||||
///
|
||||
/// All trap instructions have an explicit trap code.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, Error, MemoryUsage)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Error, MemoryUsage)]
|
||||
#[cfg_attr(
|
||||
feature = "enable-rkyv",
|
||||
derive(RkyvSerialize, RkyvDeserialize, Archive)
|
||||
)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
#[repr(u32)]
|
||||
pub enum TrapCode {
|
||||
/// The current stack space was exhausted.
|
||||
|
||||
@@ -12,6 +12,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../types", version = "=2.2.1" }
|
||||
wasmer-artifact = { path = "../artifact", version = "=2.2.1" }
|
||||
libc = { version = "^0.2", default-features = false }
|
||||
memoffset = "0.6"
|
||||
indexmap = { version = "1.6", features = ["serde-1"] }
|
||||
|
||||
@@ -50,12 +50,11 @@ pub use crate::sig_registry::SignatureRegistry;
|
||||
pub use crate::table::{LinearTable, Table, TableElement};
|
||||
pub use crate::trap::*;
|
||||
pub use crate::vmcontext::{
|
||||
VMCallerCheckedAnyfunc, VMContext, VMDynamicFunctionContext, VMFunctionBody,
|
||||
VMFunctionEnvironment, VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport,
|
||||
VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport,
|
||||
VMTrampoline,
|
||||
VMCallerCheckedAnyfunc, VMContext, VMDynamicFunctionContext, VMFunctionEnvironment,
|
||||
VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport, VMMemoryDefinition,
|
||||
VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMTrampoline,
|
||||
};
|
||||
use loupe::MemoryUsage;
|
||||
pub use wasmer_artifact::{FunctionBodyPtr, VMFunctionBody};
|
||||
pub use wasmer_types::LibCall;
|
||||
pub use wasmer_types::TableStyle;
|
||||
#[deprecated(
|
||||
@@ -71,28 +70,6 @@ pub use wasmer_types::{
|
||||
/// Version number of this crate.
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
/// A safe wrapper around `VMFunctionBody`.
|
||||
#[derive(Clone, Copy, Debug, MemoryUsage)]
|
||||
#[repr(transparent)]
|
||||
pub struct FunctionBodyPtr(pub *const VMFunctionBody);
|
||||
|
||||
impl std::ops::Deref for FunctionBodyPtr {
|
||||
type Target = *const VMFunctionBody;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// The VMFunctionBody that this points to is opaque, so there's no data to
|
||||
/// read or write through this pointer. This is essentially a usize.
|
||||
unsafe impl Send for FunctionBodyPtr {}
|
||||
/// # Safety
|
||||
/// The VMFunctionBody that this points to is opaque, so there's no data to
|
||||
/// read or write through this pointer. This is essentially a usize.
|
||||
unsafe impl Sync for FunctionBodyPtr {}
|
||||
|
||||
/// Pointers to section data.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(transparent)]
|
||||
|
||||
@@ -20,6 +20,7 @@ use std::mem;
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::sync::Arc;
|
||||
use std::u32;
|
||||
pub use wasmer_artifact::VMFunctionBody;
|
||||
|
||||
/// Union representing the first parameter passed when calling a function.
|
||||
///
|
||||
@@ -169,24 +170,6 @@ mod test_vmdynamicfunction_import_context {
|
||||
}
|
||||
}
|
||||
|
||||
/// A placeholder byte-sized type which is just used to provide some amount of type
|
||||
/// safety when dealing with pointers to JIT-compiled function bodies. Note that it's
|
||||
/// deliberately not Copy, as we shouldn't be carelessly copying function body bytes
|
||||
/// around.
|
||||
#[repr(C)]
|
||||
pub struct VMFunctionBody(u8);
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_vmfunction_body {
|
||||
use super::VMFunctionBody;
|
||||
use std::mem::size_of;
|
||||
|
||||
#[test]
|
||||
fn check_vmfunction_body_offsets() {
|
||||
assert_eq!(size_of::<VMFunctionBody>(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// A function kind is a calling convention into and out of wasm code.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, MemoryUsage)]
|
||||
#[repr(C)]
|
||||
@@ -799,9 +782,8 @@ pub struct VMSharedSignatureIndex(u32);
|
||||
#[cfg(test)]
|
||||
mod test_vmshared_signature_index {
|
||||
use super::VMSharedSignatureIndex;
|
||||
use crate::vmoffsets::{TargetSharedSignatureIndex, VMOffsets};
|
||||
use std::mem::size_of;
|
||||
use wasmer_types::ModuleInfo;
|
||||
use wasmer_types::{ModuleInfo, TargetSharedSignatureIndex, VMOffsets};
|
||||
|
||||
#[test]
|
||||
fn check_vmshared_signature_index() {
|
||||
|
||||
@@ -8,6 +8,7 @@ edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
wasmer-artifact = { path = "../../../lib/artifact", version = "=2.2.1" }
|
||||
wasmer-types = { path = "../../../lib/types", version = "=2.2.1" }
|
||||
wasmer-compiler = { path = "../../../lib/compiler", version = "=2.2.1" }
|
||||
wasmer-vm = { path = "../../../lib/vm", version = "=2.2.1" }
|
||||
|
||||
@@ -7,6 +7,7 @@ use loupe::MemoryUsage;
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
use wasmer_artifact::ArtifactCreate;
|
||||
#[cfg(feature = "compiler")]
|
||||
use wasmer_compiler::ModuleEnvironment;
|
||||
use wasmer_compiler::{CompileError, CpuFeature};
|
||||
@@ -193,7 +194,7 @@ impl DummyArtifact {
|
||||
}
|
||||
}
|
||||
|
||||
impl Artifact for DummyArtifact {
|
||||
impl ArtifactCreate for DummyArtifact {
|
||||
fn module(&self) -> Arc<ModuleInfo> {
|
||||
self.metadata.module.clone()
|
||||
}
|
||||
@@ -229,7 +230,25 @@ impl Artifact for DummyArtifact {
|
||||
fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle> {
|
||||
&self.metadata.table_styles
|
||||
}
|
||||
#[cfg(feature = "serialize")]
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
let bytes = bincode::serialize(&self.metadata)
|
||||
.map_err(|e| SerializeError::Generic(format!("{:?}", e)))?;
|
||||
|
||||
// Prepend the header.
|
||||
let mut serialized = Self::MAGIC_HEADER.to_vec();
|
||||
serialized.extend(bytes);
|
||||
Ok(serialized)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "serialize"))]
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
Err(SerializeError::Generic(
|
||||
"The serializer feature is not enabled in the DummyEngine",
|
||||
))
|
||||
}
|
||||
}
|
||||
impl Artifact for DummyArtifact {
|
||||
fn finished_functions(&self) -> &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr> {
|
||||
&self.finished_functions
|
||||
}
|
||||
@@ -249,22 +268,4 @@ impl Artifact for DummyArtifact {
|
||||
fn func_data_registry(&self) -> &FuncDataRegistry {
|
||||
&self.func_data_registry
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
let bytes = bincode::serialize(&self.metadata)
|
||||
.map_err(|e| SerializeError::Generic(format!("{:?}", e)))?;
|
||||
|
||||
// Prepend the header.
|
||||
let mut serialized = Self::MAGIC_HEADER.to_vec();
|
||||
serialized.extend(bytes);
|
||||
Ok(serialized)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "serialize"))]
|
||||
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
Err(SerializeError::Generic(
|
||||
"The serializer feature is not enabled in the DummyEngine",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user