Skip to content

Commit 51b1558

Browse files
committed
feat(wast): add support for map custom keyword and encoding in component model
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
1 parent ffc3be3 commit 51b1558

File tree

9 files changed

+148
-6
lines changed

9 files changed

+148
-6
lines changed

crates/wasmparser/src/validator/component.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3922,16 +3922,13 @@ impl ComponentState {
39223922
)),
39233923
crate::ComponentDefinedType::Map(key, value) => {
39243924
if !self.features.cm_map() {
3925-
bail!(
3926-
offset,
3927-
"Maps require the component model map feature"
3928-
)
3925+
bail!(offset, "Maps require the component model map feature")
39293926
}
39303927
Ok(ComponentDefinedType::Map(
39313928
self.create_component_val_type(key, offset)?,
39323929
self.create_component_val_type(value, offset)?,
39333930
))
3934-
},
3931+
}
39353932
crate::ComponentDefinedType::FixedSizeList(ty, elements) => {
39363933
if !self.features.cm_fixed_size_list() {
39373934
bail!(

crates/wast/src/component/binary.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ fn encode_defined_type(encoder: ComponentDefinedTypeEncoder, ty: &ComponentDefin
109109
ComponentDefinedType::List(l) => {
110110
encoder.list(l.element.as_ref());
111111
}
112+
ComponentDefinedType::Map(m) => {
113+
encoder.map(m.key.as_ref(), m.value.as_ref());
114+
}
112115
ComponentDefinedType::FixedSizeList(l) => {
113116
encoder.fixed_size_list(l.element.as_ref(), l.elements);
114117
}

crates/wast/src/component/expand.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,10 @@ impl<'a> Expander<'a> {
557557
}) => {
558558
self.expand_component_val_ty(t);
559559
}
560+
ComponentDefinedType::Map(Map { key: k, value: v }) => {
561+
self.expand_component_val_ty(k);
562+
self.expand_component_val_ty(v);
563+
}
560564
ComponentDefinedType::Tuple(t) => {
561565
for field in t.fields.iter_mut() {
562566
self.expand_component_val_ty(field);

crates/wast/src/component/resolve.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,10 @@ impl<'a> Resolver<'a> {
566566
}) => {
567567
self.component_val_type(t)?;
568568
}
569+
ComponentDefinedType::Map(Map { key: k, value: v }) => {
570+
self.component_val_type(k)?;
571+
self.component_val_type(v)?;
572+
}
569573
ComponentDefinedType::Tuple(t) => {
570574
for field in t.fields.iter_mut() {
571575
self.component_val_type(field)?;

crates/wast/src/component/types.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ pub enum ComponentDefinedType<'a> {
386386
Record(Record<'a>),
387387
Variant(Variant<'a>),
388388
List(List<'a>),
389+
Map(Map<'a>),
389390
FixedSizeList(FixedSizeList<'a>),
390391
Tuple(Tuple<'a>),
391392
Flags(Flags<'a>),
@@ -407,6 +408,8 @@ impl<'a> ComponentDefinedType<'a> {
407408
Ok(Self::Variant(parser.parse()?))
408409
} else if l.peek::<kw::list>()? {
409410
parse_list(parser)
411+
} else if l.peek::<kw::map>()? {
412+
Ok(Self::Map(parser.parse()?))
410413
} else if l.peek::<kw::tuple>()? {
411414
Ok(Self::Tuple(parser.parse()?))
412415
} else if l.peek::<kw::flags>()? {
@@ -451,6 +454,7 @@ impl Peek for ComponentDefinedType<'_> {
451454
Some(("record", _))
452455
| Some(("variant", _))
453456
| Some(("list", _))
457+
| Some(("map", _))
454458
| Some(("tuple", _))
455459
| Some(("flags", _))
456460
| Some(("enum", _))
@@ -587,6 +591,15 @@ pub struct List<'a> {
587591
pub element: Box<ComponentValType<'a>>,
588592
}
589593

594+
/// A map type.
595+
#[derive(Debug)]
596+
pub struct Map<'a> {
597+
/// The key type of the map.
598+
pub key: Box<ComponentValType<'a>>,
599+
/// The value type of the map.
600+
pub value: Box<ComponentValType<'a>>,
601+
}
602+
590603
/// A fixed size list type.
591604
#[derive(Debug)]
592605
pub struct FixedSizeList<'a> {
@@ -612,6 +625,18 @@ fn parse_list<'a>(parser: Parser<'a>) -> Result<ComponentDefinedType<'a>> {
612625
}
613626
}
614627

628+
impl<'a> Parse<'a> for Map<'a> {
629+
fn parse(parser: Parser<'a>) -> Result<Self> {
630+
parser.parse::<kw::map>()?;
631+
let key = parser.parse()?;
632+
let value = parser.parse()?;
633+
Ok(Self {
634+
key: Box::new(key),
635+
value: Box::new(value),
636+
})
637+
}
638+
}
639+
615640
/// A tuple type.
616641
#[derive(Debug)]
617642
pub struct Tuple<'a> {

crates/wast/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ pub mod kw {
533533
custom_keyword!(option);
534534
custom_keyword!(tuple);
535535
custom_keyword!(list);
536+
custom_keyword!(map);
536537
custom_keyword!(error);
537538
custom_keyword!(canon);
538539
custom_keyword!(lift);

tests/cli/component-model/map.wast

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
;; RUN: wast % --assert default --snapshot tests/snapshots -f cm-map
2+
3+
(component
4+
(core module $m
5+
(memory (export "memory") 1)
6+
(func (export "ret-map") (result i32 i32) unreachable)
7+
)
8+
(core instance $i (instantiate $m))
9+
10+
(func (export "ret-map") (result (map string u32))
11+
(canon lift (core func $i "ret-map") (memory $i "memory"))
12+
)
13+
)
14+
15+
(component
16+
(core module $m
17+
(func (export "param-map") (param i32 i32) unreachable)
18+
)
19+
(core instance $i (instantiate $m))
20+
21+
(func (export "param-map") (param "m" (map string u32))
22+
(canon lift (core func $i "param-map"))
23+
)
24+
)
25+
26+
(component
27+
(type $map-type (map u32 string))
28+
(func (export "f") (param "x" $map-type))
29+
)
30+
31+
(component
32+
(type $nested-map (map string (map string u32)))
33+
(func (export "f") (param "x" $nested-map))
34+
)
35+
36+
(component
37+
(type $map-with-list (map string (list u32)))
38+
(func (export "f") (param "x" $map-with-list))
39+
)
40+
41+
(component
42+
(type $map-with-option (map u32 (option string)))
43+
(func (export "f") (param "x" $map-with-option))
44+
)
45+
46+
(assert_invalid
47+
(component
48+
(import "y" (component $c
49+
(type $t (map string u32))
50+
(import "x" (type (eq $t)))
51+
))
52+
53+
(type $x (map u32 string))
54+
(instance (instantiate $c (with "x" (type $x))))
55+
)
56+
"type mismatch for import `x`")
57+
58+
(assert_invalid
59+
(component
60+
(import "y" (component $c
61+
(type $t (map string u32))
62+
(import "x" (type (eq $t)))
63+
))
64+
65+
(type $x (list u32))
66+
(instance (instantiate $c (with "x" (type $x))))
67+
)
68+
"type mismatch for import `x`")
69+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
;; RUN: wast % --assert default --snapshot tests/snapshots
2+
3+
(assert_invalid
4+
(component
5+
(core module $m
6+
(memory (export "memory") 1)
7+
(func (export "ret-map") (result i32 i32) unreachable)
8+
)
9+
(core instance $i (instantiate $m))
10+
11+
(func (export "ret-map") (result (map string u32))
12+
(canon lift (core func $i "ret-map") (memory $i "memory"))
13+
)
14+
)
15+
"Maps require the component model map feature (at offset 0x54)"
16+
)
17+
18+
(assert_invalid
19+
(component
20+
(core module $m
21+
(func (export "param-map") (param i32 i32) unreachable)
22+
)
23+
(core instance $i (instantiate $m))
24+
25+
(func (export "param-map") (param "m" (map string u32))
26+
(canon lift (core func $i "param-map"))
27+
)
28+
)
29+
"Maps require the component model map feature"
30+
)
31+
32+
(assert_invalid
33+
(component
34+
(type $map-type (map u32 string))
35+
(func (export "f") (param "x" $map-type))
36+
)
37+
"Maps require the component model map feature"
38+
)
39+
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
error: invalid value 'unknown' for '--features <FEATURES>': unknown feature `unknown`
2-
Valid features: mutable-global, saturating-float-to-int, sign-extension, reference-types, multi-value, bulk-memory, simd, relaxed-simd, threads, shared-everything-threads, tail-call, floats, multi-memory, exceptions, memory64, extended-const, component-model, function-references, memory-control, gc, custom-page-sizes, legacy-exceptions, gc-types, stack-switching, wide-arithmetic, cm-values, cm-nested-names, cm-async, cm-async-stackful, cm-async-builtins, cm-threading, cm-error-context, cm-fixed-size-list, cm-gc, call-indirect-overlong, bulk-memory-opt, custom-descriptors, mvp, wasm1, wasm2, wasm3, lime1, all
2+
Valid features: mutable-global, saturating-float-to-int, sign-extension, reference-types, multi-value, bulk-memory, simd, relaxed-simd, threads, shared-everything-threads, tail-call, floats, multi-memory, exceptions, memory64, extended-const, component-model, function-references, memory-control, gc, custom-page-sizes, legacy-exceptions, gc-types, stack-switching, wide-arithmetic, cm-values, cm-nested-names, cm-async, cm-async-stackful, cm-async-builtins, cm-threading, cm-error-context, cm-fixed-size-list, cm-gc, cm-map, call-indirect-overlong, bulk-memory-opt, custom-descriptors, mvp, wasm1, wasm2, wasm3, lime1, all
33

44
For more information, try '--help'.

0 commit comments

Comments
 (0)