Skip to content

Commit baba2f0

Browse files
refactor(moonbit): reuse WIT types for canonical lists
1 parent 5bb09f4 commit baba2f0

2 files changed

Lines changed: 84 additions & 82 deletions

File tree

crates/moonbit/src/lib.rs

Lines changed: 82 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use wit_bindgen_core::{
1111
AsyncFilterSet, Direction, Files, InterfaceGenerator as CoreInterfaceGenerator, Ns, Source,
1212
WorldGenerator,
1313
abi::{self, AbiVariant, Bindgen, Bitcast, Instruction, LiftLower, WasmType},
14-
uwrite, uwriteln,
14+
dealias, uwrite, uwriteln,
1515
wit_parser::{
1616
Alignment, ArchitectureSize, Docs, Enum, Flags, FlagsRepr, Function, Int, InterfaceId,
1717
LiftLowerAbi, LiveTypes, ManglingAndAbi, Param, Record, Resolve, ResourceIntrinsic,
@@ -29,54 +29,23 @@ mod async_support;
2929
mod ffi;
3030
mod pkg;
3131

32-
#[derive(Clone, Copy)]
33-
pub(crate) enum CanonicalListElement {
34-
Bool,
35-
U8,
36-
U16,
37-
U32,
38-
U64,
39-
S16,
40-
S32,
41-
S64,
42-
F32,
43-
F64,
44-
}
45-
46-
impl CanonicalListElement {
47-
pub(crate) fn fixed_array_type(self) -> &'static str {
48-
match self {
49-
Self::Bool => "FixedArray[Bool]",
50-
Self::U8 => "FixedArray[Byte]",
51-
Self::U16 => "FixedArray[UInt16]",
52-
Self::U32 => "FixedArray[UInt]",
53-
Self::U64 => "FixedArray[UInt64]",
54-
Self::S16 => "FixedArray[Int16]",
55-
Self::S32 => "FixedArray[Int]",
56-
Self::S64 => "FixedArray[Int64]",
57-
Self::F32 => "FixedArray[Float]",
58-
Self::F64 => "FixedArray[Double]",
59-
}
60-
}
61-
}
62-
63-
pub(crate) fn canonical_list_element(resolve: &Resolve, ty: &Type) -> Option<CanonicalListElement> {
64-
match ty {
65-
Type::Id(id) => match &resolve.types[*id].kind {
66-
TypeDefKind::Type(ty) => canonical_list_element(resolve, ty),
67-
_ => None,
32+
pub(crate) fn is_list_canonical(resolve: &Resolve, element: &Type) -> bool {
33+
match element {
34+
Type::Bool
35+
| Type::U8
36+
| Type::U16
37+
| Type::U32
38+
| Type::U64
39+
| Type::S16
40+
| Type::S32
41+
| Type::S64
42+
| Type::F32
43+
| Type::F64 => true,
44+
Type::Id(id) => match &resolve.types[dealias(resolve, *id)].kind {
45+
TypeDefKind::Type(element) => is_list_canonical(resolve, element),
46+
_ => false,
6847
},
69-
Type::Bool => Some(CanonicalListElement::Bool),
70-
Type::U8 => Some(CanonicalListElement::U8),
71-
Type::U16 => Some(CanonicalListElement::U16),
72-
Type::U32 => Some(CanonicalListElement::U32),
73-
Type::U64 => Some(CanonicalListElement::U64),
74-
Type::S16 => Some(CanonicalListElement::S16),
75-
Type::S32 => Some(CanonicalListElement::S32),
76-
Type::S64 => Some(CanonicalListElement::S64),
77-
Type::F32 => Some(CanonicalListElement::F32),
78-
Type::F64 => Some(CanonicalListElement::F64),
79-
_ => None,
48+
_ => false,
8049
}
8150
}
8251

@@ -86,7 +55,7 @@ fn collect_direct_canonical_lists(
8655
expression: String,
8756
wasm_param: usize,
8857
expressions: &mut HashSet<String>,
89-
wasm_params: &mut BTreeMap<usize, &'static str>,
58+
wasm_params: &mut BTreeMap<usize, Type>,
9059
) {
9160
let Type::Id(id) = ty else {
9261
return;
@@ -101,9 +70,9 @@ fn collect_direct_canonical_lists(
10170
wasm_params,
10271
),
10372
TypeDefKind::List(element) => {
104-
if let Some(element) = canonical_list_element(resolve, element) {
73+
if is_list_canonical(resolve, element) {
10574
expressions.insert(expression);
106-
wasm_params.insert(wasm_param, element.fixed_array_type());
75+
wasm_params.insert(wasm_param, *element);
10776
}
10877
}
10978
TypeDefKind::Record(record) => {
@@ -791,8 +760,9 @@ impl InterfaceGenerator<'_> {
791760
.iter()
792761
.enumerate()
793762
.map(|(i, param)| {
794-
if let Some(array_type) = direct_canonical_wasm_params.get(&i) {
795-
format!("p{i} : {array_type}")
763+
if let Some(element) = direct_canonical_wasm_params.get(&i) {
764+
let element = self.world_gen.pkg_resolver.type_name(self.name, element);
765+
format!("p{i} : FixedArray[{element}]")
796766
} else if i > 0 && direct_canonical_wasm_params.contains_key(&(i - 1)) {
797767
format!("p{i}? : Int = p{}.length()", i - 1)
798768
} else {
@@ -2165,9 +2135,16 @@ impl Bindgen for FunctionBindgen<'_, '_> {
21652135
)),
21662136

21672137
Instruction::ListCanonLower { element, realloc } => {
2168-
let element = canonical_list_element(resolve, element).unwrap();
2138+
let element: &Type = element;
2139+
let element = match element {
2140+
Type::Id(id) => match &resolve.types[dealias(resolve, *id)].kind {
2141+
TypeDefKind::Type(element) => element,
2142+
_ => unreachable!("unsupported list element type"),
2143+
},
2144+
_ => element,
2145+
};
21692146
match element {
2170-
CanonicalListElement::U8 => {
2147+
Type::U8 => {
21712148
let op = &operands[0];
21722149
if realloc.is_none() && self.direct_canonical_list_params.contains(op) {
21732150
results.push(op.clone());
@@ -2188,7 +2165,15 @@ impl Bindgen for FunctionBindgen<'_, '_> {
21882165
self.cleanup.push(Cleanup { address: ptr });
21892166
}
21902167
}
2191-
element => {
2168+
Type::Bool
2169+
| Type::U16
2170+
| Type::U32
2171+
| Type::U64
2172+
| Type::S16
2173+
| Type::S32
2174+
| Type::S64
2175+
| Type::F32
2176+
| Type::F64 => {
21922177
let op = &operands[0];
21932178
if realloc.is_none() && self.direct_canonical_list_params.contains(op) {
21942179
results.push(op.clone());
@@ -2197,16 +2182,16 @@ impl Bindgen for FunctionBindgen<'_, '_> {
21972182
}
21982183
let ptr = self.locals.tmp("ptr");
21992184
let (owned_ffi, ty) = match element {
2200-
CanonicalListElement::Bool => (ffi::BOOL_ARRAY2PTR, "bool"),
2201-
CanonicalListElement::U16 => (ffi::UINT16_ARRAY2PTR, "uint16"),
2202-
CanonicalListElement::U32 => (ffi::UINT_ARRAY2PTR, "uint"),
2203-
CanonicalListElement::U64 => (ffi::UINT64_ARRAY2PTR, "uint64"),
2204-
CanonicalListElement::S16 => (ffi::INT16_ARRAY2PTR, "int16"),
2205-
CanonicalListElement::S32 => (ffi::INT_ARRAY2PTR, "int"),
2206-
CanonicalListElement::S64 => (ffi::INT64_ARRAY2PTR, "int64"),
2207-
CanonicalListElement::F32 => (ffi::FLOAT_ARRAY2PTR, "float"),
2208-
CanonicalListElement::F64 => (ffi::DOUBLE_ARRAY2PTR, "double"),
2209-
CanonicalListElement::U8 => unreachable!(),
2185+
Type::Bool => (ffi::BOOL_ARRAY2PTR, "bool"),
2186+
Type::U16 => (ffi::UINT16_ARRAY2PTR, "uint16"),
2187+
Type::U32 => (ffi::UINT_ARRAY2PTR, "uint"),
2188+
Type::U64 => (ffi::UINT64_ARRAY2PTR, "uint64"),
2189+
Type::S16 => (ffi::INT16_ARRAY2PTR, "int16"),
2190+
Type::S32 => (ffi::INT_ARRAY2PTR, "int"),
2191+
Type::S64 => (ffi::INT64_ARRAY2PTR, "int64"),
2192+
Type::F32 => (ffi::FLOAT_ARRAY2PTR, "float"),
2193+
Type::F64 => (ffi::DOUBLE_ARRAY2PTR, "double"),
2194+
_ => unreachable!(),
22102195
};
22112196
self.use_ffi(owned_ffi);
22122197

@@ -2222,13 +2207,21 @@ impl Bindgen for FunctionBindgen<'_, '_> {
22222207
self.cleanup.push(Cleanup { address: ptr });
22232208
}
22242209
}
2210+
_ => unreachable!("unsupported list element type"),
22252211
}
22262212
}
22272213

22282214
Instruction::ListCanonLift { element, .. } => {
2229-
let element = canonical_list_element(resolve, element).unwrap();
2215+
let element: &Type = element;
2216+
let element = match element {
2217+
Type::Id(id) => match &resolve.types[dealias(resolve, *id)].kind {
2218+
TypeDefKind::Type(element) => element,
2219+
_ => unreachable!("unsupported list element type"),
2220+
},
2221+
_ => element,
2222+
};
22302223
match element {
2231-
CanonicalListElement::U8 => {
2224+
Type::U8 => {
22322225
let result = self.locals.tmp("result");
22332226
let address = &operands[0];
22342227
let length = &operands[1];
@@ -2242,45 +2235,53 @@ impl Bindgen for FunctionBindgen<'_, '_> {
22422235

22432236
results.push(result);
22442237
}
2245-
element => {
2238+
Type::Bool
2239+
| Type::U16
2240+
| Type::U32
2241+
| Type::U64
2242+
| Type::S16
2243+
| Type::S32
2244+
| Type::S64
2245+
| Type::F32
2246+
| Type::F64 => {
22462247
let ty = match element {
2247-
CanonicalListElement::Bool => {
2248+
Type::Bool => {
22482249
self.use_ffi(ffi::PTR2BOOL_ARRAY);
22492250
"bool"
22502251
}
2251-
CanonicalListElement::U16 => {
2252+
Type::U16 => {
22522253
self.use_ffi(ffi::PTR2UINT16_ARRAY);
22532254
"uint16"
22542255
}
2255-
CanonicalListElement::U32 => {
2256+
Type::U32 => {
22562257
self.use_ffi(ffi::PTR2UINT_ARRAY);
22572258
"uint"
22582259
}
2259-
CanonicalListElement::U64 => {
2260+
Type::U64 => {
22602261
self.use_ffi(ffi::PTR2UINT64_ARRAY);
22612262
"uint64"
22622263
}
2263-
CanonicalListElement::S16 => {
2264+
Type::S16 => {
22642265
self.use_ffi(ffi::PTR2INT16_ARRAY);
22652266
"int16"
22662267
}
2267-
CanonicalListElement::S32 => {
2268+
Type::S32 => {
22682269
self.use_ffi(ffi::PTR2INT_ARRAY);
22692270
"int"
22702271
}
2271-
CanonicalListElement::S64 => {
2272+
Type::S64 => {
22722273
self.use_ffi(ffi::PTR2INT64_ARRAY);
22732274
"int64"
22742275
}
2275-
CanonicalListElement::F32 => {
2276+
Type::F32 => {
22762277
self.use_ffi(ffi::PTR2FLOAT_ARRAY);
22772278
"float"
22782279
}
2279-
CanonicalListElement::F64 => {
2280+
Type::F64 => {
22802281
self.use_ffi(ffi::PTR2DOUBLE_ARRAY);
22812282
"double"
22822283
}
2283-
CanonicalListElement::U8 => unreachable!(),
2284+
_ => unreachable!(),
22842285
};
22852286

22862287
let result = self.locals.tmp("result");
@@ -2296,6 +2297,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
22962297

22972298
results.push(result);
22982299
}
2300+
_ => unreachable!("unsupported list element type"),
22992301
}
23002302
}
23012303

@@ -3073,7 +3075,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
30733075
}
30743076

30753077
fn is_list_canonical(&self, resolve: &Resolve, element: &Type) -> bool {
3076-
canonical_list_element(resolve, element).is_some()
3078+
crate::is_list_canonical(resolve, element)
30773079
}
30783080
}
30793081

crates/moonbit/src/pkg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ impl PkgResolver {
192192
match ty.kind {
193193
TypeDefKind::Type(ty) => self.type_name(this, &ty),
194194
TypeDefKind::List(ty) => {
195-
if let Some(element) = crate::canonical_list_element(&self.resolve, &ty) {
196-
element.fixed_array_type().to_string()
195+
if crate::is_list_canonical(&self.resolve, &ty) {
196+
format!("FixedArray[{}]", self.type_name(this, &ty))
197197
} else {
198198
format!("Array[{}]", self.type_name(this, &ty))
199199
}

0 commit comments

Comments
 (0)