Bug 1624363 - Vendor wat 0.1.14. r=lth

This commit updates the wat version in tree.
 * Implements MVP GC syntax
 * Updated abs SIMD opcodes

Differential Revision: https://phabricator.services.mozilla.com/D69405

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ryan Hunt 2020-04-02 19:42:57 +00:00
Родитель 300a5cfe2a
Коммит 4f62abea70
22 изменённых файлов: 418 добавлений и 280 удалений

8
Cargo.lock сгенерированный
Просмотреть файл

@ -4850,18 +4850,18 @@ checksum = "aeb1956b19469d1c5e63e459d29e7b5aa0f558d9f16fcef09736f8a265e6c10a"
[[package]]
name = "wast"
version = "11.0.0"
version = "13.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df4d67ba9266f4fcaf2e8a1afadc5e2a959e51aecc07b1ecbdf85a6ddaf08bde"
checksum = "5b20abd8b4a26f7e0d4dd5e357e90a3d555ec190e94472c9b2b27c5b9777f9ae"
dependencies = [
"leb128",
]
[[package]]
name = "wat"
version = "1.0.12"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a9400dc1c8512087b2d974b1b9b0a6c4e6e26e7e8acf629e3e351165a1ed301"
checksum = "51a615830ee3e7200b505c441fec09aac2f114deae69df52f215cb828ba112c4"
dependencies = [
"wast",
]

Просмотреть файл

@ -9,5 +9,5 @@ crate-type = ["rlib"]
name = "wasm_rust"
[dependencies]
wat = { version = "1.0.12" }
wat = { version = "1.0.14" }
wasmparser = { version = "0.48.2" }

2
third_party/rust/wast/.cargo-checksum.json поставляемый
Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"024dfda3c577aff8df638038afab60592e156745cb30f633e2964ee20c4821db","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ad8c69458e8f19f6a796d1d791d15f014a045ed11616fe27d987aa37b49599a0","src/ast/assert_expr.rs":"0f6310eccb8a602722a13b2230cfa56dbc470e4c0ba5eb300237a81dc1bfff43","src/ast/custom.rs":"4c926ba719013537696e075c9acd8043da92a833cd28b0d843abcbfb71080fc3","src/ast/event.rs":"18f5106a87635d50b5f3b13fedd08247d3eb8158df454790151acadd41d1e0ab","src/ast/export.rs":"f296bd3238c7f9886f626d619d3a41ff0797bd51cb7bec7053278a62d8cb5355","src/ast/expr.rs":"c8ef762bbea3135d8f6a1d652d1d55ef97bfa03c9bda4a28dfedeb1d2bd84741","src/ast/func.rs":"149d947957414548b65739212a2cf1362f0ec9ecdda517653ae83949aa8a89f5","src/ast/gc.rs":"90049f183f359158e6664e7a038ee50082b2e7935450a799f9edce0d4e6a828c","src/ast/global.rs":"41b617886012277e7377600047611b78564c2c594d8c0792de1509b89676244f","src/ast/import.rs":"53f39569b8486cd5fde6b3a826bc7dc221fc925afa043e45a0a1550987332ba7","src/ast/memory.rs":"836135f8f5a7bffa90ddaad1a862b9133d9c0e680b63736daa3e2377c23cb785","src/ast/mod.rs":"f6cf3886ca07283a4f38b2524d00d46d96b55327c8c6d9dd1e2e30a2d9acaad5","src/ast/module.rs":"9f34d3d945c71fef57bb38d5ec129d2fd5787b95bbffff76cc58a724f3e70aed","src/ast/table.rs":"74e9a0588515dd039c76e8e775470ee752607f06ece3e05c7d6a4141adfb89ea","src/ast/token.rs":"0bceed5587ca46d7c5c6865fb04e2afc0eba05d503bc9055840ce7d88456a8b4","src/ast/types.rs":"12261956028dade22d921737cd90165d885bfc00d8a01d841486b511611e281e","src/ast/wast.rs":"e2a69b8fd2ff84f7f69934d1e4c7651645efd8d90d5a3ee4762576f5d5dfee29","src/binary.rs":"23fc7334a9daec9747aa88eddfeca12af99ef8f3093cafba1f09152d2e319cc8","src/lexer.rs":"1e62516a22ca89aa9510d255c264a27776a86c831b4c22a1fd00d20272e7b96c","src/lib.rs":"5fc7614c3d4a89f5fcac328d4a82cecaa445e0620bdf6bd55308cb1ead73d297","src/parser.rs":"eb0a681be02f27e1ecda97f4d8a2a0336e23be9d30a1d66a36d226ef019a4c58","src/resolve/expand.rs":"f7ecf82bb00d7c770f78f5582ec5427c25189ff11943c052572ffab2f996b12c","src/resolve/mod.rs":"916ce2c88f633e36609767f3bccfabef4438586e98475cc8f0e4cbea5d2caaf4","src/resolve/names.rs":"82b990dab9c8f58f5e20ccff1d03a90e848727b3a33b1ad1434c43c5dc06869d","src/resolve/tyexpand.rs":"69701f2fc566fd5da4b253643a91e3048dd3c41795d5fed6ac94a386ec01947a"},"package":"df4d67ba9266f4fcaf2e8a1afadc5e2a959e51aecc07b1ecbdf85a6ddaf08bde"}
{"files":{"Cargo.toml":"24568dfb6c7dba37de238f00d47ccecb9e35a9a990183a0bf6fcf79d41faa06c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ad8c69458e8f19f6a796d1d791d15f014a045ed11616fe27d987aa37b49599a0","src/ast/assert_expr.rs":"0f6310eccb8a602722a13b2230cfa56dbc470e4c0ba5eb300237a81dc1bfff43","src/ast/custom.rs":"4c926ba719013537696e075c9acd8043da92a833cd28b0d843abcbfb71080fc3","src/ast/event.rs":"18f5106a87635d50b5f3b13fedd08247d3eb8158df454790151acadd41d1e0ab","src/ast/export.rs":"f296bd3238c7f9886f626d619d3a41ff0797bd51cb7bec7053278a62d8cb5355","src/ast/expr.rs":"25b7e290cc6a3b7c416bf583b2869648cc690d0d1f26a0dcaf165b238bd4b373","src/ast/func.rs":"149d947957414548b65739212a2cf1362f0ec9ecdda517653ae83949aa8a89f5","src/ast/global.rs":"41b617886012277e7377600047611b78564c2c594d8c0792de1509b89676244f","src/ast/import.rs":"53f39569b8486cd5fde6b3a826bc7dc221fc925afa043e45a0a1550987332ba7","src/ast/memory.rs":"836135f8f5a7bffa90ddaad1a862b9133d9c0e680b63736daa3e2377c23cb785","src/ast/mod.rs":"74fb35f65f786e82f66e7c85c9102051923d6938f8615eb2b57c3363476ae153","src/ast/module.rs":"b25df1f5648ea6fd7666537d52aa18221d435301793e4e01c8affa4ebb0da7c9","src/ast/table.rs":"74e9a0588515dd039c76e8e775470ee752607f06ece3e05c7d6a4141adfb89ea","src/ast/token.rs":"cdaaa6f50a9868ed7d0ec7088447ba94e3df5c81d38bc471c55d0968c249f73c","src/ast/types.rs":"9066d8b425005a6a70d5ada5e0ae316bf9bcab8e685fd941cc6d0ebb7e204473","src/ast/wast.rs":"9e64d00baf809d09181a06073a3fa9ac5907ac8248336cfd2089735d017075e3","src/binary.rs":"7f97251d6dd80dde667559e25fe38cdd9f540468416532a796a1bafd77c4b44a","src/lexer.rs":"1e62516a22ca89aa9510d255c264a27776a86c831b4c22a1fd00d20272e7b96c","src/lib.rs":"5fc7614c3d4a89f5fcac328d4a82cecaa445e0620bdf6bd55308cb1ead73d297","src/parser.rs":"926838cf6a6bef8bdad1013194f3d9305b2237e9f7fb2df2fa8ca44f557483aa","src/resolve/expand.rs":"f7ecf82bb00d7c770f78f5582ec5427c25189ff11943c052572ffab2f996b12c","src/resolve/mod.rs":"916ce2c88f633e36609767f3bccfabef4438586e98475cc8f0e4cbea5d2caaf4","src/resolve/names.rs":"13e67ac425ae4fda25388102eab66aae4a2927c9ad80e1fe72ca9de6f8df8b22","src/resolve/tyexpand.rs":"69701f2fc566fd5da4b253643a91e3048dd3c41795d5fed6ac94a386ec01947a"},"package":"5b20abd8b4a26f7e0d4dd5e357e90a3d555ec190e94472c9b2b27c5b9777f9ae"}

