Update Cranelift to 0.82

This commit is contained in:
Amanieu d'Antras
2022-04-04 00:58:34 +01:00
parent 3ad9552e2e
commit 4c946257cf
25 changed files with 308 additions and 462 deletions

48
Cargo.lock generated
View File

@@ -8,7 +8,7 @@ version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [ dependencies = [
"gimli 0.26.1", "gimli",
] ]
[[package]] [[package]]
@@ -434,24 +434,24 @@ dependencies = [
[[package]] [[package]]
name = "cranelift-bforest" name = "cranelift-bforest"
version = "0.76.0" version = "0.82.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e6bea67967505247f54fa2c85cf4f6e0e31c4e5692c9b70e4ae58e339067333" checksum = "d16922317bd7dd104d509a373887822caa0242fc1def00de66abb538db221db4"
dependencies = [ dependencies = [
"cranelift-entity", "cranelift-entity",
] ]
[[package]] [[package]]
name = "cranelift-codegen" name = "cranelift-codegen"
version = "0.76.0" version = "0.82.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48194035d2752bdd5bdae429e3ab88676e95f52a2b1355a5d4e809f9e39b1d74" checksum = "8b80bf40380256307b68a3dcbe1b91cac92a533e212b5b635abc3e4525781a0a"
dependencies = [ dependencies = [
"cranelift-bforest", "cranelift-bforest",
"cranelift-codegen-meta", "cranelift-codegen-meta",
"cranelift-codegen-shared", "cranelift-codegen-shared",
"cranelift-entity", "cranelift-entity",
"gimli 0.25.0", "gimli",
"hashbrown 0.9.1", "hashbrown 0.9.1",
"log", "log",
"regalloc", "regalloc",
@@ -461,31 +461,30 @@ dependencies = [
[[package]] [[package]]
name = "cranelift-codegen-meta" name = "cranelift-codegen-meta"
version = "0.76.0" version = "0.82.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976efb22fcab4f2cd6bd4e9913764616a54d895c1a23530128d04e03633c555f" checksum = "703d0ed7d3bc6c7a814ca12858175bf4e93167a3584127858c686e4b5dd6e432"
dependencies = [ dependencies = [
"cranelift-codegen-shared", "cranelift-codegen-shared",
"cranelift-entity",
] ]
[[package]] [[package]]
name = "cranelift-codegen-shared" name = "cranelift-codegen-shared"
version = "0.76.0" version = "0.82.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dabb5fe66e04d4652e434195b45ae65b5c8172d520247b8f66d8df42b2b45dc" checksum = "80f52311e1c90de12dcf8c4b9999c6ebfd1ed360373e88c357160936844511f6"
[[package]] [[package]]
name = "cranelift-entity" name = "cranelift-entity"
version = "0.76.0" version = "0.82.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3329733e4d4b8e91c809efcaa4faee80bf66f20164e3dd16d707346bd3494799" checksum = "66bc82ef522c1f643baf7d4d40b7c52643ee4549d8960b0e6a047daacb83f897"
[[package]] [[package]]
name = "cranelift-frontend" name = "cranelift-frontend"
version = "0.76.0" version = "0.82.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "279afcc0d3e651b773f94837c3d581177b348c8d69e928104b2e9fccb226f921" checksum = "3cc35e4251864b17515845ba47447bca88fec9ca1a4186b19fe42526e36140e8"
dependencies = [ dependencies = [
"cranelift-codegen", "cranelift-codegen",
"hashbrown 0.9.1", "hashbrown 0.9.1",
@@ -960,17 +959,6 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "gimli"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
dependencies = [
"fallible-iterator",
"indexmap",
"stable_deref_trait",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.26.1" version = "0.26.1"
@@ -1800,9 +1788,9 @@ checksum = "a0d51660a68078997855ba5602f73ab3a5031bd7ad480a9d4c90fbbf04e1fff0"
[[package]] [[package]]
name = "regalloc" name = "regalloc"
version = "0.0.31" version = "0.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5" checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02"
dependencies = [ dependencies = [
"log", "log",
"rustc-hash", "rustc-hash",
@@ -2913,7 +2901,7 @@ dependencies = [
"cranelift-codegen", "cranelift-codegen",
"cranelift-entity", "cranelift-entity",
"cranelift-frontend", "cranelift-frontend",
"gimli 0.25.0", "gimli",
"hashbrown 0.11.2", "hashbrown 0.11.2",
"lazy_static", "lazy_static",
"loupe", "loupe",
@@ -2957,7 +2945,7 @@ dependencies = [
"byteorder", "byteorder",
"dynasm", "dynasm",
"dynasmrt", "dynasmrt",
"gimli 0.26.1", "gimli",
"hashbrown 0.11.2", "hashbrown 0.11.2",
"lazy_static", "lazy_static",
"loupe", "loupe",

View File

@@ -15,20 +15,20 @@ edition = "2018"
wasmer-compiler = { path = "../compiler", version = "=2.2.1", features = ["translator"], default-features = false } wasmer-compiler = { path = "../compiler", version = "=2.2.1", features = ["translator"], default-features = false }
wasmer-vm = { path = "../vm", version = "=2.2.1" } wasmer-vm = { path = "../vm", version = "=2.2.1" }
wasmer-types = { path = "../types", version = "=2.2.1", default-features = false, features = ["std"] } wasmer-types = { path = "../types", version = "=2.2.1", default-features = false, features = ["std"] }
cranelift-entity = { version = "0.76", default-features = false } cranelift-entity = { version = "0.82", default-features = false }
cranelift-codegen = { version = "0.76", default-features = false, features = ["x86", "arm64"] } cranelift-codegen = { version = "0.82", default-features = false, features = ["x86", "arm64"] }
cranelift-frontend = { version = "0.76", default-features = false } cranelift-frontend = { version = "0.82", default-features = false }
tracing = "0.1" tracing = "0.1"
hashbrown = { version = "0.11", optional = true } hashbrown = { version = "0.11", optional = true }
rayon = "1.5" rayon = "1.5"
more-asserts = "0.2" more-asserts = "0.2"
gimli = { version = "0.25", optional = true } gimli = { version = "0.26", optional = true }
smallvec = "1.6" smallvec = "1.6"
loupe = "0.1" loupe = "0.1"
target-lexicon = { version = "0.12.2", default-features = false } target-lexicon = { version = "0.12.2", default-features = false }
[dev-dependencies] [dev-dependencies]
cranelift-codegen = { version = "0.76", features = ["all-arch"] } cranelift-codegen = { version = "0.82", features = ["all-arch"] }
lazy_static = "1.4" lazy_static = "1.4"
[badges] [badges]

View File

@@ -1,44 +1,26 @@
// This file contains code from external sources. // This file contains code from external sources.
// Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md // Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md
use cranelift_codegen::Context;
use cranelift_codegen::MachSrcLoc; use cranelift_codegen::MachSrcLoc;
use cranelift_codegen::{isa, Context};
use wasmer_compiler::{wasmparser::Range, FunctionAddressMap, InstructionAddressMap, SourceLoc}; use wasmer_compiler::{wasmparser::Range, FunctionAddressMap, InstructionAddressMap, SourceLoc};
pub fn get_function_address_map<'data>( pub fn get_function_address_map<'data>(
context: &Context, context: &Context,
range: Range, range: Range,
body_len: usize, body_len: usize,
isa: &dyn isa::TargetIsa,
) -> FunctionAddressMap { ) -> FunctionAddressMap {
let mut instructions = Vec::new(); let mut instructions = Vec::new();
if let Some(ref mcr) = &context.mach_compile_result { // New-style backend: we have a `MachCompileResult` that will give us `MachSrcLoc` mapping
// New-style backend: we have a `MachCompileResult` that will give us `MachSrcLoc` mapping // tuples.
// tuples. let mcr = context.mach_compile_result.as_ref().unwrap();
for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() { for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() {
instructions.push(InstructionAddressMap { instructions.push(InstructionAddressMap {
srcloc: SourceLoc::new(loc.bits()), srcloc: SourceLoc::new(loc.bits()),
code_offset: start as usize, code_offset: start as usize,
code_len: (end - start) as usize, code_len: (end - start) as usize,
}); });
}
} else {
let func = &context.func;
let mut blocks = func.layout.blocks().collect::<Vec<_>>();
blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase
let encinfo = isa.encoding_info();
for block in blocks {
for (offset, inst, size) in func.inst_offsets(block, &encinfo) {
let srcloc = func.srclocs[inst];
instructions.push(InstructionAddressMap {
srcloc: SourceLoc::new(srcloc.bits()),
code_offset: offset as usize,
code_len: size as usize,
});
}
}
} }
// Generate artificial srcloc for function start/end to identify boundary // Generate artificial srcloc for function start/end to identify boundary

View File

@@ -5,32 +5,35 @@ use crate::config::Cranelift;
#[cfg(feature = "unwind")] #[cfg(feature = "unwind")]
use crate::dwarf::WriterRelocate; use crate::dwarf::WriterRelocate;
use crate::func_environ::{get_function_name, FuncEnvironment}; use crate::func_environ::{get_function_name, FuncEnvironment};
use crate::sink::{RelocSink, TrapSink};
use crate::trampoline::{ use crate::trampoline::{
make_trampoline_dynamic_function, make_trampoline_function_call, FunctionBuilderContext, make_trampoline_dynamic_function, make_trampoline_function_call, FunctionBuilderContext,
}; };
use crate::translator::{ use crate::translator::{
compiled_function_unwind_info, signature_to_cranelift_ir, transform_jump_table, compiled_function_unwind_info, irlibcall_to_libcall, irreloc_to_relocationkind,
CraneliftUnwindInfo, FuncTranslator, signature_to_cranelift_ir, CraneliftUnwindInfo, FuncTranslator,
}; };
use cranelift_codegen::ir; use cranelift_codegen::ir::ExternalName;
use cranelift_codegen::print_errors::pretty_error; use cranelift_codegen::print_errors::pretty_error;
use cranelift_codegen::{binemit, Context}; use cranelift_codegen::{ir, MachReloc};
use cranelift_codegen::{Context, MachTrap};
#[cfg(feature = "unwind")] #[cfg(feature = "unwind")]
use gimli::write::{Address, EhFrame, FrameTable}; use gimli::write::{Address, EhFrame, FrameTable};
use loupe::MemoryUsage; use loupe::MemoryUsage;
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
use std::sync::Arc; use std::sync::Arc;
use wasmer_compiler::CompileError; use wasmer_compiler::{
use wasmer_compiler::{CallingConvention, ModuleTranslationState, Target}; CallingConvention, ModuleTranslationState, RelocationTarget, Target, TrapInformation,
};
use wasmer_compiler::{ use wasmer_compiler::{
Compilation, CompileModuleInfo, CompiledFunction, CompiledFunctionFrameInfo, Compilation, CompileModuleInfo, CompiledFunction, CompiledFunctionFrameInfo,
CompiledFunctionUnwindInfo, Compiler, Dwarf, FunctionBinaryReader, FunctionBody, CompiledFunctionUnwindInfo, Compiler, Dwarf, FunctionBinaryReader, FunctionBody,
FunctionBodyData, MiddlewareBinaryReader, ModuleMiddleware, ModuleMiddlewareChain, FunctionBodyData, MiddlewareBinaryReader, ModuleMiddleware, ModuleMiddlewareChain,
SectionIndex, SectionIndex,
}; };
use wasmer_compiler::{CompileError, Relocation};
use wasmer_types::entity::{EntityRef, PrimaryMap}; use wasmer_types::entity::{EntityRef, PrimaryMap};
use wasmer_types::{FunctionIndex, LocalFunctionIndex, SignatureIndex}; use wasmer_types::{FunctionIndex, LocalFunctionIndex, ModuleInfo, SignatureIndex};
use wasmer_vm::TrapCode;
/// A compiler that compiles a WebAssembly module with Cranelift, translating the Wasm to Cranelift IR, /// A compiler that compiles a WebAssembly module with Cranelift, translating the Wasm to Cranelift IR,
/// optimizing it and then translating to assembly. /// optimizing it and then translating to assembly.
@@ -66,7 +69,10 @@ impl Compiler for CraneliftCompiler {
module_translation_state: &ModuleTranslationState, module_translation_state: &ModuleTranslationState,
function_body_inputs: PrimaryMap<LocalFunctionIndex, FunctionBodyData<'_>>, function_body_inputs: PrimaryMap<LocalFunctionIndex, FunctionBodyData<'_>>,
) -> Result<Compilation, CompileError> { ) -> Result<Compilation, CompileError> {
let isa = self.config().isa(target); let isa = self
.config()
.isa(target)
.map_err(|error| CompileError::Codegen(error.to_string()))?;
let frontend_config = isa.frontend_config(); let frontend_config = isa.frontend_config();
let memory_styles = &compile_info.memory_styles; let memory_styles = &compile_info.memory_styles;
let table_styles = &compile_info.table_styles; let table_styles = &compile_info.table_styles;
@@ -139,20 +145,24 @@ impl Compiler for CraneliftCompiler {
)?; )?;
let mut code_buf: Vec<u8> = Vec::new(); let mut code_buf: Vec<u8> = Vec::new();
let mut reloc_sink = RelocSink::new(&module, func_index);
let mut trap_sink = TrapSink::new();
let mut stackmap_sink = binemit::NullStackMapSink {};
context context
.compile_and_emit( .compile_and_emit(&*isa, &mut code_buf)
&*isa, .map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
&mut code_buf,
&mut reloc_sink, let result = context.mach_compile_result.as_ref().unwrap();
&mut trap_sink, let func_relocs = result
&mut stackmap_sink, .buffer
) .relocs()
.map_err(|error| { .into_iter()
CompileError::Codegen(pretty_error(&context.func, Some(&*isa), error)) .map(|r| mach_reloc_to_reloc(module, r))
})?; .collect::<Vec<_>>();
let traps = result
.buffer
.traps()
.into_iter()
.map(mach_trap_to_trap)
.collect::<Vec<_>>();
let (unwind_info, fde) = match compiled_function_unwind_info(&*isa, &context)? { let (unwind_info, fde) = match compiled_function_unwind_info(&*isa, &context)? {
#[cfg(feature = "unwind")] #[cfg(feature = "unwind")]
@@ -182,10 +192,7 @@ impl Compiler for CraneliftCompiler {
}; };
let range = reader.range(); let range = reader.range();
let address_map = get_function_address_map(&context, range, code_buf.len(), &*isa); let address_map = get_function_address_map(&context, range, code_buf.len());
// We transform the Cranelift JumpTable's into compiler JumpTables
let func_jt_offsets = transform_jump_table(context.func.jt_offsets);
Ok(( Ok((
CompiledFunction { CompiledFunction {
@@ -193,12 +200,8 @@ impl Compiler for CraneliftCompiler {
body: code_buf, body: code_buf,
unwind_info, unwind_info,
}, },
jt_offsets: func_jt_offsets, relocations: func_relocs,
relocations: reloc_sink.func_relocs, frame_info: CompiledFunctionFrameInfo { address_map, traps },
frame_info: CompiledFunctionFrameInfo {
address_map,
traps: trap_sink.traps,
},
}, },
fde, fde,
)) ))
@@ -262,3 +265,63 @@ impl Compiler for CraneliftCompiler {
)) ))
} }
} }
fn mach_reloc_to_reloc(module: &ModuleInfo, reloc: &MachReloc) -> Relocation {
let &MachReloc {
offset,
srcloc: _,
kind,
ref name,
addend,
} = reloc;
let reloc_target = if let ExternalName::User { namespace, index } = *name {
debug_assert_eq!(namespace, 0);
RelocationTarget::LocalFunc(
module
.local_func_index(FunctionIndex::from_u32(index))
.expect("The provided function should be local"),
)
} else if let ExternalName::LibCall(libcall) = *name {
RelocationTarget::LibCall(irlibcall_to_libcall(libcall))
} else {
panic!("unrecognized external name")
};
Relocation {
kind: irreloc_to_relocationkind(kind),
reloc_target,
offset,
addend,
}
}
fn mach_trap_to_trap(trap: &MachTrap) -> TrapInformation {
let &MachTrap {
offset,
srcloc: _,
code,
} = trap;
TrapInformation {
code_offset: offset,
trap_code: translate_ir_trapcode(code),
}
}
/// Translates the Cranelift IR TrapCode into generic Trap Code
fn translate_ir_trapcode(trap: ir::TrapCode) -> TrapCode {
match trap {
ir::TrapCode::StackOverflow => TrapCode::StackOverflow,
ir::TrapCode::HeapOutOfBounds => TrapCode::HeapAccessOutOfBounds,
ir::TrapCode::HeapMisaligned => TrapCode::HeapMisaligned,
ir::TrapCode::TableOutOfBounds => TrapCode::TableAccessOutOfBounds,
ir::TrapCode::IndirectCallToNull => TrapCode::IndirectCallToNull,
ir::TrapCode::BadSignature => TrapCode::BadSignature,
ir::TrapCode::IntegerOverflow => TrapCode::IntegerOverflow,
ir::TrapCode::IntegerDivisionByZero => TrapCode::IntegerDivisionByZero,
ir::TrapCode::BadConversionToInteger => TrapCode::BadConversionToInteger,
ir::TrapCode::UnreachableCodeReached => TrapCode::UnreachableCodeReached,
ir::TrapCode::Interrupt => unimplemented!("Interrupts not supported"),
ir::TrapCode::User(_user_code) => unimplemented!("User trap code not supported"),
// ir::TrapCode::Interrupt => TrapCode::Interrupt,
// ir::TrapCode::User(user_code) => TrapCode::User(user_code),
}
}

View File

@@ -1,6 +1,7 @@
use crate::compiler::CraneliftCompiler; use crate::compiler::CraneliftCompiler;
use cranelift_codegen::isa::{lookup, TargetIsa}; use cranelift_codegen::isa::{lookup, TargetIsa};
use cranelift_codegen::settings::{self, Configurable}; use cranelift_codegen::settings::{self, Configurable};
use cranelift_codegen::CodegenResult;
use loupe::MemoryUsage; use loupe::MemoryUsage;
use std::sync::Arc; use std::sync::Arc;
use wasmer_compiler::{ use wasmer_compiler::{
@@ -67,7 +68,7 @@ impl Cranelift {
} }
/// Generates the ISA for the provided target /// Generates the ISA for the provided target
pub fn isa(&self, target: &Target) -> Box<dyn TargetIsa> { pub fn isa(&self, target: &Target) -> CodegenResult<Box<dyn TargetIsa>> {
let mut builder = let mut builder =
lookup(target.triple().clone()).expect("construct Cranelift ISA for triple"); lookup(target.triple().clone()).expect("construct Cranelift ISA for triple");
// Cpu Features // Cpu Features

View File

@@ -51,7 +51,6 @@ mod debug;
#[cfg(feature = "unwind")] #[cfg(feature = "unwind")]
mod dwarf; mod dwarf;
mod func_environ; mod func_environ;
mod sink;
mod trampoline; mod trampoline;
mod translator; mod translator;

View File

@@ -1,132 +0,0 @@
//! Support for compiling with Cranelift.
use crate::translator::{irlibcall_to_libcall, irreloc_to_relocationkind};
use cranelift_codegen::binemit;
use cranelift_codegen::ir::{self, ExternalName};
use cranelift_entity::EntityRef as CraneliftEntityRef;
use wasmer_compiler::{JumpTable, Relocation, RelocationTarget, TrapInformation};
use wasmer_types::entity::EntityRef;
use wasmer_types::{FunctionIndex, LocalFunctionIndex, ModuleInfo};
use wasmer_vm::TrapCode;
/// Implementation of a relocation sink that just saves all the information for later
pub(crate) struct RelocSink<'a> {
module: &'a ModuleInfo,
/// Current function index.
local_func_index: LocalFunctionIndex,
/// Relocations recorded for the function.
pub func_relocs: Vec<Relocation>,
}
impl<'a> binemit::RelocSink for RelocSink<'a> {
fn reloc_external(
&mut self,
offset: binemit::CodeOffset,
_source_loc: ir::SourceLoc,
reloc: binemit::Reloc,
name: &ExternalName,
addend: binemit::Addend,
) {
let reloc_target = if let ExternalName::User { namespace, index } = *name {
debug_assert_eq!(namespace, 0);
RelocationTarget::LocalFunc(
self.module
.local_func_index(FunctionIndex::from_u32(index))
.expect("The provided function should be local"),
)
} else if let ExternalName::LibCall(libcall) = *name {
RelocationTarget::LibCall(irlibcall_to_libcall(libcall))
} else {
panic!("unrecognized external name")
};
self.func_relocs.push(Relocation {
kind: irreloc_to_relocationkind(reloc),
reloc_target,
offset,
addend,
});
}
fn reloc_constant(
&mut self,
_code_offset: binemit::CodeOffset,
_reloc: binemit::Reloc,
_constant_offset: ir::ConstantOffset,
) {
// Do nothing for now: cranelift emits constant data after the function code and also emits
// function code with correct relative offsets to the constant data.
}
fn reloc_jt(&mut self, offset: binemit::CodeOffset, reloc: binemit::Reloc, jt: ir::JumpTable) {
self.func_relocs.push(Relocation {
kind: irreloc_to_relocationkind(reloc),
reloc_target: RelocationTarget::JumpTable(
self.local_func_index,
JumpTable::new(jt.index()),
),
offset,
addend: 0,
});
}
}
impl<'a> RelocSink<'a> {
/// Return a new `RelocSink` instance.
pub fn new(module: &'a ModuleInfo, func_index: FunctionIndex) -> Self {
let local_func_index = module
.local_func_index(func_index)
.expect("The provided function should be local");
Self {
module,
local_func_index,
func_relocs: Vec::new(),
}
}
}
pub(crate) struct TrapSink {
pub traps: Vec<TrapInformation>,
}
impl TrapSink {
pub fn new() -> Self {
Self { traps: Vec::new() }
}
}
impl binemit::TrapSink for TrapSink {
fn trap(
&mut self,
code_offset: binemit::CodeOffset,
_source_loc: ir::SourceLoc,
trap_code: ir::TrapCode,
) {
self.traps.push(TrapInformation {
code_offset,
// TODO: Translate properly environment Trapcode into cranelift IR
trap_code: translate_ir_trapcode(trap_code),
});
}
}
/// Translates the Cranelift IR TrapCode into generic Trap Code
fn translate_ir_trapcode(trap: ir::TrapCode) -> TrapCode {
match trap {
ir::TrapCode::StackOverflow => TrapCode::StackOverflow,
ir::TrapCode::HeapOutOfBounds => TrapCode::HeapAccessOutOfBounds,
ir::TrapCode::HeapMisaligned => TrapCode::HeapMisaligned,
ir::TrapCode::TableOutOfBounds => TrapCode::TableAccessOutOfBounds,
ir::TrapCode::IndirectCallToNull => TrapCode::IndirectCallToNull,
ir::TrapCode::BadSignature => TrapCode::BadSignature,
ir::TrapCode::IntegerOverflow => TrapCode::IntegerOverflow,
ir::TrapCode::IntegerDivisionByZero => TrapCode::IntegerDivisionByZero,
ir::TrapCode::BadConversionToInteger => TrapCode::BadConversionToInteger,
ir::TrapCode::UnreachableCodeReached => TrapCode::UnreachableCodeReached,
ir::TrapCode::Interrupt => unimplemented!("Interrupts not supported"),
ir::TrapCode::User(_user_code) => unimplemented!("User trap code not supported"),
// ir::TrapCode::Interrupt => TrapCode::Interrupt,
// ir::TrapCode::User(user_code) => TrapCode::User(user_code),
}
}

View File

@@ -3,15 +3,14 @@
//! A trampoline generator for calling dynamic host functions from Wasm. //! A trampoline generator for calling dynamic host functions from Wasm.
use super::binemit::TrampolineRelocSink;
use crate::translator::{compiled_function_unwind_info, signature_to_cranelift_ir}; use crate::translator::{compiled_function_unwind_info, signature_to_cranelift_ir};
use cranelift_codegen::ir;
use cranelift_codegen::ir::{ use cranelift_codegen::ir::{
ExternalName, Function, InstBuilder, MemFlags, StackSlotData, StackSlotKind, ExternalName, Function, InstBuilder, MemFlags, StackSlotData, StackSlotKind,
}; };
use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::print_errors::pretty_error; use cranelift_codegen::print_errors::pretty_error;
use cranelift_codegen::Context; use cranelift_codegen::Context;
use cranelift_codegen::{binemit, ir};
use std::cmp; use std::cmp;
use std::mem; use std::mem;
@@ -108,18 +107,9 @@ pub fn make_trampoline_dynamic_function(
} }
let mut code_buf = Vec::new(); let mut code_buf = Vec::new();
let mut reloc_sink = TrampolineRelocSink {};
let mut trap_sink = binemit::NullTrapSink {};
let mut stackmap_sink = binemit::NullStackMapSink {};
context context
.compile_and_emit( .compile_and_emit(isa, &mut code_buf)
isa, .map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
&mut code_buf,
&mut reloc_sink,
&mut trap_sink,
&mut stackmap_sink,
)
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?;
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind(); let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();

View File

@@ -8,15 +8,12 @@
//! let my_func = instance.exports.get("func"); //! let my_func = instance.exports.get("func");
//! my_func.call([1, 2]) //! my_func.call([1, 2])
//! ``` //! ```
use super::binemit::TrampolineRelocSink; use crate::translator::{compiled_function_unwind_info, signature_to_cranelift_ir};
use crate::translator::{ use cranelift_codegen::ir;
compiled_function_unwind_info, signature_to_cranelift_ir, /*transform_jump_table, */
};
use cranelift_codegen::ir::InstBuilder; use cranelift_codegen::ir::InstBuilder;
use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::print_errors::pretty_error; use cranelift_codegen::print_errors::pretty_error;
use cranelift_codegen::Context; use cranelift_codegen::Context;
use cranelift_codegen::{binemit, ir};
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use std::mem; use std::mem;
use wasmer_compiler::{CompileError, FunctionBody}; use wasmer_compiler::{CompileError, FunctionBody};
@@ -106,25 +103,15 @@ pub fn make_trampoline_function_call(
} }
let mut code_buf = Vec::new(); let mut code_buf = Vec::new();
let mut reloc_sink = TrampolineRelocSink {};
let mut trap_sink = binemit::NullTrapSink {};
let mut stackmap_sink = binemit::NullStackMapSink {};
context context
.compile_and_emit( .compile_and_emit(isa, &mut code_buf)
isa, .map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
&mut code_buf,
&mut reloc_sink,
&mut trap_sink,
&mut stackmap_sink,
)
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?;
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind(); let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();
Ok(FunctionBody { Ok(FunctionBody {
body: code_buf, body: code_buf,
unwind_info, unwind_info,
// jt_offsets: transform_jump_table(context.func.jt_offsets),
}) })
} }

View File

@@ -9,43 +9,3 @@ pub use self::function_call::make_trampoline_function_call;
pub use cranelift_codegen::print_errors::pretty_error; pub use cranelift_codegen::print_errors::pretty_error;
pub use cranelift_codegen::Context; pub use cranelift_codegen::Context;
pub use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; pub use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
pub mod binemit {
pub use cranelift_codegen::binemit::NullTrapSink;
pub use cranelift_codegen::binemit::{CodeOffset, NullStackMapSink, TrapSink};
use cranelift_codegen::{binemit, ir};
/// We don't expect trampoline compilation to produce any relocations, so
/// this `RelocSink` just asserts that it doesn't recieve any.
pub struct TrampolineRelocSink {}
impl binemit::RelocSink for TrampolineRelocSink {
fn reloc_external(
&mut self,
_offset: binemit::CodeOffset,
_source_loc: ir::SourceLoc,
_reloc: binemit::Reloc,
_name: &ir::ExternalName,
_addend: binemit::Addend,
) {
panic!("trampoline compilation should not produce external symbol relocs");
}
fn reloc_constant(
&mut self,
_code_offset: binemit::CodeOffset,
_reloc: binemit::Reloc,
_constant_offset: ir::ConstantOffset,
) {
panic!("trampoline compilation should not produce constant relocs");
}
fn reloc_jt(
&mut self,
_offset: binemit::CodeOffset,
_reloc: binemit::Reloc,
_jt: ir::JumpTable,
) {
panic!("trampoline compilation should not produce jump table relocs");
}
}
}

View File

@@ -1868,14 +1868,43 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let a = pop1_with_bitcast(state, I32X4, builder); let a = pop1_with_bitcast(state, I32X4, builder);
state.push1(builder.ins().fcvt_low_from_sint(F64X2, a)); state.push1(builder.ins().fcvt_low_from_sint(F64X2, a));
} }
Operator::F64x2ConvertLowI32x4U => {
let a = pop1_with_bitcast(state, I32X4, builder);
let widened_a = builder.ins().uwiden_low(a);
state.push1(builder.ins().fcvt_from_uint(F64X2, widened_a));
}
Operator::F64x2PromoteLowF32x4 => {
let a = pop1_with_bitcast(state, F32X4, builder);
state.push1(builder.ins().fvpromote_low(a));
}
Operator::F32x4DemoteF64x2Zero => {
let a = pop1_with_bitcast(state, F64X2, builder);
state.push1(builder.ins().fvdemote(a));
}
Operator::I32x4TruncSatF32x4S => { Operator::I32x4TruncSatF32x4S => {
let a = pop1_with_bitcast(state, F32X4, builder); let a = pop1_with_bitcast(state, F32X4, builder);
state.push1(builder.ins().fcvt_to_sint_sat(I32X4, a)) state.push1(builder.ins().fcvt_to_sint_sat(I32X4, a))
} }
Operator::I32x4TruncSatF64x2SZero => {
let a = pop1_with_bitcast(state, F64X2, builder);
let converted_a = builder.ins().fcvt_to_sint_sat(I64X2, a);
let handle = builder.func.dfg.constants.insert(vec![0u8; 16].into());
let zero = builder.ins().vconst(I64X2, handle);
state.push1(builder.ins().snarrow(converted_a, zero));
}
Operator::I32x4TruncSatF32x4U => { Operator::I32x4TruncSatF32x4U => {
let a = pop1_with_bitcast(state, F32X4, builder); let a = pop1_with_bitcast(state, F32X4, builder);
state.push1(builder.ins().fcvt_to_uint_sat(I32X4, a)) state.push1(builder.ins().fcvt_to_uint_sat(I32X4, a))
} }
Operator::I32x4TruncSatF64x2UZero => {
let a = pop1_with_bitcast(state, F64X2, builder);
let converted_a = builder.ins().fcvt_to_uint_sat(I64X2, a);
let handle = builder.func.dfg.constants.insert(vec![0u8; 16].into());
let zero = builder.ins().vconst(I64X2, handle);
state.push1(builder.ins().uunarrow(converted_a, zero));
}
Operator::I8x16NarrowI16x8S => { Operator::I8x16NarrowI16x8S => {
let (a, b) = pop2_with_bitcast(state, I16X8, builder); let (a, b) = pop2_with_bitcast(state, I16X8, builder);
state.push1(builder.ins().snarrow(a, b)) state.push1(builder.ins().snarrow(a, b))
@@ -1925,6 +1954,46 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
state.push1(builder.ins().uwiden_high(a)) state.push1(builder.ins().uwiden_high(a))
} }
Operator::I64x2ExtendLowI32x4S => {
let a = pop1_with_bitcast(state, I32X4, builder);
state.push1(builder.ins().swiden_low(a))
}
Operator::I64x2ExtendHighI32x4S => {
let a = pop1_with_bitcast(state, I32X4, builder);
state.push1(builder.ins().swiden_high(a))
}
Operator::I64x2ExtendLowI32x4U => {
let a = pop1_with_bitcast(state, I32X4, builder);
state.push1(builder.ins().uwiden_low(a))
}
Operator::I64x2ExtendHighI32x4U => {
let a = pop1_with_bitcast(state, I32X4, builder);
state.push1(builder.ins().uwiden_high(a))
}
Operator::I16x8ExtAddPairwiseI8x16S => {
let a = pop1_with_bitcast(state, I8X16, builder);
let widen_low = builder.ins().swiden_low(a);
let widen_high = builder.ins().swiden_high(a);
state.push1(builder.ins().iadd_pairwise(widen_low, widen_high));
}
Operator::I32x4ExtAddPairwiseI16x8S => {
let a = pop1_with_bitcast(state, I16X8, builder);
let widen_low = builder.ins().swiden_low(a);
let widen_high = builder.ins().swiden_high(a);
state.push1(builder.ins().iadd_pairwise(widen_low, widen_high));
}
Operator::I16x8ExtAddPairwiseI8x16U => {
let a = pop1_with_bitcast(state, I8X16, builder);
let widen_low = builder.ins().uwiden_low(a);
let widen_high = builder.ins().uwiden_high(a);
state.push1(builder.ins().iadd_pairwise(widen_low, widen_high));
}
Operator::I32x4ExtAddPairwiseI16x8U => {
let a = pop1_with_bitcast(state, I16X8, builder);
let widen_low = builder.ins().uwiden_low(a);
let widen_high = builder.ins().uwiden_high(a);
state.push1(builder.ins().iadd_pairwise(widen_low, widen_high));
}
Operator::F32x4Ceil | Operator::F64x2Ceil => { Operator::F32x4Ceil | Operator::F64x2Ceil => {
// This is something of a misuse of `type_of`, because that produces the return type // This is something of a misuse of `type_of`, because that produces the return type
// of `op`. In this case we want the arg type, but we know it's the same as the // of `op`. In this case we want the arg type, but we know it's the same as the
@@ -1948,34 +2017,90 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let (a, b) = pop2_with_bitcast(state, I16X8, builder); let (a, b) = pop2_with_bitcast(state, I16X8, builder);
state.push1(builder.ins().widening_pairwise_dot_product_s(a, b)); state.push1(builder.ins().widening_pairwise_dot_product_s(a, b));
} }
Operator::I64x2ExtendLowI32x4S Operator::I8x16Popcnt => {
| Operator::I64x2ExtendHighI32x4S let arg = pop1_with_bitcast(state, type_of(op), builder);
| Operator::I64x2ExtendLowI32x4U state.push1(builder.ins().popcnt(arg));
| Operator::I64x2ExtendHighI32x4U }
| Operator::I16x8Q15MulrSatS Operator::I16x8Q15MulrSatS => {
| Operator::I16x8ExtMulLowI8x16S let (a, b) = pop2_with_bitcast(state, I16X8, builder);
| Operator::I16x8ExtMulHighI8x16S state.push1(builder.ins().sqmul_round_sat(a, b))
| Operator::I16x8ExtMulLowI8x16U }
| Operator::I16x8ExtMulHighI8x16U Operator::I16x8ExtMulLowI8x16S => {
| Operator::I32x4ExtMulLowI16x8S let (a, b) = pop2_with_bitcast(state, I8X16, builder);
| Operator::I32x4ExtMulHighI16x8S let a_low = builder.ins().swiden_low(a);
| Operator::I32x4ExtMulLowI16x8U let b_low = builder.ins().swiden_low(b);
| Operator::I32x4ExtMulHighI16x8U state.push1(builder.ins().imul(a_low, b_low));
| Operator::I64x2ExtMulLowI32x4S }
| Operator::I64x2ExtMulHighI32x4S Operator::I16x8ExtMulHighI8x16S => {
| Operator::I64x2ExtMulLowI32x4U let (a, b) = pop2_with_bitcast(state, I8X16, builder);
| Operator::I64x2ExtMulHighI32x4U let a_high = builder.ins().swiden_high(a);
| Operator::I16x8ExtAddPairwiseI8x16S let b_high = builder.ins().swiden_high(b);
| Operator::I16x8ExtAddPairwiseI8x16U state.push1(builder.ins().imul(a_high, b_high));
| Operator::I32x4ExtAddPairwiseI16x8S }
| Operator::I32x4ExtAddPairwiseI16x8U Operator::I16x8ExtMulLowI8x16U => {
| Operator::F32x4DemoteF64x2Zero let (a, b) = pop2_with_bitcast(state, I8X16, builder);
| Operator::F64x2PromoteLowF32x4 let a_low = builder.ins().uwiden_low(a);
| Operator::F64x2ConvertLowI32x4U let b_low = builder.ins().uwiden_low(b);
| Operator::I32x4TruncSatF64x2SZero state.push1(builder.ins().imul(a_low, b_low));
| Operator::I32x4TruncSatF64x2UZero }
| Operator::I8x16Popcnt Operator::I16x8ExtMulHighI8x16U => {
| Operator::I8x16RelaxedSwizzle let (a, b) = pop2_with_bitcast(state, I8X16, builder);
let a_high = builder.ins().uwiden_high(a);
let b_high = builder.ins().uwiden_high(b);
state.push1(builder.ins().imul(a_high, b_high));
}
Operator::I32x4ExtMulLowI16x8S => {
let (a, b) = pop2_with_bitcast(state, I16X8, builder);
let a_low = builder.ins().swiden_low(a);
let b_low = builder.ins().swiden_low(b);
state.push1(builder.ins().imul(a_low, b_low));
}
Operator::I32x4ExtMulHighI16x8S => {
let (a, b) = pop2_with_bitcast(state, I16X8, builder);
let a_high = builder.ins().swiden_high(a);
let b_high = builder.ins().swiden_high(b);
state.push1(builder.ins().imul(a_high, b_high));
}
Operator::I32x4ExtMulLowI16x8U => {
let (a, b) = pop2_with_bitcast(state, I16X8, builder);
let a_low = builder.ins().uwiden_low(a);
let b_low = builder.ins().uwiden_low(b);
state.push1(builder.ins().imul(a_low, b_low));
}
Operator::I32x4ExtMulHighI16x8U => {
let (a, b) = pop2_with_bitcast(state, I16X8, builder);
let a_high = builder.ins().uwiden_high(a);
let b_high = builder.ins().uwiden_high(b);
state.push1(builder.ins().imul(a_high, b_high));
}
Operator::I64x2ExtMulLowI32x4S => {
let (a, b) = pop2_with_bitcast(state, I32X4, builder);
let a_low = builder.ins().swiden_low(a);
let b_low = builder.ins().swiden_low(b);
state.push1(builder.ins().imul(a_low, b_low));
}
Operator::I64x2ExtMulHighI32x4S => {
let (a, b) = pop2_with_bitcast(state, I32X4, builder);
let a_high = builder.ins().swiden_high(a);
let b_high = builder.ins().swiden_high(b);
state.push1(builder.ins().imul(a_high, b_high));
}
Operator::I64x2ExtMulLowI32x4U => {
let (a, b) = pop2_with_bitcast(state, I32X4, builder);
let a_low = builder.ins().uwiden_low(a);
let b_low = builder.ins().uwiden_low(b);
state.push1(builder.ins().imul(a_low, b_low));
}
Operator::I64x2ExtMulHighI32x4U => {
let (a, b) = pop2_with_bitcast(state, I32X4, builder);
let a_high = builder.ins().uwiden_high(a);
let b_high = builder.ins().uwiden_high(b);
state.push1(builder.ins().imul(a_high, b_high));
}
Operator::ReturnCall { .. } | Operator::ReturnCallIndirect { .. } => {
return Err(wasm_unsupported!("proposed tail-call operator {:?}", op));
}
Operator::I8x16RelaxedSwizzle
| Operator::I32x4RelaxedTruncSatF32x4S | Operator::I32x4RelaxedTruncSatF32x4S
| Operator::I32x4RelaxedTruncSatF32x4U | Operator::I32x4RelaxedTruncSatF32x4U
| Operator::I32x4RelaxedTruncSatF64x2SZero | Operator::I32x4RelaxedTruncSatF64x2SZero
@@ -1992,10 +2117,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
| Operator::F32x4RelaxedMax | Operator::F32x4RelaxedMax
| Operator::F64x2RelaxedMin | Operator::F64x2RelaxedMin
| Operator::F64x2RelaxedMax => { | Operator::F64x2RelaxedMax => {
return Err(wasm_unsupported!("proposed simd operator {:?}", op)); return Err(wasm_unsupported!("proposed relaxed-simd operator {:?}", op));
}
Operator::ReturnCall { .. } | Operator::ReturnCallIndirect { .. } => {
return Err(wasm_unsupported!("proposed tail-call operator {:?}", op));
} }
}; };
Ok(()) Ok(())
@@ -2697,7 +2819,8 @@ fn type_of(operator: &Operator) -> Type {
| Operator::I8x16MaxS | Operator::I8x16MaxS
| Operator::I8x16MaxU | Operator::I8x16MaxU
| Operator::I8x16RoundingAverageU | Operator::I8x16RoundingAverageU
| Operator::I8x16Bitmask => I8X16, | Operator::I8x16Bitmask
| Operator::I8x16Popcnt => I8X16,
Operator::I16x8Splat Operator::I16x8Splat
| Operator::V128Load16Splat { .. } | Operator::V128Load16Splat { .. }
@@ -2765,9 +2888,9 @@ fn type_of(operator: &Operator) -> Type {
| Operator::I32x4MinU | Operator::I32x4MinU
| Operator::I32x4MaxS | Operator::I32x4MaxS
| Operator::I32x4MaxU | Operator::I32x4MaxU
| Operator::F32x4ConvertI32x4S
| Operator::F32x4ConvertI32x4U
| Operator::I32x4Bitmask | Operator::I32x4Bitmask
| Operator::I32x4TruncSatF32x4S
| Operator::I32x4TruncSatF32x4U
| Operator::V128Load32Zero { .. } => I32X4, | Operator::V128Load32Zero { .. } => I32X4,
Operator::I64x2Splat Operator::I64x2Splat
@@ -2814,8 +2937,8 @@ fn type_of(operator: &Operator) -> Type {
| Operator::F32x4Max | Operator::F32x4Max
| Operator::F32x4PMin | Operator::F32x4PMin
| Operator::F32x4PMax | Operator::F32x4PMax
| Operator::I32x4TruncSatF32x4S | Operator::F32x4ConvertI32x4S
| Operator::I32x4TruncSatF32x4U | Operator::F32x4ConvertI32x4U
| Operator::F32x4Ceil | Operator::F32x4Ceil
| Operator::F32x4Floor | Operator::F32x4Floor
| Operator::F32x4Trunc | Operator::F32x4Trunc

View File

@@ -12,6 +12,6 @@ pub use self::func_state::FuncTranslationState;
pub use self::func_translator::FuncTranslator; pub use self::func_translator::FuncTranslator;
pub use self::translation_utils::{ pub use self::translation_utils::{
get_vmctx_value_label, irlibcall_to_libcall, irreloc_to_relocationkind, get_vmctx_value_label, irlibcall_to_libcall, irreloc_to_relocationkind,
signature_to_cranelift_ir, transform_jump_table, type_to_irtype, signature_to_cranelift_ir, type_to_irtype,
}; };
pub(crate) use self::unwind::{compiled_function_unwind_info, CraneliftUnwindInfo}; pub(crate) use self::unwind::{compiled_function_unwind_info, CraneliftUnwindInfo};

View File

@@ -6,13 +6,11 @@ use core::u32;
use cranelift_codegen::binemit::Reloc; use cranelift_codegen::binemit::Reloc;
use cranelift_codegen::ir::{self, AbiParam}; use cranelift_codegen::ir::{self, AbiParam};
use cranelift_codegen::isa::TargetFrontendConfig; use cranelift_codegen::isa::TargetFrontendConfig;
use cranelift_entity::{EntityRef as CraneliftEntityRef, SecondaryMap as CraneliftSecondaryMap};
use cranelift_frontend::FunctionBuilder; use cranelift_frontend::FunctionBuilder;
use wasmer_compiler::wasm_unsupported; use wasmer_compiler::wasm_unsupported;
use wasmer_compiler::wasmparser; use wasmer_compiler::wasmparser;
use wasmer_compiler::{JumpTable, RelocationKind}; use wasmer_compiler::RelocationKind;
use wasmer_compiler::{WasmError, WasmResult}; use wasmer_compiler::{WasmError, WasmResult};
use wasmer_types::entity::{EntityRef, SecondaryMap};
use wasmer_types::{FunctionType, Type}; use wasmer_types::{FunctionType, Type};
use wasmer_vm::libcalls::LibCall; use wasmer_vm::libcalls::LibCall;
@@ -86,7 +84,6 @@ pub fn irreloc_to_relocationkind(reloc: Reloc) -> RelocationKind {
Reloc::Abs4 => RelocationKind::Abs4, Reloc::Abs4 => RelocationKind::Abs4,
Reloc::Abs8 => RelocationKind::Abs8, Reloc::Abs8 => RelocationKind::Abs8,
Reloc::X86PCRel4 => RelocationKind::X86PCRel4, Reloc::X86PCRel4 => RelocationKind::X86PCRel4,
Reloc::X86PCRelRodata4 => RelocationKind::X86PCRelRodata4,
Reloc::X86CallPCRel4 => RelocationKind::X86CallPCRel4, Reloc::X86CallPCRel4 => RelocationKind::X86CallPCRel4,
Reloc::X86CallPLTRel4 => RelocationKind::X86CallPLTRel4, Reloc::X86CallPLTRel4 => RelocationKind::X86CallPLTRel4,
Reloc::X86GOTPCRel4 => RelocationKind::X86GOTPCRel4, Reloc::X86GOTPCRel4 => RelocationKind::X86GOTPCRel4,
@@ -148,16 +145,3 @@ pub fn get_vmctx_value_label() -> ir::ValueLabel {
const VMCTX_LABEL: u32 = 0xffff_fffe; const VMCTX_LABEL: u32 = 0xffff_fffe;
ir::ValueLabel::from_u32(VMCTX_LABEL) ir::ValueLabel::from_u32(VMCTX_LABEL)
} }
/// Transforms Cranelift JumpTable's into runtime JumpTables
pub fn transform_jump_table(
jt_offsets: CraneliftSecondaryMap<ir::JumpTable, u32>,
) -> SecondaryMap<JumpTable, u32> {
let mut func_jt_offsets = SecondaryMap::with_capacity(jt_offsets.capacity());
for (key, value) in jt_offsets.iter() {
let new_key = JumpTable::new(key.index());
func_jt_offsets[new_key] = *value;
}
func_jt_offsets
}

View File

@@ -43,7 +43,7 @@ pub(crate) fn compiled_function_unwind_info(
) -> Result<CraneliftUnwindInfo, CompileError> { ) -> Result<CraneliftUnwindInfo, CompileError> {
let unwind_info = context let unwind_info = context
.create_unwind_info(isa) .create_unwind_info(isa)
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?; .map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
match unwind_info { match unwind_info {
Some(UnwindInfo::WindowsX64(unwind)) => { Some(UnwindInfo::WindowsX64(unwind)) => {

View File

@@ -9,7 +9,7 @@ use wasmer_compiler::{
CustomSections, FunctionAddressMap, FunctionBody, InstructionAddressMap, Relocation, CustomSections, FunctionAddressMap, FunctionBody, InstructionAddressMap, Relocation,
RelocationKind, RelocationTarget, SectionBody, SectionIndex, SourceLoc, RelocationKind, RelocationTarget, SectionBody, SectionIndex, SourceLoc,
}; };
use wasmer_types::entity::{PrimaryMap, SecondaryMap}; use wasmer_types::entity::PrimaryMap;
use wasmer_vm::libcalls::LibCall; use wasmer_vm::libcalls::LibCall;
fn map_tryfromint_err(error: TryFromIntError) -> CompileError { fn map_tryfromint_err(error: TryFromIntError) -> CompileError {
@@ -331,7 +331,6 @@ where
Ok(CompiledFunction { Ok(CompiledFunction {
compiled_function: wasmer_compiler::CompiledFunction { compiled_function: wasmer_compiler::CompiledFunction {
body: function_body, body: function_body,
jt_offsets: SecondaryMap::new(),
relocations: relocations relocations: relocations
.remove_entry(&root_section_index) .remove_entry(&root_section_index)
.map_or(vec![], |(_, v)| v), .map_or(vec![], |(_, v)| v),

View File

@@ -155,11 +155,6 @@ impl FuncTrampoline {
"trampoline generation produced relocations".into(), "trampoline generation produced relocations".into(),
)); ));
} }
if !compiled_function.jt_offsets.is_empty() {
return Err(CompileError::Codegen(
"trampoline generation produced jump tables".into(),
));
}
// Ignore CompiledFunctionFrameInfo. Extra frame info isn't a problem. // Ignore CompiledFunctionFrameInfo. Extra frame info isn't a problem.
Ok(FunctionBody { Ok(FunctionBody {
@@ -280,11 +275,6 @@ impl FuncTrampoline {
"trampoline generation produced relocations".into(), "trampoline generation produced relocations".into(),
)); ));
} }
if !compiled_function.jt_offsets.is_empty() {
return Err(CompileError::Codegen(
"trampoline generation produced jump tables".into(),
));
}
// Ignore CompiledFunctionFrameInfo. Extra frame info isn't a problem. // Ignore CompiledFunctionFrameInfo. Extra frame info isn't a problem.
Ok(FunctionBody { Ok(FunctionBody {

View File

@@ -18,7 +18,7 @@ use wasmer_compiler::{
Relocation, RelocationTarget, SectionIndex, Relocation, RelocationTarget, SectionIndex,
}; };
use wasmer_types::{ use wasmer_types::{
entity::{EntityRef, PrimaryMap, SecondaryMap}, entity::{EntityRef, PrimaryMap},
FunctionType, FunctionType,
}; };
use wasmer_types::{ use wasmer_types::{
@@ -5935,7 +5935,6 @@ impl<'a, M: Machine> FuncGen<'a, M> {
unwind_info, unwind_info,
}, },
relocations: self.relocations.clone(), relocations: self.relocations.clone(),
jt_offsets: SecondaryMap::new(),
frame_info: CompiledFunctionFrameInfo { frame_info: CompiledFunctionFrameInfo {
traps: traps, traps: traps,
address_map, address_map,

View File

@@ -7,7 +7,7 @@
use crate::lib::std::vec::Vec; use crate::lib::std::vec::Vec;
use crate::section::{CustomSection, SectionIndex}; use crate::section::{CustomSection, SectionIndex};
use crate::trap::TrapInformation; use crate::trap::TrapInformation;
use crate::{CompiledFunctionUnwindInfo, FunctionAddressMap, JumpTableOffsets, Relocation}; use crate::{CompiledFunctionUnwindInfo, FunctionAddressMap, Relocation};
use loupe::MemoryUsage; use loupe::MemoryUsage;
#[cfg(feature = "enable-rkyv")] #[cfg(feature = "enable-rkyv")]
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
@@ -70,9 +70,6 @@ pub struct CompiledFunction {
/// The relocations (in the body) /// The relocations (in the body)
pub relocations: Vec<Relocation>, pub relocations: Vec<Relocation>,
/// The jump tables offsets (in the body).
pub jt_offsets: JumpTableOffsets,
/// The frame information. /// The frame information.
pub frame_info: CompiledFunctionFrameInfo, pub frame_info: CompiledFunctionFrameInfo,
} }
@@ -206,14 +203,6 @@ impl Compilation {
.collect::<PrimaryMap<LocalFunctionIndex, _>>() .collect::<PrimaryMap<LocalFunctionIndex, _>>()
} }
/// Gets functions jump table offsets.
pub fn get_jt_offsets(&self) -> PrimaryMap<LocalFunctionIndex, JumpTableOffsets> {
self.functions
.iter()
.map(|(_, func)| func.jt_offsets.clone())
.collect::<PrimaryMap<LocalFunctionIndex, _>>()
}
/// Gets functions frame info. /// Gets functions frame info.
pub fn get_frame_info(&self) -> PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo> { pub fn get_frame_info(&self) -> PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo> {
self.functions self.functions

View File

@@ -1,43 +0,0 @@
//! A jump table is a method of transferring program control (branching)
//! to another part of a program (or a different program that may have
//! been dynamically loaded) using a table of branch or jump instructions.
//!
//! [Learn more](https://en.wikipedia.org/wiki/Branch_table).
use super::CodeOffset;
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 wasmer_types::entity::{entity_impl, SecondaryMap};
/// An opaque reference to a [jump table](https://en.wikipedia.org/wiki/Branch_table).
///
/// `JumpTable`s are used for indirect branching and are specialized for dense,
/// 0-based jump offsets.
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "enable-rkyv",
derive(RkyvSerialize, RkyvDeserialize, Archive)
)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, MemoryUsage)]
pub struct JumpTable(u32);
entity_impl!(JumpTable, "jt");
impl JumpTable {
/// Create a new jump table reference from its number.
///
/// This method is for use by the parser.
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::max_value() {
Some(Self(n))
} else {
None
}
}
}
/// Code offsets for Jump Tables.
pub type JumpTableOffsets = SecondaryMap<JumpTable, CodeOffset>;

View File

@@ -54,7 +54,6 @@ mod address_map;
mod compiler; mod compiler;
mod error; mod error;
mod function; mod function;
mod jump_table;
mod module; mod module;
mod relocation; mod relocation;
mod target; mod target;
@@ -76,7 +75,6 @@ pub use crate::function::{
Compilation, CompiledFunction, CompiledFunctionFrameInfo, CustomSections, Dwarf, FunctionBody, Compilation, CompiledFunction, CompiledFunctionFrameInfo, CustomSections, Dwarf, FunctionBody,
Functions, Functions,
}; };
pub use crate::jump_table::{JumpTable, JumpTableOffsets};
pub use crate::module::CompileModuleInfo; pub use crate::module::CompileModuleInfo;
pub use crate::relocation::{Relocation, RelocationKind, RelocationTarget, Relocations}; pub use crate::relocation::{Relocation, RelocationKind, RelocationTarget, Relocations};
pub use crate::section::{CustomSection, CustomSectionProtection, SectionBody, SectionIndex}; pub use crate::section::{CustomSection, CustomSectionProtection, SectionBody, SectionIndex};

View File

@@ -12,7 +12,7 @@
use crate::lib::std::fmt; use crate::lib::std::fmt;
use crate::lib::std::vec::Vec; use crate::lib::std::vec::Vec;
use crate::section::SectionIndex; use crate::section::SectionIndex;
use crate::{Addend, CodeOffset, JumpTable}; use crate::{Addend, CodeOffset};
use loupe::MemoryUsage; use loupe::MemoryUsage;
#[cfg(feature = "enable-rkyv")] #[cfg(feature = "enable-rkyv")]
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
@@ -38,8 +38,6 @@ pub enum RelocationKind {
X86PCRel4, X86PCRel4,
/// x86 PC-relative 8-byte /// x86 PC-relative 8-byte
X86PCRel8, X86PCRel8,
/// x86 PC-relative 4-byte offset to trailing rodata
X86PCRelRodata4,
/// x86 call to PC-relative 4-byte /// x86 call to PC-relative 4-byte
X86CallPCRel4, X86CallPCRel4,
/// x86 call to PLT-relative 4-byte /// x86 call to PLT-relative 4-byte
@@ -67,7 +65,6 @@ impl fmt::Display for RelocationKind {
Self::Abs8 => write!(f, "Abs8"), Self::Abs8 => write!(f, "Abs8"),
Self::X86PCRel4 => write!(f, "PCRel4"), Self::X86PCRel4 => write!(f, "PCRel4"),
Self::X86PCRel8 => write!(f, "PCRel8"), Self::X86PCRel8 => write!(f, "PCRel8"),
Self::X86PCRelRodata4 => write!(f, "PCRelRodata4"),
Self::X86CallPCRel4 => write!(f, "CallPCRel4"), Self::X86CallPCRel4 => write!(f, "CallPCRel4"),
Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"), Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"),
Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"), Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"),
@@ -108,8 +105,6 @@ pub enum RelocationTarget {
LocalFunc(LocalFunctionIndex), LocalFunc(LocalFunctionIndex),
/// A compiler-generated libcall. /// A compiler-generated libcall.
LibCall(LibCall), LibCall(LibCall),
/// Jump table index.
JumpTable(LocalFunctionIndex, JumpTable),
/// Custom sections generated by the compiler /// Custom sections generated by the compiler
CustomSection(SectionIndex), CustomSection(SectionIndex),
} }
@@ -163,9 +158,6 @@ impl Relocation {
.wrapping_add(reloc_addend as u64); .wrapping_add(reloc_addend as u64);
(reloc_address, reloc_delta_u32) (reloc_address, reloc_delta_u32)
} }
// RelocationKind::X86PCRelRodata4 => {
// (start, target_func_address)
// }
_ => panic!("Relocation kind unsupported"), _ => panic!("Relocation kind unsupported"),
} }
} }

View File

@@ -123,7 +123,6 @@ impl UniversalArtifact {
let serializable_compilation = SerializableCompilation { let serializable_compilation = SerializableCompilation {
function_bodies: compilation.get_function_bodies(), function_bodies: compilation.get_function_bodies(),
function_relocations: compilation.get_relocations(), function_relocations: compilation.get_relocations(),
function_jt_offsets: compilation.get_jt_offsets(),
function_frame_info: frame_infos, function_frame_info: frame_infos,
function_call_trampolines, function_call_trampolines,
dynamic_function_trampolines, dynamic_function_trampolines,
@@ -193,7 +192,6 @@ impl UniversalArtifact {
link_module( link_module(
&serializable.compile_info.module, &serializable.compile_info.module,
&finished_functions, &finished_functions,
&serializable.compilation.function_jt_offsets,
serializable.compilation.function_relocations.clone(), serializable.compilation.function_relocations.clone(),
&custom_sections, &custom_sections,
&serializable.compilation.custom_section_relocations, &serializable.compilation.custom_section_relocations,

View File

@@ -2,12 +2,9 @@
use crate::trampoline::get_libcall_trampoline; use crate::trampoline::get_libcall_trampoline;
use std::ptr::{read_unaligned, write_unaligned}; use std::ptr::{read_unaligned, write_unaligned};
use wasmer_compiler::{ use wasmer_compiler::{Relocation, RelocationKind, RelocationTarget, Relocations, SectionIndex};
JumpTable, JumpTableOffsets, Relocation, RelocationKind, RelocationTarget, Relocations,
SectionIndex,
};
use wasmer_engine::FunctionExtent; use wasmer_engine::FunctionExtent;
use wasmer_types::entity::{EntityRef, PrimaryMap}; use wasmer_types::entity::PrimaryMap;
use wasmer_types::{LocalFunctionIndex, ModuleInfo}; use wasmer_types::{LocalFunctionIndex, ModuleInfo};
use wasmer_vm::SectionBodyPtr; use wasmer_vm::SectionBodyPtr;
@@ -15,7 +12,6 @@ fn apply_relocation(
body: usize, body: usize,
r: &Relocation, r: &Relocation,
allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionExtent>, allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionExtent>,
jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>, allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
libcall_trampolines: SectionIndex, libcall_trampolines: SectionIndex,
libcall_trampoline_len: usize, libcall_trampoline_len: usize,
@@ -38,13 +34,6 @@ fn apply_relocation(
RelocationTarget::CustomSection(custom_section) => { RelocationTarget::CustomSection(custom_section) => {
*allocated_sections[custom_section] as usize *allocated_sections[custom_section] as usize
} }
RelocationTarget::JumpTable(func_index, jt) => {
let offset = *jt_offsets
.get(func_index)
.and_then(|ofs| ofs.get(JumpTable::new(jt.index())))
.expect("func jump table");
*allocated_functions[func_index].ptr as usize + offset as usize
}
}; };
match r.kind { match r.kind {
@@ -67,7 +56,6 @@ fn apply_relocation(
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64); let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
write_unaligned(reloc_address as *mut u32, reloc_delta as _); write_unaligned(reloc_address as *mut u32, reloc_delta as _);
}, },
RelocationKind::X86PCRelRodata4 => {}
RelocationKind::Arm64Call => unsafe { RelocationKind::Arm64Call => unsafe {
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64); let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
if (reloc_delta as i64).abs() >= 0x1000_0000 { if (reloc_delta as i64).abs() >= 0x1000_0000 {
@@ -95,7 +83,6 @@ fn apply_relocation(
pub fn link_module( pub fn link_module(
_module: &ModuleInfo, _module: &ModuleInfo,
allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionExtent>, allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionExtent>,
jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
function_relocations: Relocations, function_relocations: Relocations,
allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>, allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
section_relocations: &PrimaryMap<SectionIndex, Vec<Relocation>>, section_relocations: &PrimaryMap<SectionIndex, Vec<Relocation>>,
@@ -109,7 +96,6 @@ pub fn link_module(
body, body,
r, r,
allocated_functions, allocated_functions,
jt_offsets,
allocated_sections, allocated_sections,
libcall_trampolines, libcall_trampolines,
trampoline_len, trampoline_len,
@@ -123,7 +109,6 @@ pub fn link_module(
body, body,
r, r,
allocated_functions, allocated_functions,
jt_offsets,
allocated_sections, allocated_sections,
libcall_trampolines, libcall_trampolines,
trampoline_len, trampoline_len,

View File

@@ -5,8 +5,8 @@ use rkyv::{
Serialize as RkyvSerialize, Serialize as RkyvSerialize,
}; };
use wasmer_compiler::{ use wasmer_compiler::{
CompileModuleInfo, CompiledFunctionFrameInfo, CustomSection, Dwarf, FunctionBody, CompileModuleInfo, CompiledFunctionFrameInfo, CustomSection, Dwarf, FunctionBody, Relocation,
JumpTableOffsets, Relocation, SectionIndex, SectionIndex,
}; };
use wasmer_engine::{DeserializeError, SerializeError}; use wasmer_engine::{DeserializeError, SerializeError};
use wasmer_types::entity::PrimaryMap; use wasmer_types::entity::PrimaryMap;
@@ -17,7 +17,6 @@ use wasmer_types::{FunctionIndex, LocalFunctionIndex, OwnedDataInitializer, Sign
pub struct SerializableCompilation { pub struct SerializableCompilation {
pub function_bodies: PrimaryMap<LocalFunctionIndex, FunctionBody>, pub function_bodies: PrimaryMap<LocalFunctionIndex, FunctionBody>,
pub function_relocations: PrimaryMap<LocalFunctionIndex, Vec<Relocation>>, pub function_relocations: PrimaryMap<LocalFunctionIndex, Vec<Relocation>>,
pub function_jt_offsets: PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
pub function_frame_info: PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo>, pub function_frame_info: PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo>,
pub function_call_trampolines: PrimaryMap<SignatureIndex, FunctionBody>, pub function_call_trampolines: PrimaryMap<SignatureIndex, FunctionBody>,
pub dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBody>, pub dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBody>,

View File

@@ -292,8 +292,6 @@ pub fn emit_compilation(
Reloc::X86GOTPCRel4 => { Reloc::X86GOTPCRel4 => {
(RelocationKind::GotRelative, RelocationEncoding::Generic, 32) (RelocationKind::GotRelative, RelocationEncoding::Generic, 32)
} }
// Reloc::X86PCRelRodata4 => {
// }
Reloc::Arm64Call => ( Reloc::Arm64Call => (
match obj.format() { match obj.format() {
object::BinaryFormat::Elf => RelocationKind::Elf(elf::R_AARCH64_CALL26), object::BinaryFormat::Elf => RelocationKind::Elf(elf::R_AARCH64_CALL26),
@@ -378,9 +376,6 @@ pub fn emit_compilation(
) )
.map_err(ObjectError::Write)?; .map_err(ObjectError::Write)?;
} }
RelocationTarget::JumpTable(_func_index, _jt) => {
// do nothing
}
}; };
} }
} }