mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-16 17:18:57 +00:00
Merge #1781
1781: Cranelift upgrade r=syrusakbary a=syrusakbary <!-- Prior to submitting a PR, review the CONTRIBUTING.md document for recommendations on how to test: https://github.com/wasmerio/wasmer/blob/master/CONTRIBUTING.md#pull-requests --> # Description Upgrade Cranelift to `0.67`. This upgrade also enables all SIMD tests (with one small exception operator that is still not fixed in Cranelift). <!-- Provide details regarding the change including motivation, links to related issues, and the context of the PR. --> Co-authored-by: Syrus <me@syrusakbary.com> Co-authored-by: Syrus Akbary <me@syrusakbary.com>
This commit is contained in:
33
Cargo.lock
generated
33
Cargo.lock
generated
@@ -317,18 +317,18 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-bforest"
|
name = "cranelift-bforest"
|
||||||
version = "0.65.0"
|
version = "0.67.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9413a2c6bdb01ab8acc867421bd7343ddea491d015453f4e56f4f60c816d120"
|
checksum = "0f065f6889758f817f61a230220d1811ba99a9762af2fb69ae23048314f75ff2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen"
|
name = "cranelift-codegen"
|
||||||
version = "0.65.0"
|
version = "0.67.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f28d389588c2375bb95292e0bc6cbf010e7f30fb4e9734738b576521b737826a"
|
checksum = "510aa2ab4307644100682b94e449940a0ea15c5887f1d4b9678b8dd5ef31e736"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"cranelift-bforest",
|
"cranelift-bforest",
|
||||||
@@ -347,9 +347,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-meta"
|
name = "cranelift-codegen-meta"
|
||||||
version = "0.65.0"
|
version = "0.67.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74dd3cf6f107c1df4c2b8aab91ec4181aee7ff17289673fcbec63325e7e40a83"
|
checksum = "b4cb0c7e87c60d63b35f9670c15479ee4a5e557dd127efab88b2f9b2ca83c9a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen-shared",
|
"cranelift-codegen-shared",
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
@@ -357,24 +357,24 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-shared"
|
name = "cranelift-codegen-shared"
|
||||||
version = "0.65.0"
|
version = "0.67.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "efaf050fab2dbf324544489443ff3cc8c67c9420c8902ec6628bd906bd7393e9"
|
checksum = "60636227098693e06de8d6d88beea2a7d32ecf8a8030dacdb57c68e06f381826"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-entity"
|
name = "cranelift-entity"
|
||||||
version = "0.65.0"
|
version = "0.67.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f07eb8aa0a5da94b56339e4e3052c496a3df4354357cd5da8c7b02c6e8f1dc1d"
|
checksum = "6156db73e0c9f65f80c512988d63ec736be0dee3dd66bf951e3e28aed9dc02d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-frontend"
|
name = "cranelift-frontend"
|
||||||
version = "0.65.0"
|
version = "0.67.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f6fe1d3e968576f4b60d23f40ee90281f8de2cdf23d2110f3b0296ff420555e"
|
checksum = "e09cd158c9a820a4cc14a34076811da225cce1d31dc6d03c5ef85b91aef560b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"hashbrown 0.7.2",
|
"hashbrown 0.7.2",
|
||||||
@@ -1568,9 +1568,9 @@ checksum = "d813022b2e00774a48eaf43caaa3c20b45f040ba8cbf398e2e8911a06668dbe6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regalloc"
|
name = "regalloc"
|
||||||
version = "0.0.26"
|
version = "0.0.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7c03092d79e0fd610932d89ed53895a38c0dd3bcd317a0046e69940de32f1d95"
|
checksum = "2041c2d34f6ff346d6f428974f03d8bf12679b0c816bb640dc5eb1d48848d8d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
@@ -1855,9 +1855,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "target-lexicon"
|
name = "target-lexicon"
|
||||||
version = "0.10.0"
|
version = "0.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d"
|
checksum = "4ee5a98e506fb7231a304c3a1bd7c132a55016cf65001e0282480665870dfcb9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
@@ -2263,6 +2263,7 @@ dependencies = [
|
|||||||
"more-asserts",
|
"more-asserts",
|
||||||
"rayon",
|
"rayon",
|
||||||
"serde",
|
"serde",
|
||||||
|
"smallvec",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"tracing",
|
"tracing",
|
||||||
"wasmer-compiler",
|
"wasmer-compiler",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ cfg-if = "0.1"
|
|||||||
wat = { version = "1.0", optional = true }
|
wat = { version = "1.0", optional = true }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
more-asserts = "0.2"
|
more-asserts = "0.2"
|
||||||
target-lexicon = { version = "0.10", default-features = false }
|
target-lexicon = { version = "0.11", default-features = false }
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = "0.3"
|
winapi = "0.3"
|
||||||
|
|||||||
@@ -15,18 +15,19 @@ edition = "2018"
|
|||||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4", features = ["translator"], default-features = false }
|
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4", features = ["translator"], default-features = false }
|
||||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4", default-features = false, features = ["std"] }
|
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4", default-features = false, features = ["std"] }
|
||||||
cranelift-codegen = { version = "0.65", default-features = false, features = ["x86", "arm64"] }
|
cranelift-codegen = { version = "0.67", default-features = false, features = ["x86", "arm64"] }
|
||||||
cranelift-frontend = { version = "0.65", default-features = false }
|
cranelift-frontend = { version = "0.67", default-features = false }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
hashbrown = { version = "0.8", optional = true }
|
hashbrown = { version = "0.8", optional = true }
|
||||||
rayon = "1.3"
|
rayon = "1.3"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
more-asserts = "0.2"
|
more-asserts = "0.2"
|
||||||
gimli = { version = "0.21", optional = true }
|
gimli = { version = "0.21", optional = true }
|
||||||
|
smallvec = "1.0.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
target-lexicon = { version = "0.10", default-features = false }
|
target-lexicon = { version = "0.11", default-features = false }
|
||||||
cranelift-codegen = { version = "0.65", features = ["enable-serde", "all-arch"] }
|
cranelift-codegen = { version = "0.67", features = ["enable-serde", "all-arch"] }
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
@@ -35,6 +36,6 @@ maintenance = { status = "actively-developed" }
|
|||||||
[features]
|
[features]
|
||||||
default = ["std", "enable-serde", "unwind"]
|
default = ["std", "enable-serde", "unwind"]
|
||||||
unwind = ["cranelift-codegen/unwind", "gimli"]
|
unwind = ["cranelift-codegen/unwind", "gimli"]
|
||||||
enable-serde = ["wasmer-compiler/enable-serde", "cranelift-codegen/enable-serde", "wasmer-types/enable-serde"]
|
enable-serde = ["wasmer-compiler/enable-serde", "wasmer-types/enable-serde"]
|
||||||
std = ["cranelift-codegen/std", "cranelift-frontend/std", "wasmer-compiler/std", "wasmer-types/std"]
|
std = ["cranelift-codegen/std", "cranelift-frontend/std", "wasmer-compiler/std", "wasmer-types/std"]
|
||||||
core = ["hashbrown", "cranelift-codegen/core", "cranelift-frontend/core"]
|
core = ["hashbrown", "cranelift-codegen/core", "cranelift-frontend/core"]
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ impl Compiler for CraneliftCompiler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let functions = function_body_inputs
|
let functions = function_body_inputs
|
||||||
.into_iter()
|
.iter()
|
||||||
.collect::<Vec<(LocalFunctionIndex, &FunctionBodyData<'_>)>>()
|
.collect::<Vec<(LocalFunctionIndex, &FunctionBodyData<'_>)>>()
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map_init(FuncTranslator::new, |func_translator, (i, input)| {
|
.map_init(FuncTranslator::new, |func_translator, (i, input)| {
|
||||||
@@ -127,7 +127,7 @@ 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 reloc_sink = RelocSink::new(module, func_index);
|
||||||
let mut trap_sink = TrapSink::new();
|
let mut trap_sink = TrapSink::new();
|
||||||
let mut stackmap_sink = binemit::NullStackmapSink {};
|
let mut stackmap_sink = binemit::NullStackMapSink {};
|
||||||
context
|
context
|
||||||
.compile_and_emit(
|
.compile_and_emit(
|
||||||
&*isa,
|
&*isa,
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ use cranelift_codegen::ir::immediates::{Offset32, Uimm64};
|
|||||||
use cranelift_codegen::ir::types::*;
|
use cranelift_codegen::ir::types::*;
|
||||||
use cranelift_codegen::ir::{AbiParam, ArgumentPurpose, Function, InstBuilder, Signature};
|
use cranelift_codegen::ir::{AbiParam, ArgumentPurpose, Function, InstBuilder, Signature};
|
||||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||||
|
use cranelift_frontend::FunctionBuilder;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use wasmer_compiler::wasmparser::Type;
|
||||||
use wasmer_compiler::{WasmError, WasmResult};
|
use wasmer_compiler::{WasmError, WasmResult};
|
||||||
use wasmer_types::entity::EntityRef;
|
use wasmer_types::entity::EntityRef;
|
||||||
use wasmer_types::entity::PrimaryMap;
|
use wasmer_types::entity::PrimaryMap;
|
||||||
@@ -538,10 +540,11 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
|
|
||||||
fn translate_table_grow(
|
fn translate_table_grow(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: cranelift_codegen::cursor::FuncCursor<'_>,
|
mut _pos: cranelift_codegen::cursor::FuncCursor<'_>,
|
||||||
_: TableIndex,
|
_table_index: TableIndex,
|
||||||
_: ir::Value,
|
_table: ir::Table,
|
||||||
_: ir::Value,
|
_delta: ir::Value,
|
||||||
|
_init_value: ir::Value,
|
||||||
) -> WasmResult<ir::Value> {
|
) -> WasmResult<ir::Value> {
|
||||||
Err(WasmError::Unsupported(
|
Err(WasmError::Unsupported(
|
||||||
"the `table.grow` instruction is not supported yet".into(),
|
"the `table.grow` instruction is not supported yet".into(),
|
||||||
@@ -550,9 +553,10 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
|
|
||||||
fn translate_table_get(
|
fn translate_table_get(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: cranelift_codegen::cursor::FuncCursor<'_>,
|
_builder: &mut FunctionBuilder,
|
||||||
_: TableIndex,
|
_table_index: TableIndex,
|
||||||
_: ir::Value,
|
_table: ir::Table,
|
||||||
|
_index: ir::Value,
|
||||||
) -> WasmResult<ir::Value> {
|
) -> WasmResult<ir::Value> {
|
||||||
Err(WasmError::Unsupported(
|
Err(WasmError::Unsupported(
|
||||||
"the `table.get` instruction is not supported yet".into(),
|
"the `table.get` instruction is not supported yet".into(),
|
||||||
@@ -561,10 +565,11 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
|
|
||||||
fn translate_table_set(
|
fn translate_table_set(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: cranelift_codegen::cursor::FuncCursor<'_>,
|
_builder: &mut FunctionBuilder,
|
||||||
_: TableIndex,
|
_table_index: TableIndex,
|
||||||
_: ir::Value,
|
_table: ir::Table,
|
||||||
_: ir::Value,
|
_value: ir::Value,
|
||||||
|
_index: ir::Value,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
Err(WasmError::Unsupported(
|
Err(WasmError::Unsupported(
|
||||||
"the `table.set` instruction is not supported yet".into(),
|
"the `table.set` instruction is not supported yet".into(),
|
||||||
@@ -573,21 +578,56 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
|
|
||||||
fn translate_table_fill(
|
fn translate_table_fill(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: cranelift_codegen::cursor::FuncCursor<'_>,
|
mut _pos: cranelift_codegen::cursor::FuncCursor<'_>,
|
||||||
_: TableIndex,
|
_table_index: TableIndex,
|
||||||
_: ir::Value,
|
_dst: ir::Value,
|
||||||
_: ir::Value,
|
_val: ir::Value,
|
||||||
_: ir::Value,
|
_len: ir::Value,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
Err(WasmError::Unsupported(
|
Err(WasmError::Unsupported(
|
||||||
"the `table.fill` instruction is not supported yet".into(),
|
"the `table.fill` instruction is not supported yet".into(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn translate_ref_null(
|
||||||
|
&mut self,
|
||||||
|
mut pos: cranelift_codegen::cursor::FuncCursor,
|
||||||
|
ty: Type,
|
||||||
|
) -> WasmResult<ir::Value> {
|
||||||
|
Ok(match ty {
|
||||||
|
Type::FuncRef => pos.ins().iconst(self.pointer_type(), 0),
|
||||||
|
// Type::ExternRef => pos.ins().null(self.reference_type(ty)),
|
||||||
|
_ => {
|
||||||
|
return Err(WasmError::Unsupported(
|
||||||
|
"`ref.null T` that is not a `funcref`".into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn translate_ref_is_null(
|
||||||
|
&mut self,
|
||||||
|
mut pos: cranelift_codegen::cursor::FuncCursor,
|
||||||
|
value: ir::Value,
|
||||||
|
) -> WasmResult<ir::Value> {
|
||||||
|
let bool_is_null = match pos.func.dfg.value_type(value) {
|
||||||
|
// `externref`
|
||||||
|
ty if ty.is_ref() => pos.ins().is_null(value),
|
||||||
|
// `funcref`
|
||||||
|
ty if ty == self.pointer_type() => {
|
||||||
|
pos.ins()
|
||||||
|
.icmp_imm(cranelift_codegen::ir::condcodes::IntCC::Equal, value, 0)
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(pos.ins().bint(ir::types::I32, bool_is_null))
|
||||||
|
}
|
||||||
|
|
||||||
fn translate_ref_func(
|
fn translate_ref_func(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: cranelift_codegen::cursor::FuncCursor<'_>,
|
mut _pos: cranelift_codegen::cursor::FuncCursor<'_>,
|
||||||
_: u32,
|
_func_index: FunctionIndex,
|
||||||
) -> WasmResult<ir::Value> {
|
) -> WasmResult<ir::Value> {
|
||||||
Err(WasmError::Unsupported(
|
Err(WasmError::Unsupported(
|
||||||
"the `ref.func` instruction is not supported yet".into(),
|
"the `ref.func` instruction is not supported yet".into(),
|
||||||
@@ -596,17 +636,17 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
|
|
||||||
fn translate_custom_global_get(
|
fn translate_custom_global_get(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: cranelift_codegen::cursor::FuncCursor<'_>,
|
mut _pos: cranelift_codegen::cursor::FuncCursor<'_>,
|
||||||
_: GlobalIndex,
|
_index: GlobalIndex,
|
||||||
) -> WasmResult<ir::Value> {
|
) -> WasmResult<ir::Value> {
|
||||||
unreachable!("we don't make any custom globals")
|
unreachable!("we don't make any custom globals")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_custom_global_set(
|
fn translate_custom_global_set(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: cranelift_codegen::cursor::FuncCursor<'_>,
|
mut _pos: cranelift_codegen::cursor::FuncCursor<'_>,
|
||||||
_: GlobalIndex,
|
_index: GlobalIndex,
|
||||||
_: ir::Value,
|
_value: ir::Value,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
unreachable!("we don't make any custom globals")
|
unreachable!("we don't make any custom globals")
|
||||||
}
|
}
|
||||||
@@ -771,7 +811,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
match self.table_styles[table_index] {
|
match self.table_styles[table_index] {
|
||||||
TableStyle::CallerChecksSignature => {
|
TableStyle::CallerChecksSignature => {
|
||||||
let sig_id_size = self.offsets.size_of_vmshared_signature_index();
|
let sig_id_size = self.offsets.size_of_vmshared_signature_index();
|
||||||
let sig_id_type = Type::int(u16::from(sig_id_size) * 8).unwrap();
|
let sig_id_type = ir::Type::int(u16::from(sig_id_size) * 8).unwrap();
|
||||||
let vmctx = self.vmctx(pos.func);
|
let vmctx = self.vmctx(pos.func);
|
||||||
let base = pos.ins().global_value(pointer_type, vmctx);
|
let base = pos.ins().global_value(pointer_type, vmctx);
|
||||||
let offset =
|
let offset =
|
||||||
@@ -897,24 +937,22 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
fn translate_memory_copy(
|
fn translate_memory_copy(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut pos: FuncCursor,
|
mut pos: FuncCursor,
|
||||||
memory_index: MemoryIndex,
|
src_index: MemoryIndex,
|
||||||
_heap: ir::Heap,
|
_src_heap: ir::Heap,
|
||||||
|
_dst_index: MemoryIndex,
|
||||||
|
_dst_heap: ir::Heap,
|
||||||
dst: ir::Value,
|
dst: ir::Value,
|
||||||
src: ir::Value,
|
src: ir::Value,
|
||||||
len: ir::Value,
|
len: ir::Value,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
let (func_sig, memory_index, func_idx) =
|
let (func_sig, src_index, func_idx) = self.get_memory_copy_func(&mut pos.func, src_index);
|
||||||
self.get_memory_copy_func(&mut pos.func, memory_index);
|
|
||||||
|
|
||||||
let memory_index_arg = pos.ins().iconst(I32, memory_index as i64);
|
let src_index_arg = pos.ins().iconst(I32, src_index as i64);
|
||||||
|
|
||||||
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
|
|
||||||
pos.ins().call_indirect(
|
pos.ins()
|
||||||
func_sig,
|
.call_indirect(func_sig, func_addr, &[vmctx, src_index_arg, dst, src, len]);
|
||||||
func_addr,
|
|
||||||
&[vmctx, memory_index_arg, dst, src, len],
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -981,8 +1019,8 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
|
|
||||||
fn translate_table_size(
|
fn translate_table_size(
|
||||||
&mut self,
|
&mut self,
|
||||||
_pos: FuncCursor,
|
mut _pos: FuncCursor,
|
||||||
_index: TableIndex,
|
_table_index: TableIndex,
|
||||||
_table: ir::Table,
|
_table: ir::Table,
|
||||||
) -> WasmResult<ir::Value> {
|
) -> WasmResult<ir::Value> {
|
||||||
Err(WasmError::Unsupported(
|
Err(WasmError::Unsupported(
|
||||||
@@ -1064,4 +1102,31 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn translate_atomic_wait(
|
||||||
|
&mut self,
|
||||||
|
_pos: FuncCursor,
|
||||||
|
_index: MemoryIndex,
|
||||||
|
_heap: ir::Heap,
|
||||||
|
_addr: ir::Value,
|
||||||
|
_expected: ir::Value,
|
||||||
|
_timeout: ir::Value,
|
||||||
|
) -> WasmResult<ir::Value> {
|
||||||
|
Err(WasmError::Unsupported(
|
||||||
|
"wasm atomics (fn translate_atomic_wait)".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn translate_atomic_notify(
|
||||||
|
&mut self,
|
||||||
|
_pos: FuncCursor,
|
||||||
|
_index: MemoryIndex,
|
||||||
|
_heap: ir::Heap,
|
||||||
|
_addr: ir::Value,
|
||||||
|
_count: ir::Value,
|
||||||
|
) -> WasmResult<ir::Value> {
|
||||||
|
Err(WasmError::Unsupported(
|
||||||
|
"wasm atomics (fn translate_atomic_notify)".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ fn translate_ir_trapcode(trap: ir::TrapCode) -> TrapCode {
|
|||||||
match trap {
|
match trap {
|
||||||
ir::TrapCode::StackOverflow => TrapCode::StackOverflow,
|
ir::TrapCode::StackOverflow => TrapCode::StackOverflow,
|
||||||
ir::TrapCode::HeapOutOfBounds => TrapCode::HeapAccessOutOfBounds,
|
ir::TrapCode::HeapOutOfBounds => TrapCode::HeapAccessOutOfBounds,
|
||||||
|
ir::TrapCode::HeapMisaligned => TrapCode::HeapMisaligned,
|
||||||
ir::TrapCode::TableOutOfBounds => TrapCode::TableAccessOutOfBounds,
|
ir::TrapCode::TableOutOfBounds => TrapCode::TableAccessOutOfBounds,
|
||||||
ir::TrapCode::IndirectCallToNull => TrapCode::IndirectCallToNull,
|
ir::TrapCode::IndirectCallToNull => TrapCode::IndirectCallToNull,
|
||||||
ir::TrapCode::BadSignature => TrapCode::BadSignature,
|
ir::TrapCode::BadSignature => TrapCode::BadSignature,
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ 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 reloc_sink = TrampolineRelocSink {};
|
||||||
let mut trap_sink = binemit::NullTrapSink {};
|
let mut trap_sink = binemit::NullTrapSink {};
|
||||||
let mut stackmap_sink = binemit::NullStackmapSink {};
|
let mut stackmap_sink = binemit::NullStackMapSink {};
|
||||||
context
|
context
|
||||||
.compile_and_emit(
|
.compile_and_emit(
|
||||||
isa,
|
isa,
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ 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 reloc_sink = TrampolineRelocSink {};
|
||||||
let mut trap_sink = binemit::NullTrapSink {};
|
let mut trap_sink = binemit::NullTrapSink {};
|
||||||
let mut stackmap_sink = binemit::NullStackmapSink {};
|
let mut stackmap_sink = binemit::NullStackMapSink {};
|
||||||
|
|
||||||
context
|
context
|
||||||
.compile_and_emit(
|
.compile_and_emit(
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pub use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
|
|||||||
|
|
||||||
pub mod binemit {
|
pub mod binemit {
|
||||||
pub use cranelift_codegen::binemit::NullTrapSink;
|
pub use cranelift_codegen::binemit::NullTrapSink;
|
||||||
pub use cranelift_codegen::binemit::{CodeOffset, NullStackmapSink, TrapSink};
|
pub use cranelift_codegen::binemit::{CodeOffset, NullStackMapSink, TrapSink};
|
||||||
|
|
||||||
use cranelift_codegen::{binemit, ir};
|
use cranelift_codegen::{binemit, ir};
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@ use cranelift_codegen::ir::immediates::Offset32;
|
|||||||
use cranelift_codegen::ir::{self, InstBuilder};
|
use cranelift_codegen::ir::{self, InstBuilder};
|
||||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||||
use cranelift_frontend::FunctionBuilder;
|
use cranelift_frontend::FunctionBuilder;
|
||||||
use wasmer_compiler::wasmparser::Operator;
|
use wasmer_compiler::wasmparser::{Operator, Type};
|
||||||
use wasmer_compiler::WasmResult;
|
use wasmer_compiler::WasmResult;
|
||||||
use wasmer_types::{FunctionIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex};
|
use wasmer_types::{FunctionIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex};
|
||||||
|
|
||||||
@@ -229,8 +229,10 @@ pub trait FuncEnvironment: TargetEnvironment {
|
|||||||
fn translate_memory_copy(
|
fn translate_memory_copy(
|
||||||
&mut self,
|
&mut self,
|
||||||
pos: FuncCursor,
|
pos: FuncCursor,
|
||||||
index: MemoryIndex,
|
src_index: MemoryIndex,
|
||||||
heap: ir::Heap,
|
src_heap: ir::Heap,
|
||||||
|
dst_index: MemoryIndex,
|
||||||
|
dst_heap: ir::Heap,
|
||||||
dst: ir::Value,
|
dst: ir::Value,
|
||||||
src: ir::Value,
|
src: ir::Value,
|
||||||
len: ir::Value,
|
len: ir::Value,
|
||||||
@@ -283,6 +285,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
|||||||
&mut self,
|
&mut self,
|
||||||
pos: FuncCursor,
|
pos: FuncCursor,
|
||||||
table_index: TableIndex,
|
table_index: TableIndex,
|
||||||
|
table: ir::Table,
|
||||||
delta: ir::Value,
|
delta: ir::Value,
|
||||||
init_value: ir::Value,
|
init_value: ir::Value,
|
||||||
) -> WasmResult<ir::Value>;
|
) -> WasmResult<ir::Value>;
|
||||||
@@ -290,16 +293,18 @@ pub trait FuncEnvironment: TargetEnvironment {
|
|||||||
/// Translate a `table.get` WebAssembly instruction.
|
/// Translate a `table.get` WebAssembly instruction.
|
||||||
fn translate_table_get(
|
fn translate_table_get(
|
||||||
&mut self,
|
&mut self,
|
||||||
pos: FuncCursor,
|
builder: &mut FunctionBuilder,
|
||||||
table_index: TableIndex,
|
table_index: TableIndex,
|
||||||
|
table: ir::Table,
|
||||||
index: ir::Value,
|
index: ir::Value,
|
||||||
) -> WasmResult<ir::Value>;
|
) -> WasmResult<ir::Value>;
|
||||||
|
|
||||||
/// Translate a `table.set` WebAssembly instruction.
|
/// Translate a `table.set` WebAssembly instruction.
|
||||||
fn translate_table_set(
|
fn translate_table_set(
|
||||||
&mut self,
|
&mut self,
|
||||||
pos: FuncCursor,
|
builder: &mut FunctionBuilder,
|
||||||
table_index: TableIndex,
|
table_index: TableIndex,
|
||||||
|
table: ir::Table,
|
||||||
value: ir::Value,
|
value: ir::Value,
|
||||||
index: ir::Value,
|
index: ir::Value,
|
||||||
) -> WasmResult<()>;
|
) -> WasmResult<()>;
|
||||||
@@ -344,8 +349,44 @@ pub trait FuncEnvironment: TargetEnvironment {
|
|||||||
/// Translate a `elem.drop` WebAssembly instruction.
|
/// Translate a `elem.drop` WebAssembly instruction.
|
||||||
fn translate_elem_drop(&mut self, pos: FuncCursor, seg_index: u32) -> WasmResult<()>;
|
fn translate_elem_drop(&mut self, pos: FuncCursor, seg_index: u32) -> WasmResult<()>;
|
||||||
|
|
||||||
|
/// Translate a `ref.null T` WebAssembly instruction.
|
||||||
|
///
|
||||||
|
/// By default, translates into a null reference type.
|
||||||
|
///
|
||||||
|
/// Override this if you don't use Cranelift reference types for all Wasm
|
||||||
|
/// reference types (e.g. you use a raw pointer for `funcref`s) or if the
|
||||||
|
/// null sentinel is not a null reference type pointer for your type. If you
|
||||||
|
/// override this method, then you should also override
|
||||||
|
/// `translate_ref_is_null` as well.
|
||||||
|
fn translate_ref_null(&mut self, pos: FuncCursor, ty: Type) -> WasmResult<ir::Value>;
|
||||||
|
// {
|
||||||
|
// let _ = ty;
|
||||||
|
// Ok(pos.ins().null(self.reference_type(ty)))
|
||||||
|
// }
|
||||||
|
|
||||||
|
/// Translate a `ref.is_null` WebAssembly instruction.
|
||||||
|
///
|
||||||
|
/// By default, assumes that `value` is a Cranelift reference type, and that
|
||||||
|
/// a null Cranelift reference type is the null value for all Wasm reference
|
||||||
|
/// types.
|
||||||
|
///
|
||||||
|
/// If you override this method, you probably also want to override
|
||||||
|
/// `translate_ref_null` as well.
|
||||||
|
fn translate_ref_is_null(
|
||||||
|
&mut self,
|
||||||
|
mut pos: FuncCursor,
|
||||||
|
value: ir::Value,
|
||||||
|
) -> WasmResult<ir::Value> {
|
||||||
|
let is_null = pos.ins().is_null(value);
|
||||||
|
Ok(pos.ins().bint(ir::types::I32, is_null))
|
||||||
|
}
|
||||||
|
|
||||||
/// Translate a `ref.func` WebAssembly instruction.
|
/// Translate a `ref.func` WebAssembly instruction.
|
||||||
fn translate_ref_func(&mut self, pos: FuncCursor, func_index: u32) -> WasmResult<ir::Value>;
|
fn translate_ref_func(
|
||||||
|
&mut self,
|
||||||
|
pos: FuncCursor,
|
||||||
|
func_index: FunctionIndex,
|
||||||
|
) -> WasmResult<ir::Value>;
|
||||||
|
|
||||||
/// Translate a `global.get` WebAssembly instruction at `pos` for a global
|
/// Translate a `global.get` WebAssembly instruction at `pos` for a global
|
||||||
/// that is custom.
|
/// that is custom.
|
||||||
@@ -364,6 +405,38 @@ pub trait FuncEnvironment: TargetEnvironment {
|
|||||||
val: ir::Value,
|
val: ir::Value,
|
||||||
) -> WasmResult<()>;
|
) -> WasmResult<()>;
|
||||||
|
|
||||||
|
/// Translate an `i32.atomic.wait` or `i64.atomic.wait` WebAssembly instruction.
|
||||||
|
/// The `index` provided identifies the linear memory containing the value
|
||||||
|
/// to wait on, and `heap` is the heap reference returned by `make_heap`
|
||||||
|
/// for the same index. Whether the waited-on value is 32- or 64-bit can be
|
||||||
|
/// determined by examining the type of `expected`, which must be only I32 or I64.
|
||||||
|
///
|
||||||
|
/// Returns an i32, which is negative if the helper call failed.
|
||||||
|
fn translate_atomic_wait(
|
||||||
|
&mut self,
|
||||||
|
pos: FuncCursor,
|
||||||
|
index: MemoryIndex,
|
||||||
|
heap: ir::Heap,
|
||||||
|
addr: ir::Value,
|
||||||
|
expected: ir::Value,
|
||||||
|
timeout: ir::Value,
|
||||||
|
) -> WasmResult<ir::Value>;
|
||||||
|
|
||||||
|
/// Translate an `atomic.notify` WebAssembly instruction.
|
||||||
|
/// The `index` provided identifies the linear memory containing the value
|
||||||
|
/// to wait on, and `heap` is the heap reference returned by `make_heap`
|
||||||
|
/// for the same index.
|
||||||
|
///
|
||||||
|
/// Returns an i64, which is negative if the helper call failed.
|
||||||
|
fn translate_atomic_notify(
|
||||||
|
&mut self,
|
||||||
|
pos: FuncCursor,
|
||||||
|
index: MemoryIndex,
|
||||||
|
heap: ir::Heap,
|
||||||
|
addr: ir::Value,
|
||||||
|
count: ir::Value,
|
||||||
|
) -> WasmResult<ir::Value>;
|
||||||
|
|
||||||
/// Emit code at the beginning of every wasm loop.
|
/// Emit code at the beginning of every wasm loop.
|
||||||
///
|
///
|
||||||
/// This can be used to insert explicit interrupt or safepoint checking at
|
/// This can be used to insert explicit interrupt or safepoint checking at
|
||||||
|
|||||||
@@ -132,7 +132,9 @@ impl ControlStackFrame {
|
|||||||
Self::Loop { header, .. } => header,
|
Self::Loop { header, .. } => header,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn original_stack_size(&self) -> usize {
|
/// Private helper. Use `truncate_value_stack_to_else_params()` or
|
||||||
|
/// `truncate_value_stack_to_original_size()` to restore value-stack state.
|
||||||
|
fn original_stack_size(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
Self::If {
|
Self::If {
|
||||||
original_stack_size,
|
original_stack_size,
|
||||||
@@ -182,6 +184,33 @@ impl ControlStackFrame {
|
|||||||
Self::Loop { .. } => {}
|
Self::Loop { .. } => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pop values from the value stack so that it is left at the
|
||||||
|
/// input-parameters to an else-block.
|
||||||
|
pub fn truncate_value_stack_to_else_params(&self, stack: &mut Vec<Value>) {
|
||||||
|
debug_assert!(matches!(self, &ControlStackFrame::If { .. }));
|
||||||
|
stack.truncate(self.original_stack_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pop values from the value stack so that it is left at the state it was
|
||||||
|
/// before this control-flow frame.
|
||||||
|
pub fn truncate_value_stack_to_original_size(&self, stack: &mut Vec<Value>) {
|
||||||
|
// The "If" frame pushes its parameters twice, so they're available to the else block
|
||||||
|
// (see also `FuncTranslationState::push_if`).
|
||||||
|
// Yet, the original_stack_size member accounts for them only once, so that the else
|
||||||
|
// block can see the same number of parameters as the consequent block. As a matter of
|
||||||
|
// fact, we need to substract an extra number of parameter values for if blocks.
|
||||||
|
let num_duplicated_params = match self {
|
||||||
|
&ControlStackFrame::If {
|
||||||
|
num_param_values, ..
|
||||||
|
} => {
|
||||||
|
debug_assert!(num_param_values <= self.original_stack_size());
|
||||||
|
num_param_values
|
||||||
|
}
|
||||||
|
_ => 0,
|
||||||
|
};
|
||||||
|
stack.truncate(self.original_stack_size() - num_duplicated_params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contains information passed along during a function's translation and that records:
|
/// Contains information passed along during a function's translation and that records:
|
||||||
@@ -219,6 +248,16 @@ pub struct FuncTranslationState {
|
|||||||
functions: HashMap<FunctionIndex, (ir::FuncRef, usize)>,
|
functions: HashMap<FunctionIndex, (ir::FuncRef, usize)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Public methods that are exposed to non-`cranelift_wasm` API consumers.
|
||||||
|
impl FuncTranslationState {
|
||||||
|
/// True if the current translation state expresses reachable code, false if it is unreachable.
|
||||||
|
#[inline]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn reachable(&self) -> bool {
|
||||||
|
self.reachable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FuncTranslationState {
|
impl FuncTranslationState {
|
||||||
/// Construct a new, empty, `FuncTranslationState`
|
/// Construct a new, empty, `FuncTranslationState`
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
@@ -441,7 +480,7 @@ impl FuncTranslationState {
|
|||||||
|
|
||||||
/// Get the `Table` reference that should be used to access table `index`.
|
/// Get the `Table` reference that should be used to access table `index`.
|
||||||
/// Create the reference if necessary.
|
/// Create the reference if necessary.
|
||||||
pub(crate) fn get_table<FE: FuncEnvironment + ?Sized>(
|
pub(crate) fn get_or_create_table<FE: FuncEnvironment + ?Sized>(
|
||||||
&mut self,
|
&mut self,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
index: u32,
|
index: u32,
|
||||||
|
|||||||
@@ -176,12 +176,9 @@ fn parse_local_decls<FE: FuncEnvironment + ?Sized>(
|
|||||||
let mut next_local = num_params;
|
let mut next_local = num_params;
|
||||||
let local_count = reader.read_local_count().map_err(to_wasm_error)?;
|
let local_count = reader.read_local_count().map_err(to_wasm_error)?;
|
||||||
|
|
||||||
let mut locals_total = 0;
|
|
||||||
for _ in 0..local_count {
|
for _ in 0..local_count {
|
||||||
builder.set_srcloc(cur_srcloc(reader));
|
builder.set_srcloc(cur_srcloc(reader));
|
||||||
let (count, ty) = reader
|
let (count, ty) = reader.read_local_decl().map_err(to_wasm_error)?;
|
||||||
.read_local_decl(&mut locals_total)
|
|
||||||
.map_err(to_wasm_error)?;
|
|
||||||
declare_locals(builder, count, ty, &mut next_local, environ)?;
|
declare_locals(builder, count, ty, &mut next_local, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ edition = "2018"
|
|||||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4", features = ["translator"] }
|
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4", features = ["translator"] }
|
||||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||||
target-lexicon = { version = "0.10", default-features = false }
|
target-lexicon = { version = "0.11", default-features = false }
|
||||||
smallvec = "1"
|
smallvec = "1"
|
||||||
goblin = "0.2"
|
goblin = "0.2"
|
||||||
libc = { version = "^0.2.69", default-features = false }
|
libc = { version = "^0.2.69", default-features = false }
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ impl LLVMCompiler {
|
|||||||
compile_info
|
compile_info
|
||||||
.module
|
.module
|
||||||
.signatures
|
.signatures
|
||||||
.into_iter()
|
.iter()
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map_init(
|
.map_init(
|
||||||
@@ -149,7 +149,7 @@ impl LLVMCompiler {
|
|||||||
compile_info
|
compile_info
|
||||||
.module
|
.module
|
||||||
.functions
|
.functions
|
||||||
.into_iter()
|
.iter()
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map_init(
|
.map_init(
|
||||||
@@ -248,7 +248,7 @@ impl Compiler for LLVMCompiler {
|
|||||||
let mut frame_section_bytes = vec![];
|
let mut frame_section_bytes = vec![];
|
||||||
let mut frame_section_relocations = vec![];
|
let mut frame_section_relocations = vec![];
|
||||||
let functions = function_body_inputs
|
let functions = function_body_inputs
|
||||||
.into_iter()
|
.iter()
|
||||||
.collect::<Vec<(LocalFunctionIndex, &FunctionBodyData<'_>)>>()
|
.collect::<Vec<(LocalFunctionIndex, &FunctionBodyData<'_>)>>()
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map_init(
|
.map_init(
|
||||||
|
|||||||
@@ -184,10 +184,7 @@ impl FuncTranslator {
|
|||||||
let mut locals = vec![];
|
let mut locals = vec![];
|
||||||
let num_locals = reader.read_local_count().map_err(to_wasm_error)?;
|
let num_locals = reader.read_local_count().map_err(to_wasm_error)?;
|
||||||
for _ in 0..num_locals {
|
for _ in 0..num_locals {
|
||||||
let mut counter = 0;
|
let (count, ty) = reader.read_local_decl().map_err(to_wasm_error)?;
|
||||||
let (count, ty) = reader
|
|
||||||
.read_local_decl(&mut counter)
|
|
||||||
.map_err(to_wasm_error)?;
|
|
||||||
let ty = wptype_to_type(ty).map_err(to_compile_error)?;
|
let ty = wptype_to_type(ty).map_err(to_compile_error)?;
|
||||||
let ty = type_to_llvm(&intrinsics, ty)?;
|
let ty = type_to_llvm(&intrinsics, ty)?;
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ impl Compiler for SinglepassCompiler {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.collect();
|
.collect();
|
||||||
let functions = function_body_inputs
|
let functions = function_body_inputs
|
||||||
.into_iter()
|
.iter()
|
||||||
.collect::<Vec<(LocalFunctionIndex, &FunctionBodyData<'_>)>>()
|
.collect::<Vec<(LocalFunctionIndex, &FunctionBodyData<'_>)>>()
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|(i, input)| {
|
.map(|(i, input)| {
|
||||||
@@ -82,10 +82,7 @@ impl Compiler for SinglepassCompiler {
|
|||||||
let mut locals = vec![];
|
let mut locals = vec![];
|
||||||
let num_locals = reader.read_local_count().map_err(to_compile_error)?;
|
let num_locals = reader.read_local_count().map_err(to_compile_error)?;
|
||||||
for _ in 0..num_locals {
|
for _ in 0..num_locals {
|
||||||
let mut counter = 0;
|
let (count, ty) = reader.read_local_decl().map_err(to_compile_error)?;
|
||||||
let (count, ty) = reader
|
|
||||||
.read_local_decl(&mut counter)
|
|
||||||
.map_err(to_compile_error)?;
|
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
locals.push(ty);
|
locals.push(ty);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ edition = "2018"
|
|||||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4", default-features = false }
|
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4", default-features = false }
|
||||||
wasmparser = { version = "0.65", optional = true, default-features = false }
|
wasmparser = { version = "0.65", optional = true, default-features = false }
|
||||||
target-lexicon = { version = "0.10", default-features = false }
|
target-lexicon = { version = "0.11", default-features = false }
|
||||||
enumset = "1.0"
|
enumset = "1.0"
|
||||||
hashbrown = { version = "0.8", optional = true }
|
hashbrown = { version = "0.8", optional = true }
|
||||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ impl<'a> MiddlewareBinaryReader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read a `(count, value_type)` declaration of local variables of the same type.
|
/// Read a `(count, value_type)` declaration of local variables of the same type.
|
||||||
pub fn read_local_decl(&mut self, locals_total: &mut usize) -> WpResult<(u32, Type)> {
|
pub fn read_local_decl(&mut self) -> WpResult<(u32, Type)> {
|
||||||
let count = self.state.inner.read_var_u32()?;
|
let count = self.state.inner.read_var_u32()?;
|
||||||
let ty = self.state.inner.read_type()?;
|
let ty = self.state.inner.read_type()?;
|
||||||
Ok((count, ty))
|
Ok((count, ty))
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ pub fn link_module(
|
|||||||
apply_relocation(body, r, allocated_functions, jt_offsets, allocated_sections);
|
apply_relocation(body, r, allocated_functions, jt_offsets, allocated_sections);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i, function_relocs) in function_relocations.into_iter() {
|
for (i, function_relocs) in function_relocations.iter() {
|
||||||
let fatptr: *const [VMFunctionBody] = allocated_functions[i].0;
|
let fatptr: *const [VMFunctionBody] = allocated_functions[i].0;
|
||||||
let body = fatptr as *const VMFunctionBody as usize;
|
let body = fatptr as *const VMFunctionBody as usize;
|
||||||
for r in function_relocs {
|
for r in function_relocs {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ edition = "2018"
|
|||||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4" }
|
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4" }
|
||||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||||
target-lexicon = { version = "0.10", default-features = false }
|
target-lexicon = { version = "0.11", default-features = false }
|
||||||
# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" }
|
# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" }
|
||||||
backtrace = "0.3"
|
backtrace = "0.3"
|
||||||
rustc-demangle = "0.1"
|
rustc-demangle = "0.1"
|
||||||
|
|||||||
@@ -32,44 +32,47 @@ pub enum TrapCode {
|
|||||||
/// offset-guard pages.
|
/// offset-guard pages.
|
||||||
HeapAccessOutOfBounds = 2,
|
HeapAccessOutOfBounds = 2,
|
||||||
|
|
||||||
|
/// A `heap_addr` instruction was misaligned.
|
||||||
|
HeapMisaligned = 3,
|
||||||
|
|
||||||
/// Table Elements doesn't fit the table size.
|
/// Table Elements doesn't fit the table size.
|
||||||
///
|
///
|
||||||
/// This only can happen during instantiation.
|
/// This only can happen during instantiation.
|
||||||
TableSetterOutOfBounds = 3,
|
TableSetterOutOfBounds = 4,
|
||||||
|
|
||||||
/// A `table_addr` instruction detected an out-of-bounds error.
|
/// A `table_addr` instruction detected an out-of-bounds error.
|
||||||
TableAccessOutOfBounds = 4,
|
TableAccessOutOfBounds = 5,
|
||||||
|
|
||||||
/// Other bounds checking error.
|
/// Other bounds checking error.
|
||||||
OutOfBounds = 5,
|
OutOfBounds = 6,
|
||||||
|
|
||||||
/// Indirect call to a null table entry.
|
/// Indirect call to a null table entry.
|
||||||
IndirectCallToNull = 6,
|
IndirectCallToNull = 7,
|
||||||
|
|
||||||
/// Signature mismatch on indirect call.
|
/// Signature mismatch on indirect call.
|
||||||
BadSignature = 7,
|
BadSignature = 8,
|
||||||
|
|
||||||
/// An integer arithmetic operation caused an overflow.
|
/// An integer arithmetic operation caused an overflow.
|
||||||
IntegerOverflow = 8,
|
IntegerOverflow = 9,
|
||||||
|
|
||||||
/// An integer division by zero.
|
/// An integer division by zero.
|
||||||
IntegerDivisionByZero = 9,
|
IntegerDivisionByZero = 10,
|
||||||
|
|
||||||
/// Failed float-to-int conversion.
|
/// Failed float-to-int conversion.
|
||||||
BadConversionToInteger = 10,
|
BadConversionToInteger = 11,
|
||||||
|
|
||||||
/// Code that was supposed to have been unreachable was reached.
|
/// Code that was supposed to have been unreachable was reached.
|
||||||
UnreachableCodeReached = 11,
|
UnreachableCodeReached = 12,
|
||||||
|
|
||||||
/// Execution has potentially run too long and may be interrupted.
|
/// Execution has potentially run too long and may be interrupted.
|
||||||
/// This trap is resumable.
|
/// This trap is resumable.
|
||||||
Interrupt = 12,
|
Interrupt = 13,
|
||||||
|
|
||||||
/// An atomic memory access was attempted with an unaligned pointer.
|
/// An atomic memory access was attempted with an unaligned pointer.
|
||||||
UnalignedAtomic = 13,
|
UnalignedAtomic = 14,
|
||||||
|
|
||||||
/// A trap indicating that the runtime was unable to allocate sufficient memory.
|
/// A trap indicating that the runtime was unable to allocate sufficient memory.
|
||||||
VMOutOfMemory = 14,
|
VMOutOfMemory = 15,
|
||||||
// /// A user-defined trap code.
|
// /// A user-defined trap code.
|
||||||
// User(u16),
|
// User(u16),
|
||||||
}
|
}
|
||||||
@@ -81,6 +84,7 @@ impl TrapCode {
|
|||||||
Self::StackOverflow => "call stack exhausted",
|
Self::StackOverflow => "call stack exhausted",
|
||||||
Self::HeapSetterOutOfBounds => "memory out of bounds: data segment does not fit",
|
Self::HeapSetterOutOfBounds => "memory out of bounds: data segment does not fit",
|
||||||
Self::HeapAccessOutOfBounds => "out of bounds memory access",
|
Self::HeapAccessOutOfBounds => "out of bounds memory access",
|
||||||
|
Self::HeapMisaligned => "misaligned heap",
|
||||||
Self::TableSetterOutOfBounds => "table out of bounds: elements segment does not fit",
|
Self::TableSetterOutOfBounds => "table out of bounds: elements segment does not fit",
|
||||||
Self::TableAccessOutOfBounds => "undefined element: out of bounds table access",
|
Self::TableAccessOutOfBounds => "undefined element: out of bounds table access",
|
||||||
Self::OutOfBounds => "out of bounds",
|
Self::OutOfBounds => "out of bounds",
|
||||||
@@ -104,6 +108,7 @@ impl Display for TrapCode {
|
|||||||
Self::StackOverflow => "stk_ovf",
|
Self::StackOverflow => "stk_ovf",
|
||||||
Self::HeapSetterOutOfBounds => "heap_set_oob",
|
Self::HeapSetterOutOfBounds => "heap_set_oob",
|
||||||
Self::HeapAccessOutOfBounds => "heap_get_oob",
|
Self::HeapAccessOutOfBounds => "heap_get_oob",
|
||||||
|
Self::HeapMisaligned => "heap_misaligned",
|
||||||
Self::TableSetterOutOfBounds => "table_set_oob",
|
Self::TableSetterOutOfBounds => "table_set_oob",
|
||||||
Self::TableAccessOutOfBounds => "table_get_oob",
|
Self::TableAccessOutOfBounds => "table_get_oob",
|
||||||
Self::OutOfBounds => "oob",
|
Self::OutOfBounds => "oob",
|
||||||
@@ -131,6 +136,7 @@ impl FromStr for TrapCode {
|
|||||||
"stk_ovf" => Ok(StackOverflow),
|
"stk_ovf" => Ok(StackOverflow),
|
||||||
"heap_set_oob" => Ok(HeapSetterOutOfBounds),
|
"heap_set_oob" => Ok(HeapSetterOutOfBounds),
|
||||||
"heap_get_oob" => Ok(HeapAccessOutOfBounds),
|
"heap_get_oob" => Ok(HeapAccessOutOfBounds),
|
||||||
|
"heap_misaligned" => Ok(HeapMisaligned),
|
||||||
"table_set_oob" => Ok(TableSetterOutOfBounds),
|
"table_set_oob" => Ok(TableSetterOutOfBounds),
|
||||||
"table_get_oob" => Ok(TableAccessOutOfBounds),
|
"table_get_oob" => Ok(TableAccessOutOfBounds),
|
||||||
"oob" => Ok(OutOfBounds),
|
"oob" => Ok(OutOfBounds),
|
||||||
@@ -154,10 +160,11 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// Everything but user-defined codes.
|
// Everything but user-defined codes.
|
||||||
const CODES: [TrapCode; 14] = [
|
const CODES: [TrapCode; 15] = [
|
||||||
TrapCode::StackOverflow,
|
TrapCode::StackOverflow,
|
||||||
TrapCode::HeapSetterOutOfBounds,
|
TrapCode::HeapSetterOutOfBounds,
|
||||||
TrapCode::HeapAccessOutOfBounds,
|
TrapCode::HeapAccessOutOfBounds,
|
||||||
|
TrapCode::HeapMisaligned,
|
||||||
TrapCode::TableSetterOutOfBounds,
|
TrapCode::TableSetterOutOfBounds,
|
||||||
TrapCode::TableAccessOutOfBounds,
|
TrapCode::TableAccessOutOfBounds,
|
||||||
TrapCode::OutOfBounds,
|
TrapCode::OutOfBounds,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
# We use `cranelift-entity` here because it's a lightweight dependency and it contains
|
# We use `cranelift-entity` here because it's a lightweight dependency and it contains
|
||||||
# some useful data structures
|
# some useful data structures
|
||||||
cranelift-entity = "0.65"
|
cranelift-entity = "0.67"
|
||||||
serde = { version = "1.0", features = ["derive"], optional = true, default-features = false }
|
serde = { version = "1.0", features = ["derive"], optional = true, default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
@@ -2,17 +2,8 @@
|
|||||||
singlepass::spec::multi_value
|
singlepass::spec::multi_value
|
||||||
singlepass::spec::simd
|
singlepass::spec::simd
|
||||||
|
|
||||||
## SIMD in Cranelift 0.65 is not fully supported
|
## SIMD in Cranelift 0.67 has a small bug
|
||||||
cranelift::spec::simd::simd_conversions
|
|
||||||
cranelift::spec::simd::simd_f32x4
|
|
||||||
cranelift::spec::simd::simd_f64x2
|
|
||||||
cranelift::spec::simd::simd_f64x2_arith
|
cranelift::spec::simd::simd_f64x2_arith
|
||||||
cranelift::spec::simd::simd_i16x8_arith2
|
|
||||||
cranelift::spec::simd::simd_i32x4_arith2
|
|
||||||
cranelift::spec::simd::simd_i8x16_arith2
|
|
||||||
cranelift::spec::simd::simd_load
|
|
||||||
cranelift::spec::simd::simd_splat
|
|
||||||
|
|
||||||
|
|
||||||
singlepass on windows # Singlepass is not yet supported on Windows
|
singlepass on windows # Singlepass is not yet supported on Windows
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ publish = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
target-lexicon = "0.10"
|
target-lexicon = "0.11"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
test-native = []
|
test-native = []
|
||||||
|
|||||||
Reference in New Issue
Block a user