diff --git a/Cargo.lock b/Cargo.lock index ee17ad71a..5f37faf27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2530,6 +2530,7 @@ version = "0.34.0" dependencies = [ "anyhow", "clap", + "futures", "heck 0.5.0", "indexmap", "prettyplease", diff --git a/Cargo.toml b/Cargo.toml index 90bd4080a..3877c136b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ clap = { version = "4.3.19", features = ["derive"] } indexmap = "2.0.0" prettyplease = "0.2.20" syn = { version = "2.0", features = ["printing"] } +futures = "0.3.31" wasmparser = { git = "https://github.com/dicej/wasm-tools", branch = "async" } wasm-encoder = { git = "https://github.com/dicej/wasm-tools", branch = "async" } diff --git a/crates/c/src/lib.rs b/crates/c/src/lib.rs index 26d5ee13f..fd7a5cc81 100644 --- a/crates/c/src/lib.rs +++ b/crates/c/src/lib.rs @@ -1342,6 +1342,21 @@ void __wasm_export_{ns}_{snake}_dtor({ns}_{snake}_t* arg) {{ self.finish_typedef_struct(id); } + fn type_future(&mut self, id: TypeId, name: &str, ty: &Option, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) { + _ = (id, name, docs); + todo!() + } + fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) { let _ = (id, name, ty, docs); } diff --git a/crates/c/tests/codegen.rs b/crates/c/tests/codegen.rs index 7546cd846..359217cb1 100644 --- a/crates/c/tests/codegen.rs +++ b/crates/c/tests/codegen.rs @@ -6,6 +6,14 @@ use std::process::Command; use wit_parser::{Resolve, UnresolvedPackageGroup}; macro_rules! codegen_test { + // TODO: implement support for stream, future, and error-context, and then + // remove these lines: + (streams $name:tt $test:tt) => {}; + (futures $name:tt $test:tt) => {}; + (resources_with_streams $name:tt $test:tt) => {}; + (resources_with_futures $name:tt $test:tt) => {}; + (error_context $name:tt $test:tt) => {}; + ($id:ident $name:tt $test:tt) => { #[test] fn $id() { diff --git a/crates/core/src/abi.rs b/crates/core/src/abi.rs index 9cf2f13f0..33851a0e5 100644 --- a/crates/core/src/abi.rs +++ b/crates/core/src/abi.rs @@ -845,9 +845,7 @@ fn needs_post_return(resolve: &Resolve, ty: &Type) -> bool { .filter_map(|t| t.as_ref()) .any(|t| needs_post_return(resolve, t)), TypeDefKind::Flags(_) | TypeDefKind::Enum(_) => false, - TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => { - unimplemented!() - } + TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => false, TypeDefKind::Unknown => unreachable!(), }, diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index b0cc21a47..ccebe94d1 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -170,6 +170,9 @@ pub trait InterfaceGenerator<'a> { fn type_alias(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs); fn type_list(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs); fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs); + fn type_future(&mut self, id: TypeId, name: &str, ty: &Option, docs: &Docs); + fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs); + fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs); fn types(&mut self, iface: InterfaceId) { let iface = &self.resolve().interfaces[iface]; for (name, id) in iface.types.iter() { @@ -190,12 +193,10 @@ pub trait InterfaceGenerator<'a> { TypeDefKind::Result(r) => self.type_result(id, name, r, &ty.docs), TypeDefKind::List(t) => self.type_list(id, name, t, &ty.docs), TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs), - TypeDefKind::Future(_) => panic!("future types do not require definition"), - TypeDefKind::Stream(_) => panic!("stream types do not require definition"), + TypeDefKind::Future(t) => self.type_future(id, name, t, &ty.docs), + TypeDefKind::Stream(t) => self.type_stream(id, name, t, &ty.docs), TypeDefKind::Handle(_) => panic!("handle types do not require definition"), - TypeDefKind::ErrorContext => { - panic!("the error-context type does not require definition") - } + TypeDefKind::ErrorContext => self.type_error_context(id, name, &ty.docs), TypeDefKind::Unknown => unreachable!(), } } diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index 45030c0ea..42f4f60e6 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -193,7 +193,9 @@ impl Types { info = self.optional_type_info(resolve, r.ok.as_ref()); info |= self.optional_type_info(resolve, r.err.as_ref()); } - TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => {} + TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => { + info.has_resource = true; + } TypeDefKind::Unknown => unreachable!(), } let prev = self.type_info.insert(ty, info); diff --git a/crates/csharp/src/lib.rs b/crates/csharp/src/lib.rs index ff415d33b..22621d504 100644 --- a/crates/csharp/src/lib.rs +++ b/crates/csharp/src/lib.rs @@ -1903,6 +1903,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { self.type_name(&Type::Id(id)); } + fn type_future(&mut self, id: TypeId, name: &str, ty: &Option, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) { + _ = (id, name, docs); + todo!() + } + fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) { unimplemented!(); } diff --git a/crates/csharp/tests/codegen.rs b/crates/csharp/tests/codegen.rs index 6d10104cd..9501e6df0 100644 --- a/crates/csharp/tests/codegen.rs +++ b/crates/csharp/tests/codegen.rs @@ -8,6 +8,14 @@ use std::{ use wit_component::StringEncoding; macro_rules! codegen_test { + // TODO: implement support for stream, future, and error-context, and then + // remove these lines: + (streams $name:tt $test:tt) => {}; + (futures $name:tt $test:tt) => {}; + (resources_with_streams $name:tt $test:tt) => {}; + (resources_with_futures $name:tt $test:tt) => {}; + (error_context $name:tt $test:tt) => {}; + ($id:ident $name:tt $test:tt) => { #[test] fn $id() { diff --git a/crates/go/src/interface.rs b/crates/go/src/interface.rs index e47438a02..39c54aef1 100644 --- a/crates/go/src/interface.rs +++ b/crates/go/src/interface.rs @@ -1266,6 +1266,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { // no impl since these types are generated as anonymous types } + fn type_future(&mut self, id: TypeId, name: &str, ty: &Option, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) { + _ = (id, name, docs); + todo!() + } + fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) { todo!("type_builtin") } diff --git a/crates/go/tests/codegen.rs b/crates/go/tests/codegen.rs index 9a7d8b837..daa437658 100644 --- a/crates/go/tests/codegen.rs +++ b/crates/go/tests/codegen.rs @@ -8,6 +8,15 @@ use heck::*; macro_rules! codegen_test { (issue668 $name:tt $test:tt) => {}; (multiversion $name:tt $test:tt) => {}; + + // TODO: implement support for stream, future, and error-context, and then + // remove these lines: + (streams $name:tt $test:tt) => {}; + (futures $name:tt $test:tt) => {}; + (resources_with_streams $name:tt $test:tt) => {}; + (resources_with_futures $name:tt $test:tt) => {}; + (error_context $name:tt $test:tt) => {}; + ($id:ident $name:tt $test:tt) => { #[test] fn $id() { diff --git a/crates/markdown/src/lib.rs b/crates/markdown/src/lib.rs index 2ecd5421f..e41cb7a3a 100644 --- a/crates/markdown/src/lib.rs +++ b/crates/markdown/src/lib.rs @@ -656,6 +656,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { self.type_alias(id, name, &Type::Id(id), docs); } + fn type_future(&mut self, id: TypeId, name: &str, ty: &Option, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) { + _ = (id, name, docs); + todo!() + } + fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) { self.type_alias(id, name, ty, docs) } diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index 6ddd7a288..72be26664 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -1499,6 +1499,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { // Not needed } + fn type_future(&mut self, id: TypeId, name: &str, ty: &Option, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) { + _ = (id, name, docs); + todo!() + } + fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) { unimplemented!(); } diff --git a/crates/moonbit/tests/codegen.rs b/crates/moonbit/tests/codegen.rs index a015cc880..c0857dded 100644 --- a/crates/moonbit/tests/codegen.rs +++ b/crates/moonbit/tests/codegen.rs @@ -2,6 +2,14 @@ use std::path::Path; use std::process::Command; macro_rules! codegen_test { + // TODO: implement support for stream, future, and error-context, and then + // remove these lines: + (streams $name:tt $test:tt) => {}; + (futures $name:tt $test:tt) => {}; + (resources_with_streams $name:tt $test:tt) => {}; + (resources_with_futures $name:tt $test:tt) => {}; + (error_context $name:tt $test:tt) => {}; + ($id:ident $name:tt $test:tt) => { #[test] fn $id() { diff --git a/crates/rust/Cargo.toml b/crates/rust/Cargo.toml index 7c64aea6c..ddaa117e2 100644 --- a/crates/rust/Cargo.toml +++ b/crates/rust/Cargo.toml @@ -27,6 +27,7 @@ syn = { workspace = true } prettyplease = { workspace = true } [dev-dependencies] +futures = { workspace = true } wit-bindgen = { path = '../guest-rust' } wit-bindgen-rt = { path = '../guest-rust/rt' } test-helpers = { path = '../test-helpers' } diff --git a/crates/rust/src/interface.rs b/crates/rust/src/interface.rs index 31fa98d88..a3a9cb421 100644 --- a/crates/rust/src/interface.rs +++ b/crates/rust/src/interface.rs @@ -2694,6 +2694,48 @@ impl<'a> {camel}Borrow<'a>{{ } } + fn type_future(&mut self, _id: TypeId, name: &str, ty: &Option, docs: &Docs) { + let stream_and_future_support = self.path_to_stream_and_future_support(); + let mode = TypeMode { + style: TypeOwnershipStyle::Owned, + lists_borrowed: false, + lifetime: None, + }; + self.rustdoc(docs); + self.push_str(&format!("pub type {}", name.to_upper_camel_case())); + self.print_generics(mode.lifetime); + self.push_str(" = "); + self.push_str(&format!("{stream_and_future_support}::FutureReader<")); + self.print_optional_ty(ty.as_ref(), mode); + self.push_str(">"); + self.push_str(";\n"); + } + + fn type_stream(&mut self, _id: TypeId, name: &str, ty: &Type, docs: &Docs) { + let stream_and_future_support = self.path_to_stream_and_future_support(); + let mode = TypeMode { + style: TypeOwnershipStyle::Owned, + lists_borrowed: false, + lifetime: None, + }; + self.rustdoc(docs); + self.push_str(&format!("pub type {}", name.to_upper_camel_case())); + self.print_generics(mode.lifetime); + self.push_str(" = "); + self.push_str(&format!("{stream_and_future_support}::StreamReader<")); + self.print_ty(ty, mode); + self.push_str(">"); + self.push_str(";\n"); + } + + fn type_error_context(&mut self, _id: TypeId, name: &str, docs: &Docs) { + let async_support = self.path_to_async_support(); + self.rustdoc(docs); + self.push_str(&format!("pub type {} = ", name.to_upper_camel_case())); + self.push_str(&format!("{async_support}::ErrorContext")); + self.push_str(";\n"); + } + fn type_builtin(&mut self, _id: TypeId, name: &str, ty: &Type, docs: &Docs) { self.rustdoc(docs); self.src @@ -2784,17 +2826,27 @@ impl<'a, 'b> wit_bindgen_core::AnonymousTypeGenerator<'a> for AnonTypeGenerator< fn anonymous_type_future(&mut self, _id: TypeId, ty: &Option, _docs: &Docs) { let stream_and_future_support = self.interface.path_to_stream_and_future_support(); + let mode = TypeMode { + style: TypeOwnershipStyle::Owned, + lists_borrowed: false, + lifetime: None, + }; self.interface .push_str(&format!("{stream_and_future_support}::FutureReader<")); - self.interface.print_optional_ty(ty.as_ref(), self.mode); + self.interface.print_optional_ty(ty.as_ref(), mode); self.interface.push_str(">"); } fn anonymous_type_stream(&mut self, _id: TypeId, ty: &Type, _docs: &Docs) { let stream_and_future_support = self.interface.path_to_stream_and_future_support(); + let mode = TypeMode { + style: TypeOwnershipStyle::Owned, + lists_borrowed: false, + lifetime: None, + }; self.interface .push_str(&format!("{stream_and_future_support}::StreamReader<")); - self.interface.print_ty(ty, self.mode); + self.interface.print_ty(ty, mode); self.interface.push_str(">"); } diff --git a/crates/rust/src/lib.rs b/crates/rust/src/lib.rs index 745e49361..ef9187d6a 100644 --- a/crates/rust/src/lib.rs +++ b/crates/rust/src/lib.rs @@ -441,7 +441,7 @@ impl RustWasm { self.src.push_str("}\n"); if emitted.contains(&RuntimeItem::StreamAndFutureSupport) { self.src - .push_str("pub use _rt::stream_and_future_support;\n"); + .push_str("#[allow(unused_imports)]\npub use _rt::stream_and_future_support;\n"); } } diff --git a/crates/rust/src/stream_and_future_support.rs b/crates/rust/src/stream_and_future_support.rs index 7a61bb5e1..ef1f7b722 100644 --- a/crates/rust/src/stream_and_future_support.rs +++ b/crates/rust/src/stream_and_future_support.rs @@ -8,6 +8,7 @@ use { std::{ collections::hash_map::Entry, convert::Infallible, + fmt, future::{Future, IntoFuture}, iter, marker::PhantomData, @@ -33,6 +34,14 @@ pub struct FutureWriter { _phantom: PhantomData, } +impl fmt::Debug for FutureWriter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FutureWriter") + .field("handle", &self.handle) + .finish() + } +} + impl FutureWriter { /// Write the specified value to this `future`. pub async fn write(self, v: T) { @@ -101,6 +110,14 @@ pub struct FutureReader { _phantom: PhantomData, } +impl fmt::Debug for FutureReader { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FutureReader") + .field("handle", &self.handle) + .finish() + } +} + impl FutureReader { #[doc(hidden)] pub fn from_handle(handle: u32) -> Self { @@ -219,6 +236,14 @@ pub struct StreamWriter { _phantom: PhantomData, } +impl fmt::Debug for StreamWriter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("StreamWriter") + .field("handle", &self.handle) + .finish() + } +} + impl Sink> for StreamWriter { type Error = Infallible; @@ -334,6 +359,14 @@ pub struct StreamReader { _phantom: PhantomData, } +impl fmt::Debug for StreamReader { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("StreamReader") + .field("handle", &self.handle) + .finish() + } +} + impl StreamReader { #[doc(hidden)] pub fn from_handle(handle: u32) -> Self { diff --git a/crates/rust/tests/codegen.rs b/crates/rust/tests/codegen.rs index b38ac189b..a5ad0ef88 100644 --- a/crates/rust/tests/codegen.rs +++ b/crates/rust/tests/codegen.rs @@ -57,9 +57,8 @@ mod codegen_tests { wit_bindgen::generate!({ path: $test, stubs, - export_prefix: "[async]", + export_prefix: "[async-prefix]", generate_all, - async: true }); #[test] diff --git a/crates/rust/tests/codegen_no_std.rs b/crates/rust/tests/codegen_no_std.rs index 6c2db154d..362931c92 100644 --- a/crates/rust/tests/codegen_no_std.rs +++ b/crates/rust/tests/codegen_no_std.rs @@ -12,6 +12,16 @@ mod codegen_tests { macro_rules! codegen_test { (wasi_cli $name:tt $test:tt) => {}; (wasi_http $name:tt $test:tt) => {}; + + // TODO: We should be able to support streams, futures, and + // error-contexts in no_std mode if desired, but haven't done the work + // yet. + (streams $name:tt $test:tt) => {}; + (futures $name:tt $test:tt) => {}; + (resources_with_streams $name:tt $test:tt) => {}; + (resources_with_futures $name:tt $test:tt) => {}; + (error_context $name:tt $test:tt) => {}; + ($id:ident $name:tt $test:tt) => { mod $id { wit_bindgen::generate!({ diff --git a/crates/teavm-java/src/lib.rs b/crates/teavm-java/src/lib.rs index 0a9689e90..014bd6ace 100644 --- a/crates/teavm-java/src/lib.rs +++ b/crates/teavm-java/src/lib.rs @@ -1070,6 +1070,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { self.type_name(&Type::Id(id)); } + fn type_future(&mut self, id: TypeId, name: &str, ty: &Option, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) { + _ = (id, name, ty, docs); + todo!() + } + + fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) { + _ = (id, name, docs); + todo!() + } + fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) { unimplemented!(); } diff --git a/crates/teavm-java/tests/codegen.rs b/crates/teavm-java/tests/codegen.rs index 16d3f107b..ab637cf04 100644 --- a/crates/teavm-java/tests/codegen.rs +++ b/crates/teavm-java/tests/codegen.rs @@ -30,6 +30,14 @@ macro_rules! codegen_test { (issue929_no_export $name:tt $test:tt) => {}; (issue929_only_methods $name:tt $test:tt) => {}; + // TODO: implement support for stream, future, and error-context, and then + // remove these lines: + (streams $name:tt $test:tt) => {}; + (futures $name:tt $test:tt) => {}; + (resources_with_streams $name:tt $test:tt) => {}; + (resources_with_futures $name:tt $test:tt) => {}; + (error_context $name:tt $test:tt) => {}; + ($id:ident $name:tt $test:tt) => { #[test] fn $id() { diff --git a/tests/codegen/error-context.wit b/tests/codegen/error-context.wit new file mode 100644 index 000000000..d76f89685 --- /dev/null +++ b/tests/codegen/error-context.wit @@ -0,0 +1,12 @@ +package foo:foo; + +interface error-contexts { + type foo = error-context; + + bar: func(x: foo, y: error-context, z: future) -> result, error-context>; +} + +world foo { + import error-contexts; + export error-contexts; +} diff --git a/tests/codegen/futures.wit b/tests/codegen/futures.wit new file mode 100644 index 000000000..2d634a400 --- /dev/null +++ b/tests/codegen/futures.wit @@ -0,0 +1,87 @@ +package foo:foo; + +interface futures { + future-param: func(x: future); + future-u8-param: func(x: future); + future-u16-param: func(x: future); + future-u32-param: func(x: future); + future-u64-param: func(x: future); + future-s8-param: func(x: future); + future-s16-param: func(x: future); + future-s32-param: func(x: future); + future-s64-param: func(x: future); + future-f32-param: func(x: future); + future-f64-param: func(x: future); + + future-ret: func(x: future); + future-u8-ret: func() -> future; + future-u16-ret: func() -> future; + future-u32-ret: func() -> future; + future-u64-ret: func() -> future; + future-s8-ret: func() -> future; + future-s16-ret: func() -> future; + future-s32-ret: func() -> future; + future-s64-ret: func() -> future; + future-f32-ret: func() -> future; + future-f64-ret: func() -> future; + + tuple-future: func(x: future>) -> future>; + string-future-arg: func(a: future); + string-future-ret: func() -> future; + tuple-string-future: func(x: future>) -> future>; + string-future: func(x: future) -> future; + + record some-record { + x: string, + y: other-record, + z: future, + c1: u32, + c2: u64, + c3: s32, + c4: s64, + } + record other-record { + a1: u32, + a2: u64, + a3: s32, + a4: s64, + b: string, + c: future, + } + record-future: func(x: future) -> future; + record-future-reverse: func(x: future) -> future; + + variant some-variant { + a(string), + b, + c(u32), + d(future), + } + variant other-variant { + a, + b(u32), + c(string), + } + variant-future: func(x: future) -> future; + + type load-store-all-sizes = future>; + load-store-everything: func(a: load-store-all-sizes) -> load-store-all-sizes; +} + +world the-futures { + import futures; + export futures; +} diff --git a/tests/codegen/resources-with-futures.wit b/tests/codegen/resources-with-futures.wit new file mode 100644 index 000000000..33a2b2aeb --- /dev/null +++ b/tests/codegen/resources-with-futures.wit @@ -0,0 +1,17 @@ +package my:resources; + +interface with-futures { + resource x { + constructor(l: future); + get: func() -> future; + set: func(l: future); + etc: static func(l: future) -> future; + } + + foo: func(x: future) -> future; +} + +world resources { + import with-futures; + export with-futures; +} diff --git a/tests/codegen/resources-with-streams.wit b/tests/codegen/resources-with-streams.wit new file mode 100644 index 000000000..d9e3620fc --- /dev/null +++ b/tests/codegen/resources-with-streams.wit @@ -0,0 +1,17 @@ +package my:resources; + +interface with-streams { + resource x { + constructor(l: stream); + get: func() -> stream; + set: func(l: stream); + etc: static func(l: stream) -> stream; + } + + foo: func(x: stream) -> stream; +} + +world resources { + import with-streams; + export with-streams; +} diff --git a/tests/codegen/streams.wit b/tests/codegen/streams.wit new file mode 100644 index 000000000..fd00239b7 --- /dev/null +++ b/tests/codegen/streams.wit @@ -0,0 +1,85 @@ +package foo:foo; + +interface streams { + stream-u8-param: func(x: stream); + stream-u16-param: func(x: stream); + stream-u32-param: func(x: stream); + stream-u64-param: func(x: stream); + stream-s8-param: func(x: stream); + stream-s16-param: func(x: stream); + stream-s32-param: func(x: stream); + stream-s64-param: func(x: stream); + stream-f32-param: func(x: stream); + stream-f64-param: func(x: stream); + + stream-u8-ret: func() -> stream; + stream-u16-ret: func() -> stream; + stream-u32-ret: func() -> stream; + stream-u64-ret: func() -> stream; + stream-s8-ret: func() -> stream; + stream-s16-ret: func() -> stream; + stream-s32-ret: func() -> stream; + stream-s64-ret: func() -> stream; + stream-f32-ret: func() -> stream; + stream-f64-ret: func() -> stream; + + tuple-stream: func(x: stream>) -> stream>; + string-stream-arg: func(a: stream); + string-stream-ret: func() -> stream; + tuple-string-stream: func(x: stream>) -> stream>; + string-stream: func(x: stream) -> stream; + + record some-record { + x: string, + y: other-record, + z: stream, + c1: u32, + c2: u64, + c3: s32, + c4: s64, + } + record other-record { + a1: u32, + a2: u64, + a3: s32, + a4: s64, + b: string, + c: stream, + } + record-stream: func(x: stream) -> stream; + record-stream-reverse: func(x: stream) -> stream; + + variant some-variant { + a(string), + b, + c(u32), + d(stream), + } + variant other-variant { + a, + b(u32), + c(string), + } + variant-stream: func(x: stream) -> stream; + + type load-store-all-sizes = stream>; + load-store-everything: func(a: load-store-all-sizes) -> load-store-all-sizes; +} + +world the-streams { + import streams; + export streams; +}