diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 1954c0f7f03..77a8a3b7511 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -1156,6 +1156,9 @@ impl<'a> ToTokens for DescribeImport<'a> { impl ToTokens for ast::Enum { fn to_tokens(&self, into: &mut TokenStream) { let enum_name = &self.rust_name; + let name_str = self.js_name.to_string(); + let name_len = name_str.len() as u32; + let name_chars = name_str.chars().map(|c| c as u32); let hole = &self.hole; let cast_clauses = self.variants.iter().map(|variant| { let variant_name = &variant.name; @@ -1205,6 +1208,8 @@ impl ToTokens for ast::Enum { fn describe() { use wasm_bindgen::describe::*; inform(ENUM); + inform(#name_len); + #(inform(#name_chars);)* inform(#hole); } } diff --git a/crates/cli-support/src/descriptor.rs b/crates/cli-support/src/descriptor.rs index d5c4dd7f07a..5045dae0772 100644 --- a/crates/cli-support/src/descriptor.rs +++ b/crates/cli-support/src/descriptor.rs @@ -64,7 +64,7 @@ pub enum Descriptor { String, Externref, NamedExternref(String), - Enum { hole: u32 }, + Enum { name: String, hole: u32 }, RustStruct(String), Char, Option(Box), @@ -134,7 +134,11 @@ impl Descriptor { CACHED_STRING => Descriptor::CachedString, STRING => Descriptor::String, EXTERNREF => Descriptor::Externref, - ENUM => Descriptor::Enum { hole: get(data) }, + ENUM => { + let name = get_string(data); + let hole = get(data); + Descriptor::Enum { name, hole } + } RUST_STRUCT => { let name = get_string(data); Descriptor::RustStruct(name) diff --git a/crates/cli-support/src/js/binding.rs b/crates/cli-support/src/js/binding.rs index 8a86bd1282b..450cd088a29 100644 --- a/crates/cli-support/src/js/binding.rs +++ b/crates/cli-support/src/js/binding.rs @@ -1233,6 +1233,7 @@ fn adapter2ts(ty: &AdapterType, dst: &mut String) { } AdapterType::NamedExternref(name) => dst.push_str(name), AdapterType::Struct(name) => dst.push_str(name), + AdapterType::Enum(name) => dst.push_str(name), AdapterType::Function => dst.push_str("any"), } } diff --git a/crates/cli-support/src/wit/incoming.rs b/crates/cli-support/src/wit/incoming.rs index 05a7d757ba4..cbf1364d2e3 100644 --- a/crates/cli-support/src/wit/incoming.rs +++ b/crates/cli-support/src/wit/incoming.rs @@ -99,7 +99,18 @@ impl InstructionBuilder<'_, '_> { self.get(AdapterType::F64); self.output.push(AdapterType::F64); } - Descriptor::Enum { .. } => self.number(WitVT::U32, WasmVT::I32), + Descriptor::Enum { name, .. } => { + let std = wit_walrus::Instruction::IntToWasm { + input: WitVT::U32, + output: WasmVT::I32, + trap: false, + }; + self.instruction( + &[AdapterType::Enum(name.clone())], + Instruction::Standard(std), + &[AdapterType::I32], + ); + } Descriptor::Ref(d) => self.incoming_ref(false, d)?, Descriptor::RefMut(d) => self.incoming_ref(true, d)?, Descriptor::Option(d) => self.incoming_option(d)?, @@ -280,9 +291,9 @@ impl InstructionBuilder<'_, '_> { &[AdapterType::I32], ); } - Descriptor::Enum { hole } => { + Descriptor::Enum { name, hole } => { self.instruction( - &[AdapterType::U32.option()], + &[AdapterType::Enum(name.clone()).option()], Instruction::I32FromOptionEnum { hole: *hole }, &[AdapterType::I32], ); diff --git a/crates/cli-support/src/wit/outgoing.rs b/crates/cli-support/src/wit/outgoing.rs index d6b4692c4a0..8a7fbce54f1 100644 --- a/crates/cli-support/src/wit/outgoing.rs +++ b/crates/cli-support/src/wit/outgoing.rs @@ -60,7 +60,7 @@ impl InstructionBuilder<'_, '_> { self.get(AdapterType::F64); self.output.push(AdapterType::F64); } - Descriptor::Enum { .. } => self.outgoing_i32(AdapterType::U32), + Descriptor::Enum { name, .. } => self.outgoing_i32(AdapterType::Enum(name.clone())), Descriptor::Char => { self.instruction( @@ -281,11 +281,11 @@ impl InstructionBuilder<'_, '_> { &[AdapterType::String.option()], ); } - Descriptor::Enum { hole } => { + Descriptor::Enum { name, hole } => { self.instruction( &[AdapterType::I32], Instruction::OptionEnumFromI32 { hole: *hole }, - &[AdapterType::U32.option()], + &[AdapterType::Enum(name.clone()).option()], ); } Descriptor::RustStruct(name) => { diff --git a/crates/cli-support/src/wit/standard.rs b/crates/cli-support/src/wit/standard.rs index 0ab0d34ec59..1bb0097c8ad 100644 --- a/crates/cli-support/src/wit/standard.rs +++ b/crates/cli-support/src/wit/standard.rs @@ -84,6 +84,7 @@ pub enum AdapterType { Vector(VectorKind), Option(Box), Struct(String), + Enum(String), NamedExternref(String), Function, } @@ -347,6 +348,7 @@ impl AdapterType { AdapterType::I32 => wit_walrus::ValType::I32, AdapterType::I64 => wit_walrus::ValType::I64, + AdapterType::Enum(_) => wit_walrus::ValType::U32, AdapterType::Option(_) | AdapterType::Function | AdapterType::Struct(_) diff --git a/crates/typescript-tests/src/enums.rs b/crates/typescript-tests/src/enums.rs new file mode 100644 index 00000000000..52e206f2cac --- /dev/null +++ b/crates/typescript-tests/src/enums.rs @@ -0,0 +1,24 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub enum Shape { + Circle, + Rectangle, + Triangle, +} + +#[wasm_bindgen] +pub fn accepts_enum(_: Shape) {} + +#[wasm_bindgen] +pub fn take_and_return_enum(s: Shape) -> Shape { + s +} + +#[wasm_bindgen] +pub fn accepts_option_enum(_: Option) {} + +#[wasm_bindgen] +pub fn take_and_return_option_enum(s: Option) -> Option { + s +} diff --git a/crates/typescript-tests/src/enums.ts b/crates/typescript-tests/src/enums.ts new file mode 100644 index 00000000000..24dcd560a43 --- /dev/null +++ b/crates/typescript-tests/src/enums.ts @@ -0,0 +1,7 @@ +import * as wbg from '../pkg/typescript_tests'; + +const wbg_accepts_enum: (a: wbg.Shape) => void = wbg.accepts_enum; +const wbg_take_and_return_enum: (a: wbg.Shape) => wbg.Shape = wbg.take_and_return_enum; + +const wbg_accepts_option_enum: (a: wbg.Shape | undefined) => void = wbg.accepts_option_enum; +const wbg_take_and_return_option_enum: (a: wbg.Shape | undefined) => wbg.Shape | undefined = wbg.take_and_return_option_enum; diff --git a/crates/typescript-tests/src/lib.rs b/crates/typescript-tests/src/lib.rs index 6c6db10e2f2..9ea20e14fda 100644 --- a/crates/typescript-tests/src/lib.rs +++ b/crates/typescript-tests/src/lib.rs @@ -1,4 +1,5 @@ pub mod custom_section; +pub mod enums; pub mod getters_setters; pub mod omit_definition; pub mod opt_args_and_ret;