summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wast/tests/annotations.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/wast/tests/annotations.rs')
-rw-r--r--third_party/rust/wast/tests/annotations.rs200
1 files changed, 200 insertions, 0 deletions
diff --git a/third_party/rust/wast/tests/annotations.rs b/third_party/rust/wast/tests/annotations.rs
new file mode 100644
index 0000000000..706a392cc1
--- /dev/null
+++ b/third_party/rust/wast/tests/annotations.rs
@@ -0,0 +1,200 @@
+use wasmparser::*;
+
+#[test]
+fn name_annotations() -> anyhow::Result<()> {
+ assert_module_name("foo", r#"(module $foo)"#)?;
+ assert_module_name("foo", r#"(module (@name "foo"))"#)?;
+ assert_module_name("foo", r#"(module $bar (@name "foo"))"#)?;
+ assert_module_name("foo bar", r#"(module $bar (@name "foo bar"))"#)?;
+ Ok(())
+}
+
+fn assert_module_name(expected_name: &str, wat: &str) -> anyhow::Result<()> {
+ let wasm = wat::parse_str(wat)?;
+ let mut found = false;
+ for s in get_name_section(&wasm)? {
+ match s? {
+ Name::Module { name, .. } => {
+ assert_eq!(name, expected_name);
+ found = true;
+ }
+ _ => {}
+ }
+ }
+ assert!(found);
+ Ok(())
+}
+
+#[test]
+fn func_annotations() -> anyhow::Result<()> {
+ assert_func_name("foo", r#"(module (func $foo))"#)?;
+ assert_func_name("foo", r#"(module (func (@name "foo")))"#)?;
+ assert_func_name("foo", r#"(module (func $bar (@name "foo")))"#)?;
+ assert_func_name("foo bar", r#"(module (func $bar (@name "foo bar")))"#)?;
+ Ok(())
+}
+
+fn assert_func_name(name: &str, wat: &str) -> anyhow::Result<()> {
+ let wasm = wat::parse_str(wat)?;
+ let mut found = false;
+ for s in get_name_section(&wasm)? {
+ match s? {
+ Name::Function(n) => {
+ let naming = n.into_iter().next().unwrap()?;
+ assert_eq!(naming.index, 0);
+ assert_eq!(naming.name, name);
+ found = true;
+ }
+ _ => {}
+ }
+ }
+ assert!(found);
+ Ok(())
+}
+
+#[test]
+fn local_annotations() -> anyhow::Result<()> {
+ assert_local_name("foo", r#"(module (func (param $foo i32)))"#)?;
+ assert_local_name("foo", r#"(module (func (local $foo i32)))"#)?;
+ assert_local_name("foo", r#"(module (func (param (@name "foo") i32)))"#)?;
+ assert_local_name("foo", r#"(module (func (local (@name "foo") i32)))"#)?;
+ assert_local_name("foo", r#"(module (func (param $bar (@name "foo") i32)))"#)?;
+ assert_local_name("foo", r#"(module (func (local $bar (@name "foo") i32)))"#)?;
+ assert_local_name(
+ "foo bar",
+ r#"(module (func (param $bar (@name "foo bar") i32)))"#,
+ )?;
+ assert_local_name(
+ "foo bar",
+ r#"(module (func (local $bar (@name "foo bar") i32)))"#,
+ )?;
+ Ok(())
+}
+
+fn assert_local_name(name: &str, wat: &str) -> anyhow::Result<()> {
+ let wasm = wat::parse_str(wat)?;
+ let mut found = false;
+ for s in get_name_section(&wasm)? {
+ match s? {
+ Name::Local(n) => {
+ let naming = n
+ .into_iter()
+ .next()
+ .unwrap()?
+ .names
+ .into_iter()
+ .next()
+ .unwrap()?;
+ assert_eq!(naming.index, 0);
+ assert_eq!(naming.name, name);
+ found = true;
+ }
+ _ => {}
+ }
+ }
+ assert!(found);
+ Ok(())
+}
+
+fn get_name_section(wasm: &[u8]) -> anyhow::Result<NameSectionReader<'_>> {
+ for payload in Parser::new(0).parse_all(&wasm) {
+ if let Payload::CustomSection(c) = payload? {
+ if c.name() == "name" {
+ return Ok(NameSectionReader::new(c.data(), c.data_offset()));
+ }
+ }
+ }
+ panic!("no name section found");
+}
+
+#[test]
+fn custom_section_order() -> anyhow::Result<()> {
+ let bytes = wat::parse_str(
+ r#"
+ (module
+ (@custom "A" "aaa")
+ (type (func))
+ (@custom "B" (after func) "bbb")
+ (@custom "C" (before func) "ccc")
+ (@custom "D" (after last) "ddd")
+ (table 10 funcref)
+ (func (type 0))
+ (@custom "E" (after import) "eee")
+ (@custom "F" (before type) "fff")
+ (@custom "G" (after data) "ggg")
+ (@custom "H" (after code) "hhh")
+ (@custom "I" (after func) "iii")
+ (@custom "J" (before func) "jjj")
+ (@custom "K" (before first) "kkk")
+ )
+ "#,
+ )?;
+ macro_rules! assert_matches {
+ ($a:expr, $b:pat $(if $cond:expr)? $(,)?) => {
+ match &$a {
+ $b $(if $cond)? => {}
+ a => panic!("`{:?}` doesn't match `{}`", a, stringify!($b)),
+ }
+ };
+ }
+ let wasm = Parser::new(0)
+ .parse_all(&bytes)
+ .collect::<Result<Vec<_>>>()?;
+ assert_matches!(wasm[0], Payload::Version { .. });
+ assert_matches!(
+ wasm[1],
+ Payload::CustomSection(c) if c.name() == "K"
+ );
+ assert_matches!(
+ wasm[2],
+ Payload::CustomSection(c) if c.name() == "F"
+ );
+ assert_matches!(wasm[3], Payload::TypeSection(_));
+ assert_matches!(
+ wasm[4],
+ Payload::CustomSection(c) if c.name() == "E"
+ );
+ assert_matches!(
+ wasm[5],
+ Payload::CustomSection(c) if c.name() == "C"
+ );
+ assert_matches!(
+ wasm[6],
+ Payload::CustomSection(c) if c.name() == "J"
+ );
+ assert_matches!(wasm[7], Payload::FunctionSection(_));
+ assert_matches!(
+ wasm[8],
+ Payload::CustomSection(c) if c.name() == "B"
+ );
+ assert_matches!(
+ wasm[9],
+ Payload::CustomSection(c) if c.name() == "I"
+ );
+ assert_matches!(wasm[10], Payload::TableSection(_));
+ assert_matches!(wasm[11], Payload::CodeSectionStart { .. });
+ assert_matches!(wasm[12], Payload::CodeSectionEntry { .. });
+ assert_matches!(
+ wasm[13],
+ Payload::CustomSection(c) if c.name() == "H"
+ );
+ assert_matches!(
+ wasm[14],
+ Payload::CustomSection(c) if c.name() == "G"
+ );
+ assert_matches!(
+ wasm[15],
+ Payload::CustomSection(c) if c.name() == "A"
+ );
+ assert_matches!(
+ wasm[16],
+ Payload::CustomSection(c) if c.name() == "D"
+ );
+
+ match &wasm[17] {
+ Payload::End(x) if *x == bytes.len() => {}
+ p => panic!("`{:?}` doesn't match expected length of {}", p, bytes.len()),
+ }
+
+ Ok(())
+}