Skip to content

Commit ffb4329

Browse files
authored
wasmparser(CM+GC): start doing subtyping checking when validating components' core function linking (#2173)
1 parent c0f3082 commit ffb4329

File tree

5 files changed

+200
-1
lines changed

5 files changed

+200
-1
lines changed

crates/wasmparser/src/validator/component_types.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3093,7 +3093,7 @@ impl<'a> SubtypeCx<'a> {
30933093
fn core_func_type(&self, a: CoreTypeId, b: CoreTypeId, offset: usize) -> Result<()> {
30943094
debug_assert!(self.a.get(a).is_some());
30953095
debug_assert!(self.b.get(b).is_some());
3096-
if a == b {
3096+
if self.a.id_is_subtype(a, b) {
30973097
debug_assert!(self.a.get(b).is_some());
30983098
debug_assert!(self.b.get(a).is_some());
30993099
Ok(())
@@ -3368,6 +3368,18 @@ impl<'a> SubtypeArena<'a> {
33683368
self.list.get(temp_id)
33693369
}
33703370
}
3371+
3372+
/// Is `a == b` or was `a` declared (potentially transitively) to be a
3373+
/// subtype of `b`?
3374+
fn id_is_subtype(&self, a: CoreTypeId, b: CoreTypeId) -> bool {
3375+
self.get(a).is_some() && self.get(b).is_some() && {
3376+
// NB: we can query `self.types.id_is_subtype` directly, and ignore
3377+
// `self.list`, because `self.list` should never contain core types.
3378+
debug_assert!(a.index() < CoreTypeId::list(self.types).len());
3379+
debug_assert!(b.index() < CoreTypeId::list(self.types).len());
3380+
self.types.id_is_subtype(a, b)
3381+
}
3382+
}
33713383
}
33723384

33733385
impl<T> Index<T> for SubtypeArena<'_>

tests/cli/component-model-gc/core-type.wat

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,113 @@
8282
)
8383
"type mismatch for export `b` of module instantiation argument `a`"
8484
)
85+
86+
;; Satisfying an import with an exact subtype should succeed.
87+
(component
88+
(import "f" (func $f (param "x" u32) (param "y" u32) (result u32)))
89+
90+
(core type $super_ty (sub (func (param i32 i32) (result i32))))
91+
(core type $sub_ty (sub $super_ty (func (param i32 i32) (result i32))))
92+
93+
(core func $f (canon lower (func $f) (core-type $sub_ty)))
94+
95+
(core module $m
96+
(type $super_ty (sub (func (param i32 i32) (result i32))))
97+
(type $sub_ty (sub $super_ty (func (param i32 i32) (result i32))))
98+
(import "a" "b" (func (type $sub_ty)))
99+
)
100+
101+
(core instance (instantiate $m (with "a" (instance (export "b" (func $f))))))
102+
)
103+
104+
;; Satisfying an import with a subtype should succeed.
105+
(component
106+
(import "f" (func $f (param "x" u32) (param "y" u32) (result u32)))
107+
108+
(core type $super_ty (sub (func (param i32 i32) (result i32))))
109+
(core type $sub_ty (sub $super_ty (func (param i32 i32) (result i32))))
110+
111+
(core func $f (canon lower (func $f) (core-type $sub_ty)))
112+
113+
(core module $m
114+
(type $super_ty (sub (func (param i32 i32) (result i32))))
115+
(import "a" "b" (func (type $super_ty)))
116+
)
117+
118+
(core instance (instantiate $m (with "a" (instance (export "b" (func $f))))))
119+
)
120+
121+
;; Satisfying an import with the "same" type but from a different subtyping
122+
;; hierarchy should fail.
123+
(assert_invalid
124+
(component
125+
(import "f" (func $f (param "x" u32) (param "y" u32) (result u32)))
126+
127+
(core type $ty (func (param i32 i32) (result i32)))
128+
(core func $f (canon lower (func $f) (core-type $ty)))
129+
130+
(core module $m
131+
(type $super_ty (sub (func (param i32 i32) (result i32))))
132+
(type $sub_ty (sub $super_ty (func (param i32 i32) (result i32))))
133+
(import "a" "b" (func (type $sub_ty)))
134+
)
135+
136+
(core instance (instantiate $m (with "a" (instance (export "b" (func $f))))))
137+
)
138+
"type mismatch for export `b` of module instantiation argument `a`"
139+
)
140+
141+
;; Satisfying an import with the "same" type but is a supertype, rather than a
142+
;; subtype, should fail.
143+
(assert_invalid
144+
(component
145+
(import "f" (func $f (param "x" u32) (param "y" u32) (result u32)))
146+
147+
(core type $super_ty (sub (func (param i32 i32) (result i32))))
148+
(core func $f (canon lower (func $f) (core-type $super_ty)))
149+
150+
(core module $m
151+
(type $super_ty (sub (func (param i32 i32) (result i32))))
152+
(type $sub_ty (sub $super_ty (func (param i32 i32) (result i32))))
153+
(import "a" "b" (func (type $sub_ty)))
154+
)
155+
156+
(core instance (instantiate $m (with "a" (instance (export "b" (func $f))))))
157+
)
158+
"type mismatch for export `b` of module instantiation argument `a`"
159+
)
160+
161+
;; Satisfying an import with the "same" type but with the wrong finality should
162+
;; fail.
163+
(assert_invalid
164+
(component
165+
(import "f" (func $f (param "x" u32) (param "y" u32) (result u32)))
166+
167+
(core type $ty (sub final (func (param i32 i32) (result i32))))
168+
(core func $f (canon lower (func $f) (core-type $ty)))
169+
170+
(core module $m
171+
(type $ty (sub (func (param i32 i32) (result i32))))
172+
(import "a" "b" (func (type $ty)))
173+
)
174+
175+
(core instance (instantiate $m (with "a" (instance (export "b" (func $f))))))
176+
)
177+
"type mismatch for export `b` of module instantiation argument `a`"
178+
)
179+
(assert_invalid
180+
(component
181+
(import "f" (func $f (param "x" u32) (param "y" u32) (result u32)))
182+
183+
(core type $ty (sub (func (param i32 i32) (result i32))))
184+
(core func $f (canon lower (func $f) (core-type $ty)))
185+
186+
(core module $m
187+
(type $ty (sub final (func (param i32 i32) (result i32))))
188+
(import "a" "b" (func (type $ty)))
189+
)
190+
191+
(core instance (instantiate $m (with "a" (instance (export "b" (func $f))))))
192+
)
193+
"type mismatch for export `b` of module instantiation argument `a`"
194+
)

