Skip to content

Commit

Permalink
Disallow empty types in the component model (#1142)
Browse files Browse the repository at this point in the history
This updates the component validation phase to account for
WebAssembly/component-model#218
  • Loading branch information
alexcrichton authored Jul 25, 2023
1 parent 23a2d6c commit 69b5213
Show file tree
Hide file tree
Showing 63 changed files with 287 additions and 208 deletions.
23 changes: 19 additions & 4 deletions crates/wasmparser/src/validator/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,10 @@ impl ComponentState {
let mut type_size = 1;
let mut field_map = IndexMap::with_capacity(fields.len());

if fields.is_empty() {
bail!(offset, "record type must have at least one field");
}

for (name, ty) in fields {
let name = to_kebab_str(name, "record field", offset)?;
let ty = self.create_component_val_type(*ty, types, offset)?;
Expand Down Expand Up @@ -2515,10 +2519,7 @@ impl ComponentState {
let mut case_map: IndexMap<KebabString, VariantCase> = IndexMap::with_capacity(cases.len());

if cases.is_empty() {
return Err(BinaryReaderError::new(
"variant type must have at least one case",
offset,
));
bail!(offset, "variant type must have at least one case");
}

if cases.len() > u32::MAX as usize {
Expand Down Expand Up @@ -2584,6 +2585,9 @@ impl ComponentState {
offset: usize,
) -> Result<ComponentDefinedType> {
let mut type_size = 1;
if tys.is_empty() {
bail!(offset, "tuple type must have at least one type");
}
let types = tys
.iter()
.map(|ty| {
Expand All @@ -2599,6 +2603,10 @@ impl ComponentState {
fn create_flags_type(&self, names: &[&str], offset: usize) -> Result<ComponentDefinedType> {
let mut names_set = IndexSet::with_capacity(names.len());

if names.is_empty() {
bail!(offset, "flags must have at least one entry");
}

for name in names {
let name = to_kebab_str(name, "flag", offset)?;
if !names_set.insert(name.to_owned()) {
Expand All @@ -2621,6 +2629,10 @@ impl ComponentState {
));
}

if cases.is_empty() {
bail!(offset, "enum type must have at least one variant");
}

let mut tags = IndexSet::with_capacity(cases.len());

for tag in cases {
Expand All @@ -2644,6 +2656,9 @@ impl ComponentState {
offset: usize,
) -> Result<ComponentDefinedType> {
let mut type_size = 1;
if tys.is_empty() {
bail!(offset, "union type must have at least one case");
}
let types = tys
.iter()
.map(|ty| {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(component
(type (;0;)
(instance
(type (;0;) (record))
(type (;0;) (record (field "f" u32)))
(export (;1;) "f" (type (eq 0)))
(type (;2;) (record (field "f" 1)))
(export (;3;) "r" (type (eq 2)))
Expand All @@ -18,7 +18,7 @@
(alias export 0 "f" (type (;1;)))
(alias export 0 "r" (type (;2;)))
(component (;0;)
(type (;0;) (record))
(type (;0;) (record (field "f" u32)))
(import "import-type-f" (type (;1;) (eq 0)))
(type (;2;) (record (field "f" 1)))
(import "import-type-r" (type (;3;) (eq 2)))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package foo:foo

interface foo {
record f {}
record f {
f: u32,
}

record r {
f: f,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(component
(core module (;0;)
(type (;0;) (func))
(func (;0;) (type 0))
(type (;0;) (func (param i32)))
(func (;0;) (type 0) (param i32))
(export "name#a" (func 0))
(@producers
(processed-by "wit-component" "$CARGO_PKG_VERSION")
Expand All @@ -10,7 +10,7 @@
)
(core instance (;0;) (instantiate 0))
(component (;0;)
(type (;0;) (record))
(type (;0;) (record (field "f" u32)))
(export (;1;) "foo" (type 0))
)
(instance (;0;) (instantiate 0))
Expand All @@ -20,7 +20,7 @@
(alias core export 0 "name#a" (core func (;0;)))
(func (;0;) (type 1) (canon lift (core func 0)))
(component (;1;)
(type (;0;) (record))
(type (;0;) (record (field "f" u32)))
(import "import-type-foo" (type (;1;) (eq 0)))
(import "import-type-foo0" (type (;2;) (eq 1)))
(type (;3;) (func (param "f" 2)))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
(module
(func (export "name#a"))
(func (export "name#a") (param i32))
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package foo:foo

interface name {
record foo {}
record foo {
f: u32,
}
}

world module {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
(component
(type (;0;)
(instance
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(export (;1;) "foo" (type (eq 0)))
)
)
(import (interface "foo:foo/foo") (instance (;0;) (type 0)))
(core module (;0;)
(type (;0;) (func))
(func (;0;) (type 0))
(type (;0;) (func (result i32)))
(func (;0;) (type 0) (result i32)
unreachable
)
(export "bar#foo" (func 0))
(@producers
(processed-by "wit-component" "$CARGO_PKG_VERSION")
Expand All @@ -22,7 +24,7 @@
(func (;0;) (type 2) (canon lift (core func 0)))
(alias export 0 "foo" (type (;3;)))
(component (;0;)
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(import "import-type-foo" (type (;1;) (eq 0)))
(import "import-type-bar" (type (;2;) (eq 1)))
(type (;3;) (func (result 2)))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
(module
(func (export "bar#foo"))
(func (export "bar#foo") (result i32)
unreachable
)
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package foo:foo

interface foo {
record foo {}
record foo {
f: u8,
}
}

world module {
Expand Down
4 changes: 3 additions & 1 deletion crates/wit-component/tests/components/imports/module.wit
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ world module {

// doesn't show up in the wit output despite being exported here since it's
// not actually used by anything
record unused-record {}
record unused-record {
f: u8,
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(component
(type (;0;)
(instance
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(export (;1;) "r1" (type (eq 0)))
(type (;2;) (record (field "x" 1)))
(export (;3;) "r2" (type (eq 2)))
Expand All @@ -19,7 +19,7 @@
)
(core instance (;0;) (instantiate 0))
(component (;0;)
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(export (;1;) "r1" (type 0))
(type (;2;) (record (field "x" 1)))
(export (;3;) "r2" (type 2))
Expand All @@ -32,7 +32,7 @@
(alias export 2 "r1" (type (;2;)))
(alias export 2 "r2" (type (;3;)))
(component (;1;)
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(import "import-type-r1" (type (;1;) (eq 0)))
(type (;2;) (record (field "x" 1)))
(import "import-type-r2" (type (;3;) (eq 2)))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package foo:foo

interface name {
record r1 {}
record r1 {
f: u8,
}

record r2 {
x: r1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(component
(type (;0;)
(instance
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(export (;1;) "bar" (type (eq 0)))
)
)
Expand All @@ -17,7 +17,7 @@
)
(import "other-name" (instance (;1;) (type 2)))
(core module (;0;)
(type (;0;) (func))
(type (;0;) (func (result i32)))
(import "other-name" "a" (func (;0;) (type 0)))
(@producers
(processed-by "wit-component" "$CARGO_PKG_VERSION")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
(module
(import "other-name" "a" (func))
(import "other-name" "a" (func (result i32)))
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package foo:foo

interface foo {
record bar {}
record bar {
f: u8,
}

a: func() -> bar
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(component
(type (;0;)
(instance
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(export (;1;) "name" (type (eq 0)))
)
)
Expand All @@ -24,7 +24,7 @@
(alias export 0 "name" (type (;3;)))
(alias export 1 "name" (type (;4;)))
(component (;0;)
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(import "import-type-name" (type (;1;) (eq 0)))
(import "import-type-name0" (type (;2;) (eq 1)))
(export (;3;) "name" (type 1))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package foo:foo

interface name1 {
record name {}
record name {
f: u8,
}
}

interface name2 {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(component
(type (;0;)
(instance
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(export (;1;) "some-type" (type (eq 0)))
(type (;2;) (func (result 1)))
(export (;0;) "the-func" (func (type 2)))
Expand All @@ -13,9 +13,9 @@
(core module (;0;)
(type (;0;) (func (param i32 i64 i32)))
(type (;1;) (func (param i32 i32 i32 i32) (result i32)))
(type (;2;) (func))
(type (;2;) (func (result i32)))
(import "foo:foo/i" "the-func" (func (;0;) (type 2)))
(func (;1;) (type 2)
(func (;1;) (type 2) (result i32)
unreachable
)
(func (;2;) (type 1) (param i32 i32 i32 i32) (result i32)
Expand All @@ -41,16 +41,16 @@
)
(alias core export 1 "memory" (core memory (;0;)))
(alias core export 1 "cabi_realloc" (core func (;1;)))
(type (;3;) (record))
(type (;3;) (record (field "f" u8)))
(type (;4;) (func (result 3)))
(alias core export 1 "foo:foo/i#the-func" (core func (;2;)))
(func (;1;) (type 4) (canon lift (core func 2)))
(component (;0;)
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(import "import-type-some-type" (type (;1;) (eq 0)))
(type (;2;) (func (result 1)))
(import "import-func-the-func" (func (;0;) (type 2)))
(type (;3;) (record))
(type (;3;) (record (field "f" u8)))
(export (;4;) "some-type" (type 3))
(type (;5;) (func (result 4)))
(export (;1;) "the-func" (func 0) (func (type 5)))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
(module
(type (;0;) (func (param i32 i64 i32)))
(type (;1;) (func (param i32 i32 i32 i32) (result i32)))
(import "foo:foo/i" "the-func" (func (;0;)))
(func (export "foo:foo/i#the-func")
(import "foo:foo/i" "the-func" (func (result i32)))
(func (export "foo:foo/i#the-func") (result i32)
unreachable
)
(func (;2;) (export "cabi_realloc") (param i32 i32 i32 i32) (result i32)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package foo:foo

interface i {
record some-type {
f: u8,
}

the-func: func() -> some-type
Expand Down
2 changes: 1 addition & 1 deletion crates/wit-component/tests/interfaces/multi-doc.wat
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
(component
(type (;0;)
(instance
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(export (;1;) "the-type" (type (eq 0)))
)
)
Expand Down
4 changes: 3 additions & 1 deletion crates/wit-component/tests/interfaces/multi-doc/b.wit
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ interface a2 {
}

interface b {
record the-type {}
record the-type {
f: u8,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package foo:foo

interface b {
record the-type {
f: u8,
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/wit-component/tests/interfaces/pkg-use-chain2.wat
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
(component
(type (;0;)
(instance
(type (;0;) (record))
(type (;0;) (record (field "f" u8)))
(export (;1;) "name" (type (eq 0)))
)
)
Expand Down
4 changes: 3 additions & 1 deletion crates/wit-component/tests/interfaces/pkg-use-chain2/bar.wit
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ interface bar {
}

interface other {
record name {}
record name {
f: u8,
}
}
Loading

0 comments on commit 69b5213

Please sign in to comment.