4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,3 +1,7 @@
|
|||||||
[submodule "spec_testsuite"]
|
[submodule "spec_testsuite"]
|
||||||
path = spec_testsuite
|
path = spec_testsuite
|
||||||
url = https://github.com/WebAssembly/testsuite
|
url = https://github.com/WebAssembly/testsuite
|
||||||
|
[submodule "lightbeam"]
|
||||||
|
path = lightbeam
|
||||||
|
url = https://github.com/CraneStation/lightbeam.git
|
||||||
|
branch = master
|
||||||
|
|||||||
@@ -44,3 +44,6 @@ libc = "0.2.50"
|
|||||||
errno = "0.2.4"
|
errno = "0.2.4"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
lightbeam = ["wasmtime-environ/lightbeam", "wasmtime-jit/lightbeam"]
|
||||||
|
|||||||
1
lightbeam
Submodule
1
lightbeam
Submodule
Submodule lightbeam added at 762cd3fb32
Submodule spec_testsuite updated: 89cc463fa1...b2800641d6
@@ -49,7 +49,7 @@ use std::str;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use target_lexicon::Triple;
|
use target_lexicon::Triple;
|
||||||
use wasmtime_debug::{emit_debugsections, read_debuginfo};
|
use wasmtime_debug::{emit_debugsections, read_debuginfo};
|
||||||
use wasmtime_environ::{cranelift, ModuleEnvironment, Tunables};
|
use wasmtime_environ::{Compiler, Cranelift, ModuleEnvironment, Tunables};
|
||||||
use wasmtime_obj::emit_module;
|
use wasmtime_obj::emit_module;
|
||||||
|
|
||||||
const USAGE: &str = "
|
const USAGE: &str = "
|
||||||
@@ -159,7 +159,7 @@ fn handle_module(
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (compilation, relocations, address_transform) = cranelift::compile_module(
|
let (compilation, relocations, address_transform) = Cranelift::compile_module(
|
||||||
&module,
|
&module,
|
||||||
lazy_function_body_inputs,
|
lazy_function_body_inputs,
|
||||||
&*isa,
|
&*isa,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ edition = "2018"
|
|||||||
cranelift-codegen = "0.30.0"
|
cranelift-codegen = "0.30.0"
|
||||||
cranelift-entity = "0.30.0"
|
cranelift-entity = "0.30.0"
|
||||||
cranelift-wasm = "0.30.0"
|
cranelift-wasm = "0.30.0"
|
||||||
|
lightbeam = { path = "../lightbeam", optional = true }
|
||||||
cast = { version = "0.2.2", default-features = false }
|
cast = { version = "0.2.2", default-features = false }
|
||||||
failure = { version = "0.1.3", default-features = false }
|
failure = { version = "0.1.3", default-features = false }
|
||||||
failure_derive = { version = "0.1.3", default-features = false }
|
failure_derive = { version = "0.1.3", default-features = false }
|
||||||
|
|||||||
@@ -1,25 +1,71 @@
|
|||||||
//! A `Compilation` contains the compiled function bodies for a WebAssembly
|
//! A `Compilation` contains the compiled function bodies for a WebAssembly
|
||||||
//! module.
|
//! module.
|
||||||
|
|
||||||
use cranelift_codegen::binemit;
|
use crate::module;
|
||||||
use cranelift_codegen::ir;
|
use crate::module_environ::FunctionBodyData;
|
||||||
use cranelift_codegen::CodegenError;
|
use cranelift_codegen::{binemit, ir, isa, CodegenError};
|
||||||
use cranelift_entity::PrimaryMap;
|
use cranelift_entity::PrimaryMap;
|
||||||
use cranelift_wasm::{DefinedFuncIndex, FuncIndex, WasmError};
|
use cranelift_wasm::{DefinedFuncIndex, FuncIndex, WasmError};
|
||||||
|
use std::ops::Range;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
|
type Functions = PrimaryMap<DefinedFuncIndex, Vec<u8>>;
|
||||||
|
|
||||||
/// The result of compiling a WebAssembly module's functions.
|
/// The result of compiling a WebAssembly module's functions.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Compilation {
|
pub struct Compilation {
|
||||||
/// Compiled machine code for the function bodies.
|
/// Compiled machine code for the function bodies.
|
||||||
pub functions: PrimaryMap<DefinedFuncIndex, Vec<u8>>,
|
functions: Functions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Compilation {
|
impl Compilation {
|
||||||
/// Allocates the compilation result with the given function bodies.
|
/// Creates a compilation artifact from a contiguous function buffer and a set of ranges
|
||||||
pub fn new(functions: PrimaryMap<DefinedFuncIndex, Vec<u8>>) -> Self {
|
pub fn new(functions: Functions) -> Self {
|
||||||
Self { functions }
|
Self { functions }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocates the compilation result with the given function bodies.
|
||||||
|
pub fn from_buffer(buffer: Vec<u8>, functions: impl IntoIterator<Item = Range<usize>>) -> Self {
|
||||||
|
Self::new(
|
||||||
|
functions
|
||||||
|
.into_iter()
|
||||||
|
.map(|range| buffer[range].to_vec())
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the bytes of a single function
|
||||||
|
pub fn get(&self, func: DefinedFuncIndex) -> &[u8] {
|
||||||
|
&self.functions[func]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the number of functions defined.
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.functions.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> IntoIterator for &'a Compilation {
|
||||||
|
type IntoIter = Iter<'a>;
|
||||||
|
type Item = <Self::IntoIter as Iterator>::Item;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
Iter {
|
||||||
|
iterator: self.functions.iter(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Iter<'a> {
|
||||||
|
iterator: <&'a Functions as IntoIterator>::IntoIter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for Iter<'a> {
|
||||||
|
type Item = &'a [u8];
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.iterator.next().map(|(_, b)| &b[..])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A record of a relocation to perform.
|
/// A record of a relocation to perform.
|
||||||
@@ -95,3 +141,14 @@ pub struct FunctionAddressTransform {
|
|||||||
|
|
||||||
/// Function AddressTransforms collection.
|
/// Function AddressTransforms collection.
|
||||||
pub type AddressTransforms = PrimaryMap<DefinedFuncIndex, FunctionAddressTransform>;
|
pub type AddressTransforms = PrimaryMap<DefinedFuncIndex, FunctionAddressTransform>;
|
||||||
|
|
||||||
|
/// An implementation of a compiler from parsed WebAssembly module to native code.
|
||||||
|
pub trait Compiler {
|
||||||
|
/// Compile a parsed module with the given `TargetIsa`.
|
||||||
|
fn compile_module<'data, 'module>(
|
||||||
|
module: &'module module::Module,
|
||||||
|
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
|
||||||
|
isa: &dyn isa::TargetIsa,
|
||||||
|
generate_debug_info: bool,
|
||||||
|
) -> Result<(Compilation, Relocations, AddressTransforms), CompileError>;
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
|
|||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Implementation of a relocation sink that just saves all the information for later
|
/// Implementation of a relocation sink that just saves all the information for later
|
||||||
struct RelocSink {
|
pub struct RelocSink {
|
||||||
/// Relocations recorded for the function.
|
/// Relocations recorded for the function.
|
||||||
func_relocs: Vec<Relocation>,
|
pub func_relocs: Vec<Relocation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl binemit::RelocSink for RelocSink {
|
impl binemit::RelocSink for RelocSink {
|
||||||
@@ -109,14 +109,19 @@ fn get_address_transform(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile the module using Cranelift, producing a compilation result with
|
/// A compiler that compiles a WebAssembly module with Cranelift, translating the Wasm to Cranelift IR,
|
||||||
/// associated relocations.
|
/// optimizing it and then translating to assembly.
|
||||||
pub fn compile_module<'data, 'module>(
|
pub struct Cranelift;
|
||||||
|
|
||||||
|
impl crate::compilation::Compiler for Cranelift {
|
||||||
|
/// Compile the module using Cranelift, producing a compilation result with
|
||||||
|
/// associated relocations.
|
||||||
|
fn compile_module<'data, 'module>(
|
||||||
module: &'module Module,
|
module: &'module Module,
|
||||||
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
|
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
|
||||||
isa: &dyn isa::TargetIsa,
|
isa: &dyn isa::TargetIsa,
|
||||||
generate_debug_info: bool,
|
generate_debug_info: bool,
|
||||||
) -> Result<(Compilation, Relocations, AddressTransforms), CompileError> {
|
) -> Result<(Compilation, Relocations, AddressTransforms), CompileError> {
|
||||||
let mut functions = PrimaryMap::with_capacity(function_body_inputs.len());
|
let mut functions = PrimaryMap::with_capacity(function_body_inputs.len());
|
||||||
let mut relocations = PrimaryMap::with_capacity(function_body_inputs.len());
|
let mut relocations = PrimaryMap::with_capacity(function_body_inputs.len());
|
||||||
let mut address_transforms = PrimaryMap::with_capacity(function_body_inputs.len());
|
let mut address_transforms = PrimaryMap::with_capacity(function_body_inputs.len());
|
||||||
@@ -174,4 +179,5 @@ pub fn compile_module<'data, 'module>(
|
|||||||
|
|
||||||
// TODO: Reorganize where we create the Vec for the resolved imports.
|
// TODO: Reorganize where we create the Vec for the resolved imports.
|
||||||
Ok((Compilation::new(functions), relocations, address_transforms))
|
Ok((Compilation::new(functions), relocations, address_transforms))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ use cranelift_codegen::ir::{
|
|||||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||||
use cranelift_entity::EntityRef;
|
use cranelift_entity::EntityRef;
|
||||||
use cranelift_wasm::{
|
use cranelift_wasm::{
|
||||||
self, FuncIndex, GlobalIndex, GlobalVariable, MemoryIndex, SignatureIndex, TableIndex,
|
self, DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, FuncIndex,
|
||||||
WasmResult,
|
GlobalIndex, GlobalVariable, MemoryIndex, SignatureIndex, TableIndex, WasmResult,
|
||||||
};
|
};
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
@@ -207,6 +207,138 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "lightbeam")]
|
||||||
|
impl lightbeam::ModuleContext for FuncEnvironment<'_> {
|
||||||
|
type Signature = ir::Signature;
|
||||||
|
type GlobalType = ir::Type;
|
||||||
|
|
||||||
|
fn func_index(&self, defined_func_index: u32) -> u32 {
|
||||||
|
self.module
|
||||||
|
.func_index(DefinedFuncIndex::from_u32(defined_func_index))
|
||||||
|
.as_u32()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn defined_func_index(&self, func_index: u32) -> Option<u32> {
|
||||||
|
self.module
|
||||||
|
.defined_func_index(FuncIndex::from_u32(func_index))
|
||||||
|
.map(|i| i.as_u32())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn defined_global_index(&self, global_index: u32) -> Option<u32> {
|
||||||
|
self.module
|
||||||
|
.defined_global_index(GlobalIndex::from_u32(global_index))
|
||||||
|
.map(|i| i.as_u32())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn global_type(&self, global_index: u32) -> &Self::GlobalType {
|
||||||
|
&self.module.globals[GlobalIndex::from_u32(global_index)].ty
|
||||||
|
}
|
||||||
|
|
||||||
|
fn func_type_index(&self, func_idx: u32) -> u32 {
|
||||||
|
self.module.functions[FuncIndex::from_u32(func_idx)].as_u32()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self, index: u32) -> &Self::Signature {
|
||||||
|
&self.module.signatures[SignatureIndex::from_u32(index)]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn defined_table_index(&self, table_index: u32) -> Option<u32> {
|
||||||
|
self.module
|
||||||
|
.defined_table_index(TableIndex::from_u32(table_index))
|
||||||
|
.map(|i| i.as_u32())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn defined_memory_index(&self, memory_index: u32) -> Option<u32> {
|
||||||
|
self.module
|
||||||
|
.defined_memory_index(MemoryIndex::from_u32(memory_index))
|
||||||
|
.map(|i| i.as_u32())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vmctx_vmfunction_import_body(&self, func_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmfunction_import_body(FuncIndex::from_u32(func_index))
|
||||||
|
}
|
||||||
|
fn vmctx_vmfunction_import_vmctx(&self, func_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmfunction_import_vmctx(FuncIndex::from_u32(func_index))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vmctx_vmglobal_import_from(&self, global_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmglobal_import_from(GlobalIndex::from_u32(global_index))
|
||||||
|
}
|
||||||
|
fn vmctx_vmglobal_definition(&self, defined_global_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmglobal_definition(DefinedGlobalIndex::from_u32(defined_global_index))
|
||||||
|
}
|
||||||
|
fn vmctx_vmmemory_import_from(&self, memory_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmmemory_import_from(MemoryIndex::from_u32(memory_index))
|
||||||
|
}
|
||||||
|
fn vmctx_vmmemory_definition(&self, defined_memory_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmmemory_definition(DefinedMemoryIndex::from_u32(defined_memory_index))
|
||||||
|
}
|
||||||
|
fn vmctx_vmmemory_definition_base(&self, defined_memory_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmmemory_definition_base(DefinedMemoryIndex::from_u32(defined_memory_index))
|
||||||
|
}
|
||||||
|
fn vmctx_vmmemory_definition_current_length(&self, defined_memory_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmmemory_definition_current_length(DefinedMemoryIndex::from_u32(
|
||||||
|
defined_memory_index,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
fn vmmemory_definition_base(&self) -> u8 {
|
||||||
|
self.offsets.vmmemory_definition_base()
|
||||||
|
}
|
||||||
|
fn vmmemory_definition_current_length(&self) -> u8 {
|
||||||
|
self.offsets.vmmemory_definition_current_length()
|
||||||
|
}
|
||||||
|
fn vmctx_vmtable_import_from(&self, table_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmtable_import_from(TableIndex::from_u32(table_index))
|
||||||
|
}
|
||||||
|
fn vmctx_vmtable_definition(&self, defined_table_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmtable_definition(DefinedTableIndex::from_u32(defined_table_index))
|
||||||
|
}
|
||||||
|
fn vmctx_vmtable_definition_base(&self, defined_table_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmtable_definition_base(DefinedTableIndex::from_u32(defined_table_index))
|
||||||
|
}
|
||||||
|
fn vmctx_vmtable_definition_current_elements(&self, defined_table_index: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmtable_definition_current_elements(DefinedTableIndex::from_u32(
|
||||||
|
defined_table_index,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
fn vmtable_definition_base(&self) -> u8 {
|
||||||
|
self.offsets.vmtable_definition_base()
|
||||||
|
}
|
||||||
|
fn vmtable_definition_current_elements(&self) -> u8 {
|
||||||
|
self.offsets.vmtable_definition_current_elements()
|
||||||
|
}
|
||||||
|
fn vmcaller_checked_anyfunc_type_index(&self) -> u8 {
|
||||||
|
self.offsets.vmcaller_checked_anyfunc_type_index()
|
||||||
|
}
|
||||||
|
fn vmcaller_checked_anyfunc_func_ptr(&self) -> u8 {
|
||||||
|
self.offsets.vmcaller_checked_anyfunc_func_ptr()
|
||||||
|
}
|
||||||
|
fn vmcaller_checked_anyfunc_vmctx(&self) -> u8 {
|
||||||
|
self.offsets.vmcaller_checked_anyfunc_vmctx()
|
||||||
|
}
|
||||||
|
fn size_of_vmcaller_checked_anyfunc(&self) -> u8 {
|
||||||
|
self.offsets.size_of_vmcaller_checked_anyfunc()
|
||||||
|
}
|
||||||
|
fn vmctx_vmshared_signature_id(&self, signature_idx: u32) -> u32 {
|
||||||
|
self.offsets
|
||||||
|
.vmctx_vmshared_signature_id(SignatureIndex::from_u32(signature_idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: type of a global
|
||||||
|
}
|
||||||
|
|
||||||
impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'module_environment> {
|
impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'module_environment> {
|
||||||
fn target_config(&self) -> TargetFrontendConfig {
|
fn target_config(&self) -> TargetFrontendConfig {
|
||||||
self.target_config
|
self.target_config
|
||||||
|
|||||||
@@ -45,11 +45,16 @@ mod tunables;
|
|||||||
mod vmoffsets;
|
mod vmoffsets;
|
||||||
|
|
||||||
pub mod cranelift;
|
pub mod cranelift;
|
||||||
|
#[cfg(feature = "lightbeam")]
|
||||||
|
pub mod lightbeam;
|
||||||
|
|
||||||
pub use crate::compilation::{
|
pub use crate::compilation::{
|
||||||
AddressTransforms, Compilation, CompileError, InstructionAddressTransform, Relocation,
|
AddressTransforms, Compilation, CompileError, Compiler, InstructionAddressTransform,
|
||||||
RelocationTarget, Relocations,
|
Relocation, RelocationTarget, Relocations,
|
||||||
};
|
};
|
||||||
|
pub use crate::cranelift::Cranelift;
|
||||||
|
#[cfg(feature = "lightbeam")]
|
||||||
|
pub use crate::lightbeam::Lightbeam;
|
||||||
pub use crate::module::{
|
pub use crate::module::{
|
||||||
Export, MemoryPlan, MemoryStyle, Module, TableElements, TablePlan, TableStyle,
|
Export, MemoryPlan, MemoryStyle, Module, TableElements, TablePlan, TableStyle,
|
||||||
};
|
};
|
||||||
|
|||||||
55
wasmtime-environ/src/lightbeam.rs
Normal file
55
wasmtime-environ/src/lightbeam.rs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
//! Support for compiling with Lightbeam.
|
||||||
|
|
||||||
|
use crate::compilation::{AddressTransforms, Compilation, CompileError, Relocations};
|
||||||
|
use crate::func_environ::FuncEnvironment;
|
||||||
|
use crate::module::Module;
|
||||||
|
use crate::module_environ::FunctionBodyData;
|
||||||
|
// TODO: Put this in `compilation`
|
||||||
|
use crate::cranelift::RelocSink;
|
||||||
|
use cranelift_codegen::isa;
|
||||||
|
use cranelift_entity::PrimaryMap;
|
||||||
|
use cranelift_wasm::DefinedFuncIndex;
|
||||||
|
use lightbeam;
|
||||||
|
|
||||||
|
/// A compiler that compiles a WebAssembly module with Lightbeam, directly translating the Wasm file.
|
||||||
|
pub struct Lightbeam;
|
||||||
|
|
||||||
|
impl crate::compilation::Compiler for Lightbeam {
|
||||||
|
/// Compile the module using Lightbeam, producing a compilation result with
|
||||||
|
/// associated relocations.
|
||||||
|
fn compile_module<'data, 'module>(
|
||||||
|
module: &'module Module,
|
||||||
|
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
|
||||||
|
isa: &dyn isa::TargetIsa,
|
||||||
|
// TODO
|
||||||
|
_generate_debug_info: bool,
|
||||||
|
) -> Result<(Compilation, Relocations, AddressTransforms), CompileError> {
|
||||||
|
let env = FuncEnvironment::new(isa.frontend_config(), module);
|
||||||
|
let mut relocations = PrimaryMap::new();
|
||||||
|
let mut codegen_session: lightbeam::CodeGenSession<_> =
|
||||||
|
lightbeam::CodeGenSession::new(function_body_inputs.len() as u32, &env);
|
||||||
|
|
||||||
|
for (i, function_body) in &function_body_inputs {
|
||||||
|
let mut reloc_sink = RelocSink::new();
|
||||||
|
|
||||||
|
lightbeam::translate_function(
|
||||||
|
&mut codegen_session,
|
||||||
|
&mut reloc_sink,
|
||||||
|
i.as_u32(),
|
||||||
|
&lightbeam::wasmparser::FunctionBody::new(0, function_body.data),
|
||||||
|
)
|
||||||
|
.expect("Failed to translate function. TODO: Stop this from panicking");
|
||||||
|
relocations.push(reloc_sink.func_relocs);
|
||||||
|
}
|
||||||
|
|
||||||
|
let code_section = codegen_session
|
||||||
|
.into_translated_code_section()
|
||||||
|
.expect("Failed to generate output code. TODO: Stop this from panicking");
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Compilation::from_buffer(code_section.buffer().to_vec(), code_section.funcs()),
|
||||||
|
relocations,
|
||||||
|
AddressTransforms::new(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ wasmparser = "0.29.2"
|
|||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = ["cranelift-codegen/std", "cranelift-wasm/std"]
|
std = ["cranelift-codegen/std", "cranelift-wasm/std"]
|
||||||
core = ["hashbrown/nightly", "cranelift-codegen/core", "cranelift-wasm/core", "wasmtime-environ/core"]
|
core = ["hashbrown/nightly", "cranelift-codegen/core", "cranelift-wasm/core", "wasmtime-environ/core"]
|
||||||
|
lightbeam = ["wasmtime-environ/lightbeam"]
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
maintenance = { status = "experimental" }
|
maintenance = { status = "experimental" }
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use std::vec::Vec;
|
|||||||
use wasmtime_debug::{emit_debugsections_image, DebugInfoData};
|
use wasmtime_debug::{emit_debugsections_image, DebugInfoData};
|
||||||
use wasmtime_environ::cranelift;
|
use wasmtime_environ::cranelift;
|
||||||
use wasmtime_environ::{
|
use wasmtime_environ::{
|
||||||
Compilation, CompileError, FunctionBodyData, Module, Relocations, Tunables,
|
Compilation, CompileError, Compiler as _C, FunctionBodyData, Module, Relocations, Tunables,
|
||||||
};
|
};
|
||||||
use wasmtime_runtime::{InstantiationError, SignatureRegistry, VMFunctionBody};
|
use wasmtime_runtime::{InstantiationError, SignatureRegistry, VMFunctionBody};
|
||||||
|
|
||||||
@@ -53,6 +53,11 @@ impl Compiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "lightbeam")]
|
||||||
|
type DefaultCompiler = wasmtime_environ::lightbeam::Lightbeam;
|
||||||
|
#[cfg(not(feature = "lightbeam"))]
|
||||||
|
type DefaultCompiler = wasmtime_environ::cranelift::Cranelift;
|
||||||
|
|
||||||
impl Compiler {
|
impl Compiler {
|
||||||
/// Return the target's frontend configuration settings.
|
/// Return the target's frontend configuration settings.
|
||||||
pub fn frontend_config(&self) -> TargetFrontendConfig {
|
pub fn frontend_config(&self) -> TargetFrontendConfig {
|
||||||
@@ -78,7 +83,7 @@ impl Compiler {
|
|||||||
),
|
),
|
||||||
SetupError,
|
SetupError,
|
||||||
> {
|
> {
|
||||||
let (compilation, relocations, address_transform) = cranelift::compile_module(
|
let (compilation, relocations, address_transform) = DefaultCompiler::compile_module(
|
||||||
module,
|
module,
|
||||||
function_body_inputs,
|
function_body_inputs,
|
||||||
&*self.isa,
|
&*self.isa,
|
||||||
@@ -100,7 +105,7 @@ impl Compiler {
|
|||||||
let mut funcs = Vec::new();
|
let mut funcs = Vec::new();
|
||||||
for (i, allocated) in allocated_functions.into_iter() {
|
for (i, allocated) in allocated_functions.into_iter() {
|
||||||
let ptr = (*allocated) as *const u8;
|
let ptr = (*allocated) as *const u8;
|
||||||
let body_len = compilation.functions[i].len();
|
let body_len = compilation.get(i).len();
|
||||||
funcs.push((ptr, body_len));
|
funcs.push((ptr, body_len));
|
||||||
}
|
}
|
||||||
let bytes = emit_debugsections_image(
|
let bytes = emit_debugsections_image(
|
||||||
@@ -255,14 +260,10 @@ fn allocate_functions(
|
|||||||
// Allocate code for all function in one continuous memory block.
|
// Allocate code for all function in one continuous memory block.
|
||||||
// First, collect all function bodies into vector to pass to the
|
// First, collect all function bodies into vector to pass to the
|
||||||
// allocate_copy_of_byte_slices.
|
// allocate_copy_of_byte_slices.
|
||||||
let bodies = compilation
|
let bodies = compilation.into_iter().collect::<Vec<&[u8]>>();
|
||||||
.functions
|
|
||||||
.values()
|
|
||||||
.map(|body| body.as_slice())
|
|
||||||
.collect::<Vec<&[u8]>>();
|
|
||||||
let fat_ptrs = code_memory.allocate_copy_of_byte_slices(&bodies)?;
|
let fat_ptrs = code_memory.allocate_copy_of_byte_slices(&bodies)?;
|
||||||
// Second, create a PrimaryMap from result vector of pointers.
|
// Second, create a PrimaryMap from result vector of pointers.
|
||||||
let mut result = PrimaryMap::with_capacity(compilation.functions.len());
|
let mut result = PrimaryMap::with_capacity(compilation.len());
|
||||||
for i in 0..fat_ptrs.len() {
|
for i in 0..fat_ptrs.len() {
|
||||||
let fat_ptr: *mut [VMFunctionBody] = fat_ptrs[i];
|
let fat_ptr: *mut [VMFunctionBody] = fat_ptrs[i];
|
||||||
result.push(fat_ptr);
|
result.push(fat_ptr);
|
||||||
|
|||||||
@@ -62,11 +62,11 @@ pub fn emit_functions(
|
|||||||
.expect("Missing enable_verifier setting");
|
.expect("Missing enable_verifier setting");
|
||||||
|
|
||||||
for (i, _function_relocs) in relocations.iter() {
|
for (i, _function_relocs) in relocations.iter() {
|
||||||
let body = &compilation.functions[i];
|
let body = compilation.get(i);
|
||||||
let func_index = module.func_index(i);
|
let func_index = module.func_index(i);
|
||||||
let string_name = format!("_wasm_function_{}", func_index.index());
|
let string_name = format!("_wasm_function_{}", func_index.index());
|
||||||
|
|
||||||
obj.define(string_name, body.clone())
|
obj.define(string_name, body.to_vec())
|
||||||
.map_err(|err| format!("{}", err))?;
|
.map_err(|err| format!("{}", err))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user