diff --git a/crates/bindgen-core/src/lib.rs b/crates/bindgen-core/src/lib.rs index ef15ccca4..a6869d45c 100644 --- a/crates/bindgen-core/src/lib.rs +++ b/crates/bindgen-core/src/lib.rs @@ -84,7 +84,6 @@ pub trait Generator { ); fn type_union(&mut self, iface: &Interface, id: TypeId, name: &str, union: &Union, docs: &Docs); fn type_enum(&mut self, iface: &Interface, id: TypeId, name: &str, enum_: &Enum, docs: &Docs); - fn type_resource(&mut self, iface: &Interface, ty: ResourceId); fn type_alias(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs); fn type_list(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs); fn type_builtin(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs); @@ -131,10 +130,6 @@ pub trait Generator { } } - for (id, _resource) in iface.resources.iter() { - self.type_resource(iface, id); - } - self.preprocess_functions(iface, dir); for f in iface.functions.iter() { @@ -181,9 +176,6 @@ pub struct TypeInfo { /// Whether or not this type (transitively) has a list. pub has_list: bool, - - /// Whether or not this type (transitively) has a handle. - pub has_handle: bool, } impl std::ops::BitOrAssign for TypeInfo { @@ -191,7 +183,6 @@ impl std::ops::BitOrAssign for TypeInfo { self.param |= rhs.param; self.result |= rhs.result; self.has_list |= rhs.has_list; - self.has_handle |= rhs.has_handle; } } @@ -271,7 +262,6 @@ impl Types { pub fn type_info(&mut self, iface: &Interface, ty: &Type) -> TypeInfo { let mut info = TypeInfo::default(); match ty { - Type::Handle(_) => info.has_handle = true, Type::String => info.has_list = true, Type::Id(id) => return self.type_id_info(iface, *id), _ => {} diff --git a/crates/gen-guest-c/src/lib.rs b/crates/gen-guest-c/src/lib.rs index 53c167505..f0be76805 100644 --- a/crates/gen-guest-c/src/lib.rs +++ b/crates/gen-guest-c/src/lib.rs @@ -238,11 +238,6 @@ impl C { Type::S64 => self.src.h("int64_t"), Type::Float32 => self.src.h("float"), Type::Float64 => self.src.h("double"), - Type::Handle(id) => { - self.print_namespace(iface); - self.src.h(&iface.resources[*id].name.to_snake_case()); - self.src.h("_t"); - } Type::String => { self.print_namespace(iface); self.src.h("string_t"); @@ -285,7 +280,6 @@ impl C { Type::S64 => self.src.h("s64"), Type::Float32 => self.src.h("float32"), Type::Float64 => self.src.h("float64"), - Type::Handle(id) => self.src.h(&iface.resources[*id].name.to_snake_case()), Type::String => self.src.h("string"), Type::Id(id) => { let ty = &iface.types[*id]; @@ -579,7 +573,6 @@ impl C { let id = match ty { Type::Id(id) => *id, Type::String => return true, - Type::Handle(_) => return true, _ => return false, }; match &iface.types[id].kind { @@ -945,10 +938,6 @@ impl Generator for C { self.types.insert(id, mem::replace(&mut self.src.h, prev)); } - fn type_resource(&mut self, iface: &Interface, ty: ResourceId) { - drop((iface, ty)); - } - fn type_alias(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs) { let prev = mem::take(&mut self.src.h); self.docs(docs); @@ -1178,90 +1167,6 @@ impl Generator for C { self.print_intrinsics(); - for (_, resource) in iface.resources.iter() { - let ns = iface.name.to_snake_case(); - let name = resource.name.to_snake_case(); - uwrite!( - self.src.h, - " - typedef struct {{ - uint32_t idx; - }} {ns}_{name}_t; - void {ns}_{name}_free({ns}_{name}_t *ptr); - {ns}_{name}_t {ns}_{name}_clone({ns}_{name}_t *ptr); - ", - ns = ns, - name = name, - ); - uwrite!( - self.src.c, - " - __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_drop_{name_orig}\"))) - void __resource_{name}_drop(uint32_t idx); - - void {ns}_{name}_free({ns}_{name}_t *ptr) {{ - __resource_{name}_drop(ptr->idx); - }} - - __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_clone_{name_orig}\"))) - uint32_t __resource_{name}_clone(uint32_t idx); - - {ns}_{name}_t {ns}_{name}_clone({ns}_{name}_t *ptr) {{ - return ({ns}_{name}_t){{__resource_{name}_clone(ptr->idx)}}; - }} - ", - ns = ns, - name = name, - name_orig = resource.name, - ); - - // Exported resources have more capabilities, they can create new - // resources and get the private value that it was created with. - // Furthermore we also define the destructor which delegates to the - // actual user-defined destructor, if any. - if !self.in_import { - uwrite!( - self.src.h, - "\ - {ns}_{name}_t {ns}_{name}_new(void *data); - void* {ns}_{name}_get({ns}_{name}_t *ptr); - - __attribute__((weak)) - void {ns}_{name}_dtor(void *data); - ", - ns = ns, - name = name, - ); - uwrite!( - self.src.c, - " - __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_new_{name_orig}\"))) - uint32_t __resource_{name}_new(uint32_t val); - - {ns}_{name}_t {ns}_{name}_new(void *data) {{ - return ({ns}_{name}_t){{__resource_{name}_new((uint32_t) data)}}; - }} - - __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_get_{name_orig}\"))) - uint32_t __resource_{name}_get(uint32_t idx); - - void* {ns}_{name}_get({ns}_{name}_t *ptr) {{ - return (void*) __resource_{name}_get(ptr->idx); - }} - - __attribute__((export_name(\"canonical_abi_drop_{name_orig}\"))) - void __resource_{name}_dtor(uint32_t val) {{ - if ({ns}_{name}_dtor) - {ns}_{name}_dtor((void*) val); - }} - ", - ns = ns, - name = name, - name_orig = resource.name, - ); - } - } - // Continuously generate anonymous types while we continue to find more // // First we take care of the public set of anonymous types. This will @@ -1595,20 +1500,6 @@ impl Bindgen for FunctionBindgen<'_> { results.push(operands[0].clone()); } - Instruction::I32FromOwnedHandle { .. } | Instruction::I32FromBorrowedHandle { .. } => { - results.push(format!("({}).idx", operands[0])); - } - - Instruction::HandleBorrowedFromI32 { ty, .. } - | Instruction::HandleOwnedFromI32 { ty, .. } => { - results.push(format!( - "({}_{}_t){{ {} }}", - iface.name.to_snake_case(), - iface.resources[*ty].name.to_snake_case(), - operands[0], - )); - } - Instruction::RecordLower { record, .. } => { let op = &operands[0]; for f in record.fields.iter() { diff --git a/crates/gen-guest-rust/src/lib.rs b/crates/gen-guest-rust/src/lib.rs index 7c0c4fd39..cbf815329 100644 --- a/crates/gen-guest-rust/src/lib.rs +++ b/crates/gen-guest-rust/src/lib.rs @@ -62,7 +62,6 @@ pub struct Opts { #[derive(Default)] struct Trait { methods: Vec, - resource_methods: BTreeMap>, } impl Opts { @@ -113,22 +112,6 @@ impl RustGenerator for RustWasm { } } - fn handle_projection(&self) -> Option<(&'static str, String)> { - None - } - - fn handle_in_super(&self) -> bool { - !self.in_import - } - - fn handle_wrapper(&self) -> Option<&'static str> { - if self.in_import { - None - } else { - Some("wit_bindgen_guest_rust::Handle") - } - } - fn push_str(&mut self, s: &str) { self.src.push_str(s); } @@ -294,172 +277,6 @@ impl Generator for RustWasm { self.print_typedef_enum(id, name, enum_, docs); } - fn type_resource(&mut self, iface: &Interface, ty: ResourceId) { - // For exported handles we synthesize some trait implementations - // automatically for runtime-required traits. - if !self.in_import { - let panic = " - #[cfg(not(target_arch = \"wasm32\"))] - { - panic!(\"handles can only be used on wasm32\"); - } - #[cfg(target_arch = \"wasm32\")] - "; - self.src.push_str(&format!( - " - unsafe impl wit_bindgen_guest_rust::HandleType for super::{ty} {{ - #[inline] - fn clone(_val: i32) -> i32 {{ - {panic_not_wasm} - {{ - #[link(wasm_import_module = \"canonical_abi\")] - extern \"C\" {{ - #[link_name = \"resource_clone_{name}\"] - fn clone(val: i32) -> i32; - }} - unsafe {{ clone(_val) }} - }} - }} - - #[inline] - fn drop(_val: i32) {{ - {panic_not_wasm} - {{ - #[link(wasm_import_module = \"canonical_abi\")] - extern \"C\" {{ - #[link_name = \"resource_drop_{name}\"] - fn drop(val: i32); - }} - unsafe {{ drop(_val) }} - }} - }} - }} - - unsafe impl wit_bindgen_guest_rust::LocalHandle for super::{ty} {{ - #[inline] - fn new(_val: i32) -> i32 {{ - {panic_not_wasm} - {{ - #[link(wasm_import_module = \"canonical_abi\")] - extern \"C\" {{ - #[link_name = \"resource_new_{name}\"] - fn new(val: i32) -> i32; - }} - unsafe {{ new(_val) }} - }} - }} - - #[inline] - fn get(_val: i32) -> i32 {{ - {panic_not_wasm} - {{ - #[link(wasm_import_module = \"canonical_abi\")] - extern \"C\" {{ - #[link_name = \"resource_get_{name}\"] - fn get(val: i32) -> i32; - }} - unsafe {{ get(_val) }} - }} - }} - }} - - const _: () = {{ - #[export_name = \"{ns}canonical_abi_drop_{name}\"] - extern \"C\" fn drop(ty: Box) {{ - ::drop_{name_snake}(*ty) - }} - }}; - ", - ty = iface.resources[ty].name.to_camel_case(), - name = iface.resources[ty].name, - name_snake = iface.resources[ty].name.to_snake_case(), - iface = iface.name.to_camel_case(), - ns = self.opts.symbol_namespace, - panic_not_wasm = panic, - )); - let trait_ = self - .traits - .entry(iface.name.to_camel_case()) - .or_insert(Trait::default()); - trait_.methods.push(format!( - " - /// An optional callback invoked when a handle is finalized - /// and destroyed. - fn drop_{}(val: super::{}) {{ - drop(val); - }} - ", - iface.resources[ty].name.to_snake_case(), - iface.resources[ty].name.to_camel_case(), - )); - return; - } - - let resource = &iface.resources[ty]; - let name = &resource.name; - - self.rustdoc(&resource.docs); - self.src.push_str("#[derive(Debug)]\n"); - self.src.push_str("#[repr(transparent)]\n"); - self.src - .push_str(&format!("pub struct {}(i32);\n", name.to_camel_case())); - self.src.push_str("impl "); - self.src.push_str(&name.to_camel_case()); - self.src.push_str( - " { - pub unsafe fn from_raw(raw: i32) -> Self { - Self(raw) - } - - pub fn into_raw(self) -> i32 { - let ret = self.0; - core::mem::forget(self); - return ret; - } - - pub fn as_raw(&self) -> i32 { - self.0 - } - }\n", - ); - - self.src.push_str("impl Drop for "); - self.src.push_str(&name.to_camel_case()); - self.src.push_str(&format!( - "{{ - fn drop(&mut self) {{ - #[link(wasm_import_module = \"canonical_abi\")] - extern \"C\" {{ - #[link_name = \"resource_drop_{}\"] - fn close(fd: i32); - }} - unsafe {{ - close(self.0); - }} - }} - }}\n", - name, - )); - - self.src.push_str("impl Clone for "); - self.src.push_str(&name.to_camel_case()); - self.src.push_str(&format!( - "{{ - fn clone(&self) -> Self {{ - #[link(wasm_import_module = \"canonical_abi\")] - extern \"C\" {{ - #[link_name = \"resource_clone_{}\"] - fn clone(val: i32) -> i32; - }} - unsafe {{ - Self(clone(self.0)) - }} - }} - }}\n", - name, - )); - } - fn type_alias(&mut self, iface: &Interface, id: TypeId, _name: &str, ty: &Type, docs: &Docs) { self.print_typedef_alias(iface, id, ty, docs); } @@ -488,21 +305,10 @@ impl Generator for RustWasm { } fn import(&mut self, iface: &Interface, func: &Function) { - let mut sig = FnSig::default(); + let sig = FnSig::default(); let param_mode = TypeMode::AllBorrowed("'_"); match &func.kind { FunctionKind::Freestanding => {} - FunctionKind::Static { resource, .. } | FunctionKind::Method { resource, .. } => { - sig.use_item_name = true; - self.src.push_str(&format!( - "impl {} {{\n", - iface.resources[*resource].name.to_camel_case() - )); - } - } - if let FunctionKind::Method { .. } = func.kind { - sig.self_arg = Some("&self".to_string()); - sig.self_is_first_param = true; } let params = self.print_signature(iface, func, param_mode, &sig); self.src.push_str("{\n"); @@ -531,9 +337,6 @@ impl Generator for RustWasm { match &func.kind { FunctionKind::Freestanding => {} - FunctionKind::Static { .. } | FunctionKind::Method { .. } => { - self.src.push_str("}\n"); - } } } @@ -637,15 +440,6 @@ impl Generator for RustWasm { self.in_trait = true; let mut sig = FnSig::default(); sig.private = true; - match &func.kind { - FunctionKind::Freestanding => {} - FunctionKind::Static { .. } => sig.use_item_name = true, - FunctionKind::Method { .. } => { - sig.use_item_name = true; - sig.self_is_first_param = true; - sig.self_arg = Some("&self".to_string()); - } - } self.print_signature(iface, func, TypeMode::Owned, &sig); self.src.push_str(";"); self.in_trait = false; @@ -655,10 +449,6 @@ impl Generator for RustWasm { .or_insert(Trait::default()); let dst = match &func.kind { FunctionKind::Freestanding => &mut trait_.methods, - FunctionKind::Static { resource, .. } | FunctionKind::Method { resource, .. } => trait_ - .resource_methods - .entry(*resource) - .or_insert(Vec::new()), }; dst.push(mem::replace(&mut self.src, prev).into()); } @@ -684,7 +474,7 @@ impl Generator for RustWasm { } } - fn finish_one(&mut self, iface: &Interface, files: &mut Files) { + fn finish_one(&mut self, _iface: &Interface, files: &mut Files) { let mut src = mem::take(&mut self.src); for (name, trait_) in self.traits.iter() { @@ -696,18 +486,6 @@ impl Generator for RustWasm { src.push_str("\n"); } src.push_str("}\n"); - - for (id, methods) in trait_.resource_methods.iter() { - src.push_str(&format!( - "pub trait {} {{\n", - iface.resources[*id].name.to_camel_case() - )); - for f in methods { - src.push_str(&f); - src.push_str("\n"); - } - src.push_str("}\n"); - } } // Close the opening `mod`. @@ -1032,32 +810,6 @@ impl Bindgen for FunctionBindgen<'_> { } } - // handles in exports - Instruction::I32FromOwnedHandle { .. } => { - results.push(format!( - "wit_bindgen_guest_rust::Handle::into_raw({})", - operands[0] - )); - } - Instruction::HandleBorrowedFromI32 { .. } => { - results.push(format!( - "wit_bindgen_guest_rust::Handle::from_raw({})", - operands[0], - )); - } - - // handles in imports - Instruction::I32FromBorrowedHandle { .. } => { - results.push(format!("{}.0", operands[0])); - } - Instruction::HandleOwnedFromI32 { ty } => { - results.push(format!( - "{}({})", - iface.resources[*ty].name.to_camel_case(), - operands[0] - )); - } - Instruction::FlagsLower { flags, .. } => { let tmp = self.tmp(); self.push_str(&format!("let flags{} = {};\n", tmp, operands[0])); @@ -1514,19 +1266,8 @@ impl Bindgen for FunctionBindgen<'_> { )); } } - FunctionKind::Static { resource, name } - | FunctionKind::Method { resource, name } => { - self.push_str(&format!( - "::{}", - name.to_snake_case(), - r = iface.resources[*resource].name.to_camel_case(), - )); - } } self.push_str("("); - if let FunctionKind::Method { .. } = func.kind { - self.push_str("&"); - } self.push_str(&operands.join(", ")); self.push_str(")"); self.push_str(";\n"); diff --git a/crates/gen-guest-teavm-java/src/lib.rs b/crates/gen-guest-teavm-java/src/lib.rs index 25097be31..ae09b4568 100644 --- a/crates/gen-guest-teavm-java/src/lib.rs +++ b/crates/gen-guest-teavm-java/src/lib.rs @@ -5,7 +5,7 @@ use wit_bindgen_core::{ wit_parser::{ abi::{AbiVariant, Bindgen, Bitcast, Instruction, LiftLower, WasmType}, Case, Docs, Enum, Flags, FlagsRepr, Function, FunctionKind, Int, Interface, Record, - ResourceId, Result_, SizeAlign, Tuple, Type, TypeDefKind, TypeId, Union, Variant, + Result_, SizeAlign, Tuple, Type, TypeDefKind, TypeId, Union, Variant, }, Direction, Files, Generator, Ns, }; @@ -59,7 +59,6 @@ impl TeaVmJava { Type::U64 | Type::S64 => "long".into(), Type::Float32 => "float".into(), Type::Float64 => "double".into(), - Type::Handle(_) => todo!("resources"), Type::String => "String".into(), Type::Id(id) => { let ty = &iface.types[*id]; @@ -558,10 +557,6 @@ impl Generator for TeaVmJava { ); } - fn type_resource(&mut self, _iface: &Interface, _ty: ResourceId) { - todo!("resources") - } - fn type_alias(&mut self, iface: &Interface, id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) { self.type_name(iface, &Type::Id(id)); } @@ -1153,14 +1148,6 @@ impl Bindgen for FunctionBindgen<'_> { } Instruction::BoolFromI32 => results.push(format!("({} != 0)", operands[0])), - // handles in exports - Instruction::I32FromOwnedHandle { .. } => todo!("resources"), - Instruction::HandleBorrowedFromI32 { .. } => todo!("resources"), - - // handles in imports - Instruction::I32FromBorrowedHandle { .. } => todo!("resources"), - Instruction::HandleOwnedFromI32 { .. } => todo!("resources"), - // TODO: checked Instruction::FlagsLower { flags, .. } => match flags_repr(flags) { Int::U8 | Int::U16 | Int::U32 => { diff --git a/crates/gen-host-js/src/lib.rs b/crates/gen-host-js/src/lib.rs index f60524f9d..2765921b9 100644 --- a/crates/gen-host-js/src/lib.rs +++ b/crates/gen-host-js/src/lib.rs @@ -18,8 +18,6 @@ pub struct Js { intrinsics: BTreeMap, all_intrinsics: BTreeSet, needs_get_export: bool, - imported_resources: BTreeSet, - exported_resources: BTreeSet, needs_ty_option: bool, needs_ty_result: bool, } @@ -27,13 +25,11 @@ pub struct Js { #[derive(Default)] struct Imports { freestanding_funcs: Vec<(String, Source)>, - resource_funcs: BTreeMap>, } #[derive(Default)] struct Exports { freestanding_funcs: Vec, - resource_funcs: BTreeMap>, } #[derive(Default, Debug, Clone)] @@ -151,7 +147,6 @@ impl Js { Type::Float32 => Some("Float32Array"), Type::Float64 => Some("Float64Array"), Type::Char => None, - Type::Handle(_) => None, Type::String => None, Type::Id(id) => match &iface.types[*id].kind { TypeDefKind::Type(t) => self.array_ty(iface, t), @@ -173,7 +168,6 @@ impl Js { | Type::Float64 => self.src.ts("number"), Type::U64 | Type::S64 => self.src.ts("bigint"), Type::Char => self.src.ts("string"), - Type::Handle(id) => self.src.ts(&iface.resources[*id].name.to_camel_case()), Type::String => self.src.ts("string"), Type::Id(id) => { let ty = &iface.types[*id]; @@ -261,39 +255,11 @@ impl Js { fn ts_func(&mut self, iface: &Interface, func: &Function) { self.docs(&func.docs); - let mut name_printed = false; - if let FunctionKind::Static { .. } = &func.kind { - // static methods in imports are still wired up to an imported host - // object, but static methods on exports are actually static - // methods on the resource object. - if self.in_import { - name_printed = true; - self.src.ts(&func.name.to_mixed_case()); - } else { - self.src.ts("static "); - } - } - if !name_printed { - self.src.ts(&func.item_name().to_mixed_case()); - } + self.src.ts(&func.item_name().to_mixed_case()); self.src.ts("("); let param_start = match &func.kind { FunctionKind::Freestanding => 0, - FunctionKind::Static { .. } if self.in_import => 0, - FunctionKind::Static { .. } => { - // the 0th argument for exported static methods will be the - // instantiated interface - self.src.ts(&iface.name.to_mixed_case()); - self.src.ts(": "); - self.src.ts(&iface.name.to_camel_case()); - if func.params.len() > 0 { - self.src.ts(", "); - } - 0 - } - // skip the first parameter on methods which is `this` - FunctionKind::Method { .. } => 1, }; for (i, (name, ty)) in func.params[param_start..].iter().enumerate() { @@ -589,12 +555,6 @@ impl Generator for Js { self.src.ts(";\n"); } - fn type_resource(&mut self, _iface: &Interface, ty: ResourceId) { - if !self.in_import { - self.exported_resources.insert(ty); - } - } - fn type_alias(&mut self, iface: &Interface, _id: TypeId, name: &str, ty: &Type, docs: &Docs) { self.docs(docs); self.src @@ -666,13 +626,7 @@ impl Generator for Js { .entry(iface.name.to_string()) .or_insert(Imports::default()); let dst = match &func.kind { - FunctionKind::Freestanding | FunctionKind::Static { .. } => { - &mut imports.freestanding_funcs - } - FunctionKind::Method { resource, .. } => imports - .resource_funcs - .entry(*resource) - .or_insert(Vec::new()), + FunctionKind::Freestanding => &mut imports.freestanding_funcs, }; dst.push((func.name.to_string(), src)); } @@ -683,38 +637,22 @@ impl Generator for Js { fn import(&mut self, iface: &Interface, func: &Function) { let prev = mem::take(&mut self.src); - let mut params = func + let params = func .params .iter() .enumerate() .map(|(i, _)| format!("arg{}", i)) .collect::>(); - let mut sig_start = 0; - let mut first_is_operand = true; let src_object = match &func.kind { FunctionKind::Freestanding => "this".to_string(), - FunctionKind::Static { .. } => { - self.src.js("static "); - params.insert(0, iface.name.to_mixed_case()); - first_is_operand = false; - iface.name.to_mixed_case() - } - FunctionKind::Method { .. } => { - params[0] = "this".to_string(); - sig_start = 1; - "this._obj".to_string() - } }; self.src.js(&format!( "{}({}) {{\n", func.item_name().to_mixed_case(), - params[sig_start..].join(", ") + params.join(", ") )); self.ts_func(iface, func); - if !first_is_operand { - params.remove(0); - } let mut f = FunctionBindgen::new(self, params); f.src_object = src_object; iface.call( @@ -757,13 +695,6 @@ impl Generator for Js { FunctionKind::Freestanding => { exports.freestanding_funcs.push(func_body); } - FunctionKind::Static { resource, .. } | FunctionKind::Method { resource, .. } => { - exports - .resource_funcs - .entry(*resource) - .or_insert(Vec::new()) - .push(func_body); - } } } @@ -796,64 +727,18 @@ impl Generator for Js { self.src .ts(&format!("export interface {} {{\n", module.to_camel_case())); - for (name, src) in funcs - .freestanding_funcs - .iter() - .chain(funcs.resource_funcs.values().flat_map(|v| v)) - { + for (name, src) in funcs.freestanding_funcs.iter() { self.src.js(&format!( - "imports[\"{}\"][\"{}\"] = {};\n", - module, - name, - src.js.trim(), + "imports[\"{module}\"][\"{name}\"] = {};\n", + src.js.trim() )); - } - - for (_, src) in funcs.freestanding_funcs.iter() { self.src.ts(&src.ts); } - if self.imported_resources.len() > 0 { - self.src - .js("if (!(\"canonical_abi\" in imports)) imports[\"canonical_abi\"] = {};\n"); - } - for resource in self.imported_resources.clone() { - let slab = self.intrinsic(Intrinsic::Slab); - self.src.js(&format!( - " - const resources{idx} = new {slab}(); - imports.canonical_abi[\"resource_drop_{name}\"] = (i) => {{ - const val = resources{idx}.remove(i); - if (obj.drop{camel}) - obj.drop{camel}(val); - }}; - ", - name = iface.resources[resource].name, - camel = iface.resources[resource].name.to_camel_case(), - idx = resource.index(), - slab = slab, - )); - self.src.ts(&format!( - "drop{}?: (val: {0}) => void;\n", - iface.resources[resource].name.to_camel_case() - )); - } self.src.js("}"); self.src.ts("}\n"); - - for (resource, _) in iface.resources.iter() { - self.src.ts(&format!( - "export interface {} {{\n", - iface.resources[resource].name.to_camel_case() - )); - if let Some(funcs) = funcs.resource_funcs.get(&resource) { - for (_, src) in funcs { - self.src.ts(&src.ts); - } - } - self.src.ts("}\n"); - } } + let imports = mem::take(&mut self.src); for (module, exports) in mem::take(&mut self.guest_exports) { @@ -870,75 +755,6 @@ impl Generator for Js { instance: WebAssembly.Instance; "); - self.src.ts(" - /** - * Constructs a new instance with internal state necessary to - * manage a wasm instance. - * - * Note that this does not actually instantiate the WebAssembly - * instance or module, you'll need to call the `instantiate` - * method below to \"activate\" this class. - */ - constructor(); - "); - if self.exported_resources.len() > 0 { - self.src.js("constructor() {\n"); - let slab = self.intrinsic(Intrinsic::Slab); - for r in self.exported_resources.iter() { - self.src.js(&format!( - "this._resource{}_slab = new {}();\n", - r.index(), - slab - )); - } - self.src.js("}\n"); - } - - self.src.ts(" - /** - * This is a low-level method which can be used to add any - * intrinsics necessary for this instance to operate to an - * import object. - * - * The `import` object given here is expected to be used later - * to actually instantiate the module this class corresponds to. - * If the `instantiate` method below actually does the - * instantiation then there's no need to call this method, but - * if you're instantiating manually elsewhere then this can be - * used to prepare the import object for external instantiation. - */ - addToImports(imports: any): void; - "); - self.src.js("addToImports(imports) {\n"); - if self.exported_resources.len() > 0 { - self.src - .js("if (!(\"canonical_abi\" in imports)) imports[\"canonical_abi\"] = {};\n"); - } - for r in self.exported_resources.iter() { - self.src.js(&format!( - " - imports.canonical_abi['resource_drop_{name}'] = i => {{ - this._resource{idx}_slab.remove(i).drop(); - }}; - imports.canonical_abi['resource_clone_{name}'] = i => {{ - const obj = this._resource{idx}_slab.get(i); - return this._resource{idx}_slab.insert(obj.clone()) - }}; - imports.canonical_abi['resource_get_{name}'] = i => {{ - return this._resource{idx}_slab.get(i)._wasm_val; - }}; - imports.canonical_abi['resource_new_{name}'] = i => {{ - const registry = this._registry{idx}; - return this._resource{idx}_slab.insert(new {class}(i, this)); - }}; - ", - name = iface.resources[*r].name, - idx = r.index(), - class = iface.resources[*r].name.to_camel_case(), - )); - } - self.src.js("}\n"); - self.src.ts(&format!( " /** @@ -980,7 +796,6 @@ impl Generator for Js { self.src.js(" async instantiate(module, imports) { imports = imports || {}; - this.addToImports(imports); "); // With intrinsics prep'd we can now instantiate the module. JS has @@ -1000,17 +815,6 @@ impl Generator for Js { } this._exports = this.instance.exports; "); - - // Exported resources all get a finalization registry, and we - // created them after instantiation so we can pass the raw wasm - // export as the destructor callback. - for r in self.exported_resources.iter() { - self.src.js(&format!( - "this._registry{} = new FinalizationRegistry(this._exports['canonical_abi_drop_{}']);\n", - r.index(), - iface.resources[*r].name, - )); - } self.src.js("}\n"); for func in exports.freestanding_funcs.iter() { @@ -1019,81 +823,6 @@ impl Generator for Js { } self.src.ts("}\n"); self.src.js("}\n"); - - for &ty in self.exported_resources.iter() { - self.src.js(&format!( - " - export class {} {{ - constructor(wasm_val, obj) {{ - this._wasm_val = wasm_val; - this._obj = obj; - this._refcnt = 1; - obj._registry{idx}.register(this, wasm_val, this); - }} - - clone() {{ - this._refcnt += 1; - return this; - }} - - drop() {{ - this._refcnt -= 1; - if (this._refcnt !== 0) - return; - this._obj._registry{idx}.unregister(this); - const dtor = this._obj._exports['canonical_abi_drop_{}']; - const wasm_val = this._wasm_val; - delete this._obj; - delete this._refcnt; - delete this._wasm_val; - dtor(wasm_val); - }} - ", - iface.resources[ty].name.to_camel_case(), - iface.resources[ty].name, - idx = ty.index(), - )); - self.src.ts(&format!( - " - export class {} {{ - // Creates a new strong reference count as a new - // object. This is only required if you're also - // calling `drop` below and want to manually manage - // the reference count from JS. - // - // If you don't call `drop`, you don't need to call - // this and can simply use the object from JS. - clone(): {0}; - - // Explicitly indicate that this JS object will no - // longer be used. If the internal reference count - // reaches zero then this will deterministically - // destroy the underlying wasm object. - // - // This is not required to be called from JS. Wasm - // destructors will be automatically called for you - // if this is not called using the JS - // `FinalizationRegistry`. - // - // Calling this method does not guarantee that the - // underlying wasm object is deallocated. Something - // else (including wasm) may be holding onto a - // strong reference count. - drop(): void; - ", - iface.resources[ty].name.to_camel_case(), - )); - - if let Some(funcs) = exports.resource_funcs.get(&ty) { - for func in funcs { - self.src.js(&func.js); - self.src.ts(&func.ts); - } - } - - self.src.ts("}\n"); - self.src.js("}\n"); - } } let exports = mem::take(&mut self.src); @@ -1404,54 +1133,6 @@ impl Bindgen for FunctionBindgen<'_> { results.push(format!("{} ? 1 : 0", operands[0])); } - // These instructions are used with handles when we're implementing - // imports. This means we interact with the `resources` slabs to - // translate the wasm-provided index into a JS value. - Instruction::I32FromOwnedHandle { ty } => { - self.gen.imported_resources.insert(*ty); - results.push(format!("resources{}.insert({})", ty.index(), operands[0])); - } - Instruction::HandleBorrowedFromI32 { ty } => { - self.gen.imported_resources.insert(*ty); - results.push(format!("resources{}.get({})", ty.index(), operands[0])); - } - - // These instructions are used for handles to objects owned in wasm. - // This means that they're interacting with a wrapper class defined - // in JS. - Instruction::I32FromBorrowedHandle { ty } => { - let tmp = self.tmp(); - self.src - .js(&format!("const obj{} = {};\n", tmp, operands[0])); - - // If this is the `this` argument then it's implicitly already valid - if operands[0] != "this" { - self.src.js(&format!( - "if (!(obj{} instanceof {})) ", - tmp, - iface.resources[*ty].name.to_camel_case() - )); - self.src.js(&format!( - "throw new TypeError('expected instance of {}');\n", - iface.resources[*ty].name.to_camel_case() - )); - } - results.push(format!( - "{}._resource{}_slab.insert(obj{}.clone())", - self.src_object, - ty.index(), - tmp, - )); - } - Instruction::HandleOwnedFromI32 { ty } => { - results.push(format!( - "{}._resource{}_slab.remove({})", - self.src_object, - ty.index(), - operands[0], - )); - } - Instruction::RecordLower { record, .. } => { // use destructuring field access to get each // field individually. @@ -2150,21 +1831,13 @@ impl Bindgen for FunctionBindgen<'_> { Instruction::CallInterface { module: _, func } => { let call = |me: &mut FunctionBindgen<'_>| match &func.kind { - FunctionKind::Freestanding | FunctionKind::Static { .. } => { + FunctionKind::Freestanding => { me.src.js(&format!( "obj.{}({})", func.name.to_mixed_case(), operands.join(", "), )); } - FunctionKind::Method { name, .. } => { - me.src.js(&format!( - "{}.{}({})", - operands[0], - name.to_mixed_case(), - operands[1..].join(", "), - )); - } }; let mut bind_results = |me: &mut FunctionBindgen<'_>| { let amt = func.results.len(); diff --git a/crates/gen-host-wasmtime-py/src/lib.rs b/crates/gen-host-wasmtime-py/src/lib.rs index 64ea9efd1..08720b986 100644 --- a/crates/gen-host-wasmtime-py/src/lib.rs +++ b/crates/gen-host-wasmtime-py/src/lib.rs @@ -37,7 +37,6 @@ enum PyUnionRepresentation { #[derive(Default)] struct Imports { freestanding_funcs: Vec, - resource_funcs: BTreeMap>, } struct Import { @@ -50,7 +49,6 @@ struct Import { #[derive(Default)] struct Exports { freestanding_funcs: Vec, - resource_funcs: BTreeMap>, fields: BTreeMap, } @@ -95,11 +93,7 @@ impl WasmtimePy { } /// Creates a `Source` with all of the required intrinsics - fn intrinsics(&mut self, iface: &Interface) -> Source { - if iface.resources.len() > 0 { - self.deps.needs_resources = true; - self.deps.pyimport("typing", "runtime_checkable"); - } + fn intrinsics(&mut self, _iface: &Interface) -> Source { self.deps.intrinsics() } } @@ -118,7 +112,6 @@ fn array_ty(iface: &Interface, ty: &Type) -> Option<&'static str> { Type::Float32 => Some("c_float"), Type::Float64 => Some("c_double"), Type::Char => None, - Type::Handle(_) => None, Type::String => None, Type::Id(id) => match &iface.types[*id].kind { TypeDefKind::Type(t) => array_ty(iface, t), @@ -332,12 +325,6 @@ impl Generator for WasmtimePy { builder.push_str("\n"); } - fn type_resource(&mut self, _iface: &Interface, _ty: ResourceId) { - // if !self.in_import { - // self.exported_resources.insert(ty); - // } - } - fn type_alias(&mut self, iface: &Interface, _id: TypeId, name: &str, ty: &Type, docs: &Docs) { let mut builder = self.src.builder(&mut self.deps, iface); builder.comment(docs); @@ -457,13 +444,7 @@ impl Generator for WasmtimePy { .entry(iface.name.to_string()) .or_insert(Imports::default()); let dst = match &func.kind { - FunctionKind::Freestanding | FunctionKind::Static { .. } => { - &mut imports.freestanding_funcs - } - FunctionKind::Method { resource, .. } => imports - .resource_funcs - .entry(*resource) - .or_insert(Vec::new()), + FunctionKind::Freestanding => &mut imports.freestanding_funcs, }; dst.push(import); } @@ -484,8 +465,6 @@ impl Generator for WasmtimePy { // Use FunctionBindgen call let src_object = match &func.kind { FunctionKind::Freestanding => "self".to_string(), - FunctionKind::Static { .. } => "obj".to_string(), - FunctionKind::Method { .. } => "self._obj".to_string(), }; let mut f = FunctionBindgen::new(self, params); f.src_object = src_object; @@ -551,12 +530,6 @@ impl Generator for WasmtimePy { let dst = match &func.kind { FunctionKind::Freestanding => &mut exports.freestanding_funcs, - FunctionKind::Static { resource, .. } | FunctionKind::Method { resource, .. } => { - exports - .resource_funcs - .entry(*resource) - .or_insert(Vec::new()) - } }; dst.push(func_body); } @@ -596,78 +569,6 @@ impl Generator for WasmtimePy { } self.src.push_str(&intrinsics); - for (id, r) in iface.resources.iter() { - let name = r.name.to_camel_case(); - if self.in_import { - self.src.push_str("@runtime_checkable\n"); - self.src.push_str(&format!("class {}(Protocol):\n", name)); - self.src.indent(); - self.src.push_str("def drop(self) -> None:\n"); - self.src.indent(); - self.src.push_str("pass\n"); - self.src.dedent(); - - for (_, funcs) in self.guest_imports.iter() { - if let Some(funcs) = funcs.resource_funcs.get(&id) { - for func in funcs { - self.src.push_str("@abstractmethod\n"); - self.src.push_str(&func.pysig); - self.src.push_str(":\n"); - self.src.indent(); - self.src.push_str("raise NotImplementedError\n"); - self.src.dedent(); - } - } - } - self.src.dedent(); - } else { - self.src.push_str(&format!("class {}:\n", name)); - self.src.indent(); - self.src.push_str(&format!( - " - _wasm_val: int - _refcnt: int - _obj: '{iface}' - _destroyed: bool - - def __init__(self, val: int, obj: '{iface}') -> None: - self._wasm_val = val - self._refcnt = 1 - self._obj = obj - self._destroyed = False - - def clone(self) -> '{name}': - self._refcnt += 1 - return self - - def drop(self, store: wasmtime.Storelike) -> None: - self._refcnt -= 1; - if self._refcnt != 0: - return - assert(not self._destroyed) - self._destroyed = True - self._obj._canonical_abi_drop_{drop}(store, self._wasm_val) - - def __del__(self) -> None: - if not self._destroyed: - raise RuntimeError('wasm object not dropped') - ", - name = name, - iface = iface.name.to_camel_case(), - drop = name.to_snake_case(), - )); - - for (_, exports) in self.guest_exports.iter() { - if let Some(funcs) = exports.resource_funcs.get(&id) { - for func in funcs { - self.src.push_str(func); - } - } - } - - self.src.dedent(); - } - } self.src.push_str(&types); for (module, funcs) in mem::take(&mut self.guest_imports) { @@ -692,19 +593,7 @@ impl Generator for WasmtimePy { )); self.src.indent(); - for (id, r) in iface.resources.iter() { - self.src.push_str(&format!( - "_resources{}: Slab[{}] = Slab()\n", - id.index(), - r.name.to_camel_case() - )); - } - - for func in funcs - .freestanding_funcs - .iter() - .chain(funcs.resource_funcs.values().flat_map(|v| v)) - { + for func in funcs.freestanding_funcs.iter() { self.src.push_str(&format!("ty = {}\n", func.wasm_ty)); self.src.push_str(&func.src); self.src.push_str(&format!( @@ -715,25 +604,6 @@ impl Generator for WasmtimePy { )); } - for (id, resource) in iface.resources.iter() { - let snake = resource.name.to_snake_case(); - - self.src.push_str(&format!( - "def resource_drop_{}(i: int) -> None:\n _resources{}.remove(i).drop()\n", - snake, - id.index(), - )); - self.src - .push_str("ty = wasmtime.FuncType([wasmtime.ValType.i32()], [])\n"); - self.src.push_str(&format!( - "linker.define(\ - 'canonical_abi', \ - 'resource_drop_{}', \ - wasmtime.Func(store, ty, resource_drop_{})\ - )\n", - resource.name, snake, - )); - } self.src.dedent(); } @@ -743,16 +613,7 @@ impl Generator for WasmtimePy { self.src .push_str(&format!("class {}:\n", iface.name.to_camel_case())); self.src.indent(); - if iface.resources.len() == 0 { - self.src.push_str("pass\n"); - } else { - for (_, r) in iface.resources.iter() { - self.src.push_str(&format!( - "_canonical_abi_drop_{}: wasmtime.Func\n", - r.name.to_snake_case(), - )); - } - } + self.src.push_str("pass\n"); self.src.dedent(); } @@ -769,49 +630,9 @@ impl Generator for WasmtimePy { export.python_type )); } - for (id, r) in iface.resources.iter() { - self.src.push_str(&format!( - "_resource{}_slab: Slab[{}]\n", - id.index(), - r.name.to_camel_case(), - )); - self.src.push_str(&format!( - "_canonical_abi_drop_{}: wasmtime.Func\n", - r.name.to_snake_case(), - )); - } self.src.push_str("def __init__(self, store: wasmtime.Store, linker: wasmtime.Linker, module: wasmtime.Module):\n"); self.src.indent(); - for (id, r) in iface.resources.iter() { - self.src.push_str(&format!( - " - ty1 = wasmtime.FuncType([wasmtime.ValType.i32()], []) - ty2 = wasmtime.FuncType([wasmtime.ValType.i32()], [wasmtime.ValType.i32()]) - def drop_{snake}(caller: wasmtime.Caller, idx: int) -> None: - self._resource{idx}_slab.remove(idx).drop(caller); - linker.define('canonical_abi', 'resource_drop_{name}', wasmtime.Func(store, ty1, drop_{snake}, access_caller = True)) - - def clone_{snake}(idx: int) -> int: - obj = self._resource{idx}_slab.get(idx) - return self._resource{idx}_slab.insert(obj.clone()) - linker.define('canonical_abi', 'resource_clone_{name}', wasmtime.Func(store, ty2, clone_{snake})) - - def get_{snake}(idx: int) -> int: - obj = self._resource{idx}_slab.get(idx) - return obj._wasm_val - linker.define('canonical_abi', 'resource_get_{name}', wasmtime.Func(store, ty2, get_{snake})) - - def new_{snake}(val: int) -> int: - return self._resource{idx}_slab.insert({camel}(val, self)) - linker.define('canonical_abi', 'resource_new_{name}', wasmtime.Func(store, ty2, new_{snake})) - ", - name = r.name, - camel = r.name.to_camel_case(), - snake = r.name.to_snake_case(), - idx = id.index(), - )); - } self.src .push_str("self.instance = linker.instantiate(store, module)\n"); self.src @@ -828,19 +649,6 @@ impl Generator for WasmtimePy { ty = export.python_type, )); } - for (id, r) in iface.resources.iter() { - self.src.push_str(&format!( - " - self._resource{idx}_slab = Slab() - canon_drop_{snake} = exports['canonical_abi_drop_{name}'] - assert(isinstance(canon_drop_{snake}, wasmtime.Func)) - self._canonical_abi_drop_{snake} = canon_drop_{snake} - ", - idx = id.index(), - name = r.name, - snake = r.name.to_snake_case(), - )); - } self.src.dedent(); for func in exports.freestanding_funcs.iter() { @@ -1076,38 +884,6 @@ impl Bindgen for FunctionBindgen<'_> { results.push(format!("int({})", operands[0])); } - // These instructions are used with handles when we're implementing - // imports. This means we interact with the `resources` slabs to - // translate the wasm-provided index into a Python value. - Instruction::I32FromOwnedHandle { ty } => { - results.push(format!("_resources{}.insert({})", ty.index(), operands[0])); - } - Instruction::HandleBorrowedFromI32 { ty } => { - results.push(format!("_resources{}.get({})", ty.index(), operands[0])); - } - - // These instructions are used for handles to objects owned in wasm. - // This means that they're interacting with a wrapper class defined - // in Python. - Instruction::I32FromBorrowedHandle { ty } => { - let obj = self.locals.tmp("obj"); - builder.push_str(&format!("{} = {}\n", obj, operands[0])); - - results.push(format!( - "{}._resource{}_slab.insert({}.clone())", - self.src_object, - ty.index(), - obj, - )); - } - Instruction::HandleOwnedFromI32 { ty } => { - results.push(format!( - "{}._resource{}_slab.remove({})", - self.src_object, - ty.index(), - operands[0], - )); - } Instruction::RecordLower { record, .. } => { if record.fields.is_empty() { return; @@ -1737,21 +1513,13 @@ impl Bindgen for FunctionBindgen<'_> { builder.push_str(" = "); } match &func.kind { - FunctionKind::Freestanding | FunctionKind::Static { .. } => { + FunctionKind::Freestanding => { builder.push_str(&format!( "host.{}({})", func.name.to_snake_case(), operands.join(", "), )); } - FunctionKind::Method { name, .. } => { - builder.push_str(&format!( - "{}.{}({})", - operands[0], - name.to_snake_case(), - operands[1..].join(", "), - )); - } } builder.push_str("\n"); } @@ -1833,7 +1601,7 @@ fn py_type_class_of(ty: &Type) -> PyTypeClass { | Type::S64 => PyTypeClass::Int, Type::Float32 | Type::Float64 => PyTypeClass::Float, Type::Char | Type::String => PyTypeClass::Str, - Type::Handle(_) | Type::Id(_) => PyTypeClass::Custom, + Type::Id(_) => PyTypeClass::Custom, } } diff --git a/crates/gen-host-wasmtime-py/src/source.rs b/crates/gen-host-wasmtime-py/src/source.rs index 007ea423c..f412e874e 100644 --- a/crates/gen-host-wasmtime-py/src/source.rs +++ b/crates/gen-host-wasmtime-py/src/source.rs @@ -185,16 +185,6 @@ impl<'s, 'd, 'i> SourceBuilder<'s, 'd, 'i> { Type::Float32 | Type::Float64 => self.push_str("float"), Type::Char => self.push_str("str"), Type::String => self.push_str("str"), - Type::Handle(id) => { - if forward_ref { - self.push_str("'"); - } - let handle_name = &self.iface.resources[*id].name.to_camel_case(); - self.source.push_str(handle_name); - if forward_ref { - self.push_str("'"); - } - } Type::Id(id) => { let ty = &self.iface.types[*id]; if let Some(name) = &ty.name { @@ -325,36 +315,15 @@ impl<'s, 'd, 'i> SourceBuilder<'s, 'd, 'i> { } pub fn print_sig(&mut self, func: &Function, in_import: bool) -> Vec { - if !in_import { - if let FunctionKind::Static { .. } = func.kind { - self.push_str("@classmethod\n"); - } - } self.source.push_str("def "); - match &func.kind { - FunctionKind::Method { .. } => self.source.push_str(&func.item_name().to_snake_case()), - FunctionKind::Static { .. } if !in_import => { - self.source.push_str(&func.item_name().to_snake_case()) - } - _ => self.source.push_str(&func.name.to_snake_case()), - } + self.source.push_str(&func.name.to_snake_case()); if in_import { self.source.push_str("(self"); - } else if let FunctionKind::Static { .. } = func.kind { - self.source.push_str("(cls, caller: wasmtime.Store, obj: '"); - self.source.push_str(&self.iface.name.to_camel_case()); - self.source.push_str("'"); } else { self.source.push_str("(self, caller: wasmtime.Store"); } let mut params = Vec::new(); - for (i, (param, ty)) in func.params.iter().enumerate() { - if i == 0 { - if let FunctionKind::Method { .. } = func.kind { - params.push("self".to_string()); - continue; - } - } + for (param, ty) in func.params.iter() { self.source.push_str(", "); self.source.push_str(¶m.to_snake_case()); params.push(param.to_snake_case()); @@ -479,48 +448,6 @@ mod tests { assert_eq!(s.s, "def foo():\n return 1\n"); } - #[test] - fn print_ty_forward_ref() { - let mut deps = Dependencies::default(); - let mut iface = Interface::default(); - // Set up a Resource type to refer to - let resource_id = iface.resources.alloc(Resource { - docs: Docs::default(), - name: "foo".into(), - supertype: None, - foreign_module: None, - }); - iface.resource_lookup.insert("foo".into(), resource_id); - let handle_ty = Type::Handle(resource_id); - // ForwardRef usage can be controlled by an argument to print_ty - let mut s1 = Source::default(); - let mut builder = s1.builder(&mut deps, &iface); - builder.print_ty(&handle_ty, true); - drop(builder); - assert_eq!(s1.s, "'Foo'"); - - let mut s2 = Source::default(); - let mut builder = s2.builder(&mut deps, &iface); - builder.print_ty(&handle_ty, false); - drop(builder); - assert_eq!(s2.s, "Foo"); - - // ForwardRef is used for any types within other types - // Even if the outer type is itself not allowed to be one - let option_id = iface.types.alloc(TypeDef { - docs: Docs::default(), - kind: TypeDefKind::Option(handle_ty), - name: None, - foreign_module: None, - }); - let option_ty = Type::Id(option_id); - let mut s3 = Source::default(); - let mut builder = s3.builder(&mut deps, &iface); - builder.print_ty(&option_ty, false); - drop(builder); - assert_eq!(s3.s, "Optional['Foo']"); - } - #[test] fn print_list_bytes() { // If the element type is u8, it is interpreted as `bytes` diff --git a/crates/gen-host-wasmtime-rust/src/lib.rs b/crates/gen-host-wasmtime-rust/src/lib.rs index 2b336a116..80e274c77 100644 --- a/crates/gen-host-wasmtime-rust/src/lib.rs +++ b/crates/gen-host-wasmtime-rust/src/lib.rs @@ -26,7 +26,6 @@ pub struct Wasmtime { needs_custom_error_to_trap: bool, needs_custom_error_to_types: BTreeSet, all_needed_handles: BTreeSet, - exported_resources: BTreeSet, types: Types, guest_imports: HashMap>, guest_exports: HashMap, @@ -197,22 +196,6 @@ impl RustGenerator for Wasmtime { } } - fn handle_projection(&self) -> Option<(&'static str, String)> { - if self.in_import { - if self.in_trait { - Some(("Self", self.trait_name.clone())) - } else { - Some(("T", self.trait_name.clone())) - } - } else { - None - } - } - - fn handle_wrapper(&self) -> Option<&'static str> { - None - } - fn push_str(&mut self, s: &str) { self.src.push_str(s); } @@ -445,29 +428,6 @@ impl Generator for Wasmtime { self.print_typedef_enum(id, name, enum_, docs); } - fn type_resource(&mut self, iface: &Interface, ty: ResourceId) { - let name = &iface.resources[ty].name; - self.all_needed_handles.insert(name.to_string()); - - // If we're binding imports then all handles are associated types so - // there's nothing that we need to do about that. - if self.in_import { - return; - } - - self.exported_resources.insert(ty); - - // ... otherwise for exports we generate a newtype wrapper around an - // `i32` to manage the resultt. - let tyname = name.to_camel_case(); - self.rustdoc(&iface.resources[ty].docs); - self.src.push_str("#[derive(Debug)]\n"); - self.src.push_str(&format!( - "pub struct {}(wit_bindgen_host_wasmtime_rust::rt::ResourceIndex);\n", - tyname - )); - } - fn type_alias(&mut self, iface: &Interface, id: TypeId, _name: &str, ty: &Type, docs: &Docs) { self.print_typedef_alias(iface, id, ty, docs); } @@ -764,7 +724,7 @@ impl Generator for Wasmtime { ); } - fn finish_one(&mut self, iface: &Interface, files: &mut Files) { + fn finish_one(&mut self, _iface: &Interface, files: &mut Files) { for (module, funcs) in sorted_iter(&self.guest_imports) { let module_camel = module.to_camel_case(); self.src.push_str("pub trait "); @@ -842,11 +802,7 @@ impl Generator for Wasmtime { let module_camel = module.to_camel_case(); self.push_str("\npub fn add_to_linker(linker: &mut wasmtime::Linker"); self.push_str(", get: impl Fn(&mut T) -> "); - if self.all_needed_handles.is_empty() { - self.push_str("&mut U"); - } else { - self.push_str(&format!("(&mut U, &mut {}Tables)", module_camel)); - } + self.push_str("&mut U"); self.push_str("+ Send + Sync + Copy + 'static) -> anyhow::Result<()> \n"); self.push_str("where U: "); self.push_str(&module_camel); @@ -864,27 +820,6 @@ impl Generator for Wasmtime { method, module, f.name, f.closure, )); } - for handle in self.all_needed_handles.iter() { - self.src.push_str(&format!( - "linker.func_wrap( - \"canonical_abi\", - \"resource_drop_{name}\", - move |mut caller: wasmtime::Caller<'_, T>, handle: u32| {{ - let (host, tables) = get(caller.data_mut()); - let handle = tables - .{snake}_table - .remove(handle) - .map_err(|e| {{ - wasmtime::Trap::new(format!(\"failed to remove handle: {{}}\", e)) - }})?; - host.drop_{snake}(handle); - Ok(()) - }} - )?;\n", - name = handle, - snake = handle.to_snake_case(), - )); - } self.push_str("Ok(())\n}\n"); } @@ -907,16 +842,6 @@ impl Generator for Wasmtime { self.push_str("pub struct "); self.push_str(&name); self.push_str("Data {\n"); - for r in self.exported_resources.iter() { - self.src.push_str(&format!( - " - index_slab{}: wit_bindgen_host_wasmtime_rust::rt::IndexSlab, - resource_slab{0}: wit_bindgen_host_wasmtime_rust::rt::ResourceSlab, - dtor{0}: Option>, - ", - r.index() - )); - } self.push_str("}\n"); self.push_str("pub struct "); @@ -936,84 +861,6 @@ impl Generator for Wasmtime { let bound = ""; self.push_str(&format!("impl {} {{\n", bound, name)); - if self.exported_resources.len() == 0 { - self.push_str("#[allow(unused_variables)]\n"); - } - self.push_str(&format!( - " - /// Adds any intrinsics, if necessary for this exported wasm - /// functionality to the `linker` provided. - /// - /// The `get_state` closure is required to access the - /// auxiliary data necessary for these wasm exports from - /// the general store's state. - pub fn add_to_linker( - linker: &mut wasmtime::Linker, - get_state: impl Fn(&mut T) -> &mut {}Data + Send + Sync + Copy + 'static, - ) -> anyhow::Result<()> {{ - ", - name, - )); - for r in self.exported_resources.iter() { - let (func_wrap, call, wait, prefix, suffix) = ("func_wrap", "call", "", "", ""); - self.src.push_str(&format!( - " - linker.{func_wrap}( - \"canonical_abi\", - \"resource_drop_{name}\", - move |mut caller: wasmtime::Caller<'_, T>, idx: u32| {prefix}{{ - let state = get_state(caller.data_mut()); - let resource_idx = state.index_slab{idx}.remove(idx)?; - let wasm = match state.resource_slab{idx}.drop(resource_idx) {{ - Some(wasm) => wasm, - None => return Ok(()), - }}; - let dtor = state.dtor{idx}.expect(\"destructor not set yet\"); - dtor.{call}(&mut caller, wasm){wait}?; - Ok(()) - }}{suffix}, - )?; - linker.func_wrap( - \"canonical_abi\", - \"resource_clone_{name}\", - move |mut caller: wasmtime::Caller<'_, T>, idx: u32| {{ - let state = get_state(caller.data_mut()); - let resource_idx = state.index_slab{idx}.get(idx)?; - state.resource_slab{idx}.clone(resource_idx)?; - Ok(state.index_slab{idx}.insert(resource_idx)) - }}, - )?; - linker.func_wrap( - \"canonical_abi\", - \"resource_get_{name}\", - move |mut caller: wasmtime::Caller<'_, T>, idx: u32| {{ - let state = get_state(caller.data_mut()); - let resource_idx = state.index_slab{idx}.get(idx)?; - Ok(state.resource_slab{idx}.get(resource_idx)) - }}, - )?; - linker.func_wrap( - \"canonical_abi\", - \"resource_new_{name}\", - move |mut caller: wasmtime::Caller<'_, T>, val: i32| {{ - let state = get_state(caller.data_mut()); - let resource_idx = state.resource_slab{idx}.insert(val); - Ok(state.index_slab{idx}.insert(resource_idx)) - }}, - )?; - ", - name = iface.resources[*r].name, - idx = r.index(), - func_wrap = func_wrap, - call = call, - wait = wait, - prefix = prefix, - suffix = suffix, - )); - } - self.push_str("Ok(())\n"); - self.push_str("}\n"); - let (instantiate, wait) = ("", ""); self.push_str(&format!( " @@ -1037,7 +884,6 @@ impl Generator for Wasmtime { linker: &mut wasmtime::Linker, get_state: impl Fn(&mut T) -> &mut {}Data + Send + Sync + Copy + 'static, ) -> anyhow::Result<(Self, wasmtime::Instance)> {{ - Self::add_to_linker(linker, get_state)?; let instance = linker.instantiate{}(&mut store, module){}?; Ok((Self::new(store, &instance,get_state)?, instance)) }} @@ -1072,19 +918,6 @@ impl Generator for Wasmtime { self.push_str(&get); self.push_str(";\n"); } - for r in self.exported_resources.iter() { - self.src.push_str(&format!( - " - get_state(store.data_mut()).dtor{} = \ - Some(instance.get_typed_func::(\ - &mut store, \ - \"canonical_abi_drop_{}\", \ - )?);\n - ", - r.index(), - iface.resources[*r].name, - )); - } self.push_str("Ok("); self.push_str(&name); self.push_str("{\n"); @@ -1100,40 +933,6 @@ impl Generator for Wasmtime { self.push_str(func); } - for r in self.exported_resources.iter() { - let (call, wait) = ("call", ""); - self.src.push_str(&format!( - " - /// Drops the host-owned handle to the resource - /// specified. - /// - /// Note that this may execute the WebAssembly-defined - /// destructor for this type. This also may not run - /// the destructor if there are still other references - /// to this type. - pub fn drop_{name_snake}( - &self, - mut store: impl wasmtime::AsContextMut, - val: {name_camel}, - ) -> Result<(), wasmtime::Trap> {{ - let mut store = store.as_context_mut(); - let data = (self.get_state)(store.data_mut()); - let wasm = match data.resource_slab{idx}.drop(val.0) {{ - Some(val) => val, - None => return Ok(()), - }}; - data.dtor{idx}.unwrap().{call}(&mut store, wasm){wait}?; - Ok(()) - }} - ", - name_snake = iface.resources[*r].name.to_snake_case(), - name_camel = iface.resources[*r].name.to_camel_case(), - idx = r.index(), - call = call, - wait = wait, - )); - } - self.push_str("}\n"); } self.print_intrinsics(); @@ -1447,52 +1246,6 @@ impl Bindgen for FunctionBindgen<'_> { )); } - Instruction::I32FromOwnedHandle { ty } => { - let name = &iface.resources[*ty].name; - results.push(format!( - "_tables.{}_table.insert({}) as i32", - name.to_snake_case(), - operands[0] - )); - } - Instruction::HandleBorrowedFromI32 { ty } => { - let name = &iface.resources[*ty].name; - results.push(format!( - "_tables.{}_table.get(({}) as u32).ok_or_else(|| {{ - wasmtime::Trap::new(\"invalid handle index\") - }})?", - name.to_snake_case(), - operands[0] - )); - } - Instruction::I32FromBorrowedHandle { ty } => { - let tmp = self.tmp(); - self.push_str(&format!( - " - let obj{tmp} = {op}; - (self.get_state)(caller.as_context_mut().data_mut()).resource_slab{idx}.clone(obj{tmp}.0)?; - let handle{tmp} = (self.get_state)(caller.as_context_mut().data_mut()).index_slab{idx}.insert(obj{tmp}.0); - ", - tmp = tmp, - idx = ty.index(), - op = operands[0], - )); - - results.push(format!("handle{} as i32", tmp,)); - } - Instruction::HandleOwnedFromI32 { ty } => { - let tmp = self.tmp(); - self.push_str(&format!( - "let handle{} = (self.get_state)(caller.as_context_mut().data_mut()).index_slab{}.remove({} as u32)?;\n", - tmp, - ty.index(), - operands[0], - )); - - let name = iface.resources[*ty].name.to_camel_case(); - results.push(format!("{}(handle{})", name, tmp)); - } - Instruction::RecordLower { ty, record, .. } => { self.record_lower(iface, *ty, record, &operands[0], results); } diff --git a/crates/gen-markdown/src/lib.rs b/crates/gen-markdown/src/lib.rs index 8c59fa44a..a2492c318 100644 --- a/crates/gen-markdown/src/lib.rs +++ b/crates/gen-markdown/src/lib.rs @@ -48,11 +48,6 @@ impl Markdown { Type::Float64 => self.src.push_str("`float64`"), Type::Char => self.src.push_str("`char`"), Type::String => self.src.push_str("`string`"), - Type::Handle(id) => { - self.src.push_str("handle<"); - self.src.push_str(&iface.resources[*id].name); - self.src.push_str(">"); - } Type::Id(id) => { let ty = &iface.types[*id]; if !skip_name { @@ -422,10 +417,6 @@ impl Generator for Markdown { self.print_type_info(id, docs); } - fn type_resource(&mut self, iface: &Interface, ty: ResourceId) { - drop((iface, ty)); - } - fn type_alias(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs) { self.print_type_header(name); self.print_ty(iface, ty, true); diff --git a/crates/gen-rust-lib/src/lib.rs b/crates/gen-rust-lib/src/lib.rs index d4314af6f..c09e2ad67 100644 --- a/crates/gen-rust-lib/src/lib.rs +++ b/crates/gen-rust-lib/src/lib.rs @@ -10,7 +10,6 @@ pub enum TypeMode { Owned, AllBorrowed(&'static str), LeafBorrowed(&'static str), - HandlesBorrowed(&'static str), } pub trait RustGenerator { @@ -31,11 +30,6 @@ pub trait RustGenerator { ); fn print_borrowed_str(&mut self, lifetime: &'static str); fn default_param_mode(&self) -> TypeMode; - fn handle_projection(&self) -> Option<(&'static str, String)>; - fn handle_wrapper(&self) -> Option<&'static str>; - fn handle_in_super(&self) -> bool { - false - } fn rustdoc(&mut self, docs: &Docs) { let docs = match &docs.contents { @@ -169,39 +163,6 @@ pub trait RustGenerator { fn print_ty(&mut self, iface: &Interface, ty: &Type, mode: TypeMode) { match ty { Type::Id(t) => self.print_tyid(iface, *t, mode), - Type::Handle(r) => { - let mut info = TypeInfo::default(); - info.has_handle = true; - let lt = self.lifetime_for(&info, mode); - // Borrowed handles are always behind a reference since - // in that case we never take ownership of the handle. - if let Some(lt) = lt { - self.push_str("&"); - if lt != "'_" { - self.push_str(lt); - } - self.push_str(" "); - } - - let suffix = match self.handle_wrapper() { - Some(wrapper) => { - self.push_str(wrapper); - self.push_str("<"); - ">" - } - None => "", - }; - if self.handle_in_super() { - self.push_str("super::"); - } - if let Some((proj, _)) = self.handle_projection() { - self.push_str(proj); - self.push_str("::"); - } - self.push_str(&iface.resources[*r].name.to_camel_case()); - self.push_str(suffix); - } - Type::Bool => self.push_str("bool"), Type::U8 => self.push_str("u8"), Type::U16 => self.push_str("u16"), @@ -218,7 +179,7 @@ pub trait RustGenerator { TypeMode::AllBorrowed(lt) | TypeMode::LeafBorrowed(lt) => { self.print_borrowed_str(lt) } - TypeMode::Owned | TypeMode::HandlesBorrowed(_) => self.push_str("String"), + TypeMode::Owned => self.push_str("String"), }, } } @@ -246,7 +207,7 @@ pub trait RustGenerator { // variant/record/list, then we need to place the // lifetime parameter on the type as well. if info.owns_data() && needs_generics(iface, &ty.kind) { - self.print_generics(&info, lt, false); + self.print_generics(lt); } return; @@ -266,7 +227,6 @@ pub trait RustGenerator { | TypeDefKind::Union(_) => true, TypeDefKind::Type(Type::Id(t)) => needs_generics(iface, &iface.types[*t].kind), TypeDefKind::Type(Type::String) => true, - TypeDefKind::Type(Type::Handle(_)) => true, TypeDefKind::Type(_) => false, } } @@ -345,7 +305,7 @@ pub trait RustGenerator { self.push_str(">"); } } - TypeMode::HandlesBorrowed(_) | TypeMode::Owned => { + TypeMode::Owned => { self.push_str("Vec<"); self.print_ty(iface, ty, mode); self.push_str(">"); @@ -373,13 +333,8 @@ pub trait RustGenerator { self.push_str("]"); } - fn print_generics(&mut self, info: &TypeInfo, lifetime: Option<&str>, bound: bool) { - let proj = if info.has_handle { - self.handle_projection() - } else { - None - }; - if lifetime.is_none() && proj.is_none() { + fn print_generics(&mut self, lifetime: Option<&str>) { + if lifetime.is_none() { return; } self.push_str("<"); @@ -387,13 +342,6 @@ pub trait RustGenerator { self.push_str(lt); self.push_str(","); } - if let Some((proj, trait_bound)) = proj { - self.push_str(proj); - if bound { - self.push_str(": "); - self.push_str(&trait_bound); - } - } self.push_str(">"); } @@ -433,7 +381,6 @@ pub trait RustGenerator { Type::Float64 => out.push_str("F64"), Type::Char => out.push_str("Char"), Type::String => out.push_str("String"), - Type::Handle(id) => out.push_str(&iface.resources[*id].name.to_camel_case()), Type::Id(id) => { let ty = &iface.types[*id]; match &ty.name { @@ -542,11 +489,11 @@ pub trait RustGenerator { if !info.owns_data() { self.push_str("#[repr(C)]\n"); self.push_str("#[derive(Copy, Clone)]\n"); - } else if !info.has_handle { + } else { self.push_str("#[derive(Clone)]\n"); } self.push_str(&format!("pub struct {}", name)); - self.print_generics(&info, lt, true); + self.print_generics(lt); self.push_str(" {\n"); for field in record.fields.iter() { self.rustdoc(&field.docs); @@ -559,10 +506,10 @@ pub trait RustGenerator { self.push_str("}\n"); self.push_str("impl"); - self.print_generics(&info, lt, true); + self.print_generics(lt); self.push_str(" core::fmt::Debug for "); self.push_str(&name); - self.print_generics(&info, lt, false); + self.print_generics(lt); self.push_str(" {\n"); self.push_str( "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n", @@ -587,7 +534,7 @@ pub trait RustGenerator { let lt = self.lifetime_for(&info, mode); self.rustdoc(docs); self.push_str(&format!("pub type {}", name)); - self.print_generics(&info, lt, true); + self.print_generics(lt); self.push_str(" = ("); for ty in tuple.types.iter() { self.print_ty(iface, ty, mode); @@ -647,11 +594,11 @@ pub trait RustGenerator { let lt = self.lifetime_for(&info, mode); if !info.owns_data() { self.push_str("#[derive(Clone, Copy)]\n"); - } else if !info.has_handle { + } else { self.push_str("#[derive(Clone)]\n"); } self.push_str(&format!("pub enum {name}")); - self.print_generics(&info, lt, true); + self.print_generics(lt); self.push_str("{\n"); for (case_name, docs, payload) in cases.clone() { self.rustdoc(docs); @@ -689,10 +636,10 @@ pub trait RustGenerator { let info = self.info(id); let lt = self.lifetime_for(&info, mode); self.push_str("impl"); - self.print_generics(&info, lt, true); + self.print_generics(lt); self.push_str(" core::fmt::Debug for "); self.push_str(name); - self.print_generics(&info, lt, false); + self.print_generics(lt); self.push_str(" {\n"); self.push_str("fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n"); self.push_str("match self {\n"); @@ -723,7 +670,7 @@ pub trait RustGenerator { self.rustdoc(docs); let lt = self.lifetime_for(&info, mode); self.push_str(&format!("pub type {}", name)); - self.print_generics(&info, lt, true); + self.print_generics(lt); self.push_str("= Option<"); self.print_ty(iface, payload, mode); self.push_str(">;\n"); @@ -743,7 +690,7 @@ pub trait RustGenerator { self.rustdoc(docs); let lt = self.lifetime_for(&info, mode); self.push_str(&format!("pub type {}", name)); - self.print_generics(&info, lt, true); + self.print_generics(lt); self.push_str("= Result<"); self.print_optional_ty(iface, result.ok.as_ref(), mode); self.push_str(","); @@ -854,7 +801,7 @@ pub trait RustGenerator { self.rustdoc(docs); self.push_str(&format!("pub type {}", name)); let lt = self.lifetime_for(&info, mode); - self.print_generics(&info, lt, true); + self.print_generics(lt); self.push_str(" = "); self.print_ty(iface, ty, mode); self.push_str(";\n"); @@ -867,7 +814,7 @@ pub trait RustGenerator { let lt = self.lifetime_for(&info, mode); self.rustdoc(docs); self.push_str(&format!("pub type {}", name)); - self.print_generics(&info, lt, true); + self.print_generics(lt); self.push_str(" = "); self.print_list(iface, ty, mode); self.push_str(";\n"); @@ -900,19 +847,13 @@ pub trait RustGenerator { && info.result && match self.default_param_mode() { TypeMode::AllBorrowed(_) | TypeMode::LeafBorrowed(_) => true, - TypeMode::HandlesBorrowed(_) => info.has_handle, TypeMode::Owned => false, } } fn lifetime_for(&self, info: &TypeInfo, mode: TypeMode) -> Option<&'static str> { match mode { - TypeMode::AllBorrowed(s) | TypeMode::LeafBorrowed(s) - if info.has_list || info.has_handle => - { - Some(s) - } - TypeMode::HandlesBorrowed(s) if info.has_handle => Some(s), + TypeMode::AllBorrowed(s) | TypeMode::LeafBorrowed(s) if info.has_list => Some(s), _ => None, } } @@ -1126,7 +1067,7 @@ trait TypeInfoExt { impl TypeInfoExt for TypeInfo { fn owns_data(&self) -> bool { - self.has_list || self.has_handle + self.has_list } } diff --git a/crates/guest-rust/src/lib.rs b/crates/guest-rust/src/lib.rs index 8613e784d..79de8da76 100644 --- a/crates/guest-rust/src/lib.rs +++ b/crates/guest-rust/src/lib.rs @@ -2,12 +2,6 @@ extern crate alloc; -use alloc::boxed::Box; -use core::fmt; -use core::marker; -use core::mem; -use core::ops::Deref; - #[cfg(feature = "macros")] pub use wit_bindgen_guest_rust_macro::{export, import}; @@ -15,117 +9,6 @@ pub use wit_bindgen_guest_rust_macro::{export, import}; #[doc(hidden)] pub use bitflags; -/// A type for handles to resources that appear in exported functions. -/// -/// This type is used as `Handle` for argument types and return values of -/// exported functions when exposing a Rust-defined resource. A `Handle` -/// represents an owned reference count on the interface-types-managed resource. -/// It's similar to an `Rc` in Rust. Internally a `Handle` can provide -/// access to `&T` when `T` is defined in the current module. -pub struct Handle { - val: i32, - _marker: marker::PhantomData, -} - -impl Handle { - /// Creates a new handle around the specified value. - /// - /// Note that the lifetime of `T` will afterwards be managed by the - /// interface types runtime. The host may hold references to `T` that wasm - /// isn't necessarily aware of, preventing its destruction. Nevertheless - /// though the `Drop for T` implementation will still be run when there are - /// no more references to `T`. - pub fn new(val: T) -> Handle - where - T: LocalHandle, - { - unsafe { Handle::from_raw(T::new(Box::into_raw(Box::new(val)) as i32)) } - } - - /// Consumes a handle and returns the underlying raw wasm i32 descriptor. - /// - /// Note that this, if used improperly, will leak the resource `T`. This - /// generally should be avoided unless you're calling raw ABI bindings and - /// managing the lifetime manually. - pub fn into_raw(handle: Handle) -> i32 { - let ret = handle.val; - mem::forget(handle); - ret - } - - /// Returns the raw underlying handle value for this handle. - /// - /// This typically isn't necessary to interact with, but can be useful when - /// interacting with raw ABI bindings. - pub fn as_raw(handle: &Handle) -> i32 { - handle.val - } - - /// Unsafely assumes that the given integer descriptor is a handle for `T`. - /// - /// This is unsafe because no validation is performed to ensure that `val` - /// is actually a valid descriptor for `T`. - pub unsafe fn from_raw(val: i32) -> Handle { - Handle { - val, - _marker: marker::PhantomData, - } - } -} - -impl Deref for Handle { - type Target = T; - - fn deref(&self) -> &T { - unsafe { &*(T::get(self.val) as *const T) } - } -} - -impl From for Handle { - fn from(val: T) -> Handle { - Handle::new(val) - } -} - -impl Clone for Handle { - fn clone(&self) -> Self { - unsafe { Handle::from_raw(T::clone(self.val)) } - } -} - -impl fmt::Debug for Handle { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Handle").field("val", &self.val).finish() - } -} - -impl Drop for Handle { - fn drop(&mut self) { - T::drop(self.val); - } -} - -/// A trait for types that can show up as the `T` in `Handle`. -/// -/// This trait is automatically synthesized for exported handles and typically -/// shouldn't be implemented manually. -pub unsafe trait HandleType { - #[doc(hidden)] - fn clone(val: i32) -> i32; - #[doc(hidden)] - fn drop(val: i32); -} - -/// An extension of the [`HandleType`] trait for locally-defined types. -/// -/// This trait may not stick around forever... -pub unsafe trait LocalHandle: HandleType { - #[doc(hidden)] - fn new(val: i32) -> i32; - #[doc(hidden)] - fn get(val: i32) -> i32; -} - #[doc(hidden)] pub mod rt { use super::alloc::alloc::Layout; diff --git a/crates/test-helpers/src/lib.rs b/crates/test-helpers/src/lib.rs index 073b17e36..b1216ac00 100644 --- a/crates/test-helpers/src/lib.rs +++ b/crates/test-helpers/src/lib.rs @@ -35,7 +35,6 @@ pub fn codegen_rust_wasm_import(input: TokenStream) -> TokenStream { #[cfg(feature = "guest-rust")] pub fn codegen_rust_wasm_export(input: TokenStream) -> TokenStream { use heck::*; - use std::collections::BTreeMap; use wit_parser::{FunctionKind, Type, TypeDefKind}; return gen_rust( @@ -62,24 +61,18 @@ pub fn codegen_rust_wasm_export(input: TokenStream) -> TokenStream { fn gen_extra(iface: &wit_parser::Interface) -> proc_macro2::TokenStream { let mut ret = quote::quote!(); - if iface.resources.len() == 0 && iface.functions.len() == 0 { + if iface.functions.len() == 0 { return ret; } let snake = quote::format_ident!("{}", iface.name.to_snake_case()); let camel = quote::format_ident!("{}", iface.name.to_camel_case()); - for (_, r) in iface.resources.iter() { - let name = quote::format_ident!("{}", r.name.to_camel_case()); - ret.extend(quote::quote!(pub struct #name;)); - } - let mut methods = Vec::new(); - let mut resources = BTreeMap::new(); for f in iface.functions.iter() { let name = quote::format_ident!("{}", f.item_name().to_snake_case()); - let mut params = f + let params = f .params .iter() .map(|(_, t)| quote_ty(true, iface, t)) @@ -89,29 +82,18 @@ pub fn codegen_rust_wasm_export(input: TokenStream) -> TokenStream { .iter_types() .map(|t| quote_ty(false, iface, t)) .collect::>(); - let mut self_ = quote::quote!(); - if let FunctionKind::Method { .. } = &f.kind { - params.remove(0); - self_ = quote::quote!(&self,); - } let ret = match rets.len() { 0 => quote::quote!(()), 1 => rets[0].clone(), _ => quote::quote!((#(#rets,)*)), }; let method = quote::quote! { - fn #name(#self_ #(_: #params),*) -> #ret { + fn #name(#(_: #params),*) -> #ret { loop {} } }; match &f.kind { FunctionKind::Freestanding => methods.push(method), - FunctionKind::Static { resource, .. } | FunctionKind::Method { resource, .. } => { - resources - .entry(*resource) - .or_insert(Vec::new()) - .push(method); - } } } ret.extend(quote::quote! { @@ -121,14 +103,6 @@ pub fn codegen_rust_wasm_export(input: TokenStream) -> TokenStream { #(#methods)* } }); - for (id, methods) in resources { - let name = quote::format_ident!("{}", iface.resources[id].name.to_camel_case()); - ret.extend(quote::quote! { - impl #snake::#name for #name { - #(#methods)* - } - }); - } ret } @@ -152,11 +126,6 @@ pub fn codegen_rust_wasm_export(input: TokenStream) -> TokenStream { Type::Float64 => quote::quote! { f64 }, Type::Char => quote::quote! { char }, Type::String => quote::quote! { String }, - Type::Handle(resource) => { - let name = - quote::format_ident!("{}", iface.resources[resource].name.to_camel_case()); - quote::quote! { wit_bindgen_guest_rust::Handle<#name> } - } Type::Id(id) => quote_id(param, iface, id), } } diff --git a/crates/test-rust-wasm/Cargo.toml b/crates/test-rust-wasm/Cargo.toml index 8afc68511..d58925b56 100644 --- a/crates/test-rust-wasm/Cargo.toml +++ b/crates/test-rust-wasm/Cargo.toml @@ -36,10 +36,6 @@ test = false name = "lists" test = false -[[bin]] -name = "handles" -test = false - [[bin]] name = "flavorful" test = false diff --git a/crates/test-rust-wasm/src/bin/handles.rs b/crates/test-rust-wasm/src/bin/handles.rs deleted file mode 100644 index 4d5732813..000000000 --- a/crates/test-rust-wasm/src/bin/handles.rs +++ /dev/null @@ -1,3 +0,0 @@ -include!("../../../../tests/runtime/handles/wasm.rs"); - -fn main() {} diff --git a/crates/wit-bindgen-demo/demo.wit b/crates/wit-bindgen-demo/demo.wit index 22235ccf7..00b06c663 100644 --- a/crates/wit-bindgen-demo/demo.wit +++ b/crates/wit-bindgen-demo/demo.wit @@ -11,12 +11,11 @@ enum lang { } -resource config { - static new: func() -> config - - render: func(lang: lang, wit: string, import: bool) -> result - - set-rust-unchecked: func(unchecked: bool) - set-wasmtime-tracing: func(unchecked: bool) - set-wasmtime-custom-error: func(custom: bool) +record options { + rust-unchecked: bool, + wasmtime-tracing: bool, + wasmtime-custom-error: bool, + import: bool, } + +render: func(lang: lang, wit: string, options: options) -> result diff --git a/crates/wit-bindgen-demo/main.ts b/crates/wit-bindgen-demo/main.ts index 9ca11b653..089f40810 100644 --- a/crates/wit-bindgen-demo/main.ts +++ b/crates/wit-bindgen-demo/main.ts @@ -1,4 +1,4 @@ -import { Demo, Config } from './demo.js'; +import { Demo, Options } from './demo.js'; import * as browser from './browser.js'; class Editor { @@ -11,7 +11,7 @@ class Editor { wasmtimeCustomError: HTMLInputElement; generatedFiles: Record; demo: Demo; - config: Config | null; + options: Options; rerender: number | null; inputEditor: AceAjax.Editor; outputEditor: AceAjax.Editor; @@ -37,7 +37,12 @@ class Editor { this.generatedFiles = {}; this.demo = new Demo(); - this.config = null; + this.options = { + rustUnchecked: false, + wasmtimeTracing: false, + wasmtimeCustomError: false, + import: false, + }; this.rerender = null; } @@ -49,7 +54,6 @@ class Editor { }; browser.addBrowserToImports(imports, obj, name => this.demo.instance.exports[name]); await this.demo.instantiate(fetch('./demo.wasm'), imports); - this.config = Config.new(this.demo); this.installListeners(); this.render(); } @@ -66,16 +70,16 @@ class Editor { this.mode.addEventListener('change', () => this.render()); this.rustUnchecked.addEventListener('change', () => { - this.config.setRustUnchecked(this.rustUnchecked.checked); + this.options.rustUnchecked = this.rustUnchecked.checked; this.render(); }); this.wasmtimeTracing.addEventListener('change', () => { - this.config.setWasmtimeTracing(this.wasmtimeTracing.checked); + this.options.wasmtimeTracing = this.wasmtimeTracing.checked; this.render(); }); this.wasmtimeCustomError.addEventListener('change', () => { - this.config.setWasmtimeCustomError(this.wasmtimeCustomError.checked); + this.options.wasmtimeCustomError = this.wasmtimeCustomError.checked; this.render(); }); this.files.addEventListener('change', () => this.updateSelectedFile()); @@ -105,7 +109,8 @@ class Editor { break; default: return; } - const result = this.config.render(lang, wit, is_import); + this.options.import = is_import; + const result = this.demo.render(lang, wit, this.options); if (result.tag === 'err') { this.outputEditor.setValue(result.val); this.outputEditor.clearSelection(); diff --git a/crates/wit-bindgen-demo/src/lib.rs b/crates/wit-bindgen-demo/src/lib.rs index a4361bc25..f925e2437 100644 --- a/crates/wit-bindgen-demo/src/lib.rs +++ b/crates/wit-bindgen-demo/src/lib.rs @@ -1,29 +1,18 @@ -use std::cell::RefCell; use std::sync::Once; use wit_bindgen_core::wit_parser::Interface; use wit_bindgen_core::Generator; -use wit_bindgen_guest_rust::Handle; wit_bindgen_guest_rust::export!("demo.wit"); wit_bindgen_guest_rust::import!("browser.wit"); struct Demo; -impl demo::Demo for Demo {} - -#[derive(Default)] -pub struct Config { - js: RefCell, - c: RefCell, - rust: RefCell, - java: RefCell, - wasmtime: RefCell, - wasmtime_py: RefCell, - markdown: RefCell, -} - -impl demo::Config for Config { - fn new() -> Handle { +impl demo::Demo for Demo { + fn render( + lang: demo::Lang, + wit: String, + options: demo::Options, + ) -> Result, String> { static INIT: Once = Once::new(); INIT.call_once(|| { let prev_hook = std::panic::take_hook(); @@ -33,27 +22,29 @@ impl demo::Config for Config { })); }); - Config::default().into() - } - - fn render( - &self, - lang: demo::Lang, - wit: String, - import: bool, - ) -> Result, String> { let mut gen: Box = match lang { - demo::Lang::Rust => Box::new(self.rust.borrow().clone().build()), - demo::Lang::Java => Box::new(self.java.borrow().clone().build()), - demo::Lang::Wasmtime => Box::new(self.wasmtime.borrow().clone().build()), - demo::Lang::WasmtimePy => Box::new(self.wasmtime_py.borrow().clone().build()), - demo::Lang::Js => Box::new(self.js.borrow().clone().build()), - demo::Lang::C => Box::new(self.c.borrow().clone().build()), - demo::Lang::Markdown => Box::new(self.markdown.borrow().clone().build()), + demo::Lang::Rust => Box::new({ + let mut opts = wit_bindgen_gen_guest_rust::Opts::default(); + opts.unchecked = options.rust_unchecked; + opts.build() + }), + demo::Lang::Java => Box::new(wit_bindgen_gen_guest_teavm_java::Opts::default().build()), + demo::Lang::Wasmtime => Box::new({ + let mut opts = wit_bindgen_gen_host_wasmtime_rust::Opts::default(); + opts.tracing = options.wasmtime_tracing; + opts.custom_error = options.wasmtime_custom_error; + opts.build() + }), + demo::Lang::WasmtimePy => { + Box::new(wit_bindgen_gen_host_wasmtime_py::Opts::default().build()) + } + demo::Lang::Js => Box::new(wit_bindgen_gen_host_js::Opts::default().build()), + demo::Lang::C => Box::new(wit_bindgen_gen_guest_c::Opts::default().build()), + demo::Lang::Markdown => Box::new(wit_bindgen_gen_markdown::Opts::default().build()), }; let iface = Interface::parse("input", &wit).map_err(|e| format!("{:?}", e))?; let mut files = Default::default(); - let (imports, exports) = if import { + let (imports, exports) = if options.import { (vec![iface], vec![]) } else { (vec![], vec![iface]) @@ -71,16 +62,4 @@ impl demo::Config for Config { }) .collect()) } - - fn set_rust_unchecked(&self, unchecked: bool) { - self.rust.borrow_mut().unchecked = unchecked; - } - - fn set_wasmtime_tracing(&self, tracing: bool) { - self.wasmtime.borrow_mut().tracing = tracing; - } - fn set_wasmtime_custom_error(&self, custom_error: bool) { - browser::log("custom error"); - self.wasmtime.borrow_mut().custom_error = custom_error; - } } diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index dc6dbd613..b236915b6 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -548,8 +548,6 @@ impl<'a> TypeEncoder<'a> { required_funcs: &IndexSet<&'a str>, imports: &mut ImportEncoder<'a>, ) -> Result<()> { - Self::validate_interface(import)?; - let mut instance = InstanceTypeEncoder::default(); for func in &import.functions { @@ -574,8 +572,6 @@ impl<'a> TypeEncoder<'a> { export_func_types: bool, ) -> Result<()> { for (export, is_default) in interfaces { - Self::validate_interface(export)?; - // TODO: stick interface documentation in a custom section? for func in &export.functions { @@ -744,9 +740,6 @@ impl<'a> TypeEncoder<'a> { encoded } - Type::Handle(_) => { - bail!("the use of handle types in interfaces is not currently supported") - } }) } @@ -915,14 +908,6 @@ impl<'a> TypeEncoder<'a> { Ok(()) } - fn validate_interface(interface: &Interface) -> Result<()> { - if interface.resources.len() != 0 { - bail!("the use of resources in interfaces is not currently not supported"); - } - - Ok(()) - } - fn validate_function(function: &Function) -> Result<()> { if function.name.is_empty() { bail!("interface has an unnamed function"); diff --git a/crates/wit-component/src/printing.rs b/crates/wit-component/src/printing.rs index 0bc89dbcf..3886d01d0 100644 --- a/crates/wit-component/src/printing.rs +++ b/crates/wit-component/src/printing.rs @@ -122,8 +122,6 @@ impl InterfacePrinter { } } } - - Type::Handle(_) => bail!("interface has unsupported type"), } Ok(()) @@ -245,8 +243,6 @@ impl InterfacePrinter { TypeDefKind::Stream(_) => todo!("declare stream"), } } - - Type::Handle(_) => bail!("interface has unsupported type"), } Ok(()) } diff --git a/crates/wit-parser/src/abi.rs b/crates/wit-parser/src/abi.rs index 66bbb12ff..02be702a7 100644 --- a/crates/wit-parser/src/abi.rs +++ b/crates/wit-parser/src/abi.rs @@ -1,7 +1,7 @@ use crate::sizealign::align_to; use crate::{ - Enum, Flags, FlagsRepr, Function, Int, Interface, Record, ResourceId, Result_, Results, Tuple, - Type, TypeDefKind, TypeId, Union, Variant, + Enum, Flags, FlagsRepr, Function, Int, Interface, Record, Result_, Results, Tuple, Type, + TypeDefKind, TypeId, Union, Variant, }; /// A raw WebAssembly signature with params and results. @@ -267,113 +267,6 @@ def_instruction! { /// Creates an `i32` from a `bool` input, must return 0 or 1. I32FromBool : [1] => [1], - // Handles - - /// Converts a "borrowed" handle into a wasm `i32` value. - /// - /// > **Note**: this documentation is outdated and does not reflect the - /// > current implementation of the canonical ABI. This needs to be - /// > updated. - /// - /// A "borrowed" handle in this case means one where ownership is not - /// being relinquished. This is only used for lowering interface types - /// parameters. - /// - /// Situations that this is used are: - /// - /// * A wasm exported function receives, as a parameter, handles defined - /// by the wasm module itself. This is effectively proof of ownership - /// by an external caller (be it host or wasm module) and the - /// ownership of the handle still lies with the caller. The wasm - /// module is only receiving a reference to the resource. - /// - /// * A wasm module is calling an import with a handle defined by the - /// import's module. Sort of the converse of the previous case this - /// means that the wasm module is handing out a reference to a - /// resource that it owns. The type in the wasm module, for example, - /// needs to reflect this. - /// - /// This instruction is not used for return values in either - /// export/import positions. - I32FromBorrowedHandle { ty: ResourceId } : [1] => [1], - - /// Converts an "owned" handle into a wasm `i32` value. - /// - /// > **Note**: this documentation is outdated and does not reflect the - /// > current implementation of the canonical ABI. This needs to be - /// > updated. - /// - /// This conversion is used for handle values which are crossing a - /// module boundary for perhaps the first time. Some example cases of - /// when this conversion is used are: - /// - /// * When a host defines a function to be imported, returned handles - /// use this instruction. Handles being returned to wasm a granting a - /// capability, which means that this new capability is typically - /// wrapped up in a new integer descriptor. - /// - /// * When a wasm module calls an imported function with a type defined - /// by itself, then it's granting a capability to the callee. This - /// means that the wasm module's type is being granted for the first - /// time, possibly, so it needs to be an owned value that's consumed. - /// Note that this doesn't actually happen with `*.witx` today due to - /// the lack of handle type imports. - /// - /// * When a wasm module export returns a handle defined within the - /// module, then it's similar to calling an imported function with - /// that handle. The capability is being granted to the caller of the - /// export, so the owned value is wrapped up in an `i32`. - /// - /// * When a host is calling a wasm module with a capability defined by - /// the host, its' similar to the host import returning a capability. - /// This would be granting the wasm module with the capability so an - /// owned version with a fresh handle is passed to the wasm module. - /// Note that this doesn't happen today with `*.witx` due to the lack - /// of handle type imports. - /// - /// Basically this instruction is used for handle->wasm conversions - /// depending on the calling context and where the handle type in - /// question was defined. - I32FromOwnedHandle { ty: ResourceId } : [1] => [1], - - /// Converts a native wasm `i32` into an owned handle value. - /// - /// > **Note**: this documentation is outdated and does not reflect the - /// > current implementation of the canonical ABI. This needs to be - /// > updated. - /// - /// This is the converse of `I32FromOwnedHandle` and is used in similar - /// situations: - /// - /// * A host definition of an import receives a handle defined in the - /// module itself. - /// * A wasm module calling an import receives a handle defined by the - /// import. - /// * A wasm module's export receives a handle defined by an external - /// module. - /// * A host calling a wasm export receives a handle defined in the - /// module. - /// - /// Note that like `I32FromOwnedHandle` the first and third bullets - /// above don't happen today because witx can't express type imports - /// just yet. - HandleOwnedFromI32 { ty: ResourceId } : [1] => [1], - - /// Converts a native wasm `i32` into a borrowedhandle value. - /// - /// > **Note**: this documentation is outdated and does not reflect the - /// > current implementation of the canonical ABI. This needs to be - /// > updated. - /// - /// This is the converse of `I32FromBorrowedHandle` and is used in similar - /// situations: - /// - /// * An exported wasm function receives, as a parameter, a handle that - /// is defined by the wasm module. - /// * An host-defined imported function is receiving a handle, as a - /// parameter, that is defined by the host itself. - HandleBorrowedFromI32 { ty: ResourceId } : [1] => [1], - // lists /// Lowers a list where the element's layout in the native language is @@ -868,8 +761,7 @@ impl Interface { | Type::U16 | Type::S32 | Type::U32 - | Type::Char - | Type::Handle(_) => result.push(WasmType::I32), + | Type::Char => result.push(WasmType::I32), Type::U64 | Type::S64 => result.push(WasmType::I64), Type::Float32 => result.push(WasmType::F32), @@ -1024,10 +916,6 @@ impl Interface { TypeDefKind::Future(_) | TypeDefKind::Stream(_) => unimplemented!(), }, - // TODO: this is probably not correct, unsure though as handles are - // in flux at the moment - Type::Handle(_) => false, - Type::Bool | Type::U8 | Type::S8 @@ -1382,40 +1270,6 @@ impl<'a, B: Bindgen> Generator<'a, B> { Type::Char => self.emit(&I32FromChar), Type::Float32 => self.emit(&F32FromFloat32), Type::Float64 => self.emit(&F64FromFloat64), - Type::Handle(ty) => { - let borrowed = match self.lift_lower { - // This means that a return value is being lowered, which is - // never borrowed. - LiftLower::LiftArgsLowerResults => false, - // There's one of three possible situations we're in: - // - // * The handle is defined by the wasm module itself. This - // is the only actual possible scenario today due to how - // witx is defined. In this situation the handle is owned - // by the host and "proof of ownership" is being offered - // and there's no need to relinquish ownership. - // - // * The handle is defined by the host, and it's passing it - // to a wasm module. This should use an owned conversion. - // This isn't expressible in today's `*.witx` format. - // - // * The handle is defined by neither the host or the wasm - // mdoule. This means that the host is passing a - // capability from another wasm module into this one, - // meaning it's doing so by reference since the host is - // retaining access to its own - // - // Note, again, only the first bullet here is possible - // today, hence the hardcoded `true` value. We'll need to - // refactor `witx` to expose the other possibilities. - LiftLower::LowerArgsLiftResults => true, - }; - if borrowed { - self.emit(&I32FromBorrowedHandle { ty }); - } else { - self.emit(&I32FromOwnedHandle { ty }); - } - } Type::String => { let realloc = self.list_realloc(); self.emit(&StringLower { realloc }); @@ -1603,19 +1457,6 @@ impl<'a, B: Bindgen> Generator<'a, B> { Type::Char => self.emit(&CharFromI32), Type::Float32 => self.emit(&Float32FromF32), Type::Float64 => self.emit(&Float64FromF64), - Type::Handle(ty) => { - // For more information on these values see the comments in - // `lower` above. - let borrowed = match self.lift_lower { - LiftLower::LiftArgsLowerResults => true, - LiftLower::LowerArgsLiftResults => false, - }; - if borrowed { - self.emit(&HandleBorrowedFromI32 { ty }); - } else { - self.emit(&HandleOwnedFromI32 { ty }); - } - } Type::String => self.emit(&StringLift), Type::Id(id) => match &self.iface.types[id].kind { TypeDefKind::Type(t) => self.lift(t), @@ -1766,7 +1607,7 @@ impl<'a, B: Bindgen> Generator<'a, B> { self.lower_and_emit(ty, addr, &I32Store8 { offset }) } Type::U16 | Type::S16 => self.lower_and_emit(ty, addr, &I32Store16 { offset }), - Type::U32 | Type::S32 | Type::Handle(_) | Type::Char => { + Type::U32 | Type::S32 | Type::Char => { self.lower_and_emit(ty, addr, &I32Store { offset }) } Type::U64 | Type::S64 => self.lower_and_emit(ty, addr, &I64Store { offset }), @@ -1965,9 +1806,7 @@ impl<'a, B: Bindgen> Generator<'a, B> { Type::S8 => self.emit_and_lift(ty, addr, &I32Load8S { offset }), Type::U16 => self.emit_and_lift(ty, addr, &I32Load16U { offset }), Type::S16 => self.emit_and_lift(ty, addr, &I32Load16S { offset }), - Type::U32 | Type::S32 | Type::Char | Type::Handle(_) => { - self.emit_and_lift(ty, addr, &I32Load { offset }) - } + Type::U32 | Type::S32 | Type::Char => self.emit_and_lift(ty, addr, &I32Load { offset }), Type::U64 | Type::S64 => self.emit_and_lift(ty, addr, &I64Load { offset }), Type::Float32 => self.emit_and_lift(ty, addr, &F32Load { offset }), Type::Float64 => self.emit_and_lift(ty, addr, &F64Load { offset }), @@ -2165,8 +2004,6 @@ impl<'a, B: Bindgen> Generator<'a, B> { } match *ty { - Type::Handle(_) => unimplemented!(), - Type::String => { self.stack.push(addr.clone()); self.emit(&Instruction::I32Load { offset }); diff --git a/crates/wit-parser/src/ast.rs b/crates/wit-parser/src/ast.rs index 269cc8d0a..f8201dfa2 100644 --- a/crates/wit-parser/src/ast.rs +++ b/crates/wit-parser/src/ast.rs @@ -16,7 +16,6 @@ pub struct Ast<'a> { pub enum Item<'a> { Use(Use<'a>), - Resource(Resource<'a>), TypeDef(TypeDef<'a>), Value(Value<'a>), Interface(Interface<'a>), @@ -55,13 +54,6 @@ struct UseName<'a> { as_: Option>, } -pub struct Resource<'a> { - docs: Docs<'a>, - name: Id<'a>, - supertype: Option>, - values: Vec<(bool, Value<'a>)>, -} - #[derive(Default)] struct Docs<'a> { docs: Vec>, @@ -223,12 +215,11 @@ impl<'a> Item<'a> { } Some((_span, Token::Record)) => TypeDef::parse_record(tokens, docs).map(Item::TypeDef), Some((_span, Token::Union)) => TypeDef::parse_union(tokens, docs).map(Item::TypeDef), - Some((_span, Token::Resource)) => Resource::parse(tokens, docs).map(Item::Resource), Some((_span, Token::Interface)) => Interface::parse(tokens, docs).map(Item::Interface), Some((_span, Token::Id)) | Some((_span, Token::ExplicitId)) => { Value::parse(tokens, docs).map(Item::Value) } - other => Err(err_expected(tokens, "`type`, `resource`, or `func`", other).into()), + other => Err(err_expected(tokens, "`type` or `func`", other).into()), } } } @@ -378,35 +369,6 @@ impl<'a> TypeDef<'a> { } } -impl<'a> Resource<'a> { - fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result { - tokens.expect(Token::Resource)?; - let name = parse_id(tokens)?; - let supertype = if tokens.eat(Token::Implements)? { - Some(parse_id(tokens)?) - } else { - None - }; - let mut values = Vec::new(); - if tokens.eat(Token::LeftBrace)? { - loop { - let docs = parse_docs(tokens)?; - if tokens.eat(Token::RightBrace)? { - break; - } - let statik = tokens.eat(Token::Static)?; - values.push((statik, Value::parse(tokens, docs)?)); - } - } - Ok(Resource { - docs, - name, - supertype, - values, - }) - } -} - impl<'a> Value<'a> { fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result { let name = parse_id(tokens)?; diff --git a/crates/wit-parser/src/ast/lex.rs b/crates/wit-parser/src/ast/lex.rs index 9ab7cc4eb..84ea3dfb3 100644 --- a/crates/wit-parser/src/ast/lex.rs +++ b/crates/wit-parser/src/ast/lex.rs @@ -48,7 +48,6 @@ pub enum Token { Use, Type, - Resource, Func, U8, U16, @@ -236,7 +235,6 @@ impl<'a> Tokenizer<'a> { match &self.input[start..end] { "use" => Use, "type" => Type, - "resource" => Resource, "func" => Func, "u8" => U8, "u16" => U16, @@ -498,7 +496,6 @@ impl Token { GreaterThan => "'>'", Use => "keyword `use`", Type => "keyword `type`", - Resource => "keyword `resource`", Func => "keyword `func`", U8 => "keyword `u8`", U16 => "keyword `u16`", diff --git a/crates/wit-parser/src/ast/resolve.rs b/crates/wit-parser/src/ast/resolve.rs index 6bf88b63e..dc946e7d3 100644 --- a/crates/wit-parser/src/ast/resolve.rs +++ b/crates/wit-parser/src/ast/resolve.rs @@ -8,10 +8,7 @@ use std::mem; pub struct Resolver { type_lookup: HashMap, types: Arena, - resource_lookup: HashMap, - resources_copied: HashMap<(String, ResourceId), ResourceId>, types_copied: HashMap<(String, TypeId), TypeId>, - resources: Arena, anon_types: HashMap, functions: Vec, globals: Vec, @@ -63,7 +60,6 @@ impl Resolver { for field in fields { match field { Item::Value(v) => self.resolve_value(v)?, - Item::Resource(r) => self.resolve_resource(r)?, Item::TypeDef(t) => { self.validate_type_not_recursive( t.name.span, @@ -81,8 +77,6 @@ impl Resolver { module: None, types: mem::take(&mut self.types), type_lookup: mem::take(&mut self.type_lookup), - resources: mem::take(&mut self.resources), - resource_lookup: mem::take(&mut self.resource_lookup), interface_lookup: Default::default(), interfaces: Default::default(), functions: mem::take(&mut self.functions), @@ -127,12 +121,6 @@ impl Resolver { }; let mut found = false; - if let Some(id) = dep.resource_lookup.get(&*name.name.name) { - let resource = self.copy_resource(&mod_name.name, dep, *id); - self.define_resource(my_name, span, resource)?; - found = true; - } - if let Some(id) = dep.type_lookup.get(&*name.name.name) { let ty = self.copy_type_def(&mod_name.name, dep, *id); self.define_type(my_name, span, ty)?; @@ -149,10 +137,6 @@ impl Resolver { } } None => { - for (id, resource) in dep.resources.iter() { - let id = self.copy_resource(&mod_name.name, dep, id); - self.define_resource(&resource.name, mod_name.span, id)?; - } let mut names = dep.type_lookup.iter().collect::>(); names.sort(); // produce a stable order by which to add names for (name, id) in names { @@ -165,27 +149,6 @@ impl Resolver { Ok(()) } - fn copy_resource(&mut self, dep_name: &str, dep: &Interface, r: ResourceId) -> ResourceId { - let resources = &mut self.resources; - *self - .resources_copied - .entry((dep_name.to_string(), r)) - .or_insert_with(|| { - let r = &dep.resources[r]; - let resource = Resource { - docs: r.docs.clone(), - name: r.name.clone(), - supertype: r.supertype.clone(), - foreign_module: Some( - r.foreign_module - .clone() - .unwrap_or_else(|| dep_name.to_string()), - ), - }; - resources.alloc(resource) - }) - } - fn copy_type_def(&mut self, dep_name: &str, dep: &Interface, dep_id: TypeId) -> TypeId { if let Some(id) = self.types_copied.get(&(dep_name.to_string(), dep_id)) { return *id; @@ -268,7 +231,6 @@ impl Resolver { fn copy_type(&mut self, dep_name: &str, dep: &Interface, ty: Type) -> Type { match ty { Type::Id(id) => Type::Id(self.copy_type_def(dep_name, dep, id)), - Type::Handle(id) => Type::Handle(self.copy_resource(dep_name, dep, id)), other => other, } } @@ -281,7 +243,6 @@ impl Resolver { ) -> Option { match ty { Some(Type::Id(id)) => Some(Type::Id(self.copy_type_def(dep_name, dep, id))), - Some(Type::Handle(id)) => Some(Type::Handle(self.copy_resource(dep_name, dep, id))), other => other, } } @@ -290,26 +251,6 @@ impl Resolver { let mut values = HashSet::new(); for field in fields { match field { - Item::Resource(r) => { - let docs = self.docs(&r.docs); - let id = self.resources.alloc(Resource { - docs, - name: r.name.name.to_string(), - supertype: r - .supertype - .as_ref() - .map(|supertype| supertype.name.to_string()), - foreign_module: None, - }); - self.define_resource(&r.name.name, r.name.span, id)?; - let type_id = self.types.alloc(TypeDef { - docs: Docs::default(), - kind: TypeDefKind::Type(Type::Handle(id)), - name: None, - foreign_module: None, - }); - self.define_type(&r.name.name, r.name.span, type_id)?; - } Item::TypeDef(t) => { let docs = self.docs(&t.docs); let id = self.types.alloc(TypeDef { @@ -340,18 +281,6 @@ impl Resolver { Ok(()) } - fn define_resource(&mut self, name: &str, span: Span, id: ResourceId) -> Result<()> { - if self.resource_lookup.insert(name.to_string(), id).is_some() { - Err(Error { - span, - msg: format!("resource {:?} defined twice", name), - } - .into()) - } else { - Ok(()) - } - } - fn define_type(&mut self, name: &str, span: Span, id: TypeId) -> Result<()> { if self.type_lookup.insert(name.to_string(), id).is_some() { Err(Error { @@ -380,24 +309,17 @@ impl Resolver { super::Type::Char => TypeDefKind::Type(Type::Char), super::Type::String => TypeDefKind::Type(Type::String), super::Type::Name(name) => { - // Because resources are referred to directly by name, - // first check to see if we can look up this name as a - // resource. - if let Some(id) = self.resource_lookup.get(&*name.name) { - TypeDefKind::Type(Type::Handle(*id)) - } else { - let id = match self.type_lookup.get(&*name.name) { - Some(id) => *id, - None => { - return Err(Error { - span: name.span, - msg: format!("no type named `{}`", name.name), - } - .into()) + let id = match self.type_lookup.get(&*name.name) { + Some(id) => *id, + None => { + return Err(Error { + span: name.span, + msg: format!("no type named `{}`", name.name), } - }; - TypeDefKind::Type(Type::Id(id)) - } + .into()) + } + }; + TypeDefKind::Type(Type::Id(id)) } super::Type::List(list) => { let ty = self.resolve_type(list)?; @@ -638,53 +560,6 @@ impl Resolver { } } - fn resolve_resource(&mut self, resource: &super::Resource<'_>) -> Result<()> { - let mut names = HashSet::new(); - let id = self.resource_lookup[&*resource.name.name]; - for (statik, value) in resource.values.iter() { - let (params, results) = match &value.kind { - ValueKind::Function { params, results } => (params, results), - ValueKind::Global(_) => { - return Err(Error { - span: value.name.span, - msg: "globals not allowed in resources".to_string(), - } - .into()); - } - }; - if !names.insert(&value.name.name) { - return Err(Error { - span: value.name.span, - msg: format!("{:?} defined twice in this resource", value.name.name), - } - .into()); - } - let docs = self.docs(&value.docs); - let mut params = self.resolve_params(params)?; - let results = self.resolve_results(results)?; - let kind = if *statik { - FunctionKind::Static { - resource: id, - name: value.name.name.to_string(), - } - } else { - params.insert(0, ("self".to_string(), Type::Handle(id))); - FunctionKind::Method { - resource: id, - name: value.name.name.to_string(), - } - }; - self.functions.push(Function { - docs, - name: format!("{}::{}", resource.name.name, value.name.name), - kind, - params, - results, - }); - } - Ok(()) - } - fn validate_type_not_recursive( &self, span: Span, diff --git a/crates/wit-parser/src/lib.rs b/crates/wit-parser/src/lib.rs index 75b877d16..0394a6009 100644 --- a/crates/wit-parser/src/lib.rs +++ b/crates/wit-parser/src/lib.rs @@ -29,8 +29,6 @@ pub struct Interface { pub module: Option, pub types: Arena, pub type_lookup: HashMap, - pub resources: Arena, - pub resource_lookup: HashMap, pub interfaces: Arena, pub interface_lookup: HashMap, pub functions: Vec, @@ -38,7 +36,6 @@ pub struct Interface { } pub type TypeId = Id; -pub type ResourceId = Id; pub type InterfaceId = Id; #[derive(Debug, Clone, PartialEq)] @@ -82,7 +79,6 @@ pub enum Type { Float64, Char, String, - Handle(ResourceId), Id(TypeId), } @@ -233,16 +229,6 @@ pub struct Docs { pub contents: Option, } -#[derive(Debug, Clone, PartialEq)] -pub struct Resource { - pub docs: Docs, - pub name: String, - pub supertype: Option, - /// `None` if this resource is defined within the containing instance, - /// otherwise `Some` if it's defined in an instance named here. - pub foreign_module: Option, -} - #[derive(Debug, Clone, PartialEq)] pub struct Global { pub docs: Docs, @@ -316,16 +302,12 @@ pub struct Function { #[derive(Debug, Clone, PartialEq)] pub enum FunctionKind { Freestanding, - Static { resource: ResourceId, name: String }, - Method { resource: ResourceId, name: String }, } impl Function { pub fn item_name(&self) -> &str { match &self.kind { FunctionKind::Freestanding => &self.name, - FunctionKind::Static { name, .. } => name, - FunctionKind::Method { name, .. } => name, } } } @@ -536,7 +518,7 @@ impl Interface { | Type::Float32 | Type::Float64 => true, - Type::Bool | Type::Char | Type::Handle(_) | Type::String => false, + Type::Bool | Type::Char | Type::String => false, Type::Id(id) => match &self.types[*id].kind { TypeDefKind::List(_) diff --git a/crates/wit-parser/src/sizealign.rs b/crates/wit-parser/src/sizealign.rs index aa6cc03b1..20c45fee6 100644 --- a/crates/wit-parser/src/sizealign.rs +++ b/crates/wit-parser/src/sizealign.rs @@ -41,7 +41,7 @@ impl SizeAlign { match ty { Type::Bool | Type::U8 | Type::S8 => 1, Type::U16 | Type::S16 => 2, - Type::U32 | Type::S32 | Type::Float32 | Type::Char | Type::Handle(_) => 4, + Type::U32 | Type::S32 | Type::Float32 | Type::Char => 4, Type::U64 | Type::S64 | Type::Float64 | Type::String => 8, Type::Id(id) => self.map[id.index()].0, } @@ -51,9 +51,7 @@ impl SizeAlign { match ty { Type::Bool | Type::U8 | Type::S8 => 1, Type::U16 | Type::S16 => 2, - Type::U32 | Type::S32 | Type::Float32 | Type::Char | Type::Handle(_) | Type::String => { - 4 - } + Type::U32 | Type::S32 | Type::Float32 | Type::Char | Type::String => 4, Type::U64 | Type::S64 | Type::Float64 => 8, Type::Id(id) => self.map[id.index()].1, } diff --git a/crates/wit-parser/tests/all.rs b/crates/wit-parser/tests/all.rs index c46e91d6f..f3778e665 100644 --- a/crates/wit-parser/tests/all.rs +++ b/crates/wit-parser/tests/all.rs @@ -168,8 +168,6 @@ impl Runner<'_> { fn to_json(i: &Interface) -> String { #[derive(Serialize)] struct Interface { - #[serde(skip_serializing_if = "Vec::is_empty")] - resources: Vec, #[serde(skip_serializing_if = "Vec::is_empty")] types: Vec, #[serde(skip_serializing_if = "Vec::is_empty")] @@ -246,16 +244,6 @@ fn to_json(i: &Interface) -> String { ty: String, } - let resources = i - .resources - .iter() - .map(|(_, r)| Resource { - name: r.name.clone(), - supertype: r.supertype.as_ref().map(|supertype| supertype.clone()), - foreign_module: r.foreign_module.clone(), - }) - .collect::>(); - let types = i .types .iter() @@ -289,7 +277,6 @@ fn to_json(i: &Interface) -> String { .collect::>(); let iface = Interface { - resources, types, functions, globals, @@ -355,7 +342,6 @@ fn to_json(i: &Interface) -> String { Type::Float64 => format!("float64"), Type::Char => format!("char"), Type::String => format!("string"), - Type::Handle(resource) => format!("handle-{}", resource.index()), Type::Id(id) => format!("type-{}", id.index()), } } diff --git a/crates/wit-parser/tests/ui/comments.wit b/crates/wit-parser/tests/ui/comments.wit index 621acc164..590ae0d32 100644 --- a/crates/wit-parser/tests/ui/comments.wit +++ b/crates/wit-parser/tests/ui/comments.wit @@ -5,6 +5,7 @@ /* this too */ /* is a comment */ /* this /* is /* a */ nested */ comment */ +type x = u32 type /* foo */ bar /* baz */ = // stream < // @@ -18,4 +19,3 @@ x > -resource /* x */ x // ... diff --git a/crates/wit-parser/tests/ui/comments.wit.result b/crates/wit-parser/tests/ui/comments.wit.result index 069a9e732..fd64607c3 100644 --- a/crates/wit-parser/tests/ui/comments.wit.result +++ b/crates/wit-parser/tests/ui/comments.wit.result @@ -1,21 +1,17 @@ { - "resources": [ - { - "name": "x" - } - ], "types": [ { "idx": 0, + "name": "x", + "primitive": "u32" + }, + { + "idx": 1, "name": "bar", "stream": { - "element": "handle-0", + "element": "type-0", "end": null } - }, - { - "idx": 1, - "primitive": "handle-0" } ] } \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/import-me-too.wit.md b/crates/wit-parser/tests/ui/import-me-too.wit.md index 189116a79..aebde3c02 100644 --- a/crates/wit-parser/tests/ui/import-me-too.wit.md +++ b/crates/wit-parser/tests/ui/import-me-too.wit.md @@ -9,17 +9,6 @@ code blocks. type foo = u32 ``` -## `x` -```wit -/// This is x. -resource x -``` - -## `handle` -```wit -/// This is handle. -type handle = x -``` ## `some-record` ```wit diff --git a/crates/wit-parser/tests/ui/import-me-too.wit.md.result b/crates/wit-parser/tests/ui/import-me-too.wit.md.result index 94a04f5eb..154da7deb 100644 --- a/crates/wit-parser/tests/ui/import-me-too.wit.md.result +++ b/crates/wit-parser/tests/ui/import-me-too.wit.md.result @@ -1,9 +1,4 @@ { - "resources": [ - { - "name": "x" - } - ], "types": [ { "idx": 0, @@ -12,15 +7,6 @@ }, { "idx": 1, - "primitive": "handle-0" - }, - { - "idx": 2, - "name": "handle", - "primitive": "handle-0" - }, - { - "idx": 3, "name": "some-record", "tuple": { "types": [ diff --git a/crates/wit-parser/tests/ui/import-me.wit b/crates/wit-parser/tests/ui/import-me.wit index 816a8f6e1..85c784265 100644 --- a/crates/wit-parser/tests/ui/import-me.wit +++ b/crates/wit-parser/tests/ui/import-me.wit @@ -1,7 +1,2 @@ type foo = u32 - -resource x - -type handle = x - type some-record = tuple diff --git a/crates/wit-parser/tests/ui/import-me.wit.result b/crates/wit-parser/tests/ui/import-me.wit.result index 94a04f5eb..154da7deb 100644 --- a/crates/wit-parser/tests/ui/import-me.wit.result +++ b/crates/wit-parser/tests/ui/import-me.wit.result @@ -1,9 +1,4 @@ { - "resources": [ - { - "name": "x" - } - ], "types": [ { "idx": 0, @@ -12,15 +7,6 @@ }, { "idx": 1, - "primitive": "handle-0" - }, - { - "idx": 2, - "name": "handle", - "primitive": "handle-0" - }, - { - "idx": 3, "name": "some-record", "tuple": { "types": [ diff --git a/crates/wit-parser/tests/ui/imports-from-wit-md.wit b/crates/wit-parser/tests/ui/imports-from-wit-md.wit index b7263bebe..a89aaf3bc 100644 --- a/crates/wit-parser/tests/ui/imports-from-wit-md.wit +++ b/crates/wit-parser/tests/ui/imports-from-wit-md.wit @@ -3,14 +3,8 @@ use { foo } from import-me-too use { foo as bar } from import-me-too -use { x as import-me-x } from import-me-too type x = foo type y = bar -type z = import-me-x - -use { handle } from import-me-too -resource xyz -type my-handle = xyz use { some-record } from import-me-too diff --git a/crates/wit-parser/tests/ui/imports-from-wit-md.wit.result b/crates/wit-parser/tests/ui/imports-from-wit-md.wit.result index d39682f46..6cdd63e74 100644 --- a/crates/wit-parser/tests/ui/imports-from-wit-md.wit.result +++ b/crates/wit-parser/tests/ui/imports-from-wit-md.wit.result @@ -1,13 +1,4 @@ { - "resources": [ - { - "name": "x", - "foreign_module": "import-me-too" - }, - { - "name": "xyz" - } - ], "types": [ { "idx": 0, @@ -17,17 +8,6 @@ }, { "idx": 1, - "primitive": "handle-0", - "foreign_module": "import-me-too" - }, - { - "idx": 2, - "name": "handle", - "primitive": "handle-0", - "foreign_module": "import-me-too" - }, - { - "idx": 3, "name": "some-record", "tuple": { "types": [ @@ -39,28 +19,14 @@ "foreign_module": "import-me-too" }, { - "idx": 4, + "idx": 2, "name": "x", "primitive": "type-0" }, { - "idx": 5, + "idx": 3, "name": "y", "primitive": "type-0" - }, - { - "idx": 6, - "name": "z", - "primitive": "handle-0" - }, - { - "idx": 7, - "primitive": "handle-1" - }, - { - "idx": 8, - "name": "my-handle", - "primitive": "handle-1" } ] } \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/imports.wit b/crates/wit-parser/tests/ui/imports.wit index 6d864d413..7b9ef0d6c 100644 --- a/crates/wit-parser/tests/ui/imports.wit +++ b/crates/wit-parser/tests/ui/imports.wit @@ -1,13 +1,8 @@ use { foo } from import-me use { foo as bar } from import-me -use { x as import-me-x } from import-me type x = foo type y = bar -type z1 = import-me-x -use { handle } from import-me -resource xyz -type my-handle = xyz use { some-record } from import-me diff --git a/crates/wit-parser/tests/ui/imports.wit.result b/crates/wit-parser/tests/ui/imports.wit.result index 5ff1344d9..316124898 100644 --- a/crates/wit-parser/tests/ui/imports.wit.result +++ b/crates/wit-parser/tests/ui/imports.wit.result @@ -1,13 +1,4 @@ { - "resources": [ - { - "name": "x", - "foreign_module": "import-me" - }, - { - "name": "xyz" - } - ], "types": [ { "idx": 0, @@ -17,17 +8,6 @@ }, { "idx": 1, - "primitive": "handle-0", - "foreign_module": "import-me" - }, - { - "idx": 2, - "name": "handle", - "primitive": "handle-0", - "foreign_module": "import-me" - }, - { - "idx": 3, "name": "some-record", "tuple": { "types": [ @@ -39,28 +19,14 @@ "foreign_module": "import-me" }, { - "idx": 4, + "idx": 2, "name": "x", "primitive": "type-0" }, { - "idx": 5, + "idx": 3, "name": "y", "primitive": "type-0" - }, - { - "idx": 6, - "name": "z1", - "primitive": "handle-0" - }, - { - "idx": 7, - "primitive": "handle-1" - }, - { - "idx": 8, - "name": "my-handle", - "primitive": "handle-1" } ] } \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/imports2.wit b/crates/wit-parser/tests/ui/imports2.wit index 709ed2f24..c7ba24134 100644 --- a/crates/wit-parser/tests/ui/imports2.wit +++ b/crates/wit-parser/tests/ui/imports2.wit @@ -1,3 +1,3 @@ use * from import-me -type my-handle = x +type my-handle = some-record diff --git a/crates/wit-parser/tests/ui/imports2.wit.result b/crates/wit-parser/tests/ui/imports2.wit.result index 6db867b07..5e02058fc 100644 --- a/crates/wit-parser/tests/ui/imports2.wit.result +++ b/crates/wit-parser/tests/ui/imports2.wit.result @@ -1,10 +1,4 @@ { - "resources": [ - { - "name": "x", - "foreign_module": "import-me" - } - ], "types": [ { "idx": 0, @@ -14,12 +8,6 @@ }, { "idx": 1, - "name": "handle", - "primitive": "handle-0", - "foreign_module": "import-me" - }, - { - "idx": 2, "name": "some-record", "tuple": { "types": [ @@ -31,14 +19,9 @@ "foreign_module": "import-me" }, { - "idx": 3, - "primitive": "handle-0", - "foreign_module": "import-me" - }, - { - "idx": 4, + "idx": 2, "name": "my-handle", - "primitive": "handle-0" + "primitive": "type-1" } ] } \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-resource.wit b/crates/wit-parser/tests/ui/parse-fail/bad-resource.wit deleted file mode 100644 index f2a8e1346..000000000 --- a/crates/wit-parser/tests/ui/parse-fail/bad-resource.wit +++ /dev/null @@ -1,5 +0,0 @@ -// parse-fail - -resource x { - x: s32 -} diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-resource.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-resource.wit.result deleted file mode 100644 index 2c6572b6a..000000000 --- a/crates/wit-parser/tests/ui/parse-fail/bad-resource.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -globals not allowed in resources - --> tests/ui/parse-fail/bad-resource.wit:4:3 - | - 4 | x: s32 - | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-resource2.wit b/crates/wit-parser/tests/ui/parse-fail/bad-resource2.wit deleted file mode 100644 index 585045a38..000000000 --- a/crates/wit-parser/tests/ui/parse-fail/bad-resource2.wit +++ /dev/null @@ -1,6 +0,0 @@ -// parse-fail - -resource x { - x: func() - x: func() -} diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-resource2.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-resource2.wit.result deleted file mode 100644 index 661e879fe..000000000 --- a/crates/wit-parser/tests/ui/parse-fail/bad-resource2.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -"x" defined twice in this resource - --> tests/ui/parse-fail/bad-resource2.wit:5:3 - | - 5 | x: func() - | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-resource.wit b/crates/wit-parser/tests/ui/parse-fail/duplicate-resource.wit deleted file mode 100644 index 336ea11cb..000000000 --- a/crates/wit-parser/tests/ui/parse-fail/duplicate-resource.wit +++ /dev/null @@ -1,4 +0,0 @@ -// parse-fail - -resource a -resource a diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-resource.wit.result b/crates/wit-parser/tests/ui/parse-fail/duplicate-resource.wit.result deleted file mode 100644 index 287fbade5..000000000 --- a/crates/wit-parser/tests/ui/parse-fail/duplicate-resource.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -resource "a" defined twice - --> tests/ui/parse-fail/duplicate-resource.wit:4:10 - | - 4 | resource a - | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/import-bad3.wit b/crates/wit-parser/tests/ui/parse-fail/import-bad3.wit index e9ad08f68..aa749d894 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-bad3.wit +++ b/crates/wit-parser/tests/ui/parse-fail/import-bad3.wit @@ -1,3 +1,3 @@ // parse-fail -use { bar } from import-me -use { bar } from import-me +use { foo } from import-me +use { foo } from import-me diff --git a/crates/wit-parser/tests/ui/parse-fail/import-bad3.wit.result b/crates/wit-parser/tests/ui/parse-fail/import-bad3.wit.result index 1d5035c93..41d5ebdc8 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-bad3.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/import-bad3.wit.result @@ -1,5 +1,5 @@ -resource "bar" defined twice +type "foo" defined twice --> tests/ui/parse-fail/import-bad3.wit:3:7 | - 3 | use { bar } from import-me + 3 | use { foo } from import-me | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/import-bad4.wit b/crates/wit-parser/tests/ui/parse-fail/import-bad4.wit index 0a5b19e20..7685afd99 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-bad4.wit +++ b/crates/wit-parser/tests/ui/parse-fail/import-bad4.wit @@ -1,2 +1,2 @@ // parse-fail -use { bar, bar } from import-me +use { foo, foo } from import-me diff --git a/crates/wit-parser/tests/ui/parse-fail/import-bad4.wit.result b/crates/wit-parser/tests/ui/parse-fail/import-bad4.wit.result index 2c136e049..83e3150dc 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-bad4.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/import-bad4.wit.result @@ -1,5 +1,5 @@ -resource "bar" defined twice +type "foo" defined twice --> tests/ui/parse-fail/import-bad4.wit:2:12 | - 2 | use { bar, bar } from import-me + 2 | use { foo, foo } from import-me | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/import-me.wit b/crates/wit-parser/tests/ui/parse-fail/import-me.wit index fe776fa4c..e4e4f1a97 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-me.wit +++ b/crates/wit-parser/tests/ui/parse-fail/import-me.wit @@ -1,2 +1 @@ type foo = u32 -resource bar diff --git a/crates/wit-parser/tests/ui/parse-fail/import-me.wit.result b/crates/wit-parser/tests/ui/parse-fail/import-me.wit.result index 915fe49b0..ce5b16ea4 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-me.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/import-me.wit.result @@ -1,18 +1,9 @@ { - "resources": [ - { - "name": "bar" - } - ], "types": [ { "idx": 0, "name": "foo", "primitive": "u32" - }, - { - "idx": 1, - "primitive": "handle-0" } ] } \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/resource.wit b/crates/wit-parser/tests/ui/resource.wit deleted file mode 100644 index ceb5a1eb4..000000000 --- a/crates/wit-parser/tests/ui/resource.wit +++ /dev/null @@ -1,16 +0,0 @@ -resource a -resource b -resource c -resource d {} -resource e { - x: func() -} -resource f { - x: func() - y: func() -} -resource g implements a -resource h implements b {} -resource i implements e { - z: func() -} diff --git a/crates/wit-parser/tests/ui/resource.wit.result b/crates/wit-parser/tests/ui/resource.wit.result deleted file mode 100644 index 77ca4b912..000000000 --- a/crates/wit-parser/tests/ui/resource.wit.result +++ /dev/null @@ -1,102 +0,0 @@ -{ - "resources": [ - { - "name": "a" - }, - { - "name": "b" - }, - { - "name": "c" - }, - { - "name": "d" - }, - { - "name": "e" - }, - { - "name": "f" - }, - { - "name": "g", - "supertype": "a" - }, - { - "name": "h", - "supertype": "b" - }, - { - "name": "i", - "supertype": "e" - } - ], - "types": [ - { - "idx": 0, - "primitive": "handle-0" - }, - { - "idx": 1, - "primitive": "handle-1" - }, - { - "idx": 2, - "primitive": "handle-2" - }, - { - "idx": 3, - "primitive": "handle-3" - }, - { - "idx": 4, - "primitive": "handle-4" - }, - { - "idx": 5, - "primitive": "handle-5" - }, - { - "idx": 6, - "primitive": "handle-6" - }, - { - "idx": 7, - "primitive": "handle-7" - }, - { - "idx": 8, - "primitive": "handle-8" - } - ], - "functions": [ - { - "name": "e::x", - "params": [ - "handle-4" - ], - "results": [] - }, - { - "name": "f::x", - "params": [ - "handle-5" - ], - "results": [] - }, - { - "name": "f::y", - "params": [ - "handle-5" - ], - "results": [] - }, - { - "name": "i::z", - "params": [ - "handle-8" - ], - "results": [] - } - ] -} \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/types.wit b/crates/wit-parser/tests/ui/types.wit index 18ad670a6..594be5cf1 100644 --- a/crates/wit-parser/tests/ui/types.wit +++ b/crates/wit-parser/tests/ui/types.wit @@ -1,5 +1,3 @@ -resource x - type t1 = u8 type t2 = u16 type t3 = u32 @@ -18,13 +16,12 @@ type t15 = result type t16 = result<_, u32> type t17 = result type t18 = result -type t19 = x record t20 {} record t21 { a: u32 } record t22 { a: u32, } record t23 { a: u32, b: u64 } record t24 { a: u32, b: u64, } -record t25 { %x: u32 } +record t25 { x: u32 } record %record {} type t26 = tuple<> type t27 = tuple diff --git a/crates/wit-parser/tests/ui/types.wit.result b/crates/wit-parser/tests/ui/types.wit.result index e9ae53339..a66b37ee4 100644 --- a/crates/wit-parser/tests/ui/types.wit.result +++ b/crates/wit-parser/tests/ui/types.wit.result @@ -1,86 +1,77 @@ { - "resources": [ - { - "name": "x" - } - ], "types": [ { "idx": 0, - "primitive": "handle-0" - }, - { - "idx": 1, "name": "t1", "primitive": "u8" }, { - "idx": 2, + "idx": 1, "name": "t2", "primitive": "u16" }, { - "idx": 3, + "idx": 2, "name": "t3", "primitive": "u32" }, { - "idx": 4, + "idx": 3, "name": "t4", "primitive": "u64" }, { - "idx": 5, + "idx": 4, "name": "t5", "primitive": "s8" }, { - "idx": 6, + "idx": 5, "name": "t6", "primitive": "s16" }, { - "idx": 7, + "idx": 6, "name": "t7", "primitive": "s32" }, { - "idx": 8, + "idx": 7, "name": "t8", "primitive": "s64" }, { - "idx": 9, + "idx": 8, "name": "t9", "primitive": "float32" }, { - "idx": 10, + "idx": 9, "name": "t10", "primitive": "float64" }, { - "idx": 11, + "idx": 10, "name": "t11", "primitive": "char" }, { - "idx": 12, + "idx": 11, "name": "t12", "list": "char" }, { - "idx": 13, + "idx": 12, "name": "t13", "primitive": "string" }, { - "idx": 14, + "idx": 13, "name": "t14", "option": "u32" }, { - "idx": 15, + "idx": 14, "name": "t15", "result": { "ok": "u32", @@ -88,7 +79,7 @@ } }, { - "idx": 16, + "idx": 15, "name": "t16", "result": { "ok": null, @@ -96,7 +87,7 @@ } }, { - "idx": 17, + "idx": 16, "name": "t17", "result": { "ok": "u32", @@ -104,7 +95,7 @@ } }, { - "idx": 18, + "idx": 17, "name": "t18", "result": { "ok": null, @@ -112,19 +103,14 @@ } }, { - "idx": 19, - "name": "t19", - "primitive": "handle-0" - }, - { - "idx": 20, + "idx": 18, "name": "t20", "record": { "fields": [] } }, { - "idx": 21, + "idx": 19, "name": "t21", "record": { "fields": [ @@ -136,7 +122,7 @@ } }, { - "idx": 22, + "idx": 20, "name": "t22", "record": { "fields": [ @@ -148,7 +134,7 @@ } }, { - "idx": 23, + "idx": 21, "name": "t23", "record": { "fields": [ @@ -164,7 +150,7 @@ } }, { - "idx": 24, + "idx": 22, "name": "t24", "record": { "fields": [ @@ -180,7 +166,7 @@ } }, { - "idx": 25, + "idx": 23, "name": "t25", "record": { "fields": [ @@ -192,21 +178,21 @@ } }, { - "idx": 26, + "idx": 24, "name": "record", "record": { "fields": [] } }, { - "idx": 27, + "idx": 25, "name": "t26", "tuple": { "types": [] } }, { - "idx": 28, + "idx": 26, "name": "t27", "tuple": { "types": [ @@ -215,7 +201,7 @@ } }, { - "idx": 29, + "idx": 27, "name": "t28", "tuple": { "types": [ @@ -224,7 +210,7 @@ } }, { - "idx": 30, + "idx": 28, "name": "t29", "tuple": { "types": [ @@ -234,14 +220,14 @@ } }, { - "idx": 31, + "idx": 29, "name": "t30", "flags": { "flags": [] } }, { - "idx": 32, + "idx": 30, "name": "t31", "flags": { "flags": [ @@ -252,7 +238,7 @@ } }, { - "idx": 33, + "idx": 31, "name": "t32", "flags": { "flags": [ @@ -263,7 +249,7 @@ } }, { - "idx": 34, + "idx": 32, "name": "t33", "variant": { "cases": [ @@ -275,7 +261,7 @@ } }, { - "idx": 35, + "idx": 33, "name": "t34", "variant": { "cases": [ @@ -291,7 +277,7 @@ } }, { - "idx": 36, + "idx": 34, "name": "t35", "variant": { "cases": [ @@ -307,7 +293,7 @@ } }, { - "idx": 37, + "idx": 35, "name": "t36", "variant": { "cases": [ @@ -323,7 +309,7 @@ } }, { - "idx": 38, + "idx": 36, "name": "t37", "variant": { "cases": [ @@ -333,13 +319,13 @@ ], [ "b", - "type-57" + "type-55" ] ] } }, { - "idx": 39, + "idx": 37, "name": "t38", "union": { "cases": [ @@ -349,27 +335,27 @@ } }, { - "idx": 40, + "idx": 38, "name": "t39", "union": { "cases": [ "u32", - "type-57" + "type-55" ] } }, { - "idx": 41, + "idx": 39, "name": "t40", "union": { "cases": [ "u32", - "type-57" + "type-55" ] } }, { - "idx": 42, + "idx": 40, "name": "t41", "enum": { "cases": [ @@ -380,7 +366,7 @@ } }, { - "idx": 43, + "idx": 41, "name": "t42", "enum": { "cases": [ @@ -391,32 +377,32 @@ } }, { - "idx": 44, + "idx": 42, "name": "t43", "primitive": "bool" }, { - "idx": 45, + "idx": 43, "name": "t44", "primitive": "string" }, { - "idx": 46, + "idx": 44, "name": "t45", - "list": "type-59" + "list": "type-57" }, { - "idx": 47, + "idx": 45, "name": "t46", - "primitive": "type-45" + "primitive": "type-43" }, { - "idx": 48, + "idx": 46, "name": "t47", - "primitive": "type-45" + "primitive": "type-43" }, { - "idx": 49, + "idx": 47, "name": "t48", "stream": { "element": "u32", @@ -424,7 +410,7 @@ } }, { - "idx": 50, + "idx": 48, "name": "t49", "stream": { "element": null, @@ -432,7 +418,7 @@ } }, { - "idx": 51, + "idx": 49, "name": "t50", "stream": { "element": "u32", @@ -440,7 +426,7 @@ } }, { - "idx": 52, + "idx": 50, "name": "t51", "stream": { "element": null, @@ -448,36 +434,36 @@ } }, { - "idx": 53, + "idx": 51, "name": "t52", "future": "u32" }, { - "idx": 54, + "idx": 52, "name": "t53", "future": null }, { - "idx": 55, + "idx": 53, "name": "foo", - "primitive": "type-56" + "primitive": "type-54" }, { - "idx": 56, + "idx": 54, "name": "bar", "primitive": "u32" }, { - "idx": 57, + "idx": 55, "option": "u32" }, { - "idx": 58, - "list": "type-33" + "idx": 56, + "list": "type-31" }, { - "idx": 59, - "list": "type-58" + "idx": 57, + "list": "type-56" } ] } \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/wasi-http.wit b/crates/wit-parser/tests/ui/wasi-http.wit deleted file mode 100644 index a0c50d789..000000000 --- a/crates/wit-parser/tests/ui/wasi-http.wit +++ /dev/null @@ -1,158 +0,0 @@ -// Note: this note isn't a doc comment. - -// Note: the following comment block is a doc comment, because it start with `///`. -// It's also a comment about the interface defined in this file, because it starts with `@interface` - -/// @interface WASI HTTP Core functionality. -/// -/// Defines requests & responses and associated types, and `fetch`. - -// `use` imports things from namespaces. The first identifier of an `ident1::ident2::[..]::identN` -// namespace chain needs to be resolved out of band. The remaining part of the chain is resolved -// as nested interfaces inside the definition of `ident1`. -// Note: I'm not sure if Result should just be an Interface Types thing instead of a WASI thing. -//use { Result, Option } from wasi::core - -/// A blocking function for turning requests into responses. -/// @param req - a `request` object to process -/// @return resp - the `Result` object produced once the blocking operation has finished. -// -// Note: the syntax for function definitions is chosen with three goals in mind: -// -// 1. maximizing human parseability and intuitive understanding, by not presupposing -// familiarity with any specific notations. Having the `function` keyword isn't otherwise -// strictly required for disambiguation. This becomes even more important given that part of -// the "weirdness budget" needs to be used for having support for multiple return values. -// -// 2. uniformity in the face of multiple return values. Basically, it's always a mapping -// of N arguments to M return values, with the same syntax for both. -// -// 3. provide an obvious place for adding attributes, like `blocking` and `reentrant`. -// -// Note: the `blocking` attribute means that different lowering can be generated for this -// function, either based on synchronous, blocking calls, or on a callback-style interface. -fetch: /*blocking*/ func(req: request) -> response - -/// A request resource, with lots of things missing for now. -// Note: `resource` blocks serve two purposes: -// 1. namespacing the definition of a Handle type with functions for operating on that handle -// 2. providing a way to define said functions such that they implicitly take the handle itself as -// the first argument. E.g., `method` in `request` is roughly equivalent to -// `request::method: func(self: request) -> (string)` -// ("Roughly" because the `resource` semantics allow us to generate better bindings for languages -// that have a concept of implicit receivers, such as `this` in JS.) -resource request { - - /// A static function acting as a constructor - /// @return req - returns a new `request` - // Note: `static` here simply means that no implicit receiver argument will be passed. - // I.e., this is ~roughly~ analogous to a top-level definition of - // `request::request: func() -> (req: request)` - // whereas without `static`, it'd be analogous to - // `request::request: func(self: request) -> (req: request)` - static request: func() -> request - - method: func() -> string - - // Note: We could consider allowing the parens to be omitted for single return values, like so: - headers: func() -> headers - - // Note: Or we could even allow leaving off the return value identifier, making it use the - // function name, like so: - body: func() -> body // This return type would be shorthand for `(body: body)` -} - -/// A response resource, with lots of things missing for now. -resource response { - status: func() -> u16 - headers: func() -> headers - body: func() -> body -} - -/// A headers resource, with lots of things missing for now. -resource headers { - /// Return values for the given header name. - /// @param name - the header's name. - /// @return values - the values for this header, seperated by ", " - // Note: in reality, it might make sense for the values to be a sequence of some kind. - get: func(name: string) -> option -} - -/// A body resource. -/// Bodies are interesting in that they can be both sources and sinks, on both requests and responses. -resource body { - /// Read from a body. - /// @param dest - destination buffer to write into - /// @return result - a result containing the number of bytes written on success - // TODO: check if `out-buffer` is the right way to express this - read: func(dest: list) -> result - - /// Write to a body. - /// @param source - source buffer to read from - /// @return result - a result containing the number of bytes read on success - // TODO: check if `in-buffer` is the right way to express this - write: func(source: list) -> result -} -/* - -/// A nested interface, doing something neat and elaborate. -interface nested-interface1 { - /// An even better request resource than the one everybody's using. - resource better-request { - // TODO: do we need to have a ctor with special semantics? E.g. to generate actual - // constructors for languages that have them, such as JS? - new: func(request: request) -> better-request - // Note: sadly, the sauce better-request uses must remain secret, so it doesn't actually - // expose any of its functionality, and hence doesn't need any other methods. - } - /// Maps a request to an even better request. - // Note: the containing scope's members are in scope in a nested interface - fun: func(request: request) -> response -} - -/// Another nested interface, doing something even more neat and elaborate. -/// It does this by adding shiny stuff to what nested-interface1 is doing. -interface nested-interface2 { - // Note: as mentioned in the comment on this file's first `use` statement, the first - // ident in a namespace chain needs to be resolved out of band. `self` is an exception to - // this rule, and allows referring to the outermost containing scope. - use self::nested-interface1::better-request - - /// The secret sauce. It's so secret and magic that you're not allowed to touch it, quite sadly. - resource the-shiny { - } - - /// Maps a better request to a plain old response. - /// @param request - the already pretty good request to add the shiny to - /// @return response - a boring, normal response - /// @return added-shiny - the shiny! - // Note: this just exists to demonstrate multiple return values, including their documentation - fun: func(request: better-request) -> tuple -} -*/ - -/// An enum with some values -// Note: should we have a way to declare the underlying representation, along the lines of -// `enum error: u8 {..}`? -// Note: what about non-numeric types? -// Note: what about heterogeneous enums? -enum error { - overflow, - unavailable, -} - -/// A function returning a Result, with the enum above as one of the options -/// @return result - a `Result` containing either the desired number, or an `error` -maybe-number: func() -> result - -/// A simple struct -record timestamp { - seconds: u64, - nanoseconds: u64, -} - -/// A simple value -my-int: u32 - -/// A handle to a request -my-request: request diff --git a/crates/wit-parser/tests/ui/wasi-http.wit.result b/crates/wit-parser/tests/ui/wasi-http.wit.result deleted file mode 100644 index 52cf7a8cc..000000000 --- a/crates/wit-parser/tests/ui/wasi-http.wit.result +++ /dev/null @@ -1,194 +0,0 @@ -{ - "resources": [ - { - "name": "request" - }, - { - "name": "response" - }, - { - "name": "headers" - }, - { - "name": "body" - } - ], - "types": [ - { - "idx": 0, - "primitive": "handle-0" - }, - { - "idx": 1, - "primitive": "handle-1" - }, - { - "idx": 2, - "primitive": "handle-2" - }, - { - "idx": 3, - "primitive": "handle-3" - }, - { - "idx": 4, - "name": "error", - "enum": { - "cases": [ - "overflow", - "unavailable" - ] - } - }, - { - "idx": 5, - "name": "timestamp", - "record": { - "fields": [ - [ - "seconds", - "u64" - ], - [ - "nanoseconds", - "u64" - ] - ] - } - }, - { - "idx": 6, - "option": "string" - }, - { - "idx": 7, - "list": "u8" - }, - { - "idx": 8, - "result": { - "ok": "u64", - "err": "type-4" - } - } - ], - "functions": [ - { - "name": "fetch", - "params": [ - "handle-0" - ], - "results": [ - "handle-1" - ] - }, - { - "name": "request::request", - "params": [], - "results": [ - "handle-0" - ] - }, - { - "name": "request::method", - "params": [ - "handle-0" - ], - "results": [ - "string" - ] - }, - { - "name": "request::headers", - "params": [ - "handle-0" - ], - "results": [ - "handle-2" - ] - }, - { - "name": "request::body", - "params": [ - "handle-0" - ], - "results": [ - "handle-3" - ] - }, - { - "name": "response::status", - "params": [ - "handle-1" - ], - "results": [ - "u16" - ] - }, - { - "name": "response::headers", - "params": [ - "handle-1" - ], - "results": [ - "handle-2" - ] - }, - { - "name": "response::body", - "params": [ - "handle-1" - ], - "results": [ - "handle-3" - ] - }, - { - "name": "headers::get", - "params": [ - "handle-2", - "string" - ], - "results": [ - "type-6" - ] - }, - { - "name": "body::read", - "params": [ - "handle-3", - "type-7" - ], - "results": [ - "type-8" - ] - }, - { - "name": "body::write", - "params": [ - "handle-3", - "type-7" - ], - "results": [ - "type-8" - ] - }, - { - "name": "maybe-number", - "params": [], - "results": [ - "type-8" - ] - } - ], - "globals": [ - { - "name": "my-int", - "ty": "u32" - }, - { - "name": "my-request", - "ty": "handle-0" - } - ] -} \ No newline at end of file diff --git a/tests/codegen/resource.wit b/tests/codegen/resource.wit deleted file mode 100644 index 3c87154f5..000000000 --- a/tests/codegen/resource.wit +++ /dev/null @@ -1,11 +0,0 @@ -resource x - -acquire-an-x: func() -> x -receive-an-x: func(val: x) - -resource y { - static some-constructor: func() -> y - method-on-y: func() - method-with-param: func(x: u32) - method-with-result: func() -> string -} diff --git a/tests/runtime/handles/exports.wit b/tests/runtime/handles/exports.wit deleted file mode 100644 index cc6aab0f7..000000000 --- a/tests/runtime/handles/exports.wit +++ /dev/null @@ -1,53 +0,0 @@ -test-imports: func() - -resource wasm-state -resource wasm-state2 - -wasm-state-create: func() -> wasm-state -wasm-state-get-val: func(a: wasm-state) -> u32 - -wasm-state2-create: func() -> wasm-state2 -wasm-state2-saw-close: func() -> bool -two-wasm-states: func(a: wasm-state, b: wasm-state2) -> (a: wasm-state, b: wasm-state2) - -record wasm-state-param-record { a: wasm-state2 } -wasm-state2-param-record: func(a: wasm-state-param-record) - -type wasm-state-param-tuple = tuple -wasm-state2-param-tuple: func(a: wasm-state-param-tuple) - -type wasm-state-param-option = option -wasm-state2-param-option: func(a: wasm-state-param-option) - -type wasm-state-param-result = result -wasm-state2-param-result: func(a: wasm-state-param-result) - -union wasm-state-param-variant { wasm-state2, u32 } -wasm-state2-param-variant: func(a: wasm-state-param-variant) - -wasm-state2-param-list: func(a: list) - - -record wasm-state-result-record { a: wasm-state2 } -wasm-state2-result-record: func() -> wasm-state-result-record - -type wasm-state-result-tuple = tuple -wasm-state2-result-tuple: func() -> wasm-state-result-tuple - -type wasm-state-result-option = option -wasm-state2-result-option: func() -> wasm-state-result-option - -type wasm-state-result-result = result -wasm-state2-result-result: func() -> wasm-state-result-result - -union wasm-state-result-variant { wasm-state2, u32 } -wasm-state2-result-variant: func() -> wasm-state-result-variant - -wasm-state2-result-list: func() -> list - -resource markdown { - static create: func() -> option - append: func(buf: string) - render: func() -> string -} - diff --git a/tests/runtime/handles/host.py b/tests/runtime/handles/host.py deleted file mode 100644 index e2ff01965..000000000 --- a/tests/runtime/handles/host.py +++ /dev/null @@ -1,189 +0,0 @@ -from dataclasses import dataclass -from exports.bindings import Exports -from imports.bindings import add_imports_to_linker, Imports -from typing import Tuple, List -import exports.bindings as e -import imports.bindings as i -import sys -import wasmtime - -@dataclass -class HostState(i.HostState): - val: int - - def __init__(self, val: int) -> None: - self.val = val - - def drop(self) -> None: - pass - - -HOST_STATE2_CLOSED = False - - -@dataclass -class HostState2(i.HostState2): - val: int - - def __init__(self, val: int) -> None: - self.val = val - - def drop(self) -> None: - global HOST_STATE2_CLOSED - HOST_STATE2_CLOSED = True - - -@dataclass -class Markdown(i.Markdown2): - buf: str = '' - - def append(self, data: str) -> None: - self.buf += data - - def render(self) -> str: - return self.buf.replace('red', 'green') - - def drop(self) -> None: - pass - - -class OddName(i.OddName): - def frob_the_odd(self) -> None: - pass - - def drop(self) -> None: - pass - - -class MyImports: - def host_state_create(self) -> i.HostState: - return HostState(100) - - def host_state_get(self, a: i.HostState) -> int: - assert(isinstance(a, HostState)) - return a.val - - def host_state2_create(self) -> i.HostState2: - return HostState2(101) - - def host_state2_saw_close(self) -> bool: - return HOST_STATE2_CLOSED - - def two_host_states(self, a: i.HostState, b: i.HostState2) -> Tuple[i.HostState, i.HostState2]: - return (b, a) - - def host_state2_param_record(self, a: i.HostStateParamRecord) -> None: - pass - - def host_state2_param_tuple(self, a: i.HostStateParamTuple) -> None: - pass - - def host_state2_param_option(self, a: i.HostStateParamOption) -> None: - pass - - def host_state2_param_result(self, a: i.HostStateParamResult) -> None: - pass - - def host_state2_param_variant(self, a: i.HostStateParamVariant) -> None: - pass - - def host_state2_param_list(self, a: List[i.HostState2]) -> None: - pass - - def host_state2_result_record(self) -> i.HostStateResultRecord: - return i.HostStateResultRecord(HostState(2)) - - def host_state2_result_tuple(self) -> i.HostStateResultTuple: - return (HostState(2),) - - def host_state2_result_option(self) -> i.HostStateResultOption: - return HostState(2) - - def host_state2_result_result(self) -> i.HostStateResultResult: - return i.Ok(HostState2(2)) - - def host_state2_result_variant(self) -> i.HostStateResultVariant: - return HostState2(2) - - def host_state2_result_list(self) -> List[i.HostState2]: - return [HostState2(2), HostState2(5)] - - def markdown2_create(self) -> i.Markdown2: - return Markdown() - - def odd_name_create(self) -> i.OddName: - return OddName() - -def run(wasm_file: str) -> None: - store = wasmtime.Store() - module = wasmtime.Module.from_file(store.engine, wasm_file) - linker = wasmtime.Linker(store.engine) - linker.define_wasi() - wasi = wasmtime.WasiConfig() - wasi.inherit_stdout() - wasi.inherit_stderr() - store.set_wasi(wasi) - - imports = MyImports() - add_imports_to_linker(linker, store, imports) - wasm = Exports(store, linker, module) - - wasm.test_imports(store) - - # Param/result of a handle works in a simple fashion - s: e.WasmState = wasm.wasm_state_create(store) - assert(wasm.wasm_state_get_val(store, s) == 100) - - # Deterministic destruction is possible - assert(wasm.wasm_state2_saw_close(store) == False) - s2: e.WasmState2 = wasm.wasm_state2_create(store) - assert(wasm.wasm_state2_saw_close(store) == False) - s2.drop(store) - assert(wasm.wasm_state2_saw_close(store) == True) - - arg1 = wasm.wasm_state_create(store) - arg2 = wasm.wasm_state2_create(store) - c, d = wasm.two_wasm_states(store, arg1, arg2) - arg1.drop(store) - arg2.drop(store) - - wasm.wasm_state2_param_record(store, e.WasmStateParamRecord(d)) - wasm.wasm_state2_param_tuple(store, (d,)) - wasm.wasm_state2_param_option(store, d) - wasm.wasm_state2_param_option(store, None) - wasm.wasm_state2_param_result(store, e.Ok(d)) - wasm.wasm_state2_param_result(store, e.Err(2)) - wasm.wasm_state2_param_variant(store, d) - wasm.wasm_state2_param_variant(store, 2) - wasm.wasm_state2_param_list(store, []) - wasm.wasm_state2_param_list(store, [d]) - wasm.wasm_state2_param_list(store, [d, d]) - - c.drop(store) - d.drop(store) - - wasm.wasm_state2_result_record(store).a.drop(store) - wasm.wasm_state2_result_tuple(store)[0].drop(store) - opt = wasm.wasm_state2_result_option(store) - assert(opt is not None) - opt.drop(store) - result = wasm.wasm_state2_result_result(store) - assert(isinstance(result, e.Ok)) - result.value.drop(store) - variant = wasm.wasm_state2_result_variant(store) - print(variant) - assert(isinstance(variant, e.WasmState2)) - variant.drop(store) - for val in wasm.wasm_state2_result_list(store): - val.drop(store) - - s.drop(store) - - md = e.Markdown.create(store, wasm) - if md: - md.append(store, "red is the best color") - assert(md.render(store) == "green is the best color") - md.drop(store) - -if __name__ == '__main__': - run(sys.argv[1]) diff --git a/tests/runtime/handles/host.rs b/tests/runtime/handles/host.rs deleted file mode 100644 index 84f555a90..000000000 --- a/tests/runtime/handles/host.rs +++ /dev/null @@ -1,156 +0,0 @@ -wit_bindgen_host_wasmtime_rust::export!("../../tests/runtime/handles/imports.wit"); - -use anyhow::Result; -use imports::*; -use std::cell::RefCell; - -#[derive(Default)] -pub struct MyImports { - host_state2_closed: bool, -} - -#[derive(Debug)] -pub struct SuchState(u32); - -#[derive(Default, Debug)] -pub struct Markdown { - buf: RefCell, -} - -impl Imports for MyImports { - type HostState = SuchState; - type HostState2 = (); - type Markdown2 = Markdown; - type OddName = (); - - fn host_state_create(&mut self) -> SuchState { - SuchState(100) - } - - fn host_state_get(&mut self, state: &SuchState) -> u32 { - state.0 - } - - fn host_state2_create(&mut self) {} - - fn host_state2_saw_close(&mut self) -> bool { - self.host_state2_closed - } - - fn drop_host_state2(&mut self, _state: ()) { - self.host_state2_closed = true; - } - - fn two_host_states(&mut self, _a: &SuchState, _b: &()) -> (SuchState, ()) { - (SuchState(2), ()) - } - - fn host_state2_param_record(&mut self, _a: HostStateParamRecord<'_, Self>) {} - fn host_state2_param_tuple(&mut self, _a: (&'_ (),)) {} - fn host_state2_param_option(&mut self, _a: Option<&'_ ()>) {} - fn host_state2_param_result(&mut self, _a: Result<&'_ (), u32>) {} - fn host_state2_param_variant(&mut self, _a: HostStateParamVariant<'_, Self>) {} - fn host_state2_param_list(&mut self, _a: Vec<&()>) {} - - fn host_state2_result_record(&mut self) -> HostStateResultRecord { - HostStateResultRecord { a: () } - } - fn host_state2_result_tuple(&mut self) -> ((),) { - ((),) - } - fn host_state2_result_option(&mut self) -> Option<()> { - Some(()) - } - fn host_state2_result_result(&mut self) -> Result<(), u32> { - Ok(()) - } - fn host_state2_result_variant(&mut self) -> HostStateResultVariant { - HostStateResultVariant::HostState2(()) - } - fn host_state2_result_list(&mut self) -> Vec<()> { - vec![(), ()] - } - - fn markdown2_create(&mut self) -> Markdown { - Markdown::default() - } - - fn markdown2_append(&mut self, md: &Markdown, buf: &str) { - md.buf.borrow_mut().push_str(buf); - } - - fn markdown2_render(&mut self, md: &Markdown) -> String { - md.buf.borrow().replace("red", "green") - } - - fn odd_name_create(&mut self) {} - fn odd_name_frob_the_odd(&mut self, _: &()) {} -} - -wit_bindgen_host_wasmtime_rust::import!("../../tests/runtime/handles/exports.wit"); - -fn run(wasm: &str) -> Result<()> { - use exports::*; - - let (exports, mut store) = crate::instantiate( - wasm, - |linker| { - imports::add_to_linker( - linker, - |cx: &mut crate::Context<(MyImports, imports::ImportsTables), _>| { - (&mut cx.imports.0, &mut cx.imports.1) - }, - ) - }, - |store, module, linker| Exports::instantiate(store, module, linker, |cx| &mut cx.exports), - )?; - - exports.test_imports(&mut store)?; - - let s: WasmState = exports.wasm_state_create(&mut store)?; - assert_eq!(exports.wasm_state_get_val(&mut store, &s)?, 100); - exports.drop_wasm_state(&mut store, s)?; - - assert_eq!(exports.wasm_state2_saw_close(&mut store)?, false); - let s: WasmState2 = exports.wasm_state2_create(&mut store)?; - assert_eq!(exports.wasm_state2_saw_close(&mut store)?, false); - exports.drop_wasm_state2(&mut store, s)?; - assert_eq!(exports.wasm_state2_saw_close(&mut store)?, true); - - let a = exports.wasm_state_create(&mut store)?; - let b = exports.wasm_state2_create(&mut store)?; - let (s1, s2) = exports.two_wasm_states(&mut store, &a, &b)?; - exports.drop_wasm_state(&mut store, a)?; - exports.drop_wasm_state(&mut store, s1)?; - exports.drop_wasm_state2(&mut store, b)?; - - exports.wasm_state2_param_record(&mut store, WasmStateParamRecord { a: &s2 })?; - exports.wasm_state2_param_tuple(&mut store, (&s2,))?; - exports.wasm_state2_param_option(&mut store, Some(&s2))?; - exports.wasm_state2_param_option(&mut store, None)?; - exports.wasm_state2_param_result(&mut store, Ok(&s2))?; - exports.wasm_state2_param_result(&mut store, Err(2))?; - exports.wasm_state2_param_variant(&mut store, WasmStateParamVariant::WasmState2(&s2))?; - exports.wasm_state2_param_variant(&mut store, WasmStateParamVariant::U32(2))?; - exports.wasm_state2_param_list(&mut store, &[])?; - exports.wasm_state2_param_list(&mut store, &[&s2])?; - exports.wasm_state2_param_list(&mut store, &[&s2, &s2])?; - exports.drop_wasm_state2(&mut store, s2)?; - - let s = exports.wasm_state2_result_record(&mut store)?.a; - exports.drop_wasm_state2(&mut store, s)?; - let s = exports.wasm_state2_result_tuple(&mut store)?.0; - exports.drop_wasm_state2(&mut store, s)?; - let s = exports.wasm_state2_result_option(&mut store)?.unwrap(); - exports.drop_wasm_state2(&mut store, s)?; - let s = exports.wasm_state2_result_result(&mut store)?.unwrap(); - match exports.wasm_state2_result_variant(&mut store)? { - WasmStateResultVariant::WasmState2(s) => exports.drop_wasm_state2(&mut store, s)?, - WasmStateResultVariant::U32(_) => panic!(), - } - exports.drop_wasm_state2(&mut store, s)?; - for s in exports.wasm_state2_result_list(&mut store)? { - exports.drop_wasm_state2(&mut store, s)?; - } - Ok(()) -} diff --git a/tests/runtime/handles/host.ts b/tests/runtime/handles/host.ts deleted file mode 100644 index e611fc997..000000000 --- a/tests/runtime/handles/host.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { addImportsToImports, Imports } from "./imports.js"; -import { Exports } from "./exports.js"; -import * as exports from "./exports.js"; -import { getWasm, addWasiToImports } from "./helpers.js"; -// @ts-ignore -import * as assert from 'assert'; - -async function run() { - const importObj = {}; - let sawClose = false; - const imports: Imports = { - hostStateCreate() { return 100; }, - hostStateGet(x) { return x as number; }, - hostState2Create() { return 101; }, - hostState2SawClose() { return sawClose; }, - dropHostState2(state) { sawClose = true; }, - twoHostStates(a, b) { return [b, a]; }, - hostState2ParamRecord(x) {}, - hostState2ParamTuple(x) {}, - hostState2ParamOption(x) {}, - hostState2ParamResult(x) {}, - hostState2ParamVariant(x) {}, - hostState2ParamList(x) {}, - - hostState2ResultRecord() { return { a: {} }; }, - hostState2ResultTuple() { return [{}]; }, - hostState2ResultOption() { return 102; }, - hostState2ResultResult() { return { tag: 'ok', val: {} }; }, - hostState2ResultVariant() { return { tag: 0, val: {} }; }, - hostState2ResultList() { return [{}, 3]; }, - - markdown2Create() { - class Markdown { - buf: string; - - constructor() { - this.buf = ''; - } - append(extra: string) { - this.buf += extra; - } - render() { - return this.buf.replace('red', 'green'); - } - } - - return new Markdown(); - }, - - oddNameCreate() { - class OddName { - frobTheOdd() {} - } - return new OddName(); - } - }; - let instance: WebAssembly.Instance; - addImportsToImports(importObj, imports, name => instance.exports[name]); - const wasi = addWasiToImports(importObj); - - const wasm = new Exports(); - await wasm.instantiate(getWasm(), importObj); - wasi.start(wasm.instance); - instance = wasm.instance; - - wasm.testImports(); - - // Param/result of a handle works in a simple fashion - const s: exports.WasmState = wasm.wasmStateCreate(); - assert.strictEqual(wasm.wasmStateGetVal(s), 100); - - // Deterministic destruction is possible - assert.strictEqual(wasm.wasmState2SawClose(), false); - const s2: exports.WasmState2 = wasm.wasmState2Create(); - assert.strictEqual(wasm.wasmState2SawClose(), false); - s2.drop(); - assert.strictEqual(wasm.wasmState2SawClose(), true); - - const arg1 = wasm.wasmStateCreate(); - const arg2 = wasm.wasmState2Create(); - const [c, d] = wasm.twoWasmStates(arg1, arg2); - arg1.drop(); - arg2.drop(); - - wasm.wasmState2ParamRecord({ a: d }); - wasm.wasmState2ParamTuple([d]); - wasm.wasmState2ParamOption(d); - wasm.wasmState2ParamOption(null); - wasm.wasmState2ParamResult({ tag: 'ok', val: d }); - wasm.wasmState2ParamResult({ tag: 'err', val: 2 }); - wasm.wasmState2ParamVariant({ tag: 0, val: d }); - wasm.wasmState2ParamVariant({ tag: 1, val: 2 }); - wasm.wasmState2ParamList([]); - wasm.wasmState2ParamList([d]); - wasm.wasmState2ParamList([d, d]); - - c.drop(); - d.drop(); - - wasm.wasmState2ResultRecord().a?.drop(); - wasm.wasmState2ResultTuple()[0].drop(); - const opt = wasm.wasmState2ResultOption(); - if (opt === null) - throw new Error('should be some'); - opt.drop(); - const result = wasm.wasmState2ResultResult(); - if (result.tag === 'err') - throw new Error('should be ok'); - result.val.drop(); - const variant = wasm.wasmState2ResultVariant(); - if (variant.tag === 1) - throw new Error('should be 0'); - variant.val.drop(); - for (let val of wasm.wasmState2ResultList()) - val.drop(); - - s.drop(); - - const md = exports.Markdown.create(wasm); - if (md) { - md.append("red is the best color"); - assert.strictEqual(md.render(), "green is the best color"); - md.drop(); - } -} - -await run() diff --git a/tests/runtime/handles/imports.wit b/tests/runtime/handles/imports.wit deleted file mode 100644 index f83f46372..000000000 --- a/tests/runtime/handles/imports.wit +++ /dev/null @@ -1,55 +0,0 @@ -resource host-state -resource host-state2 - -host-state-create: func() -> host-state -host-state-get: func(a: host-state) -> u32 - -host-state2-create: func() -> host-state2 -host-state2-saw-close: func() -> bool -two-host-states: func(a: host-state, b: host-state2) -> (a: host-state, b: host-state2) - -record host-state-param-record { a: host-state2 } -host-state2-param-record: func(a: host-state-param-record) - -type host-state-param-tuple = tuple -host-state2-param-tuple: func(a: host-state-param-tuple) - -type host-state-param-option = option -host-state2-param-option: func(a: host-state-param-option) - -type host-state-param-result = result -host-state2-param-result: func(a: host-state-param-result) - -union host-state-param-variant { host-state2, u32 } -host-state2-param-variant: func(a: host-state-param-variant) - -host-state2-param-list: func(a: list) - - -record host-state-result-record { a: host-state2 } -host-state2-result-record: func() -> host-state-result-record - -type host-state-result-tuple = tuple -host-state2-result-tuple: func() -> host-state-result-tuple - -type host-state-result-option = option -host-state2-result-option: func() -> host-state-result-option - -type host-state-result-result = result -host-state2-result-result: func() -> host-state-result-result - -union host-state-result-variant { host-state2, u32 } -host-state2-result-variant: func() -> host-state-result-variant - -host-state2-result-list: func() -> list - -resource markdown2 { - static create: func() -> markdown2 - append: func(buf: string) - render: func() -> string -} - -resource %odd-name { - static create: func() -> %odd-name - %frob-the-odd: func() -} diff --git a/tests/runtime/handles/wasm.c b/tests/runtime/handles/wasm.c deleted file mode 100644 index ef95592f8..000000000 --- a/tests/runtime/handles/wasm.c +++ /dev/null @@ -1,223 +0,0 @@ -#include -#include -#include -#include -#include - -void exports_test_imports() { - imports_host_state_t s = imports_host_state_create(); - assert(imports_host_state_get(s) == 100); - imports_host_state_free(&s); - - assert(imports_host_state2_saw_close() == false); - imports_host_state2_t s2 = imports_host_state2_create(); - assert(imports_host_state2_saw_close() == false); - imports_host_state2_free(&s2); - assert(imports_host_state2_saw_close() == true); - - { - imports_host_state_t a, b; - imports_host_state2_t c, d; - - a = imports_host_state_create(); - c = imports_host_state2_create(); - imports_two_host_states(a, c, &b, &d); - imports_host_state_free(&a); - imports_host_state_free(&b); - imports_host_state2_free(&c); - - { - imports_host_state_param_record_t a; - a.a = d; - imports_host_state2_param_record(&a); - } - { - imports_host_state_param_tuple_t a; - a.f0 = d; - imports_host_state2_param_tuple(&a); - } - { - imports_host_state_param_option_t a; - a.is_some = true; - a.val = d; - imports_host_state2_param_option(&a); - } - { - imports_host_state_param_result_t a; - a.is_err = false; - a.val.ok = d; - imports_host_state2_param_result(&a); - a.is_err = true; - a.val.err = 2; - imports_host_state2_param_result(&a); - } - { - imports_host_state_param_variant_t a; - a.tag = 0; - a.val.f0 = d; - imports_host_state2_param_variant(&a); - a.tag = 1; - a.val.f1 = 2; - imports_host_state2_param_variant(&a); - } - { - imports_host_state2_t arr[2]; - arr[0] = d; - arr[1] = d; - imports_list_host_state2_t list; - list.len = 0; - list.ptr = arr; - imports_host_state2_param_list(&list); - list.len = 1; - imports_host_state2_param_list(&list); - list.len = 2; - imports_host_state2_param_list(&list); - } - - imports_host_state2_free(&d); - } - - { - imports_host_state_result_record_t a; - imports_host_state2_result_record(&a); - imports_host_state2_free(&a.a); - } - { - imports_host_state_result_tuple_t a; - imports_host_state2_result_tuple(&a); - imports_host_state2_free(&a.f0); - } - { - imports_host_state2_t a; - assert(imports_host_state2_result_option(&a)); - imports_host_state2_free(&a); - } - { - imports_host_state_result_result_t a; - imports_host_state2_result_result(&a); - assert(!a.is_err); - imports_host_state2_free(&a.val.ok); - } - { - imports_host_state_result_variant_t a; - imports_host_state2_result_variant(&a); - assert(a.tag == 0); - imports_host_state2_free(&a.val.f0); - } - { - imports_list_host_state2_t a; - imports_host_state2_result_list(&a); - imports_list_host_state2_free(&a); - } - { - imports_markdown2_t a = imports_markdown2_create(); - imports_string_t s; - imports_string_set(&s, "red is the best color"); - imports_markdown2_append(a, &s); - imports_markdown2_render(a, &s); - - const char *expected = "green is the best color"; - assert(s.len == strlen(expected)); - assert(memcmp(s.ptr, expected, s.len) == 0); - imports_string_free(&s); - imports_markdown2_free(&a); - } -} - -exports_wasm_state_t exports_wasm_state_create(void) { - return exports_wasm_state_new((void*) 100); -} - -uint32_t exports_wasm_state_get_val(exports_wasm_state_t a) { - uint32_t ret = (uint32_t) exports_wasm_state_get(&a); - exports_wasm_state_free(&a); - return ret; -} - -exports_wasm_state2_t exports_wasm_state2_create(void) { - return exports_wasm_state2_new((void*) 33); -} - -static bool WASM_STATE2_CLOSED = false; - -bool exports_wasm_state2_saw_close(void) { - return WASM_STATE2_CLOSED; -} - -void exports_wasm_state2_dtor(void *data) { - WASM_STATE2_CLOSED = true; -} - -void exports_two_wasm_states(exports_wasm_state_t a, exports_wasm_state2_t b, exports_wasm_state_t *ret0, exports_wasm_state2_t *ret1) { - exports_wasm_state_free(&a); - exports_wasm_state2_free(&b); - - *ret0 = exports_wasm_state_new((void*) 101); - *ret1 = exports_wasm_state2_new((void*) 102); -} - -void exports_wasm_state2_param_record(exports_wasm_state_param_record_t *a) { - exports_wasm_state_param_record_free(a); -} - -void exports_wasm_state2_param_tuple(exports_wasm_state_param_tuple_t *a) { - exports_wasm_state_param_tuple_free(a); -} - -void exports_wasm_state2_param_option(exports_wasm_state_param_option_t *a) { - exports_wasm_state_param_option_free(a); -} - -void exports_wasm_state2_param_result(exports_wasm_state_param_result_t *a) { - exports_wasm_state_param_result_free(a); -} - -void exports_wasm_state2_param_variant(exports_wasm_state_param_variant_t *a) { - exports_wasm_state_param_variant_free(a); -} - -void exports_wasm_state2_param_list(exports_list_wasm_state2_t *a) { - exports_list_wasm_state2_free(a); -} - -void exports_wasm_state2_result_record(exports_wasm_state_result_record_t *ret0) { - ret0->a = exports_wasm_state2_new((void*) 222); -} - -void exports_wasm_state2_result_tuple(exports_wasm_state_result_tuple_t *ret0) { - ret0->f0 = exports_wasm_state2_new((void*) 333); -} - -bool exports_wasm_state2_result_option(exports_wasm_state2_t *ret0) { - *ret0 = exports_wasm_state2_new((void*) 444); - return true; -} - -void exports_wasm_state2_result_result(exports_wasm_state_result_result_t *ret0) { - ret0->is_err = false; - ret0->val.ok = exports_wasm_state2_new((void*) 555); -} - -void exports_wasm_state2_result_variant(exports_wasm_state_result_variant_t *ret0) { - ret0->tag = 0; - ret0->val.f0 = exports_wasm_state2_new((void*) 666); -} - -void exports_wasm_state2_result_list(exports_list_wasm_state2_t *ret0) { - ret0->len = 2; - ret0->ptr = malloc(2 * sizeof(exports_wasm_state2_t)); - ret0->ptr[0] = exports_wasm_state2_new((void*) 777); - ret0->ptr[1] = exports_wasm_state2_new((void*) 888); -} - -bool exports_markdown_create(exports_markdown_t *md) { - return false; -} - -void exports_markdown_append(exports_markdown_t md, exports_string_t *s) { - abort(); -} - -void exports_markdown_render(exports_markdown_t md, exports_string_t *ret) { - abort(); -} diff --git a/tests/runtime/handles/wasm.rs b/tests/runtime/handles/wasm.rs deleted file mode 100644 index 18b44371e..000000000 --- a/tests/runtime/handles/wasm.rs +++ /dev/null @@ -1,131 +0,0 @@ -wit_bindgen_guest_rust::import!("../../tests/runtime/handles/imports.wit"); -wit_bindgen_guest_rust::export!("../../tests/runtime/handles/exports.wit"); - -use exports::*; -use std::cell::RefCell; -use std::sync::atomic::{AtomicU32, Ordering::SeqCst}; -use wit_bindgen_guest_rust::Handle; - -struct Exports; - -static CLOSED: AtomicU32 = AtomicU32::new(0); - -pub struct WasmState(u32); - -pub struct WasmState2(u32); - -impl exports::Exports for Exports { - fn test_imports() { - use imports::*; - - let s: HostState = host_state_create(); - assert_eq!(host_state_get(&s), 100); - assert_eq!(host_state2_saw_close(), false); - let s: HostState2 = host_state2_create(); - assert_eq!(host_state2_saw_close(), false); - drop(s); - assert_eq!(host_state2_saw_close(), true); - - let (_a, s2) = two_host_states(&host_state_create(), &host_state2_create()); - - host_state2_param_record(HostStateParamRecord { a: &s2 }); - host_state2_param_tuple((&s2,)); - host_state2_param_option(Some(&s2)); - host_state2_param_option(None); - host_state2_param_result(Ok(&s2)); - host_state2_param_result(Err(2)); - host_state2_param_variant(HostStateParamVariant::HostState2(&s2)); - host_state2_param_variant(HostStateParamVariant::U32(2)); - host_state2_param_list(&[]); - host_state2_param_list(&[&s2]); - host_state2_param_list(&[&s2, &s2]); - - drop(host_state2_result_record().a); - drop(host_state2_result_tuple().0); - drop(host_state2_result_option().unwrap()); - drop(host_state2_result_result().unwrap()); - drop(host_state2_result_variant()); - drop(host_state2_result_list()); - - let md = Markdown2::create(); - md.append("red is the best color"); - assert_eq!(md.render(), "green is the best color"); - - let odd = OddName::create(); - odd.frob_the_odd(); - } - - fn wasm_state_create() -> Handle { - WasmState(100).into() - } - - fn wasm_state_get_val(state: Handle) -> u32 { - state.0 - } - - fn wasm_state2_create() -> Handle { - WasmState2(33).into() - } - - fn wasm_state2_saw_close() -> bool { - CLOSED.load(SeqCst) != 0 - } - - fn drop_wasm_state2(_state: WasmState2) { - CLOSED.store(1, SeqCst); - } - - fn two_wasm_states( - _a: Handle, - _b: Handle, - ) -> (Handle, Handle) { - (WasmState(101).into(), WasmState2(102).into()) - } - - fn wasm_state2_param_record(_a: WasmStateParamRecord) {} - fn wasm_state2_param_tuple(_a: (Handle,)) {} - fn wasm_state2_param_option(_a: Option>) {} - fn wasm_state2_param_result(_a: Result, u32>) {} - fn wasm_state2_param_variant(_a: WasmStateParamVariant) {} - fn wasm_state2_param_list(_a: Vec>) {} - - fn wasm_state2_result_record() -> WasmStateResultRecord { - WasmStateResultRecord { - a: WasmState2(222).into(), - } - } - fn wasm_state2_result_tuple() -> (Handle,) { - (WasmState2(333).into(),) - } - fn wasm_state2_result_option() -> Option> { - Some(WasmState2(444).into()) - } - fn wasm_state2_result_result() -> Result, u32> { - Ok(WasmState2(555).into()) - } - fn wasm_state2_result_variant() -> WasmStateResultVariant { - WasmStateResultVariant::WasmState2(Handle::new(WasmState2(666))) - } - fn wasm_state2_result_list() -> Vec> { - vec![WasmState2(777).into(), WasmState2(888).into()] - } -} - -#[derive(Default)] -pub struct Markdown { - buf: RefCell, -} - -impl exports::Markdown for Markdown { - fn create() -> Option> { - Some(Markdown::default().into()) - } - - fn append(&self, input: String) { - self.buf.borrow_mut().push_str(&input); - } - - fn render(&self) -> String { - self.buf.borrow().replace("red", "green") - } -} diff --git a/tests/runtime/invalid/exports.wit b/tests/runtime/invalid/exports.wit index 7272c498a..7619764fe 100644 --- a/tests/runtime/invalid/exports.wit +++ b/tests/runtime/invalid/exports.wit @@ -5,5 +5,3 @@ invalid-s16: func() invalid-char: func() invalid-bool: func() invalid-enum: func() -invalid-handle: func() -invalid-handle-close: func() diff --git a/tests/runtime/invalid/host.py b/tests/runtime/invalid/host.py index 3895cb9c1..d9a0a90b8 100644 --- a/tests/runtime/invalid/host.py +++ b/tests/runtime/invalid/host.py @@ -27,9 +27,6 @@ def roundtrip_char(self, x: str) -> str: def roundtrip_enum(self, x: i.E) -> i.E: raise Exception('unreachable') - def get_internal(self, x: i.HostState) -> int: - raise Exception('unreachable') - def run(wasm_file: str) -> None: store = wasmtime.Store() module = wasmtime.Module.from_file(store.engine, wasm_file) @@ -67,8 +64,6 @@ def assert_throws(f: Callable, msg: str) -> None: assert_throws(lambda: wasm.invalid_s16(store), 'must be between') assert_throws(lambda: wasm.invalid_char(store), 'not a valid char') assert_throws(lambda: wasm.invalid_enum(store), 'not a valid E') - assert_throws(lambda: wasm.invalid_handle(store), 'handle index not valid') - assert_throws(lambda: wasm.invalid_handle_close(store), 'handle index not valid') if __name__ == '__main__': run(sys.argv[1]) diff --git a/tests/runtime/invalid/host.rs b/tests/runtime/invalid/host.rs index 8a43c3bfd..fea0701ce 100644 --- a/tests/runtime/invalid/host.rs +++ b/tests/runtime/invalid/host.rs @@ -8,8 +8,6 @@ use wasmtime::Trap; pub struct MyImports; impl Imports for MyImports { - type HostState = (); - fn roundtrip_u8(&mut self, _: u8) -> u8 { unreachable!() } @@ -31,9 +29,6 @@ impl Imports for MyImports { fn roundtrip_enum(&mut self, _: imports::E) -> imports::E { unreachable!() } - fn get_internal(&mut self, _: &()) -> u32 { - unreachable!() - } } wit_bindgen_host_wasmtime_rust::import!("../../tests/runtime/invalid/exports.wit"); @@ -44,12 +39,9 @@ fn run(wasm: &str) -> Result<()> { let (exports, mut store) = crate::instantiate( wasm, |linker| { - imports::add_to_linker( - linker, - |cx: &mut crate::Context<(MyImports, imports::ImportsTables), _>| { - (&mut cx.imports.0, &mut cx.imports.1) - }, - ) + imports::add_to_linker(linker, |cx: &mut crate::Context| { + &mut cx.imports + }) }, |store, module, linker| Exports::instantiate(store, module, linker, |cx| &mut cx.exports), )?; @@ -82,11 +74,6 @@ fn run(wasm: &str) -> Result<()> { exports.invalid_enum(&mut store), "invalid discriminant for `E`", )?; - assert_err(exports.invalid_handle(&mut store), "invalid handle index")?; - assert_err( - exports.invalid_handle_close(&mut store), - "invalid handle index", - )?; return Ok(()); fn assert_err(result: Result<(), Trap>, err: &str) -> Result<()> { diff --git a/tests/runtime/invalid/host.ts b/tests/runtime/invalid/host.ts index 5e6cb31df..d38457227 100644 --- a/tests/runtime/invalid/host.ts +++ b/tests/runtime/invalid/host.ts @@ -14,7 +14,6 @@ async function run() { roundtripBool(x) { throw new Error('unreachable'); }, roundtripChar(x) { throw new Error('unreachable'); }, roundtripEnum(x) { throw new Error('unreachable'); }, - getInternal(x) { throw new Error('unreachable'); }, }; let instance: WebAssembly.Instance; addImportsToImports(importObj, imports); @@ -32,8 +31,6 @@ async function run() { assert.throws(() => wasm.invalidS16(), /must be between/); assert.throws(() => wasm.invalidChar(), /not a valid char/); assert.throws(() => wasm.invalidEnum(), /invalid discriminant specified for E/); - assert.throws(() => wasm.invalidHandle(), /handle index not valid/); - assert.throws(() => wasm.invalidHandleClose(), /handle index not valid/); } await run() diff --git a/tests/runtime/invalid/imports.wit b/tests/runtime/invalid/imports.wit index 420e8adef..9f236993b 100644 --- a/tests/runtime/invalid/imports.wit +++ b/tests/runtime/invalid/imports.wit @@ -8,6 +8,3 @@ enum e { a, b, c } roundtrip-enum: func(a: e) -> e roundtrip-bool: func(a: bool) -> bool - -resource host-state -get-internal: func(a: host-state) -> u32 diff --git a/tests/runtime/invalid/wasm.rs b/tests/runtime/invalid/wasm.rs index 00c95cb80..22c262a00 100644 --- a/tests/runtime/invalid/wasm.rs +++ b/tests/runtime/invalid/wasm.rs @@ -16,14 +16,6 @@ extern "C" { fn roundtrip_char(a: i32) -> i32; #[link_name = "roundtrip-enum"] fn roundtrip_enum(a: i32) -> i32; - #[link_name = "get-internal"] - fn get_internal(a: i32) -> i32; -} - -#[link(wasm_import_module = "canonical_abi")] -extern "C" { - #[link_name = "resource_drop_host-state"] - fn resource_drop_host_state(a: i32); } struct Exports; @@ -71,18 +63,4 @@ impl exports::Exports for Exports { } unreachable!(); } - - fn invalid_handle() { - unsafe { - get_internal(100); - } - unreachable!(); - } - - fn invalid_handle_close() { - unsafe { - resource_drop_host_state(100); - } - unreachable!(); - } } diff --git a/tests/runtime/js_instantiate/host.ts b/tests/runtime/js_instantiate/host.ts index 895d2fc31..e3cca6341 100644 --- a/tests/runtime/js_instantiate/host.ts +++ b/tests/runtime/js_instantiate/host.ts @@ -12,7 +12,6 @@ async function run() { (new Exports()).instantiate(new WebAssembly.Module(getWasm()), importObj); { const obj = new Exports(); - obj.addToImports(importObj); obj.instantiate(new WebAssembly.Instance(new WebAssembly.Module(getWasm()), importObj)); } }