Got half-baked engine

This commit is contained in:
Syrus
2020-05-02 18:41:05 -07:00
parent 9e107aa90d
commit d25f47d54d
27 changed files with 363 additions and 190 deletions

30
Cargo.lock generated
View File

@@ -353,6 +353,12 @@ dependencies = [
"generic-array",
]
[[package]]
name = "downcast-rs"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ba6eb47c2131e784a38b726eb54c1e1484904f013e576a25354d0124161af6"
[[package]]
name = "either"
version = "1.5.3"
@@ -1465,6 +1471,7 @@ dependencies = [
"wasmer-compiler-cranelift",
"wasmer-compiler-llvm",
"wasmer-compiler-singlepass",
"wasmer-engine",
"wasmer-jit",
"wasmer-runtime",
"wat",
@@ -1488,6 +1495,7 @@ dependencies = [
"wasmer-compiler-cranelift",
"wasmer-compiler-llvm",
"wasmer-compiler-singlepass",
"wasmer-engine",
"wasmer-jit",
"wasmer-wasi",
"wasmer-wasi-experimental-io-devices",
@@ -1574,6 +1582,27 @@ dependencies = [
"wasmer-runtime",
]
[[package]]
name = "wasmer-engine"
version = "0.16.2"
dependencies = [
"backtrace",
"bincode",
"downcast-rs",
"lazy_static",
"more-asserts",
"region",
"rustc-demangle",
"serde",
"serde_bytes",
"target-lexicon",
"thiserror",
"wasm-common",
"wasmer-compiler",
"wasmer-runtime",
"winapi",
]
[[package]]
name = "wasmer-jit"
version = "0.16.2"
@@ -1590,6 +1619,7 @@ dependencies = [
"thiserror",
"wasm-common",
"wasmer-compiler",
"wasmer-engine",
"wasmer-runtime",
"winapi",
]

View File

@@ -25,6 +25,7 @@ wasmer-compiler = { path = "lib/compiler" }
wasmer-compiler-cranelift = { path = "lib/compiler-cranelift", optional = true }
wasmer-compiler-singlepass = { path = "lib/compiler-singlepass", optional = true }
wasmer-compiler-llvm = { path = "lib/compiler-llvm", optional = true }
wasmer-engine = { path = "lib/engine" }
wasmer-jit = { path = "lib/jit" }
wasmer-wasi = { path = "lib/wasi", optional = true }
wasmer-wasi-experimental-io-devices = { path = "lib/wasi-experimental-io-devices", optional = true }

View File

@@ -14,6 +14,7 @@ wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "0.16.
wasmer-compiler-cranelift = { path = "../compiler-cranelift", version = "0.16.2", optional = true }
wasmer-compiler-llvm = { path = "../compiler-llvm", version = "0.16.2", optional = true }
wasmer-compiler = { path = "../compiler", version = "0.16.2" }
wasmer-engine = { path = "../engine", version = "0.16.2" }
wasmer-jit = { path = "../jit", version = "0.16.2" }
wasm-common = { path = "../wasm-common", version = "0.16.2" }
indexmap = { version = "1.3.2", features = ["serde-1"] }

View File

@@ -8,7 +8,7 @@ use std::{
ffi::c_void,
sync::{Arc, Mutex},
};
use wasmer_jit::Resolver;
use wasmer_engine::Resolver;
use wasmer_runtime::Export;
/// The `LikeNamespace` trait represents objects that act as a namespace for imports.

View File

@@ -3,7 +3,7 @@ use crate::externals::Extern;
use crate::module::Module;
use crate::store::Store;
use crate::InstantiationError;
use wasmer_jit::Resolver;
use wasmer_engine::Resolver;
use wasmer_runtime::InstanceHandle;
/// A WebAssembly Instance is a stateful, executable

View File

@@ -28,7 +28,7 @@ pub use crate::types::{
pub use wasm_common::{ValueType, WasmExternType, WasmTypeList};
pub use wasmer_compiler::{CompilerConfig, Features, Target};
pub use wasmer_jit::{
pub use wasmer_engine::{
DeserializeError, InstantiationError, LinkError, RuntimeError, SerializeError,
};

View File

@@ -6,7 +6,7 @@ use std::path::Path;
use std::sync::Arc;
use thiserror::Error;
use wasmer_compiler::{CompileError, WasmError};
use wasmer_jit::{CompiledModule, DeserializeError, Resolver, SerializeError};
use wasmer_engine::{CompiledModule, DeserializeError, Resolver, SerializeError};
use wasmer_runtime::InstanceHandle;
#[derive(Error, Debug)]
@@ -30,7 +30,7 @@ pub enum IoCompileError {
#[derive(Clone)]
pub struct Module {
store: Store,
compiled: Arc<CompiledModule>,
compiled: Arc<dyn CompiledModule>,
}
impl Module {
@@ -173,10 +173,11 @@ impl Module {
Ok(Self::from_compiled_module(store, compiled))
}
fn from_compiled_module(store: &Store, compiled: CompiledModule) -> Self {
fn from_compiled_module(store: &Store, compiled: Arc<CompiledModule>) -> Self
{
Module {
store: store.clone(),
compiled: Arc::new(compiled),
compiled,
}
}

View File

@@ -4,6 +4,7 @@ use target_lexicon::{OperatingSystem, PointerWidth, Triple, HOST};
use wasm_common::{MemoryType, Pages, TableType};
use wasmer_runtime::{LinearMemory, Table};
use wasmer_runtime::{MemoryPlan, MemoryStyle, TablePlan, TableStyle};
use wasmer_engine::Tunables as BaseTunables;
/// Tunable parameters for WebAssembly compilation.
#[derive(Clone)]
@@ -57,7 +58,7 @@ impl Tunables {
}
}
impl wasmer_jit::Tunables for Tunables {
impl BaseTunables for Tunables {
/// Get a `MemoryPlan` for the provided `MemoryType`
fn memory_plan(&self, memory: MemoryType) -> MemoryPlan {
// A heap with a maximum that doesn't exceed the static memory bound specified by the

34
lib/engine/Cargo.toml Normal file
View File

@@ -0,0 +1,34 @@
[package]
name = "wasmer-engine"
version = "0.16.2"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
description = "Wasmer Engine abstraction"
license = "(Apache-2.0 WITH LLVM-exception) or MIT"
categories = ["wasm"]
keywords = ["webassembly", "wasm"]
repository = "https://github.com/wasmerio/wasmer"
readme = "README.md"
edition = "2018"
[dependencies]
wasm-common = { path = "../wasm-common", version = "0.16.2" }
wasmer-compiler = { path = "../compiler", version = "0.16.2", default-features = false }
wasmer-runtime = { path = "../runtime", version = "0.16.2" }
target-lexicon = { version = "0.10.0", default-features = false }
# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" }
backtrace = "0.3.46"
rustc-demangle = "0.1.16"
more-asserts = "0.2.1"
thiserror = "1.0.16"
region = "2.1.2"
serde = { version = "1.0.106", sfeatures = ["derive", "rc"] }
serde_bytes = { version = "0.11.3" }
bincode = "1.2.1"
lazy_static = "1.4"
downcast-rs = "1.1.1"
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3.8", features = ["winnt", "impl-default"] }
[badges]
maintenance = { status = "actively-developed" }

12
lib/engine/README.md Normal file
View File

@@ -0,0 +1,12 @@
# Wasmer Engine
The Wasmer Engine is the general abstraction for Engines in Wasmer.
It currently has two implementations:
* Wasmer JIT
* Wasmer Native
### Acknowledgments
This project borrowed some of the code of the trap implementation from the [wasmtime-api](https://crates.io/crates/wasmtime), the code since then has evolved significantly.
Please check [Wasmer ATTRIBUTIONS](https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md) to further see licenses and other attributions of the project.

49
lib/engine/src/engine.rs Normal file
View File

@@ -0,0 +1,49 @@
//! JIT compilation.
use crate::error::InstantiationError;
use crate::resolver::Resolver;
use crate::tunables::Tunables;
use crate::{CompiledModule, DeserializeError, SerializeError};
use std::sync::Arc;
use wasm_common::FuncType;
use wasmer_compiler::CompileError;
use wasmer_runtime::{InstanceHandle, VMSharedSignatureIndex, VMTrampoline};
/// A unimplemented Wasmer `Engine`.
/// This trait is used by implementors to implement custom engines,
/// such as: JIT or Native.
pub trait Engine {
/// The `CompiledModule` type
type Product: CompiledModule;
/// Get the tunables
fn tunables(&self) -> &Tunables;
/// Register a signature
fn register_signature(&self, func_type: &FuncType) -> VMSharedSignatureIndex;
/// Lookup a signature
fn lookup_signature(&self, sig: VMSharedSignatureIndex) -> Option<FuncType>;
/// Retrieves a trampoline given a signature
fn trampoline(&self, sig: VMSharedSignatureIndex) -> Option<VMTrampoline>;
/// Validates a WebAssembly module
fn validate(&self, binary: &[u8]) -> Result<(), CompileError>;
/// Compile a WebAssembly binary
fn compile(&self, binary: &[u8]) -> Result<Self::Product, CompileError>;
/// Instantiates a WebAssembly module
fn instantiate(
&self,
compiled_module: &Arc<Self::Product>,
resolver: &dyn Resolver,
) -> Result<InstanceHandle, InstantiationError>;
/// Serializes a WebAssembly module
fn serialize(&self, compiled_module: &Arc<Self::Product>) -> Result<Vec<u8>, SerializeError>;
/// Deserializes a WebAssembly module
fn deserialize(&self, bytes: &[u8]) -> Result<Self::Product, DeserializeError>;
}

View File

@@ -1,4 +1,3 @@
// TODO: Move this errors into a common engine crate.
//! The WebAssembly possible errors
use crate::trap::RuntimeError;
use thiserror::Error;

45
lib/engine/src/lib.rs Normal file
View File

@@ -0,0 +1,45 @@
//! Generic Engine abstraction for Wasmer Engines.
#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
#![warn(unused_import_braces)]
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
#![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 engine;
mod error;
mod module;
mod resolver;
mod serialize;
mod trap;
mod tunables;
pub use crate::engine::Engine;
pub use crate::error::{
DeserializeError, ImportError, InstantiationError, LinkError, SerializeError,
};
pub use crate::module::CompiledModule;
pub use crate::resolver::{resolve_imports, NullResolver, Resolver};
pub use crate::trap::*;
pub use crate::tunables::Tunables;
pub use crate::serialize::SerializableFunctionFrameInfo;
pub use wasmer_compiler::CompilerConfig;
/// Version number of this crate.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

19
lib/engine/src/module.rs Normal file
View File

@@ -0,0 +1,19 @@
use std::sync::Arc;
use wasmer_runtime::Module;
use downcast_rs::{DowncastSync, impl_downcast};
/// The `CompiledModule` trait is used by engine implementors, such
/// as a JIT or Native execution.
pub trait CompiledModule: DowncastSync {
/// Return a reference-counting pointer to a module.
fn module(&self) -> &Arc<Module>;
/// Return a reference-counting pointer to a module.
fn module_mut(&mut self) -> &mut Arc<Module>;
/// Return a reference to a module.
fn module_ref(&self) -> &Module;
}
impl_downcast!(sync CompiledModule); // `sync` => also produce `Arc` downcasts.

107
lib/engine/src/serialize.rs Normal file
View File

@@ -0,0 +1,107 @@
use serde::de::{Deserializer, Visitor};
use serde::ser::Serializer;
use serde::{Deserialize, Serialize};
use std::fmt;
use wasmer_compiler::CompiledFunctionFrameInfo;
/// This is the unserialized verison of `CompiledFunctionFrameInfo`.
#[derive(Clone, Serialize, Deserialize)]
#[serde(transparent)]
#[repr(transparent)]
pub struct UnprocessedFunctionFrameInfo {
#[serde(with = "serde_bytes")]
bytes: Vec<u8>,
}
impl UnprocessedFunctionFrameInfo {
/// Converts the `UnprocessedFunctionFrameInfo` to a `CompiledFunctionFrameInfo`
pub fn deserialize(&self) -> CompiledFunctionFrameInfo {
// let r = flexbuffers::Reader::get_root(&self.bytes).expect("Can't deserialize the info");
// CompiledFunctionFrameInfo::deserialize(r).expect("Can't deserialize the info")
bincode::deserialize(&self.bytes).expect("Can't deserialize the info")
}
/// Converts the `CompiledFunctionFrameInfo` to a `UnprocessedFunctionFrameInfo`
pub fn serialize(processed: &CompiledFunctionFrameInfo) -> Self {
// let mut s = flexbuffers::FlexbufferSerializer::new();
// processed
// .serialize(&mut s)
// .expect("Can't serialize the info");
// let bytes = s.take_buffer();
let bytes = bincode::serialize(&processed).expect("Can't serialize the info");
Self { bytes }
}
}
/// We hold the frame info in two states, mainly because we want to
/// process it lazily to speed up execution.
///
/// When a Trap occurs, we process the frame info lazily for each
/// function in the frame. That way we minimize as much as we can
/// the upfront effort.
///
/// The data can also be processed upfront. This will happen in the case
/// of compiling at the same time that emiting the JIT.
/// In that case, we don't need to deserialize/process anything
/// as the data is already in memory.
#[derive(Clone)]
pub enum SerializableFunctionFrameInfo {
/// The unprocessed frame info (binary)
Unprocessed(UnprocessedFunctionFrameInfo),
/// The processed frame info (memory struct)
Processed(CompiledFunctionFrameInfo),
}
impl SerializableFunctionFrameInfo {
/// Returns true if the extra function info is not yet
/// processed
pub fn is_unprocessed(&self) -> bool {
match self {
Self::Unprocessed(_) => true,
_ => false,
}
}
}
// Below:
// The custom ser/de for `SerializableFunctionFrameInfo`.
impl Serialize for SerializableFunctionFrameInfo {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let unprocessed = match self {
Self::Processed(processed) => UnprocessedFunctionFrameInfo::serialize(processed),
Self::Unprocessed(unprocessed) => unprocessed.clone(),
};
s.serialize_bytes(&unprocessed.bytes)
}
}
struct FunctionFrameInfoVisitor;
impl<'de> Visitor<'de> for FunctionFrameInfoVisitor {
type Value = UnprocessedFunctionFrameInfo;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("bytes")
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> {
Ok(UnprocessedFunctionFrameInfo { bytes: v })
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> {
Ok(UnprocessedFunctionFrameInfo { bytes: v.to_vec() })
}
}
impl<'de> Deserialize<'de> for SerializableFunctionFrameInfo {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(SerializableFunctionFrameInfo::Unprocessed(
deserializer.deserialize_byte_buf(FunctionFrameInfoVisitor)?,
))
}
}

View File

@@ -0,0 +1,4 @@
mod error;
mod frame_info;
pub use error::RuntimeError;
pub use frame_info::{register as register_frame_info, FrameInfo, GlobalFrameInfoRegistration, FRAME_INFO};

View File

@@ -14,6 +14,7 @@ edition = "2018"
wasm-common = { path = "../wasm-common", version = "0.16.2" }
wasmer-compiler = { path = "../compiler", version = "0.16.2", default-features = false }
wasmer-runtime = { path = "../runtime", version = "0.16.2" }
wasmer-engine = { path = "../engine", version = "0.16.2" }
target-lexicon = { version = "0.10.0", default-features = false }
# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" }
backtrace = "0.3.46"

View File

@@ -1,10 +1,7 @@
//! JIT compilation.
use crate::error::InstantiationError;
use crate::resolver::Resolver;
use crate::tunables::Tunables;
use crate::CodeMemory;
use crate::{CompiledModule, DeserializeError, SerializeError};
use wasmer_engine::{Engine, InstantiationError, Resolver, Tunables, DeserializeError, SerializeError, CompiledModule as BaseCompiledModule};
use crate::{CodeMemory, CompiledModule};
use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::Arc;
@@ -12,7 +9,7 @@ use wasm_common::entity::PrimaryMap;
use wasm_common::{FuncType, LocalFuncIndex, MemoryIndex, TableIndex};
use wasmer_compiler::{
Compilation, CompileError, Compiler as BaseCompiler, CompilerConfig, FunctionBody,
FunctionBodyData, ModuleTranslationState, Target,
FunctionBodyData, ModuleTranslationState,
};
use wasmer_runtime::{
InstanceHandle, MemoryPlan, Module, SignatureRegistry, TablePlan, VMFunctionBody,
@@ -44,11 +41,6 @@ impl JITEngine {
}
}
/// Get the tunables
pub fn tunables(&self) -> &dyn Tunables {
&**self.tunables
}
pub(crate) fn compiler(&self) -> std::cell::Ref<'_, JITEngineInner> {
self.inner.borrow()
}
@@ -57,6 +49,13 @@ impl JITEngine {
self.inner.borrow_mut()
}
/// Get the tunables
pub fn tunables(&self) -> &dyn Tunables {
&**self.tunables
}
// }
// impl Engine for JITEngine {
/// Register a signature
pub fn register_signature(&self, func_type: &FuncType) -> VMSharedSignatureIndex {
let compiler = self.compiler();
@@ -80,27 +79,30 @@ impl JITEngine {
}
/// Compile a WebAssembly binary
pub fn compile(&self, binary: &[u8]) -> Result<CompiledModule, CompileError> {
CompiledModule::new(&self, binary)
pub fn compile(&self, binary: &[u8]) -> Result<Arc<dyn BaseCompiledModule>, CompileError> {
Ok(Arc::new(CompiledModule::new(&self, binary)?))
}
/// Instantiates a WebAssembly module
pub fn instantiate(
&self,
compiled_module: &CompiledModule,
compiled_module: &Arc<dyn BaseCompiledModule>,
resolver: &dyn Resolver,
) -> Result<InstanceHandle, InstantiationError> {
) -> Result<InstanceHandle, InstantiationError>
{
let compiled_module = compiled_module.downcast_ref::<CompiledModule>().unwrap();
unsafe { compiled_module.instantiate(&self, resolver, Box::new(())) }
}
/// Serializes a WebAssembly module
pub fn serialize(&self, compiled_module: &CompiledModule) -> Result<Vec<u8>, SerializeError> {
pub fn serialize(&self, compiled_module: &Arc<dyn BaseCompiledModule>) -> Result<Vec<u8>, SerializeError> {
let compiled_module = compiled_module.downcast_ref::<CompiledModule>().unwrap();
compiled_module.serialize()
}
/// Deserializes a WebAssembly module
pub fn deserialize(&self, bytes: &[u8]) -> Result<CompiledModule, DeserializeError> {
CompiledModule::deserialize(&self, bytes)
pub fn deserialize(&self, bytes: &[u8]) -> Result<Arc<dyn BaseCompiledModule>, DeserializeError> {
Ok(Arc::new(CompiledModule::deserialize(&self, bytes)?))
}
}

View File

@@ -27,28 +27,16 @@
mod code_memory;
mod engine;
mod error;
mod function_table;
mod link;
mod module;
mod resolver;
mod serialize;
mod trap;
mod tunables;
pub use crate::code_memory::CodeMemory;
pub use crate::engine::JITEngine;
pub use crate::error::{
DeserializeError, ImportError, InstantiationError, LinkError, SerializeError,
};
pub use crate::function_table::FunctionTable;
pub use crate::link::link_module;
pub use crate::module::CompiledModule;
pub use crate::resolver::{resolve_imports, NullResolver, Resolver};
pub use crate::trap::*;
pub use crate::tunables::Tunables;
pub use wasmer_compiler::CompilerConfig;
/// Version number of this crate.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

View File

@@ -7,9 +7,8 @@ use wasmer_compiler::{JumpTable, JumpTableOffsets, RelocationKind, RelocationTar
use wasmer_runtime::Module;
use wasmer_runtime::VMFunctionBody;
/// Links a module that has been compiled with `compiled_module` in `wasmer-compiler::Compiler`.
///
/// Performs all required relocations inside the function code, provided the necessary metadata.
/// Links a module, patching the allocated functions with the
/// requiredd relocations and jump tables.
pub fn link_module(
module: &Module,
allocated_functions: &PrimaryMap<LocalFuncIndex, *mut [VMFunctionBody]>,
@@ -68,10 +67,8 @@ pub fn link_module(
.wrapping_add(reloc_addend as u32);
write_unaligned(reloc_address as *mut u32, reloc_delta_u32);
}
RelocationKind::X86PCRelRodata4 => {
// ignore
}
_ => panic!("unsupported reloc kind"),
RelocationKind::X86PCRelRodata4 => {}
_ => panic!("Relocation kind unsupported"),
}
}
}

View File

@@ -4,16 +4,14 @@
//! steps.
use crate::engine::{JITEngine, JITEngineInner};
use crate::error::{DeserializeError, SerializeError};
use crate::error::{InstantiationError, LinkError};
use crate::link::link_module;
use crate::resolver::{resolve_imports, Resolver};
use crate::serialize::{
SerializableCompilation, SerializableFunctionFrameInfo, SerializableModule,
use wasmer_engine::{DeserializeError, SerializeError, InstantiationError, LinkError, SerializableFunctionFrameInfo,
resolve_imports, Resolver, register_frame_info, GlobalFrameInfoRegistration, RuntimeError,
CompiledModule as BaseCompiledModule
};
use crate::link::link_module;
use crate::serialize::{
SerializableCompilation, SerializableModule,
};
use crate::trap::register as register_frame_info;
use crate::trap::GlobalFrameInfoRegistration;
use crate::trap::RuntimeError;
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::sync::{Arc, Mutex};
@@ -168,15 +166,7 @@ impl CompiledModule {
&self.serializable.table_plans
}
/// Crate an `Instance` from this `CompiledModule`.
///
/// Note that if only one instance of this module is needed, it may be more
/// efficient to call the top-level `instantiate`, since that avoids copying
/// the data initializers.
///
/// # Unsafety
///
/// See `InstanceHandle::new`
/// Instantiate the module
pub unsafe fn instantiate(
&self,
jit: &JITEngine,
@@ -227,21 +217,6 @@ impl CompiledModule {
.map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))
}
/// Return a reference-counting pointer to a module.
pub fn module(&self) -> &Arc<Module> {
&self.serializable.module
}
/// Return a reference-counting pointer to a module.
pub fn module_mut(&mut self) -> &mut Arc<Module> {
&mut self.serializable.module
}
/// Return a reference to a module.
pub fn module_ref(&self) -> &Module {
&self.serializable.module
}
/// Register this module's stack frame information into the global scope.
///
/// This is required to ensure that any traps can be properly symbolicated.
@@ -259,6 +234,22 @@ impl CompiledModule {
));
}
}
unsafe impl Sync for CompiledModule {}
unsafe impl Send for CompiledModule {}
impl BaseCompiledModule for CompiledModule {
fn module(&self) -> &Arc<Module> {
&self.serializable.module
}
fn module_mut(&mut self) -> &mut Arc<Module> {
&mut self.serializable.module
}
fn module_ref(&self) -> &Module {
&self.serializable.module
}
}
/// Allocate memory for just the memories of the current module.
fn create_memories(

View File

@@ -1,11 +1,8 @@
use serde::de::{Deserializer, Visitor};
use serde::ser::Serializer;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::sync::Arc;
use wasmer_compiler::{CompiledFunctionFrameInfo, FunctionBody, JumpTableOffsets, Relocation};
use wasmer_compiler::{FunctionBody, JumpTableOffsets, Relocation};
use wasmer_runtime::Module;
use wasmer_engine::SerializableFunctionFrameInfo;
use wasm_common::entity::PrimaryMap;
use wasm_common::{LocalFuncIndex, MemoryIndex, OwnedDataInitializer, TableIndex};
use wasmer_runtime::{MemoryPlan, TablePlan};
@@ -33,105 +30,3 @@ pub struct SerializableModule {
pub memory_plans: PrimaryMap<MemoryIndex, MemoryPlan>,
pub table_plans: PrimaryMap<TableIndex, TablePlan>,
}
/// This is the unserialized verison of `CompiledFunctionFrameInfo`.
#[derive(Clone, Serialize, Deserialize)]
#[serde(transparent)]
#[repr(transparent)]
pub struct UnprocessedFunctionFrameInfo {
#[serde(with = "serde_bytes")]
bytes: Vec<u8>,
}
impl UnprocessedFunctionFrameInfo {
/// Converts the `UnprocessedFunctionFrameInfo` to a `CompiledFunctionFrameInfo`
pub fn deserialize(&self) -> CompiledFunctionFrameInfo {
// let r = flexbuffers::Reader::get_root(&self.bytes).expect("Can't deserialize the info");
// CompiledFunctionFrameInfo::deserialize(r).expect("Can't deserialize the info")
bincode::deserialize(&self.bytes).expect("Can't deserialize the info")
}
/// Converts the `CompiledFunctionFrameInfo` to a `UnprocessedFunctionFrameInfo`
pub fn serialize(processed: &CompiledFunctionFrameInfo) -> Self {
// let mut s = flexbuffers::FlexbufferSerializer::new();
// processed
// .serialize(&mut s)
// .expect("Can't serialize the info");
// let bytes = s.take_buffer();
let bytes = bincode::serialize(&processed).expect("Can't serialize the info");
Self { bytes }
}
}
/// We hold the frame info in two states, mainly because we want to
/// process it lazily to speed up execution.
///
/// When a Trap occurs, we process the frame info lazily for each
/// function in the frame. That way we minimize as much as we can
/// the upfront effort.
///
/// The data can also be processed upfront. This will happen in the case
/// of compiling at the same time that emiting the JIT.
/// In that case, we don't need to deserialize/process anything
/// as the data is already in memory.
#[derive(Clone)]
pub enum SerializableFunctionFrameInfo {
/// The unprocessed frame info (binary)
Unprocessed(UnprocessedFunctionFrameInfo),
/// The processed frame info (memory struct)
Processed(CompiledFunctionFrameInfo),
}
impl SerializableFunctionFrameInfo {
/// Returns true if the extra function info is not yet
/// processed
pub fn is_unprocessed(&self) -> bool {
match self {
Self::Unprocessed(_) => true,
_ => false,
}
}
}
// Below:
// The custom ser/de for `SerializableFunctionFrameInfo`.
impl Serialize for SerializableFunctionFrameInfo {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let unprocessed = match self {
Self::Processed(processed) => UnprocessedFunctionFrameInfo::serialize(processed),
Self::Unprocessed(unprocessed) => unprocessed.clone(),
};
s.serialize_bytes(&unprocessed.bytes)
}
}
struct FunctionFrameInfoVisitor;
impl<'de> Visitor<'de> for FunctionFrameInfoVisitor {
type Value = UnprocessedFunctionFrameInfo;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("bytes")
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> {
Ok(UnprocessedFunctionFrameInfo { bytes: v })
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> {
Ok(UnprocessedFunctionFrameInfo { bytes: v.to_vec() })
}
}
impl<'de> Deserialize<'de> for SerializableFunctionFrameInfo {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(SerializableFunctionFrameInfo::Unprocessed(
deserializer.deserialize_byte_buf(FunctionFrameInfoVisitor)?,
))
}
}

View File

@@ -1,4 +0,0 @@
mod error;
mod frame_info;
pub use error::RuntimeError;
pub use frame_info::{register, FrameInfo, GlobalFrameInfoRegistration, FRAME_INFO};