Merge remote-tracking branch 'origin/main' into pch/factor_borrowchecker_out_of_wiggle
This commit is contained in:
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -49,6 +49,8 @@ jobs:
|
|||||||
doc_api:
|
doc_api:
|
||||||
name: Doc - build the API documentation
|
name: Doc - build the API documentation
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
RUSTDOCFLAGS: -Dintra-doc-link-resolution-failure
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
|
|||||||
36
Cargo.lock
generated
36
Cargo.lock
generated
@@ -595,7 +595,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasmparser 0.57.0",
|
"wasmparser 0.58.0",
|
||||||
"wat",
|
"wat",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1123,7 +1123,7 @@ dependencies = [
|
|||||||
"staticvec",
|
"staticvec",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"typemap",
|
"typemap",
|
||||||
"wasmparser 0.57.0",
|
"wasmparser 0.58.0",
|
||||||
"wat",
|
"wat",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1338,6 +1338,7 @@ dependencies = [
|
|||||||
"peepmatic-automata",
|
"peepmatic-automata",
|
||||||
"peepmatic-macro",
|
"peepmatic-macro",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_test",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wast 15.0.0",
|
"wast 15.0.0",
|
||||||
]
|
]
|
||||||
@@ -1881,6 +1882,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_test"
|
||||||
|
version = "1.0.114"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f58190d074af17bd48118303db08afadbd506bc2ba511b4582cebd8f882a9b8d"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
@@ -2299,9 +2309,9 @@ checksum = "af931e2e1960c53f4a28b063fec4cacd036f35acbec8ff3a4739125b17382a87"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmparser"
|
name = "wasmparser"
|
||||||
version = "0.57.0"
|
version = "0.58.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6"
|
checksum = "721a8d79483738d7aef6397edcf8f04cd862640b1ad5973adf5bb50fc10e86db"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmprinter"
|
name = "wasmprinter"
|
||||||
@@ -2327,7 +2337,7 @@ dependencies = [
|
|||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"wasmparser 0.57.0",
|
"wasmparser 0.58.0",
|
||||||
"wasmtime-environ",
|
"wasmtime-environ",
|
||||||
"wasmtime-jit",
|
"wasmtime-jit",
|
||||||
"wasmtime-profiling",
|
"wasmtime-profiling",
|
||||||
@@ -2400,7 +2410,7 @@ dependencies = [
|
|||||||
"object 0.19.0",
|
"object 0.19.0",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasmparser 0.57.0",
|
"wasmparser 0.58.0",
|
||||||
"wasmtime-environ",
|
"wasmtime-environ",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2431,7 +2441,7 @@ dependencies = [
|
|||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"toml",
|
"toml",
|
||||||
"wasmparser 0.57.0",
|
"wasmparser 0.58.0",
|
||||||
"winapi",
|
"winapi",
|
||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
@@ -2460,7 +2470,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
"rayon",
|
"rayon",
|
||||||
"wasmparser 0.57.0",
|
"wasmparser 0.58.0",
|
||||||
"wasmprinter",
|
"wasmprinter",
|
||||||
"wasmtime",
|
"wasmtime",
|
||||||
"wasmtime-wast",
|
"wasmtime-wast",
|
||||||
@@ -2484,7 +2494,7 @@ dependencies = [
|
|||||||
"region",
|
"region",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasmparser 0.57.0",
|
"wasmparser 0.58.0",
|
||||||
"wasmtime-debug",
|
"wasmtime-debug",
|
||||||
"wasmtime-environ",
|
"wasmtime-environ",
|
||||||
"wasmtime-profiling",
|
"wasmtime-profiling",
|
||||||
@@ -2770,9 +2780,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "z3"
|
name = "z3"
|
||||||
version = "0.5.1"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ded00cd90f8e3a7ea3155bddd72573f2b099ea201877542d924e47b58dd04e72"
|
checksum = "f0354c65dfe00e08c4ab30581732906874f97156f424bfb390cf0cca2cb6ac29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
@@ -2781,9 +2791,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "z3-sys"
|
name = "z3-sys"
|
||||||
version = "0.6.1"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4002d8a1facb54d02dbfb86151281e5450618ab330936bc2f3acaab31eae11ae"
|
checksum = "e1863cafae8eb86dd7d69c9218421b288594e8836346e93d4f36ade427195a21"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cmake",
|
"cmake",
|
||||||
]
|
]
|
||||||
|
|||||||
5
build.rs
5
build.rs
@@ -205,11 +205,6 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool {
|
|||||||
("simd", "simd_i16x8_arith2") => return true,
|
("simd", "simd_i16x8_arith2") => return true,
|
||||||
("simd", "simd_i8x16_arith2") => return true,
|
("simd", "simd_i8x16_arith2") => return true,
|
||||||
|
|
||||||
// waiting for the upstream spec to get updated with new binary
|
|
||||||
// encodings of operations and for that to propagate to the
|
|
||||||
// testsuite repo.
|
|
||||||
("simd", "simd_const") => return true,
|
|
||||||
|
|
||||||
("reference_types", "table_copy_on_imported_tables")
|
("reference_types", "table_copy_on_imported_tables")
|
||||||
| ("reference_types", "externref_id_function")
|
| ("reference_types", "externref_id_function")
|
||||||
| ("reference_types", "table_size")
|
| ("reference_types", "table_size")
|
||||||
|
|||||||
@@ -383,7 +383,7 @@ pub struct ExtFuncData {
|
|||||||
/// flag is best used when the target is known to be in the same unit of code generation, such
|
/// flag is best used when the target is known to be in the same unit of code generation, such
|
||||||
/// as a Wasm module.
|
/// as a Wasm module.
|
||||||
///
|
///
|
||||||
/// See the documentation for [`RelocDistance`](machinst::RelocDistance) for more details. A
|
/// See the documentation for [`RelocDistance`](crate::machinst::RelocDistance) for more details. A
|
||||||
/// `colocated` flag value of `true` implies `RelocDistance::Near`.
|
/// `colocated` flag value of `true` implies `RelocDistance::Near`.
|
||||||
pub colocated: bool,
|
pub colocated: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ pub enum GlobalValueData {
|
|||||||
///
|
///
|
||||||
/// If `true`, some backends may use relocation forms that have limited range: for example,
|
/// If `true`, some backends may use relocation forms that have limited range: for example,
|
||||||
/// a +/- 2^27-byte range on AArch64. See the documentation for
|
/// a +/- 2^27-byte range on AArch64. See the documentation for
|
||||||
/// [`RelocDistance`](machinst::RelocDistance) for more details.
|
/// [`RelocDistance`](crate::machinst::RelocDistance) for more details.
|
||||||
colocated: bool,
|
colocated: bool,
|
||||||
|
|
||||||
/// Does this symbol refer to a thread local storage value?
|
/// Does this symbol refer to a thread local storage value?
|
||||||
|
|||||||
@@ -86,9 +86,9 @@
|
|||||||
//! formal arguments, would:
|
//! formal arguments, would:
|
||||||
//! - Accept a pointer P to the struct return area in x0 on entry.
|
//! - Accept a pointer P to the struct return area in x0 on entry.
|
||||||
//! - Return v3 in x0.
|
//! - Return v3 in x0.
|
||||||
//! - Return v2 in memory at [P].
|
//! - Return v2 in memory at `[P]`.
|
||||||
//! - Return v1 in memory at [P+8].
|
//! - Return v1 in memory at `[P+8]`.
|
||||||
//! - Return v0 in memory at [P+16].
|
//! - Return v0 in memory at `[P+16]`.
|
||||||
|
|
||||||
use crate::ir;
|
use crate::ir;
|
||||||
use crate::ir::types;
|
use crate::ir::types;
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
//! from the branch itself.
|
//! from the branch itself.
|
||||||
//!
|
//!
|
||||||
//! - The lowering of control flow from the CFG-with-edges produced by
|
//! - The lowering of control flow from the CFG-with-edges produced by
|
||||||
//! [BlockLoweringOrder], combined with many empty edge blocks when the register
|
//! [BlockLoweringOrder](super::BlockLoweringOrder), combined with many empty
|
||||||
//! allocator does not need to insert any spills/reloads/moves in edge blocks,
|
//! edge blocks when the register allocator does not need to insert any
|
||||||
//! results in many suboptimal branch patterns. The lowering also pays no
|
//! spills/reloads/moves in edge blocks, results in many suboptimal branch
|
||||||
//! attention to block order, and so two-target conditional forms (cond-br
|
//! patterns. The lowering also pays no attention to block order, and so
|
||||||
//! followed by uncond-br) can often by avoided because one of the targets is
|
//! two-target conditional forms (cond-br followed by uncond-br) can often by
|
||||||
//! the fallthrough. There are several cases here where we can simplify to use
|
//! avoided because one of the targets is the fallthrough. There are several
|
||||||
//! fewer branches.
|
//! cases here where we can simplify to use fewer branches.
|
||||||
//!
|
//!
|
||||||
//! This "buffer" implements a single-pass code emission strategy (with a later
|
//! This "buffer" implements a single-pass code emission strategy (with a later
|
||||||
//! "fixup" pass, but only through recorded fixups, not all instructions). The
|
//! "fixup" pass, but only through recorded fixups, not all instructions). The
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
//! by the emitter (e.g., vcode iterating over instruction structs). The emitter
|
//! by the emitter (e.g., vcode iterating over instruction structs). The emitter
|
||||||
//! has some awareness of this: it either asks for an island between blocks, so
|
//! has some awareness of this: it either asks for an island between blocks, so
|
||||||
//! it is not accidentally executed, or else it emits a branch around the island
|
//! it is not accidentally executed, or else it emits a branch around the island
|
||||||
//! when all other options fail (see [Inst::EmitIsland] meta-instruction).
|
//! when all other options fail (see `Inst::EmitIsland` meta-instruction).
|
||||||
//!
|
//!
|
||||||
//! - A "veneer" is an instruction (or sequence of instructions) in an "island"
|
//! - A "veneer" is an instruction (or sequence of instructions) in an "island"
|
||||||
//! that implements a longer-range reference to a label. The idea is that, for
|
//! that implements a longer-range reference to a label. The idea is that, for
|
||||||
|
|||||||
Binary file not shown.
@@ -39,7 +39,8 @@ pub struct SingleFunctionCompiler {
|
|||||||
|
|
||||||
impl SingleFunctionCompiler {
|
impl SingleFunctionCompiler {
|
||||||
/// Build a [SingleFunctionCompiler] from a [TargetIsa]. For functions to be runnable on the
|
/// Build a [SingleFunctionCompiler] from a [TargetIsa]. For functions to be runnable on the
|
||||||
/// host machine, this [TargetISA] must match the host machine's ISA (see [with_host_isa]).
|
/// host machine, this [TargetIsa] must match the host machine's ISA (see
|
||||||
|
/// [SingleFunctionCompiler::with_host_isa]).
|
||||||
pub fn new(isa: Box<dyn TargetIsa>) -> Self {
|
pub fn new(isa: Box<dyn TargetIsa>) -> Self {
|
||||||
let trampolines = HashMap::new();
|
let trampolines = HashMap::new();
|
||||||
Self { isa, trampolines }
|
Self { isa, trampolines }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//! Test command for interpreting CLIF files and verifying their results
|
//! Test command for interpreting CLIF files and verifying their results
|
||||||
//!
|
//!
|
||||||
//! The `interpret` test command interprets each function on the host machine using [RunCommand]s.
|
//! The `interpret` test command interprets each function on the host machine
|
||||||
|
//! using [RunCommand](cranelift_reader::RunCommand)s.
|
||||||
|
|
||||||
use crate::subtest::{Context, SubTest, SubtestResult};
|
use crate::subtest::{Context, SubTest, SubtestResult};
|
||||||
use cranelift_codegen::{self, ir};
|
use cranelift_codegen::{self, ir};
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ peepmatic-automata = { version = "0.2.0", path = "crates/automata", features = [
|
|||||||
peepmatic-macro = { version = "0.2.0", path = "crates/macro" }
|
peepmatic-macro = { version = "0.2.0", path = "crates/macro" }
|
||||||
peepmatic-runtime = { version = "0.2.0", path = "crates/runtime", features = ["construct"] }
|
peepmatic-runtime = { version = "0.2.0", path = "crates/runtime", features = ["construct"] }
|
||||||
wast = "15.0.0"
|
wast = "15.0.0"
|
||||||
z3 = { version = "0.5.1", features = ["static-link-z3"] }
|
z3 = { version = "0.6.0", features = ["static-link-z3"] }
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ serde = { version = "1.0.105", features = ["derive"] }
|
|||||||
thiserror = "1.0.15"
|
thiserror = "1.0.15"
|
||||||
wast = { version = "15.0.0", optional = true }
|
wast = { version = "15.0.0", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
serde_test = "1.0.114"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# Enable support for a few extra methods that are required by the `peepmatic`
|
# Enable support for a few extra methods that are required by the `peepmatic`
|
||||||
|
|||||||
@@ -5,8 +5,12 @@
|
|||||||
//! few compared to the full range of `u64`) integers we are matching against
|
//! few compared to the full range of `u64`) integers we are matching against
|
||||||
//! here and then reference them by `IntegerId`.
|
//! here and then reference them by `IntegerId`.
|
||||||
|
|
||||||
|
use serde::de::{Deserializer, SeqAccess, Visitor};
|
||||||
|
use serde::ser::{SerializeSeq, Serializer};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::fmt;
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::num::{NonZeroU16, NonZeroU32};
|
use std::num::{NonZeroU16, NonZeroU32};
|
||||||
|
|
||||||
/// An identifier for an interned integer.
|
/// An identifier for an interned integer.
|
||||||
@@ -14,7 +18,7 @@ use std::num::{NonZeroU16, NonZeroU32};
|
|||||||
pub struct IntegerId(#[doc(hidden)] pub NonZeroU16);
|
pub struct IntegerId(#[doc(hidden)] pub NonZeroU16);
|
||||||
|
|
||||||
/// An interner for integer values.
|
/// An interner for integer values.
|
||||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
#[derive(Debug, Default)]
|
||||||
pub struct IntegerInterner {
|
pub struct IntegerInterner {
|
||||||
// Note: we use `BTreeMap`s for deterministic serialization.
|
// Note: we use `BTreeMap`s for deterministic serialization.
|
||||||
map: BTreeMap<u64, IntegerId>,
|
map: BTreeMap<u64, IntegerId>,
|
||||||
@@ -71,3 +75,118 @@ impl From<IntegerId> for NonZeroU32 {
|
|||||||
id.0.into()
|
id.0.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Serialize for IntegerInterner {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let mut seq = serializer.serialize_seq(Some(self.values.len()))?;
|
||||||
|
for p in &self.values {
|
||||||
|
seq.serialize_element(&p)?;
|
||||||
|
}
|
||||||
|
seq.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for IntegerInterner {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
deserializer.deserialize_seq(IntegerInternerVisitor {
|
||||||
|
marker: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IntegerInternerVisitor {
|
||||||
|
marker: PhantomData<fn() -> IntegerInterner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for IntegerInternerVisitor {
|
||||||
|
type Value = IntegerInterner;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
formatter,
|
||||||
|
"a `peepmatic_runtime::integer_interner::IntegerInterner`"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<M>(self, mut access: M) -> Result<Self::Value, M::Error>
|
||||||
|
where
|
||||||
|
M: SeqAccess<'de>,
|
||||||
|
{
|
||||||
|
const DEFAULT_CAPACITY: usize = 16;
|
||||||
|
let capacity = access.size_hint().unwrap_or(DEFAULT_CAPACITY);
|
||||||
|
|
||||||
|
let mut interner = IntegerInterner {
|
||||||
|
map: BTreeMap::new(),
|
||||||
|
values: Vec::with_capacity(capacity),
|
||||||
|
};
|
||||||
|
|
||||||
|
while let Some(path) = access.next_element::<u64>()? {
|
||||||
|
interner.intern(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(interner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use serde_test::{assert_tokens, Token};
|
||||||
|
use std::iter::successors;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct OrderedIntegerInterner(IntegerInterner);
|
||||||
|
|
||||||
|
impl PartialEq for OrderedIntegerInterner {
|
||||||
|
fn eq(&self, other: &OrderedIntegerInterner) -> bool {
|
||||||
|
self.0.values.iter().eq(other.0.values.iter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn intern_fib(interner: &mut IntegerInterner, skip: usize, take: usize) {
|
||||||
|
successors(Some((0, 1)), |(a, b): &(u64, u64)| {
|
||||||
|
a.checked_add(*b).map(|c| (*b, c))
|
||||||
|
})
|
||||||
|
.skip(skip)
|
||||||
|
.take(take)
|
||||||
|
.for_each(|(i, _)| {
|
||||||
|
interner.intern(i);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ser_de_empty_interner() {
|
||||||
|
let interner = IntegerInterner::new();
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&OrderedIntegerInterner(interner),
|
||||||
|
&[Token::Seq { len: Some(0) }, Token::SeqEnd],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ser_de_fibonacci_interner() {
|
||||||
|
let mut interner = IntegerInterner::new();
|
||||||
|
intern_fib(&mut interner, 10, 5);
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&OrderedIntegerInterner(interner),
|
||||||
|
&[
|
||||||
|
Token::Seq { len: Some(5) },
|
||||||
|
Token::U64(55),
|
||||||
|
Token::U64(89),
|
||||||
|
Token::U64(144),
|
||||||
|
Token::U64(233),
|
||||||
|
Token::U64(377),
|
||||||
|
Token::SeqEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use std::num::NonZeroU32;
|
|||||||
/// optimizations to instructions.
|
/// optimizations to instructions.
|
||||||
///
|
///
|
||||||
/// These are created from a set of peephole optimizations with the
|
/// These are created from a set of peephole optimizations with the
|
||||||
/// [`PeepholeOptimizer::instance`][crate::PeepholeOptimizer::instance] method.
|
/// [`PeepholeOptimizations::optimizer`] method.
|
||||||
///
|
///
|
||||||
/// Reusing an instance when applying peephole optimizations to different
|
/// Reusing an instance when applying peephole optimizations to different
|
||||||
/// instruction sequences means that you reuse internal allocations that are
|
/// instruction sequences means that you reuse internal allocations that are
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ impl<'a> TypingContext<'a> {
|
|||||||
let is_void = self.is_void(&root_ty);
|
let is_void = self.is_void(&root_ty);
|
||||||
let is_cpu_flags = self.is_cpu_flags(&root_ty);
|
let is_cpu_flags = self.is_cpu_flags(&root_ty);
|
||||||
self.constraints.push((
|
self.constraints.push((
|
||||||
is_int.or(&[&is_bool, &is_void, &is_cpu_flags]),
|
z3::ast::Bool::or(&self.z3, &[&is_int, &is_bool, &is_void, &is_cpu_flags]),
|
||||||
span,
|
span,
|
||||||
Some(
|
Some(
|
||||||
"the root of an optimization must be an integer, a boolean, void, or CPU flags"
|
"the root of an optimization must be an integer, a boolean, void, or CPU flags"
|
||||||
@@ -719,7 +719,7 @@ impl<'a> TypingContextTrait<'a> for TypingContext<'a> {
|
|||||||
.as_bool()
|
.as_bool()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.constraints.push((
|
self.constraints.push((
|
||||||
is_int.or(&[&is_bool]),
|
z3::ast::Bool::or(&self.z3, &[&is_int, &is_bool]),
|
||||||
span,
|
span,
|
||||||
Some("type error: must be either an int or a bool type".into()),
|
Some("type error: must be either an int or a bool type".into()),
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ keywords = ["webassembly", "wasm"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmparser = { version = "0.57.0", default-features = false }
|
wasmparser = { version = "0.58.0", default-features = false }
|
||||||
cranelift-codegen = { path = "../codegen", version = "0.65.0", default-features = false }
|
cranelift-codegen = { path = "../codegen", version = "0.65.0", default-features = false }
|
||||||
cranelift-entity = { path = "../entity", version = "0.65.0" }
|
cranelift-entity = { path = "../entity", version = "0.65.0" }
|
||||||
cranelift-frontend = { path = "../frontend", version = "0.65.0", default-features = false }
|
cranelift-frontend = { path = "../frontend", version = "0.65.0", default-features = false }
|
||||||
|
|||||||
@@ -1575,7 +1575,10 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
| Operator::I32x4WidenLowI16x8S { .. }
|
| Operator::I32x4WidenLowI16x8S { .. }
|
||||||
| Operator::I32x4WidenHighI16x8S { .. }
|
| Operator::I32x4WidenHighI16x8S { .. }
|
||||||
| Operator::I32x4WidenLowI16x8U { .. }
|
| Operator::I32x4WidenLowI16x8U { .. }
|
||||||
| Operator::I32x4WidenHighI16x8U { .. } => {
|
| Operator::I32x4WidenHighI16x8U { .. }
|
||||||
|
| Operator::I8x16Bitmask
|
||||||
|
| Operator::I16x8Bitmask
|
||||||
|
| Operator::I32x4Bitmask => {
|
||||||
return Err(wasm_unsupported!("proposed SIMD operator {:?}", op));
|
return Err(wasm_unsupported!("proposed SIMD operator {:?}", op));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2007,7 +2010,8 @@ fn type_of(operator: &Operator) -> Type {
|
|||||||
| Operator::I8x16MinU
|
| Operator::I8x16MinU
|
||||||
| Operator::I8x16MaxS
|
| Operator::I8x16MaxS
|
||||||
| Operator::I8x16MaxU
|
| Operator::I8x16MaxU
|
||||||
| Operator::I8x16RoundingAverageU => I8X16,
|
| Operator::I8x16RoundingAverageU
|
||||||
|
| Operator::I8x16Bitmask => I8X16,
|
||||||
|
|
||||||
Operator::I16x8Splat
|
Operator::I16x8Splat
|
||||||
| Operator::V16x8LoadSplat { .. }
|
| Operator::V16x8LoadSplat { .. }
|
||||||
@@ -2041,7 +2045,8 @@ fn type_of(operator: &Operator) -> Type {
|
|||||||
| Operator::I16x8MaxS
|
| Operator::I16x8MaxS
|
||||||
| Operator::I16x8MaxU
|
| Operator::I16x8MaxU
|
||||||
| Operator::I16x8RoundingAverageU
|
| Operator::I16x8RoundingAverageU
|
||||||
| Operator::I16x8Mul => I16X8,
|
| Operator::I16x8Mul
|
||||||
|
| Operator::I16x8Bitmask => I16X8,
|
||||||
|
|
||||||
Operator::I32x4Splat
|
Operator::I32x4Splat
|
||||||
| Operator::V32x4LoadSplat { .. }
|
| Operator::V32x4LoadSplat { .. }
|
||||||
@@ -2071,7 +2076,8 @@ fn type_of(operator: &Operator) -> Type {
|
|||||||
| Operator::I32x4MaxS
|
| Operator::I32x4MaxS
|
||||||
| Operator::I32x4MaxU
|
| Operator::I32x4MaxU
|
||||||
| Operator::F32x4ConvertI32x4S
|
| Operator::F32x4ConvertI32x4S
|
||||||
| Operator::F32x4ConvertI32x4U => I32X4,
|
| Operator::F32x4ConvertI32x4U
|
||||||
|
| Operator::I32x4Bitmask => I32X4,
|
||||||
|
|
||||||
Operator::I64x2Splat
|
Operator::I64x2Splat
|
||||||
| Operator::V64x2LoadSplat { .. }
|
| Operator::V64x2LoadSplat { .. }
|
||||||
|
|||||||
@@ -71,6 +71,11 @@ pub fn translate_module<'data>(
|
|||||||
environ.reserve_passive_data(count)?;
|
environ.reserve_passive_data(count)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SectionContent::Module(_)
|
||||||
|
| SectionContent::ModuleCode(_)
|
||||||
|
| SectionContent::Instance(_)
|
||||||
|
| SectionContent::Alias(_) => unimplemented!("module linking not implemented yet"),
|
||||||
|
|
||||||
SectionContent::Custom {
|
SectionContent::Custom {
|
||||||
name,
|
name,
|
||||||
binary,
|
binary,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use wasmparser::{
|
|||||||
ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind,
|
ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind,
|
||||||
FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
|
FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
|
||||||
ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader,
|
ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader,
|
||||||
Operator, TableSectionReader, Type, TypeSectionReader,
|
Operator, TableSectionReader, Type, TypeDef, TypeSectionReader,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Parses the Type section of the wasm module.
|
/// Parses the Type section of the wasm module.
|
||||||
@@ -40,8 +40,9 @@ pub fn parse_type_section(
|
|||||||
environ.reserve_signatures(count)?;
|
environ.reserve_signatures(count)?;
|
||||||
|
|
||||||
for entry in types {
|
for entry in types {
|
||||||
let wasm_func_ty = entry?;
|
if let Ok(TypeDef::Func(wasm_func_ty)) = entry {
|
||||||
let mut sig = Signature::new(ModuleEnvironment::target_config(environ).default_call_conv);
|
let mut sig =
|
||||||
|
Signature::new(ModuleEnvironment::target_config(environ).default_call_conv);
|
||||||
sig.params.extend(wasm_func_ty.params.iter().map(|ty| {
|
sig.params.extend(wasm_func_ty.params.iter().map(|ty| {
|
||||||
let cret_arg: ir::Type = type_to_type(*ty, environ)
|
let cret_arg: ir::Type = type_to_type(*ty, environ)
|
||||||
.expect("only numeric types are supported in function signatures");
|
.expect("only numeric types are supported in function signatures");
|
||||||
@@ -56,6 +57,9 @@ pub fn parse_type_section(
|
|||||||
module_translation_state
|
module_translation_state
|
||||||
.wasm_types
|
.wasm_types
|
||||||
.push((wasm_func_ty.params, wasm_func_ty.returns));
|
.push((wasm_func_ty.params, wasm_func_ty.returns));
|
||||||
|
} else {
|
||||||
|
unimplemented!("module linking not implemented yet")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -70,7 +74,7 @@ pub fn parse_import_section<'data>(
|
|||||||
for entry in imports {
|
for entry in imports {
|
||||||
let import = entry?;
|
let import = entry?;
|
||||||
let module_name = import.module;
|
let module_name = import.module;
|
||||||
let field_name = import.field;
|
let field_name = import.field.unwrap(); // TODO Handle error when module linking is implemented.
|
||||||
|
|
||||||
match import.ty {
|
match import.ty {
|
||||||
ImportSectionEntryType::Function(sig) => {
|
ImportSectionEntryType::Function(sig) => {
|
||||||
@@ -80,6 +84,9 @@ pub fn parse_import_section<'data>(
|
|||||||
field_name,
|
field_name,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
ImportSectionEntryType::Module(_sig) | ImportSectionEntryType::Instance(_sig) => {
|
||||||
|
unimplemented!("module linking not implemented yet")
|
||||||
|
}
|
||||||
ImportSectionEntryType::Memory(MemoryType {
|
ImportSectionEntryType::Memory(MemoryType {
|
||||||
limits: ref memlimits,
|
limits: ref memlimits,
|
||||||
shared,
|
shared,
|
||||||
@@ -268,6 +275,9 @@ pub fn parse_export_section<'data>(
|
|||||||
ExternalKind::Global => {
|
ExternalKind::Global => {
|
||||||
environ.declare_global_export(GlobalIndex::new(index), field)?
|
environ.declare_global_export(GlobalIndex::new(index), field)?
|
||||||
}
|
}
|
||||||
|
ExternalKind::Type | ExternalKind::Module | ExternalKind::Instance => {
|
||||||
|
unimplemented!("module linking not implemented yet")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gimli = "0.21.0"
|
gimli = "0.21.0"
|
||||||
wasmparser = "0.57.0"
|
wasmparser = "0.58.0"
|
||||||
object = { version = "0.19", default-features = false, features = ["write"] }
|
object = { version = "0.19", default-features = false, features = ["write"] }
|
||||||
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
||||||
target-lexicon = { version = "0.10.0", default-features = false }
|
target-lexicon = { version = "0.10.0", default-features = false }
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use gimli::{
|
|||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use wasmparser::{self, ModuleReader, SectionCode};
|
use wasmparser::{self, ModuleReader, SectionCode, TypeDef};
|
||||||
|
|
||||||
trait Reader: gimli::Reader<Offset = usize, Endian = LittleEndian> {}
|
trait Reader: gimli::Reader<Offset = usize, Endian = LittleEndian> {}
|
||||||
|
|
||||||
@@ -186,7 +186,13 @@ pub fn read_debuginfo(data: &[u8]) -> Result<DebugInfoData> {
|
|||||||
signatures_params = section
|
signatures_params = section
|
||||||
.get_type_section_reader()?
|
.get_type_section_reader()?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|ft| Ok(ft?.params))
|
.map(|ft| {
|
||||||
|
if let Ok(TypeDef::Func(ft)) = ft {
|
||||||
|
Ok(ft.params)
|
||||||
|
} else {
|
||||||
|
unimplemented!("module linking not implemented yet")
|
||||||
|
}
|
||||||
|
})
|
||||||
.collect::<Result<Vec<_>>>()?;
|
.collect::<Result<Vec<_>>>()?;
|
||||||
}
|
}
|
||||||
SectionCode::Import => {
|
SectionCode::Import => {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ anyhow = "1.0"
|
|||||||
cranelift-codegen = { path = "../../cranelift/codegen", version = "0.65.0", features = ["enable-serde"] }
|
cranelift-codegen = { path = "../../cranelift/codegen", version = "0.65.0", features = ["enable-serde"] }
|
||||||
cranelift-entity = { path = "../../cranelift/entity", version = "0.65.0", features = ["enable-serde"] }
|
cranelift-entity = { path = "../../cranelift/entity", version = "0.65.0", features = ["enable-serde"] }
|
||||||
cranelift-wasm = { path = "../../cranelift/wasm", version = "0.65.0", features = ["enable-serde"] }
|
cranelift-wasm = { path = "../../cranelift/wasm", version = "0.65.0", features = ["enable-serde"] }
|
||||||
wasmparser = "0.57.0"
|
wasmparser = "0.58.0"
|
||||||
lightbeam = { path = "../lightbeam", optional = true, version = "0.18.0" }
|
lightbeam = { path = "../lightbeam", optional = true, version = "0.18.0" }
|
||||||
indexmap = "1.0.2"
|
indexmap = "1.0.2"
|
||||||
rayon = "1.2.1"
|
rayon = "1.2.1"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ binaryen = { version = "0.10.0", optional = true }
|
|||||||
env_logger = "0.7.1"
|
env_logger = "0.7.1"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
rayon = "1.2.1"
|
rayon = "1.2.1"
|
||||||
wasmparser = "0.57.0"
|
wasmparser = "0.58.0"
|
||||||
wasmprinter = "0.2.5"
|
wasmprinter = "0.2.5"
|
||||||
wasmtime = { path = "../wasmtime" }
|
wasmtime = { path = "../wasmtime" }
|
||||||
wasmtime-wast = { path = "../wast" }
|
wasmtime-wast = { path = "../wast" }
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ wasmtime-profiling = { path = "../profiling", version = "0.18.0" }
|
|||||||
region = "2.1.0"
|
region = "2.1.0"
|
||||||
thiserror = "1.0.4"
|
thiserror = "1.0.4"
|
||||||
target-lexicon = { version = "0.10.0", default-features = false }
|
target-lexicon = { version = "0.10.0", default-features = false }
|
||||||
wasmparser = "0.57.0"
|
wasmparser = "0.58.0"
|
||||||
more-asserts = "0.2.1"
|
more-asserts = "0.2.1"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
cfg-if = "0.1.9"
|
cfg-if = "0.1.9"
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ smallvec = "1.0.0"
|
|||||||
staticvec = "0.10"
|
staticvec = "0.10"
|
||||||
thiserror = "1.0.9"
|
thiserror = "1.0.9"
|
||||||
typemap = "0.3"
|
typemap = "0.3"
|
||||||
wasmparser = "0.57.0"
|
wasmparser = "0.58.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
lazy_static = "1.2"
|
lazy_static = "1.2"
|
||||||
|
|||||||
@@ -5,14 +5,18 @@ use cranelift_codegen::{binemit, ir};
|
|||||||
use wasmparser::{
|
use wasmparser::{
|
||||||
CodeSectionReader, DataSectionReader, ElementSectionReader, ExportSectionReader, FuncType,
|
CodeSectionReader, DataSectionReader, ElementSectionReader, ExportSectionReader, FuncType,
|
||||||
FunctionSectionReader, GlobalSectionReader, ImportSectionReader, MemorySectionReader,
|
FunctionSectionReader, GlobalSectionReader, ImportSectionReader, MemorySectionReader,
|
||||||
MemoryType, TableSectionReader, TableType, TypeSectionReader,
|
MemoryType, TableSectionReader, TableType, TypeDef, TypeSectionReader,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Parses the Type section of the wasm module.
|
/// Parses the Type section of the wasm module.
|
||||||
pub fn type_(types_reader: TypeSectionReader) -> Result<Vec<FuncType>, Error> {
|
pub fn type_(types_reader: TypeSectionReader) -> Result<Vec<FuncType>, Error> {
|
||||||
types_reader
|
types_reader
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| r.map_err(Into::into))
|
.map(|r| match r {
|
||||||
|
Ok(TypeDef::Func(ft)) => Ok(ft),
|
||||||
|
Ok(_) => unimplemented!("module linking is not implemented yet"),
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
//! The `VMExternData` struct is *preceded* by the dynamically-sized value boxed
|
//! The `VMExternData` struct is *preceded* by the dynamically-sized value boxed
|
||||||
//! up and referenced by one or more `VMExternRef`s:
|
//! up and referenced by one or more `VMExternRef`s:
|
||||||
//!
|
//!
|
||||||
//! ```ignore
|
//! ```text
|
||||||
//! ,-------------------------------------------------------.
|
//! ,-------------------------------------------------------.
|
||||||
//! | |
|
//! | |
|
||||||
//! V |
|
//! V |
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ wasmtime-runtime = { path = "../runtime", version = "0.18.0" }
|
|||||||
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
||||||
wasmtime-jit = { path = "../jit", version = "0.18.0" }
|
wasmtime-jit = { path = "../jit", version = "0.18.0" }
|
||||||
wasmtime-profiling = { path = "../profiling", version = "0.18.0" }
|
wasmtime-profiling = { path = "../profiling", version = "0.18.0" }
|
||||||
wasmparser = "0.57.0"
|
wasmparser = "0.58.0"
|
||||||
target-lexicon = { version = "0.10.0", default-features = false }
|
target-lexicon = { version = "0.10.0", default-features = false }
|
||||||
anyhow = "1.0.19"
|
anyhow = "1.0.19"
|
||||||
region = "2.1.0"
|
region = "2.1.0"
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ impl Config {
|
|||||||
enable_simd: false,
|
enable_simd: false,
|
||||||
enable_multi_value: true,
|
enable_multi_value: true,
|
||||||
enable_tail_call: false,
|
enable_tail_call: false,
|
||||||
|
enable_module_linking: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
flags,
|
flags,
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ pub use region::Region;
|
|||||||
///
|
///
|
||||||
/// # Using References
|
/// # Using References
|
||||||
///
|
///
|
||||||
/// The [`GuestMemory::as_slice`] or [`GuestPtr::as_str`] will return smart
|
/// The [`GuestPtr::as_slice`] or [`GuestPtr::as_str`] will return smart
|
||||||
/// pointers [`GuestSlice`] and [`GuestStr`]. These types, which implement
|
/// pointers [`GuestSlice`] and [`GuestStr`]. These types, which implement
|
||||||
/// [`std::ops::Deref`] and [`std::ops::DerefMut`], provide mutable references
|
/// [`std::ops::Deref`] and [`std::ops::DerefMut`], provide mutable references
|
||||||
/// into the memory region given by a `GuestMemory`.
|
/// into the memory region given by a `GuestMemory`.
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use config::{MissingMemoryConf, ModuleConf, TargetConf};
|
|||||||
/// where the macro is invoked. `witx_literal` takes a string of the witx document, e.g.
|
/// where the macro is invoked. `witx_literal` takes a string of the witx document, e.g.
|
||||||
/// `"(typename $foo u8)"`.
|
/// `"(typename $foo u8)"`.
|
||||||
/// * `ctx`: The context struct used for the Wiggle implementation. This must be the same
|
/// * `ctx`: The context struct used for the Wiggle implementation. This must be the same
|
||||||
/// type as the [`wasmtime_wiggle::from_witx`] macro at `target` was invoked with. However, it
|
/// type as the `wasmtime_wiggle::from_witx` macro at `target` was invoked with. However, it
|
||||||
/// must be imported to the current scope so that it is a bare identifier e.g. `CtxType`, not
|
/// must be imported to the current scope so that it is a bare identifier e.g. `CtxType`, not
|
||||||
/// `path::to::CtxType`.
|
/// `path::to::CtxType`.
|
||||||
/// * `modules`: Describes how any modules in the witx document will be implemented as Wasmtime
|
/// * `modules`: Describes how any modules in the witx document will be implemented as Wasmtime
|
||||||
|
|||||||
Reference in New Issue
Block a user