mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-24 06:01:33 +00:00
Merge branch 'master' into deterministic
This commit is contained in:
@ -1,3 +1,7 @@
|
||||
//! The codegen module provides common functions and data structures used by multiple backends
|
||||
//! during the code generation process.
|
||||
#[cfg(unix)]
|
||||
use crate::fault::FaultInfo;
|
||||
use crate::{
|
||||
backend::RunnableModule,
|
||||
backend::{Backend, CacheGen, Compiler, CompilerConfig, Features, Token},
|
||||
@ -17,22 +21,35 @@ use std::sync::{Arc, RwLock};
|
||||
use wasmparser::{self, WasmDecoder};
|
||||
use wasmparser::{Operator, Type as WpType};
|
||||
|
||||
/// A type that defines a function pointer, which is called when breakpoints occur.
|
||||
pub type BreakpointHandler =
|
||||
Box<dyn Fn(BreakpointInfo) -> Result<(), Box<dyn Any>> + Send + Sync + 'static>;
|
||||
|
||||
/// Maps instruction pointers to their breakpoint handlers.
|
||||
pub type BreakpointMap = Arc<HashMap<usize, BreakpointHandler>>;
|
||||
|
||||
/// An event generated during parsing of a wasm binary
|
||||
#[derive(Debug)]
|
||||
pub enum Event<'a, 'b> {
|
||||
/// An internal event created by the parser used to provide hooks during code generation.
|
||||
Internal(InternalEvent),
|
||||
/// An event generated by parsing a wasm operator
|
||||
Wasm(&'b Operator<'a>),
|
||||
/// An event generated by parsing a wasm operator that contains an owned `Operator`
|
||||
WasmOwned(Operator<'a>),
|
||||
}
|
||||
|
||||
/// Kinds of `InternalEvent`s created during parsing.
|
||||
pub enum InternalEvent {
|
||||
/// A function parse is about to begin.
|
||||
FunctionBegin(u32),
|
||||
/// A function parsing has just completed.
|
||||
FunctionEnd,
|
||||
/// A breakpoint emitted during parsing.
|
||||
Breakpoint(BreakpointHandler),
|
||||
/// Indicates setting an internal field.
|
||||
SetInternal(u32),
|
||||
/// Indicates getting an internal field.
|
||||
GetInternal(u32),
|
||||
}
|
||||
|
||||
@ -48,14 +65,32 @@ impl fmt::Debug for InternalEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/// Information for a breakpoint
|
||||
#[cfg(unix)]
|
||||
pub struct BreakpointInfo<'a> {
|
||||
pub fault: Option<&'a dyn Any>,
|
||||
/// Fault.
|
||||
pub fault: Option<&'a FaultInfo>,
|
||||
}
|
||||
|
||||
/// Information for a breakpoint
|
||||
#[cfg(not(unix))]
|
||||
pub struct BreakpointInfo {
|
||||
/// Fault placeholder.
|
||||
pub fault: Option<()>,
|
||||
}
|
||||
|
||||
/// A trait that represents the functions needed to be implemented to generate code for a module.
|
||||
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule, E: Debug> {
|
||||
/// Creates a new module code generator.
|
||||
fn new() -> Self;
|
||||
|
||||
/// Creates a new module code generator for specified target.
|
||||
fn new_with_target(
|
||||
triple: Option<String>,
|
||||
cpu_name: Option<String>,
|
||||
cpu_features: Option<String>,
|
||||
) -> Self;
|
||||
|
||||
/// Returns the backend id associated with this MCG.
|
||||
fn backend_id() -> Backend;
|
||||
|
||||
@ -65,7 +100,7 @@ pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule,
|
||||
}
|
||||
/// Adds an import function.
|
||||
fn feed_import_function(&mut self) -> Result<(), E>;
|
||||
|
||||
/// Sets the signatures.
|
||||
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), E>;
|
||||
/// Sets function signatures.
|
||||
fn feed_function_signatures(&mut self, assoc: Map<FuncIndex, SigIndex>) -> Result<(), E>;
|
||||
@ -80,6 +115,8 @@ pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule,
|
||||
unsafe fn from_cache(cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>;
|
||||
}
|
||||
|
||||
/// A streaming compiler which is designed to generated code for a module based on a stream
|
||||
/// of wasm parser events.
|
||||
pub struct StreamingCompiler<
|
||||
MCG: ModuleCodeGenerator<FCG, RM, E>,
|
||||
FCG: FunctionCodeGenerator<E>,
|
||||
@ -94,6 +131,7 @@ pub struct StreamingCompiler<
|
||||
_phantom_e: PhantomData<E>,
|
||||
}
|
||||
|
||||
/// A simple generator for a `StreamingCompiler`.
|
||||
pub struct SimpleStreamingCompilerGen<
|
||||
MCG: ModuleCodeGenerator<FCG, RM, E>,
|
||||
FCG: FunctionCodeGenerator<E>,
|
||||
@ -113,6 +151,7 @@ impl<
|
||||
E: Debug,
|
||||
> SimpleStreamingCompilerGen<MCG, FCG, RM, E>
|
||||
{
|
||||
/// Create a new `StreamingCompiler`.
|
||||
pub fn new() -> StreamingCompiler<MCG, FCG, RM, E, impl Fn() -> MiddlewareChain> {
|
||||
StreamingCompiler::new(|| MiddlewareChain::new())
|
||||
}
|
||||
@ -126,6 +165,7 @@ impl<
|
||||
CGEN: Fn() -> MiddlewareChain,
|
||||
> StreamingCompiler<MCG, FCG, RM, E, CGEN>
|
||||
{
|
||||
/// Create a new `StreamingCompiler` with the given `MiddlewareChain`.
|
||||
pub fn new(chain_gen: CGEN) -> Self {
|
||||
Self {
|
||||
middleware_chain_generator: chain_gen,
|
||||
@ -137,6 +177,7 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new `ValidatingParserConfig` with the given features.
|
||||
pub fn validating_parser_config(features: &Features) -> wasmparser::ValidatingParserConfig {
|
||||
wasmparser::ValidatingParserConfig {
|
||||
operator_config: wasmparser::OperatorValidatorConfig {
|
||||
@ -185,7 +226,14 @@ impl<
|
||||
validate_with_features(wasm, &compiler_config.features)?;
|
||||
}
|
||||
|
||||
let mut mcg = MCG::new();
|
||||
let mut mcg = match MCG::backend_id() {
|
||||
Backend::LLVM => MCG::new_with_target(
|
||||
compiler_config.triple.clone(),
|
||||
compiler_config.cpu_name.clone(),
|
||||
compiler_config.cpu_features.clone(),
|
||||
),
|
||||
_ => MCG::new(),
|
||||
};
|
||||
let mut chain = (self.middleware_chain_generator)();
|
||||
let info = crate::parse::read_module(
|
||||
wasm,
|
||||
@ -218,34 +266,41 @@ impl<
|
||||
fn requires_pre_validation(backend: Backend) -> bool {
|
||||
match backend {
|
||||
Backend::Cranelift => true,
|
||||
Backend::LLVM => false,
|
||||
Backend::LLVM => true,
|
||||
Backend::Singlepass => false,
|
||||
Backend::Auto => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// A sink for parse events.
|
||||
pub struct EventSink<'a, 'b> {
|
||||
buffer: SmallVec<[Event<'a, 'b>; 2]>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> EventSink<'a, 'b> {
|
||||
/// Push a new `Event` to this sink.
|
||||
pub fn push(&mut self, ev: Event<'a, 'b>) {
|
||||
self.buffer.push(ev);
|
||||
}
|
||||
}
|
||||
|
||||
/// A container for a chain of middlewares.
|
||||
pub struct MiddlewareChain {
|
||||
chain: Vec<Box<dyn GenericFunctionMiddleware>>,
|
||||
}
|
||||
|
||||
impl MiddlewareChain {
|
||||
/// Create a new empty `MiddlewareChain`.
|
||||
pub fn new() -> MiddlewareChain {
|
||||
MiddlewareChain { chain: vec![] }
|
||||
}
|
||||
|
||||
/// Push a new `FunctionMiddleware` to this `MiddlewareChain`.
|
||||
pub fn push<M: FunctionMiddleware + 'static>(&mut self, m: M) {
|
||||
self.chain.push(Box::new(m));
|
||||
}
|
||||
|
||||
/// Run this chain with the provided function code generator, event and module info.
|
||||
pub(crate) fn run<E: Debug, FCG: FunctionCodeGenerator<E>>(
|
||||
&mut self,
|
||||
fcg: Option<&mut FCG>,
|
||||
@ -273,8 +328,11 @@ impl MiddlewareChain {
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait that represents the signature required to implement middleware for a function.
|
||||
pub trait FunctionMiddleware {
|
||||
/// The error type for this middleware's functions.
|
||||
type Error: Debug;
|
||||
/// Processes the given event, module info and sink.
|
||||
fn feed_event<'a, 'b: 'a>(
|
||||
&mut self,
|
||||
op: Event<'a, 'b>,
|
||||
|
Reference in New Issue
Block a user