tests/snapshots/cli/component-model-gc/core-type.wat.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,46 @@
4040
"filename": "core-type.5.wasm",
4141
"module_type": "binary",
4242
"text": "type mismatch for export `b` of module instantiation argument `a`"
43+
},
44+
{
45+
"type": "module",
46+
"line": 87,
47+
"filename": "core-type.6.wasm",
48+
"module_type": "binary"
49+
},
50+
{
51+
"type": "module",
52+
"line": 105,
53+
"filename": "core-type.7.wasm",
54+
"module_type": "binary"
55+
},
56+
{
57+
"type": "assert_invalid",
58+
"line": 124,
59+
"filename": "core-type.8.wasm",
60+
"module_type": "binary",
61+
"text": "type mismatch for export `b` of module instantiation argument `a`"
62+
},
63+
{
64+
"type": "assert_invalid",
65+
"line": 144,
66+
"filename": "core-type.9.wasm",
67+
"module_type": "binary",
68+
"text": "type mismatch for export `b` of module instantiation argument `a`"
69+
},
70+
{
71+
"type": "assert_invalid",
72+
"line": 164,
73+
"filename": "core-type.10.wasm",
74+
"module_type": "binary",
75+
"text": "type mismatch for export `b` of module instantiation argument `a`"
76+
},
77+
{
78+
"type": "assert_invalid",
79+
"line": 180,
80+
"filename": "core-type.11.wasm",
81+
"module_type": "binary",
82+
"text": "type mismatch for export `b` of module instantiation argument `a`"
4383
}
4484
]
4585
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
(component
2+
(type (;0;) (func (param "x" u32) (param "y" u32) (result u32)))
3+
(import "f" (func $f (;0;) (type 0)))
4+
(core type $super_ty (;0;) (sub (func (param i32 i32) (result i32))))
5+
(core type $sub_ty (;1;) (sub $super_ty (func (param i32 i32) (result i32))))
6+
(core func $f (;0;) (canon lower (func $f) (core-type $sub_ty)))
7+
(core module $m (;0;)
8+
(type $super_ty (;0;) (sub (func (param i32 i32) (result i32))))
9+
(type $sub_ty (;1;) (sub $super_ty (func (param i32 i32) (result i32))))
10+
(import "a" "b" (func (;0;) (type $sub_ty)))
11+
)
12+
(core instance (;0;)
13+
(export "b" (func $f))
14+
)
15+
(core instance (;1;) (instantiate $m
16+
(with "a" (instance 0))
17+
)
18+
)
19+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
(component
2+
(type (;0;) (func (param "x" u32) (param "y" u32) (result u32)))
3+
(import "f" (func $f (;0;) (type 0)))
4+
(core type $super_ty (;0;) (sub (func (param i32 i32) (result i32))))
5+
(core type $sub_ty (;1;) (sub $super_ty (func (param i32 i32) (result i32))))
6+
(core func $f (;0;) (canon lower (func $f) (core-type $sub_ty)))
7+
(core module $m (;0;)
8+
(type $super_ty (;0;) (sub (func (param i32 i32) (result i32))))
9+
(import "a" "b" (func (;0;) (type $super_ty)))
10+
)
11+
(core instance (;0;)
12+
(export "b" (func $f))
13+
)
14+
(core instance (;1;) (instantiate $m
15+
(with "a" (instance 0))
16+
)
17+
)
18+
)

0 commit comments

Comments
 (0)