Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow empty types in the component model #1142

Merged
merged 1 commit into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading