mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Bug 1335652 - wasm exceptions part 7: vendor the latest wat r=rhunt
Differential Revision: https://phabricator.services.mozilla.com/D99594
This commit is contained in:
parent
d7a0965c77
commit
bd345c38b9
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -5641,18 +5641,18 @@ source = "git+https://github.com/mozilla-spidermonkey/wasm-tools?rev=1b7763faa48
|
||||
|
||||
[[package]]
|
||||
name = "wast"
|
||||
version = "26.0.1"
|
||||
version = "29.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3f174eed73e885ede6c8fcc3fbea8c3757afa521840676496cde56bb742ddab"
|
||||
checksum = "dcf2268937131d63c3d833242bf5e075406f9ed868b4265f3280e15dac29ac18"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wat"
|
||||
version = "1.0.27"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b2dccbce4d0e14875091846e110a2369267b18ddd0d6423479b88dad914d71"
|
||||
checksum = "0d11a88d953b298172d218d18f22853f4e6e12873b62755d05617b864d312c68"
|
||||
dependencies = [
|
||||
"wast",
|
||||
]
|
||||
|
@ -20,5 +20,5 @@ smoosh = ['jsrust_shared/smoosh']
|
||||
jsrust_shared = { path = "./shared" }
|
||||
# Workaround for https://github.com/rust-lang/rust/issues/58393
|
||||
mozglue-static = { path = "../../../mozglue/static/rust" }
|
||||
wat = { version = "1.0.27" }
|
||||
wat = { version = "1.0.30" }
|
||||
wasmparser = { version = "0.48.2" }
|
||||
|
2
third_party/rust/wast/.cargo-checksum.json
vendored
2
third_party/rust/wast/.cargo-checksum.json
vendored
File diff suppressed because one or more lines are too long
2
third_party/rust/wast/Cargo.toml
vendored
2
third_party/rust/wast/Cargo.toml
vendored
@ -13,7 +13,7 @@
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "wast"
|
||||
version = "26.0.1"
|
||||
version = "29.0.0"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
description = "Customizable Rust parsers for the WebAssembly Text formats WAT and WAST\n"
|
||||
homepage = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wast"
|
||||
|
58
third_party/rust/wast/src/ast/expr.rs
vendored
58
third_party/rust/wast/src/ast/expr.rs
vendored
@ -84,7 +84,9 @@ enum If<'a> {
|
||||
enum Try<'a> {
|
||||
/// Next thing to parse is the `do` block.
|
||||
Do(Instruction<'a>),
|
||||
/// Next thing to parse is the `catch` block.
|
||||
/// Next thing to parse is `catch`/`catch_all`, or `unwind`.
|
||||
CatchOrUnwind,
|
||||
/// Next thing to parse is a `catch` block or `catch_all`.
|
||||
Catch,
|
||||
/// This `try` statement has finished parsing and if anything remains it's a
|
||||
/// syntax error.
|
||||
@ -195,8 +197,8 @@ impl<'a> ExpressionParser<'a> {
|
||||
Level::Try(Try::Do(_)) => {
|
||||
return Err(parser.error("previous `try` had no `do`"));
|
||||
}
|
||||
Level::Try(Try::Catch) => {
|
||||
return Err(parser.error("previous `try` had no `catch`"));
|
||||
Level::Try(Try::CatchOrUnwind) => {
|
||||
return Err(parser.error("previous `try` had no `catch`, `catch_all`, or `unwind`"));
|
||||
}
|
||||
Level::Try(_) => {
|
||||
self.instrs.push(Instruction::End(None));
|
||||
@ -305,7 +307,7 @@ impl<'a> ExpressionParser<'a> {
|
||||
/// than an `if` as the syntactic form is:
|
||||
///
|
||||
/// ```wat
|
||||
/// (try (do $do) (catch $catch))
|
||||
/// (try (do $do) (catch $event $catch))
|
||||
/// ```
|
||||
///
|
||||
/// where the `do` and `catch` keywords are mandatory, even for an empty
|
||||
@ -328,7 +330,7 @@ impl<'a> ExpressionParser<'a> {
|
||||
if parser.parse::<Option<kw::r#do>>()?.is_some() {
|
||||
// The state is advanced here only if the parse succeeds in
|
||||
// order to strictly require the keyword.
|
||||
*i = Try::Catch;
|
||||
*i = Try::CatchOrUnwind;
|
||||
self.stack.push(Level::TryArm);
|
||||
return Ok(true);
|
||||
}
|
||||
@ -338,10 +340,26 @@ impl<'a> ExpressionParser<'a> {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
// `catch` handled similar to `do`, including requiring the keyword.
|
||||
if let Try::Catch = i {
|
||||
self.instrs.push(Instruction::Catch);
|
||||
// After a try's `do`, there are several possible kinds of handlers.
|
||||
if let Try::CatchOrUnwind = i {
|
||||
// `catch` may be followed by more `catch`s or `catch_all`.
|
||||
if parser.parse::<Option<kw::catch>>()?.is_some() {
|
||||
let evt = parser.parse::<ast::Index<'a>>()?;
|
||||
self.instrs.push(Instruction::Catch(evt));
|
||||
*i = Try::Catch;
|
||||
self.stack.push(Level::TryArm);
|
||||
return Ok(true);
|
||||
}
|
||||
// `catch_all` can only come at the end and has no argument.
|
||||
if parser.parse::<Option<kw::catch_all>>()?.is_some() {
|
||||
self.instrs.push(Instruction::CatchAll);
|
||||
*i = Try::End;
|
||||
self.stack.push(Level::TryArm);
|
||||
return Ok(true);
|
||||
}
|
||||
// `unwind` is similar to `catch_all`.
|
||||
if parser.parse::<Option<kw::unwind>>()?.is_some() {
|
||||
self.instrs.push(Instruction::Unwind);
|
||||
*i = Try::End;
|
||||
self.stack.push(Level::TryArm);
|
||||
return Ok(true);
|
||||
@ -349,6 +367,23 @@ impl<'a> ExpressionParser<'a> {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if let Try::Catch = i {
|
||||
if parser.parse::<Option<kw::catch>>()?.is_some() {
|
||||
let evt = parser.parse::<ast::Index<'a>>()?;
|
||||
self.instrs.push(Instruction::Catch(evt));
|
||||
*i = Try::Catch;
|
||||
self.stack.push(Level::TryArm);
|
||||
return Ok(true);
|
||||
}
|
||||
if parser.parse::<Option<kw::catch_all>>()?.is_some() {
|
||||
self.instrs.push(Instruction::CatchAll);
|
||||
*i = Try::End;
|
||||
self.stack.push(Level::TryArm);
|
||||
return Ok(true);
|
||||
}
|
||||
return Err(parser.error("unexpected items after `catch`"));
|
||||
}
|
||||
|
||||
Err(parser.error("too many payloads inside of `(try)`"))
|
||||
}
|
||||
}
|
||||
@ -997,11 +1032,12 @@ instructions! {
|
||||
V128Load64Zero(MemArg<8>) : [0xfd, 0xfd] : "v128.load64_zero",
|
||||
|
||||
// Exception handling proposal
|
||||
CatchAll : [0x05] : "catch_all", // Reuses the else opcode.
|
||||
Try(BlockType<'a>) : [0x06] : "try",
|
||||
Catch : [0x07] : "catch",
|
||||
Catch(ast::Index<'a>) : [0x07] : "catch",
|
||||
Throw(ast::Index<'a>) : [0x08] : "throw",
|
||||
Rethrow : [0x09] : "rethrow",
|
||||
BrOnExn(BrOnExn<'a>) : [0x0a] : "br_on_exn",
|
||||
Rethrow(ast::Index<'a>) : [0x09] : "rethrow",
|
||||
Unwind : [0x0a] : "unwind",
|
||||
}
|
||||
}
|
||||
|
||||
|
86
third_party/rust/wast/src/ast/memory.rs
vendored
86
third_party/rust/wast/src/ast/memory.rs
vendored
@ -1,5 +1,5 @@
|
||||
use crate::ast::{self, kw};
|
||||
use crate::parser::{Parse, Parser, Result};
|
||||
use crate::parser::{Lookahead1, Parse, Parser, Peek, Result};
|
||||
|
||||
/// A defined WebAssembly memory instance inside of a module.
|
||||
#[derive(Debug)]
|
||||
@ -33,7 +33,7 @@ pub enum MemoryKind<'a> {
|
||||
/// Whether or not this will be creating a 32-bit memory
|
||||
is_32: bool,
|
||||
/// The inline data specified for this memory
|
||||
data: Vec<&'a [u8]>,
|
||||
data: Vec<DataVal<'a>>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ pub struct Data<'a> {
|
||||
|
||||
/// Bytes for this `Data` segment, viewed as the concatenation of all the
|
||||
/// contained slices.
|
||||
pub data: Vec<&'a [u8]>,
|
||||
pub data: Vec<DataVal<'a>>,
|
||||
}
|
||||
|
||||
/// Different kinds of data segments, either passive or active.
|
||||
@ -170,3 +170,83 @@ impl<'a> Parse<'a> for Data<'a> {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Differnet ways the value of a data segment can be defined.
|
||||
#[derive(Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum DataVal<'a> {
|
||||
String(&'a [u8]),
|
||||
Integral(Vec<u8>),
|
||||
}
|
||||
|
||||
impl DataVal<'_> {
|
||||
/// Returns the length, in bytes, of the memory used to represent this data
|
||||
/// value.
|
||||
pub fn len(&self) -> usize {
|
||||
match self {
|
||||
DataVal::String(s) => s.len(),
|
||||
DataVal::Integral(s) => s.len(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes the value of this data value onto the provided list of bytes.
|
||||
pub fn push_onto(&self, dst: &mut Vec<u8>) {
|
||||
match self {
|
||||
DataVal::String(s) => dst.extend_from_slice(s),
|
||||
DataVal::Integral(s) => dst.extend_from_slice(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for DataVal<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if !parser.peek::<ast::LParen>() {
|
||||
return Ok(DataVal::String(parser.parse()?));
|
||||
}
|
||||
|
||||
return parser.parens(|p| {
|
||||
let mut result = Vec::new();
|
||||
let mut lookahead = p.lookahead1();
|
||||
let l = &mut lookahead;
|
||||
let r = &mut result;
|
||||
if consume::<kw::i8, i8, _>(p, l, r, |u, v| v.push(u as u8))?
|
||||
|| consume::<kw::i16, i16, _>(p, l, r, |u, v| v.extend(&u.to_le_bytes()))?
|
||||
|| consume::<kw::i32, i32, _>(p, l, r, |u, v| v.extend(&u.to_le_bytes()))?
|
||||
|| consume::<kw::i64, i64, _>(p, l, r, |u, v| v.extend(&u.to_le_bytes()))?
|
||||
|| consume::<kw::f32, ast::Float32, _>(p, l, r, |u, v| {
|
||||
v.extend(&u.bits.to_le_bytes())
|
||||
})?
|
||||
|| consume::<kw::f64, ast::Float64, _>(p, l, r, |u, v| {
|
||||
v.extend(&u.bits.to_le_bytes())
|
||||
})?
|
||||
|| consume::<kw::v128, ast::V128Const, _>(p, l, r, |u, v| {
|
||||
v.extend(&u.to_le_bytes())
|
||||
})?
|
||||
{
|
||||
Ok(DataVal::Integral(result))
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
});
|
||||
|
||||
fn consume<'a, T: Peek + Parse<'a>, U: Parse<'a>, F>(
|
||||
parser: Parser<'a>,
|
||||
lookahead: &mut Lookahead1<'a>,
|
||||
dst: &mut Vec<u8>,
|
||||
push: F,
|
||||
) -> Result<bool>
|
||||
where
|
||||
F: Fn(U, &mut Vec<u8>),
|
||||
{
|
||||
if !lookahead.peek::<T>() {
|
||||
return Ok(false);
|
||||
}
|
||||
parser.parse::<T>()?;
|
||||
while !parser.is_empty() {
|
||||
let val = parser.parse::<U>()?;
|
||||
push(val, dst);
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
third_party/rust/wast/src/ast/mod.rs
vendored
4
third_party/rust/wast/src/ast/mod.rs
vendored
@ -35,6 +35,8 @@
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Note that the keyword name can only start with a lower-case letter, i.e. 'a'..'z'.
|
||||
#[macro_export]
|
||||
macro_rules! custom_keyword {
|
||||
($name:ident) => {
|
||||
@ -344,6 +346,7 @@ pub mod kw {
|
||||
custom_keyword!(binary);
|
||||
custom_keyword!(block);
|
||||
custom_keyword!(catch);
|
||||
custom_keyword!(catch_all);
|
||||
custom_keyword!(code);
|
||||
custom_keyword!(data);
|
||||
custom_keyword!(declare);
|
||||
@ -414,6 +417,7 @@ pub mod kw {
|
||||
custom_keyword!(table);
|
||||
custom_keyword!(then);
|
||||
custom_keyword!(r#try = "try");
|
||||
custom_keyword!(unwind);
|
||||
custom_keyword!(v128);
|
||||
}
|
||||
|
||||
|
5
third_party/rust/wast/src/ast/types.rs
vendored
5
third_party/rust/wast/src/ast/types.rs
vendored
@ -389,6 +389,8 @@ pub enum MemoryType {
|
||||
B64 {
|
||||
/// Limits on the page sizes of this memory
|
||||
limits: Limits64,
|
||||
/// Whether or not this is a shared (atomic) memory type
|
||||
shared: bool,
|
||||
},
|
||||
}
|
||||
|
||||
@ -397,7 +399,8 @@ impl<'a> Parse<'a> for MemoryType {
|
||||
if parser.peek::<kw::i64>() {
|
||||
parser.parse::<kw::i64>()?;
|
||||
let limits = parser.parse()?;
|
||||
Ok(MemoryType::B64 { limits })
|
||||
let shared = parser.parse::<Option<kw::shared>>()?.is_some();
|
||||
Ok(MemoryType::B64 { limits, shared })
|
||||
} else {
|
||||
parser.parse::<Option<kw::i32>>()?;
|
||||
let limits = parser.parse()?;
|
||||
|
34
third_party/rust/wast/src/binary.rs
vendored
34
third_party/rust/wast/src/binary.rs
vendored
@ -61,15 +61,6 @@ fn encode_fields(
|
||||
|
||||
e.custom_sections(BeforeFirst);
|
||||
|
||||
// let moduletys = modules
|
||||
// .iter()
|
||||
// .map(|m| match &m.kind {
|
||||
// NestedModuleKind::Inline { ty, .. } => ty.as_ref().expect("type should be filled in"),
|
||||
// _ => panic!("only inline modules should be present now"),
|
||||
// })
|
||||
// .collect::<Vec<_>>();
|
||||
// e.section_list(100, Module, &moduletys);
|
||||
|
||||
let mut items = fields
|
||||
.iter()
|
||||
.filter(|i| match i {
|
||||
@ -106,13 +97,13 @@ fn encode_fields(
|
||||
}
|
||||
list!(1, Type);
|
||||
list!(2, Import);
|
||||
list!(100, NestedModule, Module, |m| match &m.kind {
|
||||
list!(14, NestedModule, Module, |m| match &m.kind {
|
||||
NestedModuleKind::Inline { ty, .. } =>
|
||||
ty.as_ref().expect("type should be filled in"),
|
||||
_ => panic!("only inline modules should be present now"),
|
||||
});
|
||||
list!(101, Instance);
|
||||
list!(102, Alias);
|
||||
list!(15, Instance);
|
||||
list!(16, Alias);
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +123,7 @@ fn encode_fields(
|
||||
if contains_bulk_memory(&funcs) {
|
||||
e.section(12, &data.len());
|
||||
}
|
||||
e.section_list(103, ModuleCode, &modules);
|
||||
e.section_list(17, ModuleCode, &modules);
|
||||
e.section_list(10, Code, &funcs);
|
||||
e.section_list(11, Data, &data);
|
||||
|
||||
@ -450,8 +441,8 @@ impl Encode for Import<'_> {
|
||||
match self.field {
|
||||
Some(s) => s.encode(e),
|
||||
None => {
|
||||
e.push(0x01);
|
||||
e.push(0xc0);
|
||||
e.push(0x00);
|
||||
e.push(0xff);
|
||||
}
|
||||
}
|
||||
self.item.encode(e);
|
||||
@ -547,8 +538,10 @@ impl Encode for MemoryType {
|
||||
max.encode(e);
|
||||
}
|
||||
}
|
||||
MemoryType::B64 { limits } => {
|
||||
let flags = (limits.max.is_some() as u8) | 0x04;
|
||||
MemoryType::B64 { limits, shared } => {
|
||||
let flag_max = limits.max.is_some() as u8;
|
||||
let flag_shared = *shared as u8;
|
||||
let flags = flag_max | (flag_shared << 1) | 0x04;
|
||||
e.push(flags);
|
||||
limits.min.encode(e);
|
||||
if let Some(max) = limits.max {
|
||||
@ -651,6 +644,9 @@ impl Encode for Elem<'_> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
// Try to switch element expressions to indices if we can which uses a
|
||||
// more MVP-compatible encoding.
|
||||
//
|
||||
// FIXME(WebAssembly/wabt#1447) ideally we wouldn't do this so we could
|
||||
// be faithful to the original format.
|
||||
let mut to_encode = self.payload.clone();
|
||||
if let ElemPayload::Exprs {
|
||||
ty:
|
||||
@ -769,8 +765,8 @@ impl Encode for Data<'_> {
|
||||
}
|
||||
}
|
||||
self.data.iter().map(|l| l.len()).sum::<usize>().encode(e);
|
||||
for list in self.data.iter() {
|
||||
e.extend_from_slice(list);
|
||||
for val in self.data.iter() {
|
||||
val.push_onto(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ pub fn run(fields: &mut Vec<ModuleField>) {
|
||||
min: u64::from(pages),
|
||||
max: Some(u64::from(pages)),
|
||||
},
|
||||
shared: false,
|
||||
}
|
||||
});
|
||||
let data = match mem::replace(&mut m.kind, kind) {
|
||||
@ -90,11 +91,7 @@ pub fn run(fields: &mut Vec<ModuleField>) {
|
||||
kind: DataKind::Active {
|
||||
memory: Index::Id(id),
|
||||
offset: Expression {
|
||||
instrs: Box::new([if is_32 {
|
||||
Instruction::I32Const(0)
|
||||
} else {
|
||||
Instruction::I64Const(0)
|
||||
}]),
|
||||
instrs: Box::new([Instruction::I32Const(0)]),
|
||||
},
|
||||
},
|
||||
data,
|
||||
|
118
third_party/rust/wast/src/resolve/expand.rs
vendored
118
third_party/rust/wast/src/resolve/expand.rs
vendored
@ -363,6 +363,9 @@ impl<'a> Expander<'a> {
|
||||
ModuleField::Alias(a) => {
|
||||
let (_idx, ns) = Ns::from_export(&a.kind);
|
||||
self.record_defined(&a.id, ns);
|
||||
if let Some(instance) = &a.instance {
|
||||
self.record_missing(instance, Ns::Instance);
|
||||
}
|
||||
}
|
||||
|
||||
ModuleField::NestedModule(m) => {
|
||||
@ -418,6 +421,121 @@ impl<'a> Expander<'a> {
|
||||
self.record_missing(&t.src, Ns::Table);
|
||||
self.record_missing(&t.dst, Ns::Table);
|
||||
}
|
||||
|
||||
MemorySize(i) | MemoryGrow(i) | MemoryFill(i) => {
|
||||
self.record_missing(&i.mem, Ns::Memory);
|
||||
}
|
||||
MemoryInit(i) => {
|
||||
self.record_missing(&i.mem, Ns::Memory);
|
||||
}
|
||||
MemoryCopy(i) => {
|
||||
self.record_missing(&i.src, Ns::Memory);
|
||||
self.record_missing(&i.dst, Ns::Memory);
|
||||
}
|
||||
|
||||
I32Load(m)
|
||||
| I64Load(m)
|
||||
| F32Load(m)
|
||||
| F64Load(m)
|
||||
| I32Load8s(m)
|
||||
| I32Load8u(m)
|
||||
| I32Load16s(m)
|
||||
| I32Load16u(m)
|
||||
| I64Load8s(m)
|
||||
| I64Load8u(m)
|
||||
| I64Load16s(m)
|
||||
| I64Load16u(m)
|
||||
| I64Load32s(m)
|
||||
| I64Load32u(m)
|
||||
| I32Store(m)
|
||||
| I64Store(m)
|
||||
| F32Store(m)
|
||||
| F64Store(m)
|
||||
| I32Store8(m)
|
||||
| I32Store16(m)
|
||||
| I64Store8(m)
|
||||
| I64Store16(m)
|
||||
| I64Store32(m)
|
||||
| I32AtomicLoad(m)
|
||||
| I64AtomicLoad(m)
|
||||
| I32AtomicLoad8u(m)
|
||||
| I32AtomicLoad16u(m)
|
||||
| I64AtomicLoad8u(m)
|
||||
| I64AtomicLoad16u(m)
|
||||
| I64AtomicLoad32u(m)
|
||||
| I32AtomicStore(m)
|
||||
| I64AtomicStore(m)
|
||||
| I32AtomicStore8(m)
|
||||
| I32AtomicStore16(m)
|
||||
| I64AtomicStore8(m)
|
||||
| I64AtomicStore16(m)
|
||||
| I64AtomicStore32(m)
|
||||
| I32AtomicRmwAdd(m)
|
||||
| I64AtomicRmwAdd(m)
|
||||
| I32AtomicRmw8AddU(m)
|
||||
| I32AtomicRmw16AddU(m)
|
||||
| I64AtomicRmw8AddU(m)
|
||||
| I64AtomicRmw16AddU(m)
|
||||
| I64AtomicRmw32AddU(m)
|
||||
| I32AtomicRmwSub(m)
|
||||
| I64AtomicRmwSub(m)
|
||||
| I32AtomicRmw8SubU(m)
|
||||
| I32AtomicRmw16SubU(m)
|
||||
| I64AtomicRmw8SubU(m)
|
||||
| I64AtomicRmw16SubU(m)
|
||||
| I64AtomicRmw32SubU(m)
|
||||
| I32AtomicRmwAnd(m)
|
||||
| I64AtomicRmwAnd(m)
|
||||
| I32AtomicRmw8AndU(m)
|
||||
| I32AtomicRmw16AndU(m)
|
||||
| I64AtomicRmw8AndU(m)
|
||||
| I64AtomicRmw16AndU(m)
|
||||
| I64AtomicRmw32AndU(m)
|
||||
| I32AtomicRmwOr(m)
|
||||
| I64AtomicRmwOr(m)
|
||||
| I32AtomicRmw8OrU(m)
|
||||
| I32AtomicRmw16OrU(m)
|
||||
| I64AtomicRmw8OrU(m)
|
||||
| I64AtomicRmw16OrU(m)
|
||||
| I64AtomicRmw32OrU(m)
|
||||
| I32AtomicRmwXor(m)
|
||||
| I64AtomicRmwXor(m)
|
||||
| I32AtomicRmw8XorU(m)
|
||||
| I32AtomicRmw16XorU(m)
|
||||
| I64AtomicRmw8XorU(m)
|
||||
| I64AtomicRmw16XorU(m)
|
||||
| I64AtomicRmw32XorU(m)
|
||||
| I32AtomicRmwXchg(m)
|
||||
| I64AtomicRmwXchg(m)
|
||||
| I32AtomicRmw8XchgU(m)
|
||||
| I32AtomicRmw16XchgU(m)
|
||||
| I64AtomicRmw8XchgU(m)
|
||||
| I64AtomicRmw16XchgU(m)
|
||||
| I64AtomicRmw32XchgU(m)
|
||||
| I32AtomicRmwCmpxchg(m)
|
||||
| I64AtomicRmwCmpxchg(m)
|
||||
| I32AtomicRmw8CmpxchgU(m)
|
||||
| I32AtomicRmw16CmpxchgU(m)
|
||||
| I64AtomicRmw8CmpxchgU(m)
|
||||
| I64AtomicRmw16CmpxchgU(m)
|
||||
| I64AtomicRmw32CmpxchgU(m)
|
||||
| V128Load(m)
|
||||
| V128Load8x8S(m)
|
||||
| V128Load8x8U(m)
|
||||
| V128Load16x4S(m)
|
||||
| V128Load16x4U(m)
|
||||
| V128Load32x2S(m)
|
||||
| V128Load32x2U(m)
|
||||
| V128Load8Splat(m)
|
||||
| V128Load16Splat(m)
|
||||
| V128Load32Splat(m)
|
||||
| V128Load64Splat(m)
|
||||
| V128Load32Zero(m)
|
||||
| V128Load64Zero(m)
|
||||
| V128Store(m)
|
||||
| MemoryAtomicNotify(m)
|
||||
| MemoryAtomicWait32(m)
|
||||
| MemoryAtomicWait64(m) => self.record_missing(&m.memory, Ns::Memory),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
115
third_party/rust/wast/src/resolve/names.rs
vendored
115
third_party/rust/wast/src/resolve/names.rs
vendored
@ -64,6 +64,13 @@ pub struct Module<'a> {
|
||||
/// currently-being-processed field. This should always be empty after
|
||||
/// processing is complete.
|
||||
to_prepend: Vec<ModuleField<'a>>,
|
||||
|
||||
/// Cache for copying over types from other modules, used for module-linking
|
||||
/// module types. The key of this map is the `(module_index, type_index)`
|
||||
/// and the value is the copied over item into this module.
|
||||
///
|
||||
/// This is used by the `copy_type_from_module` method.
|
||||
type_cache: HashMap<(usize, Index<'a>), Item<'a>>,
|
||||
}
|
||||
|
||||
enum InstanceDef<'a> {
|
||||
@ -146,22 +153,35 @@ impl<'a> Resolver<'a> {
|
||||
//
|
||||
// Practically there is no purpose to interleaving the type and module
|
||||
// section today. As a result we can safely sort all types to the front.
|
||||
// This, however, can break the roundtrip binary-text-binary for
|
||||
// strictly-speaking compliant modules with the module linking spec.
|
||||
// Anyway, this is a bummer, should figure out a better thing in the
|
||||
// future.
|
||||
//
|
||||
// I've tried to open discussion about this at
|
||||
// WebAssembly/module-linking#8
|
||||
fields.sort_by_key(|field| match field {
|
||||
ModuleField::Type(_)
|
||||
| ModuleField::Alias(Alias {
|
||||
kind: ExportKind::Type(_),
|
||||
..
|
||||
}) => 0,
|
||||
_ => 1,
|
||||
//
|
||||
// Note that to avoid breaking round-tripping and as a convenience for
|
||||
// writing tests, we don't reorder any fields if we don't have to fill
|
||||
// in the type for any modules.
|
||||
let sort_types_first = fields.iter().any(|f| match f {
|
||||
ModuleField::NestedModule(m) => match &m.kind {
|
||||
NestedModuleKind::Inline { ty, .. } => ty.is_none(),
|
||||
_ => false,
|
||||
},
|
||||
ModuleField::Import(i) => match &i.item.kind {
|
||||
ItemKind::Module(ty) => ty.index.is_none(),
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
});
|
||||
|
||||
if sort_types_first {
|
||||
fields.sort_by_key(|field| match field {
|
||||
ModuleField::Type(_)
|
||||
| ModuleField::Alias(Alias {
|
||||
kind: ExportKind::Type(_),
|
||||
..
|
||||
}) => 0,
|
||||
_ => 1,
|
||||
});
|
||||
}
|
||||
|
||||
// Number everything in the module, recording what names correspond to
|
||||
// what indices.
|
||||
let module = &mut self.modules[self.cur];
|
||||
@ -183,14 +203,16 @@ impl<'a> Resolver<'a> {
|
||||
// This is the same as the comment above, only we're doing it now after
|
||||
// the full expansion process since all types should now be present in
|
||||
// the module.
|
||||
fields.sort_by_key(|field| match field {
|
||||
ModuleField::Type(_)
|
||||
| ModuleField::Alias(Alias {
|
||||
kind: ExportKind::Type(_),
|
||||
..
|
||||
}) => 0,
|
||||
_ => 1,
|
||||
});
|
||||
if sort_types_first {
|
||||
fields.sort_by_key(|field| match field {
|
||||
ModuleField::Type(_)
|
||||
| ModuleField::Alias(Alias {
|
||||
kind: ExportKind::Type(_),
|
||||
..
|
||||
}) => 0,
|
||||
_ => 1,
|
||||
});
|
||||
}
|
||||
|
||||
// And finally the last step is to replace all our `Index::Id` instances
|
||||
// with `Index::Num` in the AST. This does not recurse into nested
|
||||
@ -694,8 +716,22 @@ impl<'a> Resolver<'a> {
|
||||
type_idx: &Index<'a>,
|
||||
switch_module_to_instance: bool,
|
||||
) -> Result<Item<'a>, Error> {
|
||||
// First check the cache to avoid doing this work multiple times if
|
||||
// necessary. Note that we also don't do this in the
|
||||
// `switch_module_to_instance` case which happens only in rare cases
|
||||
// above anyway.
|
||||
//
|
||||
// This prevents us from recursively realizing we don't need to copy
|
||||
// over types each time we are asked to copy a type. This short-circuit
|
||||
// prevents an exponential blowup of runtime for deeply nested modules.
|
||||
if !switch_module_to_instance {
|
||||
if let Some(ret) = self.modules[self.cur].type_cache.get(&(child, *type_idx)) {
|
||||
return Ok(ret.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let (ty, child) = self.type_for(child, type_idx)?;
|
||||
match ty {
|
||||
let item = match ty {
|
||||
TypeInfo::Func(key) => {
|
||||
let key = key.clone();
|
||||
let my_key = (
|
||||
@ -708,7 +744,7 @@ impl<'a> Resolver<'a> {
|
||||
.map(|ty| self.copy_valtype_from_module(span, child, *ty))
|
||||
.collect::<Result<Box<[_]>, Error>>()?,
|
||||
);
|
||||
Ok(Item::Func(self.modules[self.cur].key_to_idx(span, my_key)))
|
||||
Item::Func(self.modules[self.cur].key_to_idx(span, my_key))
|
||||
}
|
||||
|
||||
TypeInfo::Instance { key, .. } => {
|
||||
@ -720,9 +756,7 @@ impl<'a> Resolver<'a> {
|
||||
.map(|x| (*name, x))
|
||||
})
|
||||
.collect::<Result<Vec<_>, Error>>()?;
|
||||
Ok(Item::Instance(
|
||||
self.modules[self.cur].key_to_idx(span, my_key),
|
||||
))
|
||||
Item::Instance(self.modules[self.cur].key_to_idx(span, my_key))
|
||||
}
|
||||
|
||||
TypeInfo::Module { key, .. } => {
|
||||
@ -748,16 +782,20 @@ impl<'a> Resolver<'a> {
|
||||
.map(|x| (*module, *field, x))
|
||||
})
|
||||
.collect::<Result<Vec<_>, Error>>()?;
|
||||
Ok(Item::Module(
|
||||
self.modules[self.cur].key_to_idx(span, (imports, exports)),
|
||||
))
|
||||
Item::Module(self.modules[self.cur].key_to_idx(span, (imports, exports)))
|
||||
}
|
||||
|
||||
TypeInfo::Other => Err(Error::new(
|
||||
span,
|
||||
format!("cannot copy reference types between modules right now"),
|
||||
)),
|
||||
}
|
||||
TypeInfo::Other => {
|
||||
return Err(Error::new(
|
||||
span,
|
||||
format!("cannot copy reference types between modules right now"),
|
||||
))
|
||||
}
|
||||
};
|
||||
self.modules[self.cur]
|
||||
.type_cache
|
||||
.insert((child, *type_idx), item.clone());
|
||||
Ok(item)
|
||||
}
|
||||
|
||||
fn copy_reftype_from_module(
|
||||
@ -1927,10 +1965,13 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
|
||||
Throw(i) => {
|
||||
self.module.resolve(i, Ns::Event)?;
|
||||
}
|
||||
BrOnExn(b) => {
|
||||
self.resolve_label(&mut b.label)?;
|
||||
self.module.resolve(&mut b.exn, Ns::Event)?;
|
||||
Rethrow(i) => {
|
||||
self.resolve_label(i)?;
|
||||
}
|
||||
Catch(i) => {
|
||||
self.module.resolve(i, Ns::Event)?;
|
||||
}
|
||||
|
||||
BrOnCast(b) => {
|
||||
self.resolve_label(&mut b.label)?;
|
||||
self.module.resolve_heaptype(&mut b.val)?;
|
||||
@ -2077,6 +2118,8 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
|
||||
| V128Load16Splat(m)
|
||||
| V128Load32Splat(m)
|
||||
| V128Load64Splat(m)
|
||||
| V128Load32Zero(m)
|
||||
| V128Load64Zero(m)
|
||||
| V128Store(m)
|
||||
| MemoryAtomicNotify(m)
|
||||
| MemoryAtomicWait32(m)
|
||||
|
2
third_party/rust/wat/.cargo-checksum.json
vendored
2
third_party/rust/wat/.cargo-checksum.json
vendored
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"4b973805b8ce9c658bd9ca10e76e512496d02c689054c5953eec3d091a7c9b13","README.md":"6653a386a2210f0f7e36964f15214bc441e2c723c42867dfe90dfcedcd301814","src/lib.rs":"03652351228b7f7a520f4e7f1e689fa34a37b8e5e0fc8367a167cc893cdbc449"},"package":"26b2dccbce4d0e14875091846e110a2369267b18ddd0d6423479b88dad914d71"}
|
||||
{"files":{"Cargo.toml":"61a583833e6205f9c9bcb28b3a7148d23861d2ce884775c14eb2ca9bd3c64c45","README.md":"6653a386a2210f0f7e36964f15214bc441e2c723c42867dfe90dfcedcd301814","src/lib.rs":"03652351228b7f7a520f4e7f1e689fa34a37b8e5e0fc8367a167cc893cdbc449"},"package":"0d11a88d953b298172d218d18f22853f4e6e12873b62755d05617b864d312c68"}
|
4
third_party/rust/wat/Cargo.toml
vendored
4
third_party/rust/wat/Cargo.toml
vendored
@ -13,7 +13,7 @@
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "wat"
|
||||
version = "1.0.27"
|
||||
version = "1.0.30"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
description = "Rust parser for the WebAssembly Text format, WAT\n"
|
||||
homepage = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wat"
|
||||
@ -22,4 +22,4 @@ readme = "README.md"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
repository = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wat"
|
||||
[dependencies.wast]
|
||||
version = "26.0.0"
|
||||
version = "29.0.0"
|
||||
|
Loading…
Reference in New Issue
Block a user