diff --git a/test/custom/name/name.wast b/test/custom/name/name.wast new file mode 100644 index 000000000..ee672a1ea --- /dev/null +++ b/test/custom/name/name.wast @@ -0,0 +1,516 @@ +;; module name (0): "M" +(module (;(@name "M");) (@custom "name" (after data) "\00\02\01M")) + +;; function names (1): 0 = "f", 1 = "g" +(module + (func (;(@name "f");)) + (func (;(@name "g");)) + (@custom "name" (after data) "\01\07\02\00\01f\01\01g") +) + +;; local names (2): function 0, local 0 = "p", local 1 = "l" +(module + (func (param (;(@name "p");) i32) (local (;(@name "l");) i64)) + (@custom "name" (after data) "\02\09\01\00\02\00\01p\01\01l") +) + +;; label names (3): function 0, label 0 = "a", label 1 = "b" +(module + (func + block (;(@name "a");) end + loop (;(@name "b");) end + ) + (@custom "name" (after data) "\03\09\01\00\02\00\01a\01\01b") +) + +;; type names (4): 0 = "T" +(module + (type (;(@name "T");) (func)) + (@custom "name" (after data) "\04\04\01\00\01T") +) + +;; table names (5): 0 = "t" +(module + (table (;(@name "t");) 1 funcref) + (@custom "name" (after data) "\05\04\01\00\01t") +) + +;; memory names (6): 0 = "m" +(module + (memory (;(@name "m");) 1) + (@custom "name" (after data) "\06\04\01\00\01m") +) + +;; global names (7): 0 = "g" +(module + (global (;(@name "g");) i32 (i32.const 0)) + (@custom "name" (after data) "\07\04\01\00\01g") +) + +;; element segment names (8): 0 = "e" +(module + (func $f) + (table 1 funcref) + (elem (;(@name "e");) (i32.const 0) func $f) + (@custom "name" (after data) "\08\04\01\00\01e") +) + +;; data segment names (9): 0 = "d" +(module + (memory 1) + (data (;(@name "d");) (i32.const 0) "x") + (@custom "name" (after data) "\09\04\01\00\01d") +) + +;; field names (10): type 0, field 0 = "f" +(module + (type (struct (field (;(@name "f");) i32))) + (@custom "name" (after data) "\0a\06\01\00\01\00\01f") +) + +;; tag names (11): 0 = "x" +(module + (type $t (func)) + (tag (;(@name "x");) (type $t)) + (@custom "name" (after data) "\0b\04\01\00\01x") +) + +;; parameter names (12): type 0, parameter 0 = "x". +(module + (type (func (param (;(@name "x");) i32))) + (@custom "name" (after data) "\0c\06\01\00\01\00\01x") +) + +;; tag parameter names (13): tag 0, parameter 0 = "c" +(module + (type $t (func (param i32))) + (tag (type $t) (param (;(@name "c");) i32)) + (@custom "name" (after data) "\0d\06\01\00\01\00\01c") +) + + +;; All subsections at once, in increasing id order + +(module + (type (struct (field i32))) ;; type 0 + (type $ft (func (param i32))) ;; type 1 + (func (local i32) block end) ;; func 0, local 0, label 0 + (table 1 funcref) + (memory 1) + (global i32 (i32.const 0)) + (elem (i32.const 0) func 0) + (data (i32.const 0) "x") + (tag (type $ft)) + (@custom "name" (after data) + "\00\02\01M" ;; 0 module name + "\01\04\01\00\01f" ;; 1 function names + "\02\06\01\00\01\00\01l" ;; 2 local names + "\03\06\01\00\01\00\01a" ;; 3 label names + "\04\09\02\00\02T0\01\02T1" ;; 4 type names + "\05\04\01\00\01t" ;; 5 table names + "\06\04\01\00\01m" ;; 6 memory names + "\07\04\01\00\01g" ;; 7 global names + "\08\04\01\00\01e" ;; 8 element segment names + "\09\04\01\00\01d" ;; 9 data segment names + "\0a\08\01\00\01\00\03fld" ;; 10 field names + "\0b\06\01\00\03tag" ;; 11 tag names + "\0c\06\01\01\01\00\01x" ;; 12 parameter names + "\0d\06\01\00\01\00\01c" ;; 13 tag parameter names + ) +) + + +;; Well-formed edge cases + +;; An empty name map. +(module (@custom "name" (after data) "\01\01\00")) + +;; An empty inner name map in an indirect name map. +(module (func) (@custom "name" (after data) "\02\03\01\00\00")) + +;; An empty name. +(module (func) (@custom "name" (after data) "\01\03\01\00\00")) + +;; Duplicate names. +(module (func) (func) (@custom "name" (after data) "\01\07\02\00\01a\01\01a")) + + +;; Section structure + +;; Subsections must appear in increasing id order: 1 (function names) then 0 (module name) +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data) \"\\01\\04\\01\\00\\01f\\00\\02\\01M\"))" + ) + "invalid name subsection id" +) + +;; Each subsection may occur at most once: 1 (function names) twice +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data)" + " \"\\01\\04\\01\\00\\01f\\01\\04\\01\\00\\01g\"))" + ) + "invalid name subsection id" +) + +;; Invalid subsection id. +(assert_malformed_custom + (module quote + "(module (@custom \"name\" (after data) \"\\ff\\04\\01\\00\\01x\"))" + ) + "invalid name subsection id" +) + +;; Trailing bytes after the last subsection. +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data) \"\\01\\04\\01\\00\\01f\\ff\"))" + ) + "invalid name subsection id" +) + +;; A name runs past the end of its subsection. +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data) \"\\01\\04\\01\\00\\03f\"))" + ) + "unexpected end of name subsection" +) +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data)" + " \"\\01\\04\\01\\00\\03f\\00\\02\\01M\"))" + ) + "unexpected end of name subsection" +) + +;; A subsection ends in the middle of a non-name. +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data) \"\\01\\02\\01\\00\\01f\"))" + ) + "unexpected end of name subsection" +) + +;; A name map's count is too large. +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data) \"\\01\\04\\02\\00\\01f\"))" + ) + "unexpected end of name subsection" +) + +;; A subsection's declared size exceeds the bytes remaining in the section. +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data) \"\\01\\09\\01\\00\\01f\"))" + ) + "unexpected end of name section" +) + +;; The payload decodes but leaves bytes unconsumed inside the subsection. +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data) \"\\01\\05\\01\\00\\01f\\ff\"))" + ) + "name subsection size mismatch" +) + +;; Names are UTF-8. +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data) \"\\01\\04\\01\\00\\01\\ff\"))" + ) + "malformed UTF-8 encoding" +) + + +;; Name map index constraints + +;; Duplicate index in a name map. +(assert_malformed_custom + (module quote + "(module (func)" + " (@custom \"name\" (after data) \"\\01\\07\\02\\00\\01a\\00\\01b\"))" + ) + "custom @name: duplicate function name" +) + +;; Decreasing index in a name map. +(assert_malformed_custom + (module quote + "(module (func) (func)" + " (@custom \"name\" (after data) \"\\01\\07\\02\\01\\01b\\00\\01a\"))" + ) + "custom @name: function names out of order" +) + +;; Duplicate primary index in an indirect name map. +(assert_malformed_custom + (module quote + "(module (func (local i32))" + " (@custom \"name\" (after data)" + " \"\\02\\0b\\02\\00\\01\\00\\01a\\00\\01\\00\\01b\"))" + ) + "custom @name: duplicate local name map" +) + +;; Decreasing primary index in an indirect name map. +(assert_malformed_custom + (module quote + "(module (func (local i32)) (func (local i32))" + " (@custom \"name\" (after data)" + " \"\\02\\0b\\02\\01\\01\\00\\01b\\00\\01\\00\\01a\"))" + ) + "custom @name: local name maps out of order" +) + +;; Duplicate secondary index within one inner name map. +(assert_malformed_custom + (module quote + "(module (func (local i32))" + " (@custom \"name\" (after data)" + " \"\\02\\09\\01\\00\\02\\00\\01a\\00\\01b\"))" + ) + "custom @name: duplicate local name" +) + +;; Decreasing secondary index within one inner name map. +(assert_malformed_custom + (module quote + "(module (func (local i32) (local i64))" + " (@custom \"name\" (after data)" + " \"\\02\\09\\01\\00\\02\\01\\01b\\00\\01a\"))" + ) + "custom @name: local names out of order" +) + + +;; Index spaces include imports + +(module definition + (import "m" "f" (func)) + (func) + (@custom "name" (after data) "\01\04\01\01\01f") ;; function 1 = "f" +) + +(module definition + (import "m" "t" (table 1 funcref)) + (table 1 funcref) + (@custom "name" (after data) "\05\04\01\01\01t") ;; table 1 = "t" +) + +(module definition + (import "m" "m" (memory 1)) + (memory 1) + (@custom "name" (after data) "\06\04\01\01\01m") ;; memory 1 = "m" +) + +(module definition + (import "m" "g" (global i32)) + (global i32 (i32.const 0)) + (@custom "name" (after data) "\07\04\01\01\01g") ;; global 1 = "g" +) + +(module definition + (type $t (func)) + (import "m" "e" (tag (type $t))) + (tag (type $t)) + (@custom "name" (after data) "\0b\04\01\01\01t") ;; tag 1 = "t" +) + +(assert_invalid_custom + (module + (type $t (func)) + (import "m" "e" (tag (type $t))) + (tag (type $t)) + (@custom "name" (after data) "\0b\04\01\02\01?") + ) + "custom @name: invalid tag index 2" +) + +;; The local name subsection covers imported functions too. +(module definition + (type $t (func (param i32))) + (import "m" "f" (func (type $t))) + (func (type $t)) + (@custom "name" (after data) + "\02\0b\02\00\01\00\01p\01\01\00\01q" ;; params of functions 0 and 1 + ) +) + + +;; Out-of-range indices (with imports where possible) + +(assert_invalid_custom + (module (func) (@custom "name" (after data) "\01\04\01\01\01?")) + "custom @name: invalid function index 1" +) +(assert_invalid_custom + (module + (import "m" "f" (func)) + (func) + (@custom "name" (after data) "\01\04\01\02\01?") + ) + "custom @name: invalid function index 2" +) + +(assert_invalid_custom + (module (func (local i32)) (@custom "name" (after data) "\02\06\01\01\01\00\01?")) + "custom @name: invalid function index 1" +) +(assert_invalid_custom + (module + (import "m" "f" (func (param i32))) + (func (local i32)) + (@custom "name" (after data) "\02\06\01\02\01\00\01?") + ) + "custom @name: invalid function index 2" +) +(assert_invalid_custom + (module (func (param i32) (local i64)) + (@custom "name" (after data) "\02\06\01\00\01\02\01?")) + "custom @name: invalid local index 2 for function 0" +) + +(assert_invalid_custom + (module (func block end) (@custom "name" (after data) "\03\06\01\01\01\00\01?")) + "custom @name: invalid function index 1" +) +(assert_invalid_custom + (module (func block end) (@custom "name" (after data) "\03\06\01\00\01\01\01?")) + "custom @name: invalid label index 1 for function 0" +) +(assert_invalid_custom + (module (import "m" "f" (func)) (@custom "name" (after data) "\03\06\01\00\01\00\01?")) + "custom @name: invalid label index 0 for function 0" +) + +(assert_invalid_custom + (module (type (func)) (@custom "name" (after data) "\04\04\01\01\01?")) + "custom @name: invalid type index 1" +) + +(assert_invalid_custom + (module (table 1 funcref) (@custom "name" (after data) "\05\04\01\01\01?")) + "custom @name: invalid table index 1" +) +(assert_invalid_custom + (module + (import "m" "t" (table 1 funcref)) + (table 1 funcref) + (@custom "name" (after data) "\05\04\01\02\01?") + ) + "custom @name: invalid table index 2" +) + +(assert_invalid_custom + (module (memory 1) (@custom "name" (after data) "\06\04\01\01\01?")) + "custom @name: invalid memory index 1" +) +(assert_invalid_custom + (module + (import "m" "m" (memory 1)) + (memory 1) + (@custom "name" (after data) "\06\04\01\02\01?") + ) + "custom @name: invalid memory index 2" +) + +(assert_invalid_custom + (module (global i32 (i32.const 0)) + (@custom "name" (after data) "\07\04\01\01\01?")) + "custom @name: invalid global index 1" +) +(assert_invalid_custom + (module + (import "m" "g" (global i32)) + (global i32 (i32.const 0)) + (@custom "name" (after data) "\07\04\01\02\01?") + ) + "custom @name: invalid global index 2" +) + +(assert_invalid_custom + (module + (func $f) + (elem func $f) + (@custom "name" (after data) "\08\04\01\01\01?") + ) + "custom @name: invalid elem index 1" +) + +(assert_invalid_custom + (module + (data "x") + (@custom "name" (after data) "\09\04\01\01\01?") + ) + "custom @name: invalid data index 1" +) + +(assert_invalid_custom + (module (type (struct (field i32))) + (@custom "name" (after data) "\0a\06\01\01\01\00\01?")) + "custom @name: invalid type index 1" +) + +(assert_invalid_custom + (module (type (struct (field i32))) + (@custom "name" (after data) "\0a\06\01\00\01\01\01?")) + "custom @name: invalid field index 1 for type 0" +) + +(assert_invalid_custom + (module (type $t (func)) (tag (type $t)) + (@custom "name" (after data) "\0b\04\01\01\01?")) + "custom @name: invalid tag index 1" +) + +(assert_invalid_custom + (module (type (func (param i32))) + (@custom "name" (after data) "\0c\06\01\01\01\00\01?")) + "custom @name: invalid type index 1" +) +(assert_invalid_custom + (module (type (func (param i32))) + (@custom "name" (after data) "\0c\06\01\00\01\01\01?")) + "custom @name: invalid param index 1 for type 0" +) + +(assert_invalid_custom + (module (type $t (func (param i32))) (tag (type $t)) + (@custom "name" (after data) "\0d\06\01\01\01\00\01?")) + "custom @name: invalid tag index 1" +) +(assert_invalid_custom + (module (type $t (func (param i32))) (tag (type $t)) + (@custom "name" (after data) "\0d\06\01\00\01\01\01?")) + "custom @name: invalid param index 1 for tag 0" +) + + +;; Restrictions + +;; Field names only apply to struct types. +(assert_invalid_custom + (module (type (func)) (@custom "name" (after data) "\0a\06\01\00\01\00\01?")) + "custom @name: non-struct type 0" +) + +;; Parameter names only apply to function types. +(assert_invalid_custom + (module (type (struct (field i32))) + (@custom "name" (after data) "\0c\06\01\00\01\00\01?")) + "custom @name: non-function type 0" +) diff --git a/test/custom/name/name_annot.wast b/test/custom/name/name_annot.wast index bf34fd67a..557c14e4e 100644 --- a/test/custom/name/name_annot.wast +++ b/test/custom/name/name_annot.wast @@ -1,4 +1,4 @@ -;; Module names +;; Module names (subsection 0) (module (@name "Modül")) @@ -20,19 +20,382 @@ ) -;; Function names +;; Function names (subsection 1) -(module +(module definition (type $t (func)) + (import "m" "f" (func (@name "f") (type $t))) + (import "m" "g" (func $g (@name "g") (type $t))) (func (@name "λ") (type $t)) (func $lambda (@name "λ") (type $t)) ) +(module definition + (type $t (func)) + (func (@name "f") (import "m" "f") (type $t)) + (func $g (@name "g") (import "m" "g") (type $t)) +) + +(assert_malformed_custom + (module quote + "(module (type $t (func)) (func (@name \"f1\") (@name \"f2\") (type $t)))" + ) + "@name annotation: multiple function names" +) + +(assert_malformed_custom + (module quote "(module (type $t (func)) (func (type $t) (@name \"f\")))") + "misplaced @name annotation" +) + -;; Tag names +;; Local names (subsection 2) (module - (type $t (func)) + (func + (param (@name "p0") i32) (param $p1 (@name "p1") i64) + (local (@name "l0") f32) (local $l1 (@name "l1") f64) + ) +) + +(module definition + (import "m" "f" (func (param (@name "p") i32))) +) + +(assert_malformed_custom + (module quote + "(module (func (local (@name \"l1\") (@name \"l2\") i32)))" + ) + "@name annotation: multiple local names" +) + +(assert_malformed_custom + (module quote "(module (func (local (@name \"l\") i32 i64)))") + "@name annotation: multiple locals declared" +) + + +;; Label names (subsection 3) + +(module + (func + block (@name "a") end + block end + loop (@name "b") end + i32.const 1 + if (@name "c") + block (@name "d") end + else + block (@name "e") end + end + block $f (@name "f") + try_table (@name "g") (catch_all $f) end + end + ) +) + +;; These two modules should have the same label names. +(module + (func (result i32) + block (@name "a") (result i32) i32.const 1 end + if (@name "b") (result i32) + i32.const 2 + else + i32.const 3 + end + ) +) +(module + (func (result i32) + (if (@name "b") (result i32) + (block (@name "a") (result i32) (i32.const 1)) + (then (i32.const 2)) + (else (i32.const 3)) + ) + ) +) + +(assert_malformed_custom + (module quote + "(module (func block (@name \"b1\") (@name \"b2\") end))" + ) + "@name annotation: multiple label names" +) + +;; The label identifier at the matching `end` is not a binding occurrence. +(assert_malformed_custom + (module quote "(module (func block $b end $b (@name \"b\")))") + "misplaced @name annotation" +) + +;; Nor is a branch target a binding occurrence. +(assert_malformed_custom + (module quote "(module (func block $b br $b (@name \"b\") end))") + "misplaced @name annotation" +) + + +;; Type and field names (subsections 4 and 10) + +(module + (type (@name "T") (func)) + (type (@name "T") (func (param i32))) + (type (@name "S") (sub final (struct))) + (rec + (type (@name "R1") (struct + (field (@name "f") i32) + (field (@name "g") (ref null $r2)) + )) + (type $r2 (@name "R2") (array (mut i8))) + ) +) + +(assert_malformed_custom + (module quote "(module (type (@name \"T1\") (@name \"T2\") (func)))") + "@name annotation: multiple type names" +) + +(assert_malformed_custom + (module quote + "(module (type (struct (field (@name \"f1\") (@name \"f2\") i32))))" + ) + "@name annotation: multiple field names" +) + +(assert_malformed_custom + (module quote "(module (type (struct (field (@name \"f\") i32 i64))))") + "@name annotation: multiple fields declared" +) + + +;; Table, memory, and global names (subsections 5, 6, and 7) + +(module definition + (import "m" "t" (table (@name "t0") 1 funcref)) + (import "m" "m" (memory (@name "m0") 1)) + (import "m" "g" (global (@name "g0") i32)) + (table (@name "t1") 1 funcref) + (memory (@name "m1") 1) + (global (@name "g1") i32 (i32.const 0)) +) + +(module + (func $f) + (table (@name "t") (export "t") funcref (elem $f)) + (memory (@name "m") (export "m") (data "hello")) + (global (@name "g") (export "g") i32 (i32.const 0)) +) + +(assert_malformed_custom + (module quote "(module (table (@name \"t1\") (@name \"t2\") 1 funcref))") + "@name annotation: multiple table names" +) + +(assert_malformed_custom + (module quote "(module (memory (@name \"m1\") (@name \"m2\") 1))") + "@name annotation: multiple memory names" +) + +(assert_malformed_custom + (module quote + "(module (global (@name \"g1\") (@name \"g2\") i32 (i32.const 0)))" + ) + "@name annotation: multiple global names" +) + +(assert_malformed_custom + (module quote "(module (table 1 funcref (@name \"t\")))") + "misplaced @name annotation" +) + + +;; Element and data segment names (subsections 8 and 9) + +(module + (func $f) + (table 1 funcref) + (memory 1) + (elem (@name "active") (i32.const 0) func $f) + (elem (@name "passive") func $f) + (elem (@name "declarative") declare func $f) + (data (@name "active") (i32.const 0) "a") + (data (@name "passive") "c") +) + +(assert_malformed_custom + (module quote + "(module (func $f) (elem (@name \"e1\") (@name \"e2\") func $f))" + ) + "@name annotation: multiple elem names" +) + +(assert_malformed_custom + (module quote "(module (data (@name \"d1\") (@name \"d2\") \"a\"))") + "@name annotation: multiple data names" +) + + +;; Tag and tag parameter names (subsections 11 and 13) + +(module definition + (type $t (func (param i32))) + (import "m" "e" (tag (@name "e") (type $t))) (tag (@name "θ") (type $t)) (tag $theta (@name "θ") (type $t)) + (tag (@name "exn") (param (@name "code") i32) (param $extra (@name "extra") i64)) +) + +(assert_malformed_custom + (module quote + "(module (type $t (func)) (tag (@name \"t1\") (@name \"t2\") (type $t)))" + ) + "@name annotation: multiple tag names" +) + +(assert_malformed_custom + (module quote + "(module (tag (param (@name \"p1\") (@name \"p2\") i32)))" + ) + "@name annotation: multiple tag param names" +) + + +;; Parameter names (subsection 12) + +(module + (type (func (param (@name "x") i32) (param $y (@name "y") i64))) + (rec + (type (func (param (@name "p") (ref null $r)))) + (type $r (func)) + ) +) + +(assert_malformed_custom + (module quote + "(module (type (func (param (@name \"p1\") (@name \"p2\") i32))))" + ) + "@name annotation: multiple param names" +) + +(assert_malformed_custom + (module quote "(module (type (func (param (@name \"p\") i32 i64))))") + "@name annotation: multiple params declared" +) + +(assert_malformed_custom + (module quote + "(module (type $t (func (param i32)))" + " (func (i32.const 1) (block (type $t) (param (@name \"p\") i32) (drop))))" + ) + "@name annotation: param names not allowed here" +) + +(assert_malformed_custom + (module quote + "(module (table 1 funcref)" + " (func (call_indirect (param (@name \"p\") i32) (i32.const 7) (i32.const 0))))" + ) + "@name annotation: param names not allowed here" +) + + +;; Misplaced annotations + +;; Before the identifier +(assert_malformed_custom + (module quote "(module (type $t (func)) (func (@name \"f\") $f (type $t)))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (table (@name \"t\") $t 1 funcref))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (func (local (@name \"l\") $l i32)))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (type (struct (field (@name \"f\") $f i32))))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (func block (@name \"b\") $b end))") + "misplaced @name annotation" +) + +;; Before the keyword +(assert_malformed_custom + (module quote "(module (type $t (func)) ((@name \"f\") func (type $t)))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module ((@name \"t\") table 1 funcref))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (type (struct ((@name \"f\") field i32))))") + "misplaced @name annotation" +) + +;; After an inline export or import clause +(assert_malformed_custom + (module quote "(module (func (export \"f\") (@name \"f\")))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (memory (export \"m\") (@name \"m\") 1))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (func (import \"m\" \"f\") (@name \"f\")))") + "misplaced @name annotation" +) + +;; Elsewhere inside a declaration +(assert_malformed_custom + (module quote "(module (table 1 (@name \"t\") funcref))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (global (mut i32) (@name \"g\") (i32.const 0)))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (type (func (param i32) (@name \"T\") (result i32))))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (memory 1) (data (i32.const 0) (@name \"d\") \"x\"))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (import \"m\" (@name \"f\") \"f\" (func)))") + "misplaced @name annotation" +) +(assert_malformed_custom + (module quote "(module (func (local i32) (@name \"l\") (local i64)))") + "misplaced @name annotation" +) + + +;; Annotation payload syntax + +(assert_malformed_custom + (module quote "(module (@name))") + "@name annotation: string expected" +) + +(assert_malformed_custom + (module quote "(module (@name 1))") + "@name annotation: string expected" +) + +(assert_malformed_custom + (module quote "(module (@name \"a\" \"b\"))") + "@name annotation: unexpected token" +) + +(assert_malformed_custom + (module quote "(module (@name \"\\ff\"))") + "malformed UTF-8 encoding" )