2
third_party/rust/wast/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "wast"
version = "11.0.0"
version = "13.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/wat/tree/master/crates/wast"

58
third_party/rust/wast/src/ast/expr.rs поставляемый
Просмотреть файл

@ -352,8 +352,16 @@ instructions! {
Return : [0x0f] : "return",
Call(ast::Index<'a>) : [0x10] : "call",
CallIndirect(CallIndirect<'a>) : [0x11] : "call_indirect",
// tail-call proposal
ReturnCall(ast::Index<'a>) : [0x12] : "return_call",
ReturnCallIndirect(CallIndirect<'a>) : [0x13] : "return_call_indirect",
// function-references proposal
CallRef : [0x14] : "call_ref",
ReturnCallRef : [0x15] : "return_call_ref",
FuncBind(ast::Index<'a>) : [0x16] : "func.bind",
Drop : [0x1a] : "drop",
Select(SelectTypes<'a>) : [] : "select",
LocalGet(ast::Index<'a>) : [0x20] : "local.get" | "get_local",
@ -405,15 +413,47 @@ instructions! {
RefNull : [0xd0] : "ref.null",
RefIsNull : [0xd1] : "ref.is_null",
RefEq : [0xf0] : "ref.eq", // unofficial, part of gc proposal
RefHost(u32) : [0xff] : "ref.host", // only used in test harness
RefFunc(ast::Index<'a>) : [0xd2] : "ref.func", // only used in test harness
RefFunc(ast::Index<'a>) : [0xd2] : "ref.func",
// unofficial, part of gc proposal
StructNew(ast::Index<'a>) : [0xfc, 0x50] : "struct.new",
StructGet(StructAccess<'a>) : [0xfc, 0x51] : "struct.get",
StructSet(StructAccess<'a>) : [0xfc, 0x52] : "struct.set",
StructNarrow(StructNarrow<'a>) : [0xfc, 0x53] : "struct.narrow",
// function-references proposal
RefAsNonNull : [0xd3] : "ref.as_non_null",
BrOnNull(ast::Index<'a>) : [0xd4] : "br_on_null",
// gc proposal: eqref
RefEq : [0xd5] : "ref.eq",
// gc proposal: struct
StructNew(ast::Index<'a>) : [0xfb, 0x00] : "struct.new",
StructNewSub(ast::Index<'a>) : [0xfb, 0x01] : "struct.new_sub",
StructNewDefault(ast::Index<'a>) : [0xfb, 0x02] : "struct.new_default",
StructGet(StructAccess<'a>) : [0xfb, 0x03] : "struct.get",
StructGetS(StructAccess<'a>) : [0xfb, 0x04] : "struct.get_s",
StructGetU(StructAccess<'a>) : [0xfb, 0x05] : "struct.get_u",
StructSet(StructAccess<'a>) : [0xfb, 0x06] : "struct.set",
StructNarrow(StructNarrow<'a>) : [0xfb, 0x07] : "struct.narrow",
// gc proposal: array
ArrayNew(ast::Index<'a>) : [0xfb, 0x10] : "array.new",
ArrayNewSub(ast::Index<'a>) : [0xfb, 0x11] : "array.new_sub",
ArrayNewDefault(ast::Index<'a>) : [0xfb, 0x12] : "array.new_default",
ArrayGet(ast::Index<'a>) : [0xfb, 0x13] : "array.get",
ArrayGetS(ast::Index<'a>) : [0xfb, 0x14] : "array.get_s",
ArrayGetU(ast::Index<'a>) : [0xfb, 0x15] : "array.get_u",
ArraySet(ast::Index<'a>) : [0xfb, 0x16] : "array.set",
ArrayLen(ast::Index<'a>) : [0xfb, 0x17] : "array.len",
// gc proposal, i31
I31New : [0xfb, 0x20] : "i31.new",
I31GetS : [0xfb, 0x21] : "i31.get_s",
I31GetU : [0xfb, 0x22] : "i31.get_u",
// gc proposal, rtt/casting
RTTGet(ast::Index<'a>) : [0xfb, 0x30] : "rtt.get",
RTTSub(ast::Index<'a>) : [0xfb, 0x31] : "rtt.sub",
RefTest : [0xfb, 0x40] : "ref.test",
RefCast : [0xfb, 0x41] : "ref.cast",
BrOnCast(ast::Index<'a>) : [0xfb, 0x42] : "br_on_cast",
I32Const(i32) : [0x41] : "i32.const",
I64Const(i64) : [0x42] : "i64.const",
@ -837,6 +877,10 @@ instructions! {
I8x16AvgrU : [0xfd, 0xd9] : "i8x16.avgr_u",
I16x8AvgrU : [0xfd, 0xda] : "i16x8.avgr_u",
I8x16Abs : [0xfd, 0xe1] : "i8x16.abs",
I16x8Abs : [0xfd, 0xe2] : "i16x8.abs",
I32x4Abs : [0xfd, 0xe3] : "i32x4.abs",
Try(BlockType<'a>) : [0x06] : "try",
Catch : [0x07] : "catch",
Throw(ast::Index<'a>) : [0x08] : "throw",

22
third_party/rust/wast/src/ast/gc.rs поставляемый
Просмотреть файл

@ -1,22 +0,0 @@
use crate::ast::{self, kw};
use crate::parser::{Parse, Parser, Result};
/// A WebAssembly GC opt-in directive, part of the GC prototype.
#[derive(Debug)]
pub struct GcOptIn {
/// Where this event was defined
pub span: ast::Span,
/// The version of the GC proposal
pub version: u8,
}
impl<'a> Parse<'a> for GcOptIn {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::gc_feature_opt_in>()?.0;
let version = parser.parse()?;
Ok(GcOptIn {
span,
version,
})
}
}

16
third_party/rust/wast/src/ast/mod.rs поставляемый
Просмотреть файл

@ -307,7 +307,6 @@ reexport! {
mod export;
mod expr;
mod func;
mod gc;
mod global;
mod import;
mod memory;
@ -320,8 +319,10 @@ reexport! {
/// Common keyword used to parse WebAssembly text files.
pub mod kw {
custom_keyword!(after);
custom_keyword!(any);
custom_keyword!(anyfunc);
custom_keyword!(anyref);
custom_keyword!(array);
custom_keyword!(assert_exhaustion);
custom_keyword!(assert_invalid);
custom_keyword!(assert_malformed);
@ -344,7 +345,11 @@ pub mod kw {
custom_keyword!(elem);
custom_keyword!(end);
custom_keyword!(event);
custom_keyword!(exn);
custom_keyword!(exnref);
custom_keyword!(export);
custom_keyword!(eq);
custom_keyword!(eqref);
custom_keyword!(f32);
custom_keyword!(f32x4);
custom_keyword!(f64);
@ -353,14 +358,17 @@ pub mod kw {
custom_keyword!(first);
custom_keyword!(func);
custom_keyword!(funcref);
custom_keyword!(gc_feature_opt_in);
custom_keyword!(get);
custom_keyword!(global);
custom_keyword!(i16);
custom_keyword!(i16x8);
custom_keyword!(i31);
custom_keyword!(i31ref);
custom_keyword!(i32);
custom_keyword!(i32x4);
custom_keyword!(i64);
custom_keyword!(i64x2);
custom_keyword!(i8);
custom_keyword!(i8x16);
custom_keyword!(import);
custom_keyword!(invoke);
@ -371,8 +379,11 @@ pub mod kw {
custom_keyword!(module);
custom_keyword!(nan_arithmetic = "nan:arithmetic");
custom_keyword!(nan_canonical = "nan:canonical");
custom_keyword!(null);
custom_keyword!(nullref);
custom_keyword!(offset);
custom_keyword!(opt);
custom_keyword!(optref);
custom_keyword!(param);
custom_keyword!(passive);
custom_keyword!(quote);
@ -386,6 +397,7 @@ pub mod kw {
custom_keyword!(ref_null = "ref.null");
custom_keyword!(register);
custom_keyword!(result);
custom_keyword!(rtt);
custom_keyword!(shared);
custom_keyword!(start);
custom_keyword!(r#struct = "struct");

10
third_party/rust/wast/src/ast/module.rs поставляемый
Просмотреть файл

@ -15,12 +15,12 @@ pub struct Wat<'a> {
impl<'a> Parse<'a> for Wat<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if !parser.has_meaningful_tokens() {
return Err(parser.error("expected at least one module field"));
}
let _r = parser.register_annotation("custom");
let module = if !parser.peek2::<kw::module>() {
let fields = ModuleField::parse_remaining(parser)?;
if fields.is_empty() {
return Err(parser.error("expected at least one module field"));
}
Module {
span: ast::Span { offset: 0 },
id: None,
@ -170,7 +170,6 @@ pub enum ModuleField<'a> {
Elem(ast::Elem<'a>),
Data(ast::Data<'a>),
Event(ast::Event<'a>),
GcOptIn(ast::GcOptIn),
Custom(ast::Custom<'a>),
}
@ -220,9 +219,6 @@ impl<'a> Parse<'a> for ModuleField<'a> {
if parser.peek::<kw::event>() {
return Ok(ModuleField::Event(parser.parse()?));
}
if parser.peek::<kw::gc_feature_opt_in>() {
return Ok(ModuleField::GcOptIn(parser.parse()?));
}
if parser.peek::<annotation::custom>() {
return Ok(ModuleField::Custom(parser.parse()?));
}

6
third_party/rust/wast/src/ast/token.rs поставляемый
Просмотреть файл

@ -1,12 +1,12 @@
use crate::ast::annotation;
use crate::lexer::FloatVal;
use crate::parser::{Cursor, Parse, Parser, Peek, Result};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::str;
use crate::ast::annotation;
/// A position in the original source stream, used to render errors.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub struct Span {
pub(crate) offset: usize,
}
@ -235,7 +235,7 @@ impl Peek for &'_ [u8] {
impl<'a> Parse<'a> for &'a str {
fn parse(parser: Parser<'a>) -> Result<Self> {
str::from_utf8(parser.parse()?).map_err(|_| parser.error("invalid UTF-8 encoding"))
str::from_utf8(parser.parse()?).map_err(|_| parser.error("malformed UTF-8 encoding"))
}
}

144
third_party/rust/wast/src/ast/types.rs поставляемый
Просмотреть файл

@ -9,11 +9,18 @@ pub enum ValType<'a> {
I64,
F32,
F64,
Anyref,
Funcref,
V128,
I8,
I16,
Funcref,
Anyref,
Nullref,
Ref(ast::Index<'a>)
Exnref,
Ref(ast::Index<'a>),
Optref(ast::Index<'a>),
Eqref,
I31ref,
Rtt(ast::Index<'a>),
}
impl<'a> Parse<'a> for ValType<'a> {
@ -31,26 +38,79 @@ impl<'a> Parse<'a> for ValType<'a> {
} else if l.peek::<kw::f64>() {
parser.parse::<kw::f64>()?;
Ok(ValType::F64)
} else if l.peek::<kw::anyref>() {
parser.parse::<kw::anyref>()?;
Ok(ValType::Anyref)
} else if l.peek::<kw::v128>() {
parser.parse::<kw::v128>()?;
Ok(ValType::V128)
} else if l.peek::<kw::i8>() {
parser.parse::<kw::i8>()?;
Ok(ValType::I8)
} else if l.peek::<kw::i16>() {
parser.parse::<kw::i16>()?;
Ok(ValType::I16)
} else if l.peek::<kw::funcref>() {
parser.parse::<kw::funcref>()?;
Ok(ValType::Funcref)
} else if l.peek::<kw::anyfunc>() {
parser.parse::<kw::anyfunc>()?;
Ok(ValType::Funcref)
} else if l.peek::<kw::anyref>() {
parser.parse::<kw::anyref>()?;
Ok(ValType::Anyref)
} else if l.peek::<kw::nullref>() {
parser.parse::<kw::nullref>()?;
Ok(ValType::Nullref)
} else if l.peek::<kw::v128>() {
parser.parse::<kw::v128>()?;
Ok(ValType::V128)
} else if l.peek::<ast::LParen>() {
parser.parens(|p| {
p.parse::<kw::r#ref>()?;
Ok(ValType::Ref(parser.parse()?))
let mut l = parser.lookahead1();
if l.peek::<kw::r#ref>() {
p.parse::<kw::r#ref>()?;
let mut l = parser.lookahead1();
if l.peek::<kw::func>() {
parser.parse::<kw::func>()?;
Ok(ValType::Funcref)
} else if l.peek::<kw::any>() {
parser.parse::<kw::any>()?;
Ok(ValType::Anyref)
} else if l.peek::<kw::null>() {
parser.parse::<kw::null>()?;
Ok(ValType::Nullref)
} else if l.peek::<kw::exn>() {
parser.parse::<kw::exn>()?;
Ok(ValType::Exnref)
} else if l.peek::<kw::eq>() {
parser.parse::<kw::eq>()?;
Ok(ValType::Eqref)
} else if l.peek::<kw::i31>() {
parser.parse::<kw::i31>()?;
Ok(ValType::I31ref)
} else if l.peek::<kw::opt>() {
parser.parse::<kw::opt>()?;
Ok(ValType::Optref(parser.parse()?))
} else if l.peek::<ast::Index>() {
Ok(ValType::Ref(parser.parse()?))
} else {
Err(l.error())
}
} else if l.peek::<kw::optref>() {
p.parse::<kw::optref>()?;
Ok(ValType::Optref(parser.parse()?))
} else if l.peek::<kw::rtt>() {
p.parse::<kw::rtt>()?;
Ok(ValType::Rtt(parser.parse()?))
} else {
Err(l.error())
}
})
} else if l.peek::<kw::exnref>() {
parser.parse::<kw::exnref>()?;
Ok(ValType::Exnref)
} else if l.peek::<kw::eqref>() {
parser.parse::<kw::eqref>()?;
Ok(ValType::Eqref)
} else if l.peek::<kw::i31ref>() {
parser.parse::<kw::i31ref>()?;
Ok(ValType::I31ref)
} else {
Err(l.error())
}
@ -96,6 +156,8 @@ pub enum TableElemType {
Anyref,
/// An element for a table that is a list of `nullref` values.
Nullref,
/// An element for a table that is a list of `exnref` values.
Exnref,
}
impl<'a> Parse<'a> for TableElemType {
@ -115,6 +177,9 @@ impl<'a> Parse<'a> for TableElemType {
} else if l.peek::<kw::nullref>() {
parser.parse::<kw::nullref>()?;
Ok(TableElemType::Nullref)
} else if l.peek::<kw::exnref>() {
parser.parse::<kw::exnref>()?;
Ok(TableElemType::Exnref)
} else {
Err(l.error())
}
@ -127,6 +192,7 @@ impl Peek for TableElemType {
|| kw::anyref::peek(cursor)
|| kw::nullref::peek(cursor)
|| /* legacy */ kw::anyfunc::peek(cursor)
|| kw::exnref::peek(cursor)
}
fn display() -> &'static str {
"table element type"
@ -267,10 +333,15 @@ impl<'a> Parse<'a> for StructType<'a> {
fields: Vec::new(),
};
while !parser.is_empty() {
parser.parens(|parser| {
ret.fields.push(parser.parse()?);
Ok(())
})?;
let field = if parser.peek2::<kw::field>() {
parser.parens(|parser| {
parser.parse::<kw::field>()?;
StructField::parse(parser, true)
})
} else {
StructField::parse(parser, false)
};
ret.fields.push(field?);
}
Ok(ret)
}
@ -287,10 +358,13 @@ pub struct StructField<'a> {
pub ty: ValType<'a>,
}
impl<'a> Parse<'a> for StructField<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::field>()?;
let id = parser.parse()?;
impl<'a> StructField<'a> {
fn parse(parser: Parser<'a>, with_id: bool) -> Result<Self> {
let id = if with_id {
parser.parse()?
} else {
None
};
let (ty, mutable) = if parser.peek2::<kw::r#mut>() {
let ty = parser.parens(|parser| {
parser.parse::<kw::r#mut>()?;
@ -308,6 +382,34 @@ impl<'a> Parse<'a> for StructField<'a> {
}
}
/// An array type with fields.
#[derive(Clone, Debug)]
pub struct ArrayType<'a> {
/// Whether this field may be mutated or not.
pub mutable: bool,
/// The value type stored in this field.
pub ty: ValType<'a>,
}
impl<'a> Parse<'a> for ArrayType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::array>()?;
let (ty, mutable) = if parser.peek2::<kw::r#mut>() {
let ty = parser.parens(|parser| {
parser.parse::<kw::r#mut>()?;
parser.parse()
})?;
(ty, true)
} else {
(parser.parse::<ValType<'a>>()?, false)
};
Ok(ArrayType {
mutable,
ty
})
}
}
/// A definition of a type.
#[derive(Debug)]
pub enum TypeDef<'a> {
@ -315,6 +417,8 @@ pub enum TypeDef<'a> {
Func(FunctionType<'a>),
/// A struct type definition.
Struct(StructType<'a>),
/// An array type definition.
Array(ArrayType<'a>),
}
/// A type declaration in a module
@ -337,6 +441,8 @@ impl<'a> Parse<'a> for Type<'a> {
Ok(TypeDef::Func(parser.parse()?))
} else if l.peek::<kw::r#struct>() {
Ok(TypeDef::Struct(parser.parse()?))
} else if l.peek::<kw::array>() {
Ok(TypeDef::Array(parser.parse()?))
} else {
Err(l.error())
}

19
third_party/rust/wast/src/ast/wast.rs поставляемый
Просмотреть файл

@ -53,6 +53,10 @@ impl Peek for WastDirectiveToken {
#[allow(missing_docs)]
pub enum WastDirective<'a> {
Module(ast::Module<'a>),
QuoteModule {
span: ast::Span,
source: Vec<&'a [u8]>,
},
AssertMalformed {
span: ast::Span,
module: QuoteModule<'a>,
@ -98,6 +102,7 @@ impl WastDirective<'_> {
WastDirective::Module(m) => m.span,
WastDirective::AssertMalformed { span, .. }
| WastDirective::Register { span, .. }
| WastDirective::QuoteModule{ span, .. }
| WastDirective::AssertTrap { span, .. }
| WastDirective::AssertReturn { span, .. }
| WastDirective::AssertExhaustion { span, .. }
@ -112,7 +117,17 @@ impl<'a> Parse<'a> for WastDirective<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut l = parser.lookahead1();
if l.peek::<kw::module>() {
Ok(WastDirective::Module(parser.parse()?))
if parser.peek2::<kw::quote>() {
parser.parse::<kw::module>()?;
let span = parser.parse::<kw::quote>()?.0;
let mut source = Vec::new();
while !parser.is_empty() {
source.push(parser.parse()?);
}
Ok(WastDirective::QuoteModule { span, source })
} else {
Ok(WastDirective::Module(parser.parse()?))
}
} else if l.peek::<kw::assert_malformed>() {
let span = parser.parse::<kw::assert_malformed>()?.0;
Ok(WastDirective::AssertMalformed {
@ -296,7 +311,7 @@ impl<'a> Parse<'a> for WastInvoke<'a> {
#[allow(missing_docs)]
pub enum QuoteModule<'a> {
Module(ast::Module<'a>),
Quote(Vec<&'a str>),
Quote(Vec<&'a [u8]>),
}
impl<'a> Parse<'a> for QuoteModule<'a> {

42
third_party/rust/wast/src/binary.rs поставляемый
Просмотреть файл

@ -22,7 +22,6 @@ pub fn encode(module: &Module<'_>) -> Vec<u8> {
let mut elem = Vec::new();
let mut data = Vec::new();
let mut events = Vec::new();
let mut gcs = Vec::new();
let mut customs = Vec::new();
for field in fields {
match field {
@ -37,7 +36,6 @@ pub fn encode(module: &Module<'_>) -> Vec<u8> {
ModuleField::Elem(i) => elem.push(i),
ModuleField::Data(i) => data.push(i),
ModuleField::Event(i) => events.push(i),
ModuleField::GcOptIn(i) => gcs.push(i),
ModuleField::Custom(i) => customs.push(i),
}
}
@ -51,17 +49,14 @@ pub fn encode(module: &Module<'_>) -> Vec<u8> {
e.wasm.extend(b"\x01\0\0\0");
e.custom_sections(BeforeFirst);
if let Some(gc) = gcs.get(0) {
e.section(42, gc);
}
e.section_list(1, Type, &types);
e.section_list(2, Import, &imports);
let functys = funcs.iter().map(|f| &f.ty).collect::<Vec<_>>();
e.section_list(3, Func, &functys);
e.section_list(4, Table, &tables);
e.section_list(5, Memory, &memories);
e.section_list(6, Global, &globals);
e.section_list(13, Event, &events);
e.section_list(6, Global, &globals);
e.section_list(7, Export, &exports);
e.custom_sections(Before(Start));
if let Some(start) = start.get(0) {
@ -200,12 +195,19 @@ impl Encode for StructType<'_> {
fn encode(&self, e: &mut Vec<u8>) {
self.fields.len().encode(e);
for field in self.fields.iter() {
(field.mutable as i32).encode(e);
field.ty.encode(e);
(field.mutable as i32).encode(e);
}
}
}
impl Encode for ArrayType<'_> {
fn encode(&self, e: &mut Vec<u8>) {
self.ty.encode(e);
(self.mutable as i32).encode(e);
}
}
impl Encode for Type<'_> {
fn encode(&self, e: &mut Vec<u8>) {
match &self.def {
@ -214,9 +216,13 @@ impl Encode for Type<'_> {
func.encode(e)
}
TypeDef::Struct(r#struct) => {
e.push(0x50);
e.push(0x5f);
r#struct.encode(e)
}
TypeDef::Array(array) => {
e.push(0x5e);
array.encode(e)
}
}
}
}
@ -242,6 +248,8 @@ impl<'a> Encode for ValType<'a> {
ValType::F32 => e.push(0x7d),
ValType::F64 => e.push(0x7c),
ValType::V128 => e.push(0x7b),
ValType::I8 => e.push(0x7a),
ValType::I16 => e.push(0x79),
ValType::Funcref => e.push(0x70),
ValType::Anyref => e.push(0x6f),
ValType::Nullref => e.push(0x6e),
@ -249,6 +257,17 @@ impl<'a> Encode for ValType<'a> {
e.push(0x6d);
index.encode(e);
}
ValType::Optref(index) => {
e.push(0x6c);
index.encode(e);
}
ValType::Eqref => e.push(0x6b),
ValType::I31ref => e.push(0x6a),
ValType::Rtt(index) => {
e.push(0x69);
index.encode(e);
}
ValType::Exnref => e.push(0x68),
}
}
}
@ -313,6 +332,7 @@ impl Encode for TableElemType {
TableElemType::Funcref => ValType::Funcref.encode(e),
TableElemType::Anyref => ValType::Anyref.encode(e),
TableElemType::Nullref => ValType::Nullref.encode(e),
TableElemType::Exnref => ValType::Exnref.encode(e),
}
}
}
@ -786,12 +806,6 @@ impl Encode for Custom<'_> {
}
}
impl Encode for GcOptIn {
fn encode(&self, e: &mut Vec<u8>) {
self.version.encode(e);
}
}
impl Encode for Event<'_> {
fn encode(&self, e: &mut Vec<u8>) {
self.ty.encode(e);

81
third_party/rust/wast/src/parser.rs поставляемый
Просмотреть файл

@ -275,7 +275,7 @@ pub struct ParseBuffer<'a> {
known_annotations: RefCell<HashMap<String, usize>>,
}
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
enum NextTokenAt {
/// Haven't computed where the next token is yet.
Unknown,
@ -329,17 +329,76 @@ impl ParseBuffer<'_> {
for token in Lexer::new(input) {
tokens.push((token?, Cell::new(NextTokenAt::Unknown)));
}
Ok(ParseBuffer {
let ret = ParseBuffer {
tokens: tokens.into_boxed_slice(),
cur: Cell::new(0),
input,
known_annotations: Default::default(),
})
};
ret.validate_annotations()?;
Ok(ret)
}
fn parser(&self) -> Parser<'_> {
Parser { buf: self }
}
// Validates that all annotations properly parse in that they have balanced
// delimiters. This is required since while parsing we generally skip
// annotations and there's no real opportunity to return a parse error.
fn validate_annotations(&self) -> Result<()> {
use crate::lexer::Source::*;
use crate::lexer::Token::*;
enum State {
None,
LParen,
Annotation { depth: usize, span: Span },
}
let mut state = State::None;
for token in self.tokens.iter() {
state = match (&token.0, state) {
// From nothing, a `(` starts the search for an annotation
(Token(LParen(_)), State::None) => State::LParen,
// ... otherwise in nothing we alwyas preserve that state.
(_, State::None) => State::None,
// If the previous state was an `LParen`, we may have an
// annotation if the next keyword is reserved
(Token(Reserved(s)), State::LParen) if s.starts_with("@") && s.len() > 0 => {
let offset = self.input_pos(s);
State::Annotation {
span: Span { offset },
depth: 1,
}
}
// ... otherwise anything after an `LParen` kills the lparen
// state.
(_, State::LParen) => State::None,
// Once we're in an annotation we need to balance parentheses,
// so handle the depth changes.
(Token(LParen(_)), State::Annotation { span, depth }) => State::Annotation {
span,
depth: depth + 1,
},
(Token(RParen(_)), State::Annotation { depth: 1, .. }) => State::None,
(Token(RParen(_)), State::Annotation { span, depth }) => State::Annotation {
span,
depth: depth - 1,
},
// ... and otherwise all tokens are allowed in annotations.
(_, s @ State::Annotation { .. }) => s,
};
}
if let State::Annotation { span, .. } = state {
return Err(Error::new(span, format!("unclosed annotation")));
}
Ok(())
}
fn input_pos(&self, src: &str) -> usize {
src.as_ptr() as usize - self.input.as_ptr() as usize
}
}
impl<'a> Parser<'a> {
@ -359,6 +418,16 @@ impl<'a> Parser<'a> {
}
}
pub(crate) fn has_meaningful_tokens(self) -> bool {
self.buf.tokens[self.cursor().cur..]
.iter()
.any(|(t, _)| match t {
Source::Token(_) => true,
Source::Comment(_) => false,
Source::Whitespace(_) => false,
})
}
/// Parses a `T` from this [`Parser`].
///
/// This method has a trivial definition (it simply calls
@ -635,10 +704,6 @@ impl<'a> Parser<'a> {
Error::parse(span, self.buf.input, msg.to_string())
}
fn input_pos(self, src: &'a str) -> usize {
src.as_ptr() as usize - self.buf.input.as_ptr() as usize
}
/// Returns the span of the current token
pub fn cur_span(&self) -> Span {
self.cursor().cur_span()
@ -802,7 +867,7 @@ impl<'a> Cursor<'a> {
/// Does not take into account whitespace or comments.
pub fn cur_span(&self) -> Span {
let offset = match self.clone().advance_token() {
Some(t) => self.parser.input_pos(t.src()),
Some(t) => self.parser.buf.input_pos(t.src()),
None => self.parser.buf.input.len(),
};
Span { offset }

40
third_party/rust/wast/src/resolve/names.rs поставляемый
Просмотреть файл

@ -83,16 +83,14 @@ impl<'a> Resolver<'a> {
}
}
}
TypeDef::Array(_) => {}
}
Ok(())
}
ModuleField::Elem(e) => register(Ns::Elem, e.id),
ModuleField::Data(d) => register(Ns::Data, d.id),
ModuleField::Event(e) => register(Ns::Event, e.id),
ModuleField::Start(_)
| ModuleField::Export(_)
| ModuleField::GcOptIn(_)
| ModuleField::Custom(_) => Ok(()),
ModuleField::Start(_) | ModuleField::Export(_) | ModuleField::Custom(_) => Ok(()),
}
}
@ -205,18 +203,18 @@ impl<'a> Resolver<'a> {
ModuleField::Event(e) => self.resolve_event_type(e.span, &mut e.ty),
ModuleField::Table(_)
| ModuleField::Memory(_)
| ModuleField::GcOptIn(_)
| ModuleField::Custom(_) => Ok(()),
ModuleField::Table(_) | ModuleField::Memory(_) | ModuleField::Custom(_) => Ok(()),
}
}
fn resolve_valtype(&self, ty: &mut ValType<'a>) -> Result<(), Error> {
if let ValType::Ref(id) = ty {
self.ns(Ns::Type)
.resolve(id)
.map_err(|id| self.resolve_error(id, "type"))?;
match ty {
ValType::Ref(i) | ValType::Optref(i) | ValType::Rtt(i) => {
self.ns(Ns::Type)
.resolve(i)
.map_err(|id| self.resolve_error(id, "type"))?;
}
_ => {}
}
Ok(())
}
@ -225,6 +223,7 @@ impl<'a> Resolver<'a> {
match &mut ty.def {
TypeDef::Func(func) => self.resolve_function_type(func),
TypeDef::Struct(r#struct) => self.resolve_struct_type(r#struct),
TypeDef::Array(array) => self.resolve_array_type(array),
}
}
@ -245,6 +244,11 @@ impl<'a> Resolver<'a> {
Ok(())
}
fn resolve_array_type(&self, array: &mut ArrayType<'a>) -> Result<(), Error> {
self.resolve_valtype(&mut array.ty)?;
Ok(())
}
fn resolve_type_use(&self, span: Span, ty: &mut TypeUse<'a>) -> Result<u32, Error> {
assert!(ty.index.is_some());
let idx = self
@ -341,7 +345,7 @@ impl<'a> Namespace<'a> {
if desc != "elem" && desc != "data" {
return Err(Error::new(
name.span(),
format!("duplicate identifier for {}", desc),
format!("duplicate {} identifier", desc),
));
}
}
@ -435,6 +439,8 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
Ok(())
}
FuncBind(i) => self.resolver.resolve_idx(i, Ns::Type),
Block(bt) | If(bt) | Loop(bt) | Try(bt) => {
self.labels.push(bt.label);
@ -508,7 +514,7 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
));
}
Br(i) | BrIf(i) => self.resolve_label(i),
Br(i) | BrIf(i) | BrOnCast(i) => self.resolve_label(i),
BrTable(i) => {
for label in i.labels.iter_mut() {
@ -530,8 +536,10 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
Ok(())
}
StructNew(s) => self.resolver.resolve_idx(s, Ns::Type),
StructSet(s) | StructGet(s) => {
StructNew(i) | StructNewSub(i) | StructNewDefault(i) | ArrayNew(i) | ArrayNewSub(i)
| ArrayNewDefault(i) | ArrayGet(i) | ArrayGetS(i) | ArrayGetU(i) | ArraySet(i)
| ArrayLen(i) | RTTGet(i) | RTTSub(i) => self.resolver.resolve_idx(i, Ns::Type),
StructSet(s) | StructGet(s) | StructGetS(s) | StructGetU(s) => {
self.resolver.resolve_idx(&mut s.r#struct, Ns::Type)?;
self.resolver.resolve_idx(&mut s.field, Ns::Field)
}

2
third_party/rust/wat/.cargo-checksum.json поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

6
third_party/rust/wat/Cargo.lock сгенерированный поставляемый
Просмотреть файл

@ -323,16 +323,16 @@ checksum = "a40d24f114a3f24b459ec292019220cff6388673b4a2c0a11483665b599ef15c"
[[package]]
name = "wast"
version = "11.0.0"
version = "13.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df4d67ba9266f4fcaf2e8a1afadc5e2a959e51aecc07b1ecbdf85a6ddaf08bde"
checksum = "5b20abd8b4a26f7e0d4dd5e357e90a3d555ec190e94472c9b2b27c5b9777f9ae"
dependencies = [
"leb128",
]
[[package]]
name = "wat"
version = "1.0.12"
version = "1.0.14"
dependencies = [
"anyhow",
"getopts",

4
third_party/rust/wat/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "wat"
version = "1.0.12"
version = "1.0.14"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
exclude = ["tests/wabt", "tests/testsuite"]
description = "Rust parser for the WebAssembly Text format, WAT\n"
@ -35,7 +35,7 @@ harness = false
name = "parse-fail"
harness = false
[dependencies.wast]
version = "11.0.0"
version = "13.0.0"
[dev-dependencies.anyhow]
version = "1.0"

4
third_party/rust/wat/tests/regression.rs поставляемый
Просмотреть файл

@ -1,4 +0,0 @@
#[test]
fn empty_string_fails() {
assert!(wat::parse_str("").is_err());
}

Просмотреть файл

@ -1,147 +0,0 @@
(@a)
(@aas-3!@$d-@#4)
(@@) (@$) (@+) (@0) (@.) (@!$@#$23414@#$)
(@a x y z)
(@a x-y $yz "aa" -2 0.3 0x3)
(@a x-y$yz"aa"-2)
(@a block func module i32.add)
(@a 0x 8q 0xfa #4g0-.@f#^&@#$*0sf -- @#)
(@a , ; ] [ }} }x{ ({) ,{{};}] ;)
(@a (bla) () (5-g) ("aa" a) ($x) (bla bla) (x (y)) ")" "(" x")"y)
(@a @ @x (@x) (@x y) (@) (@ x) (@(@(@(@)))))
(@a (;bla;) (; ) ;)
;; bla)
;; bla (@x
)
(assert_malformed (module quote "( @a)") "unknown operator")
(assert_malformed (module quote "(@)") "malformed annotation id")
(assert_malformed (module quote "(@ )") "malformed annotation id")
(assert_malformed (module quote "(@ x)") "malformed annotation id")
(assert_malformed (module quote "(@(@a)x)") "malformed annotation id")
(assert_malformed (module quote "(@x ") "unclosed annotation")
(assert_malformed (module quote "(@x ()") "unclosed annotation")
(assert_malformed (module quote "(@x (y (z))") "unclosed annotation")
(assert_malformed (module quote "(@x (@y )") "unclosed annotation")
(assert_malformed (module quote "(@x))") "unexpected token")
(assert_malformed (module quote "(@x ()))") "unexpected token")
(assert_malformed (module quote "(@x (y (z))))") "unexpected token")
(assert_malformed (module quote "(@x (@y )))") "unexpected token")
(assert_malformed (module quote "(@x \"") "unclosed string")
(assert_malformed (module quote "(@x \")") "unclosed string")
(assert_malformed (module quote "((@a)@b)") "unknown operator")
(assert_malformed (module quote "(func $(@a))") "unknown operator")
(assert_malformed (module quote "(func $(@a)f)") "unknown operator")
((@a) module (@a) $m (@a) (@a)
((@a) import (@a) "spectest" (@a) "global_i32" (@a)
((@a) global (@a) $g (@a) i32 (@a)) (@a)
) (@a)
((@a) import (@a) "spectest" (@a) "table" (@a)
((@a) table (@a) $t (@a) 10 (@a) 20 (@a) funcref (@a)) (@a)
) (@a)
((@a) import (@a) "spectest" (@a) "memory" (@a)
((@a) memory (@a) $m (@a) 1 (@a) 2 (@a)) (@a)
) (@a)
((@a) import (@a) "spectest" (@a) "print_i32_f32" (@a)
((@a) func (@a) $f (@a)
((@a) param (@a) i32 (@a) f32 (@a)) (@a)
((@a) result (@a)) (@a)
) (@a)
) (@a)
((@a) export (@a) "g" (@a)
((@a) global (@a) $g (@a)) (@a)
) (@a)
((@a) export (@a) "t" (@a)
((@a) table (@a) $t (@a)) (@a)
) (@a)
((@a) export (@a) "m" (@a)
((@a) memory (@a) $m (@a)) (@a)
) (@a)
((@a) export (@a) "f" (@a)
((@a) func (@a) $f (@a)) (@a)
) (@a)
) (@a)
((@a) module (@a) $m (@a) (@a)
((@a) global (@a) $g (@a)
((@a) export (@a) "g" (@a)) (@a)
((@a) import (@a) "spectest" (@a) "global_i32" (@a)) (@a)
i32 (@a)
) (@a)
((@a) table (@a) $t (@a)
((@a) export (@a) "t" (@a)) (@a)
((@a) import (@a) "spectest" (@a) "table" (@a)) (@a)
10 (@a) 20 (@a)
funcref (@a)
) (@a)
((@a) memory (@a) $m (@a)
((@a) export (@a) "m" (@a)) (@a)
((@a) import (@a) "spectest" (@a) "memory" (@a)) (@a)
1 (@a) 2 (@a)
) (@a)
((@a) func (@a) $f (@a)
((@a) export (@a) "f" (@a)) (@a)
((@a) import (@a) "spectest" (@a) "print_i32_f32" (@a)) (@a)
((@a) param (@a) i32 (@a) f32 (@a)) (@a)
((@a) result (@a)) (@a)
) (@a)
) (@a)
((@a) module (@a) $m (@a) (@a)
((@a) type (@a) $T (@a)
((@a) func (@a)
((@a) param (@a) i32 (@a) i64 (@a)) (@a)
((@a) param (@a) $x (@a) i32 (@a)) (@a)
((@a) result (@a) i32 (@a)) (@a)
) (@a)
) (@a)
((@a) global (@a) $g (@a)
((@a) export (@a) "g" (@a)) (@a)
i32 (@a)
((@a) i32.const (@a) 42 (@a)) (@a)
) (@a)
((@a) table (@a) $t (@a)
((@a) export (@a) "t" (@a)) (@a)
10 (@a) 20 (@a)
funcref (@a)
) (@a)
((@a) memory (@a) $m (@a)
((@a) export (@a) "m" (@a)) (@a)
1 (@a) 2 (@a)
) (@a)
((@a) func (@a) $f (@a)
((@a) export (@a) "f" (@a)) (@a)
((@a) param (@a) i32 (@a) i64 (@a)) (@a)
((@a) param (@a) $x (@a) i32 (@a)) (@a)
((@a) result (@a) i32 (@a)) (@a)
((@a) local (@a) i32 (@a) i32 (@a)) (@a)
((@a) local (@a) $y (@a) i32 (@a)) (@a)
((@a) block (@a)
((@a) result (@a) i32 (@a)) (@a)
((@a) i32.add (@a)
((@a) local.get (@a) $x (@a)) (@a)
((@a) local.get (@a) 0 (@a)) (@a)
)
)
) (@a)
((@a) elem (@a)
((@a) offset (@a) ((@a) i32.const (@a) 0 (@a)) (@a)) (@a)
$f (@a) $f (@a) (@a) $f (@a)
) (@a)
((@a) data (@a)
((@a) offset (@a) ((@a) i32.const (@a) 0 (@a)) (@a)) (@a)
"bla" (@a) "\43" (@a) (@a) "" (@a)
) (@a)
(func $s)
((@a) start (@a) $s (@a)) (@a)
) (@a)

5
third_party/rust/wat/tests/regression/empty.wast поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
(assert_malformed (module quote "") "x")
(assert_malformed (module quote "; foo") "x")
(assert_malformed (module quote "(; foo ;)") "x")
(assert_malformed (module quote " ") "x")
(assert_malformed (module quote "\t") "x")

2
third_party/rust/wat/tests/regression/exnref.wat поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
(module $m
(func $f (param exnref)))

76
third_party/rust/wat/tests/wabt.rs поставляемый
Просмотреть файл

@ -12,6 +12,7 @@ use rayon::prelude::*;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::str;
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use wast::parser::ParseBuffer;
use wast::*;
@ -138,23 +139,25 @@ fn test_wast(test: &Path, contents: &str, ntests: &AtomicUsize) -> anyhow::Resul
}
}
WastDirective::QuoteModule { source, span } => {
if let Err(e) = parse_quote_module(span, &source) {
let (line, col) = span.linecol_in(&contents);
anyhow::bail!(
"in test {}:{}:{} parsed with\nerror: {}",
test.display(),
line + 1,
col + 1,
e,
);
}
}
WastDirective::AssertMalformed {
span,
module: QuoteModule::Quote(source),
message,
} => {
let source = source.join(" ");
let result = ParseBuffer::new(&source)
.map_err(|e| e.into())
.and_then(|b| -> Result<(), wast::Error> {
let mut wat = parser::parse::<Wat>(&b)?;
wat.module.encode()?;
Ok(())
})
.map_err(|mut e| {
e.set_text(&source);
e
});
let result = parse_quote_module(span, &source);
let (line, col) = span.linecol_in(&contents);
match result {
Ok(()) => anyhow::bail!(
@ -208,6 +211,26 @@ fn test_wast(test: &Path, contents: &str, ntests: &AtomicUsize) -> anyhow::Resul
anyhow::bail!("{}", s)
}
fn parse_quote_module(span: Span, source: &[&[u8]]) -> Result<(), wast::Error> {
let mut ret = String::new();
for src in source {
match str::from_utf8(src) {
Ok(s) => ret.push_str(s),
Err(_) => {
return Err(wast::Error::new(
span,
"malformed UTF-8 encoding".to_string(),
))
}
}
ret.push_str(" ");
}
let buf = ParseBuffer::new(&ret)?;
let mut wat = parser::parse::<Wat>(&buf)?;
wat.module.encode()?;
Ok(())
}
fn error_matches(error: &str, message: &str) -> bool {
if error.contains(message) {
return true;
@ -223,13 +246,27 @@ fn error_matches(error: &str, message: &str) -> bool {
|| message == "malformed annotation id"
|| message == "alignment must be a power of two"
{
return error.contains("expected ") || error.contains("constant out of range");
return error.contains("expected ")
|| error.contains("constant out of range")
|| error.contains("extra tokens remaining");
}
if message == "illegal character" {
return error.contains("unexpected character");
}
if message == "unclosed string" {
return error.contains("unexpected end-of-file");
}
if message == "invalid UTF-8 encoding" {
return error.contains("malformed UTF-8 encoding");
}
if message == "duplicate identifier" {
return error.contains("duplicate") && error.contains("identifier");
}
return false;
}
@ -249,6 +286,7 @@ fn find_tests() -> Vec<PathBuf> {
find_tests("tests/regression".as_ref(), &mut tests);
find_tests("tests/testsuite".as_ref(), &mut tests);
tests.sort();
return tests;
fn find_tests(path: &Path, tests: &mut Vec<PathBuf>) {
@ -454,9 +492,15 @@ fn skip_test(test: &Path, contents: &str) -> bool {
return true;
}
// Waiting for https://github.com/WebAssembly/annotations/pull/7 to make its
// way into the testsuite repo.
if test.ends_with("testsuite/proposals/annotations/annotations.wast") {
// Waiting for wabt to recognize the integer abs simd opcodes; they have been added
// upstream in the spec test suite, https://github.com/WebAssembly/simd/pull/197,
// but need to be pulled, filed https://github.com/WebAssembly/wabt/issues/1379.
if test.ends_with("wabt/third_party/testsuite/proposals/simd/simd_f32x4.wast") {
return true;
}
// wait for wabt to catch up on the annotations spec test
if test.ends_with("wabt/third_party/testsuite/proposals/annotations/annotations.wast") {
return true;
}