@@ -196,6 +196,9 @@ pub struct Opts {
196
196
/// Whether or not to derive Eq for all types
197
197
#[ cfg_attr( feature = "clap" , arg( long, default_value_t = false ) ) ]
198
198
pub derive_eq : bool ,
199
+ /// Whether or not to declare as Error type for types ".*error"
200
+ #[ cfg_attr( feature = "clap" , arg( long, default_value_t = false ) ) ]
201
+ pub derive_error : bool ,
199
202
/// Whether or not to generate stub files ; useful for update after WIT change
200
203
#[ cfg_attr( feature = "clap" , arg( long, default_value_t = false ) ) ]
201
204
pub ignore_stub : bool ,
@@ -531,7 +534,10 @@ impl WorldGenerator for MoonBit {
531
534
}
532
535
533
536
// Export FFI Utils
534
- files. push ( & format ! ( "{FFI_DIR}/top.mbt" ) , FFI . as_bytes ( ) ) ;
537
+ let mut body = Source :: default ( ) ;
538
+ wit_bindgen_core:: generated_preamble ( & mut body, version) ;
539
+ body. push_str ( FFI ) ;
540
+ files. push ( & format ! ( "{FFI_DIR}/top.mbt" ) , indent ( & body) . as_bytes ( ) ) ;
535
541
files. push ( & format ! ( "{FFI_DIR}/moon.pkg.json" ) , "{}" . as_bytes ( ) ) ;
536
542
537
543
// Export project files
@@ -544,6 +550,7 @@ impl WorldGenerator for MoonBit {
544
550
let ffi_qualifier = gen. qualify_package ( & FFI_DIR . to_string ( ) ) ;
545
551
546
552
let mut body = Source :: default ( ) ;
553
+ wit_bindgen_core:: generated_preamble ( & mut body, version) ;
547
554
uwriteln ! (
548
555
& mut body,
549
556
"
@@ -1131,30 +1138,96 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
1131
1138
if self . gen . opts . derive_eq {
1132
1139
deriviation. push ( "Eq" )
1133
1140
}
1141
+ let declaration = if self . gen . opts . derive_error && name. contains ( "Error" ) {
1142
+ "type!"
1143
+ } else {
1144
+ "type"
1145
+ } ;
1134
1146
1135
1147
uwrite ! (
1136
1148
self . src,
1137
1149
r#"
1138
- pub type {name} Int derive({})
1139
-
1140
- pub fn {name}::drop(self : {name}) -> Unit {{
1141
- wasmImportResourceDrop{name}(self.0)
1142
- }}
1150
+ pub {declaration} {name} Int derive({})
1143
1151
"# ,
1144
1152
deriviation. join( ", " ) ,
1145
1153
) ;
1146
1154
1147
- uwrite ! (
1148
- if self . direction == Direction :: Import {
1149
- & mut self . ffi
1150
- } else {
1151
- & mut self . src
1152
- } ,
1153
- r#"
1154
- fn wasmImportResourceDrop{name}(resource : Int) = "{}" "[resource-drop]{type_name}"
1155
- "# ,
1156
- self . module
1157
- ) ;
1155
+ let module = self . module ;
1156
+
1157
+ if self . direction == Direction :: Import {
1158
+ uwrite ! (
1159
+ & mut self . src,
1160
+ r#"
1161
+ /// Drops a resource handle.
1162
+ pub fn {name}::drop(self : {name}) -> Unit {{
1163
+ let {name}(resource) = self
1164
+ wasmImportResourceDrop{name}(resource)
1165
+ }}
1166
+ "# ,
1167
+ ) ;
1168
+
1169
+ uwrite ! (
1170
+ & mut self . ffi,
1171
+ r#"
1172
+ fn wasmImportResourceDrop{name}(resource : Int) = "{module}" "[resource-drop]{type_name}"
1173
+ "# ,
1174
+ )
1175
+ } else {
1176
+ uwrite ! (
1177
+ & mut self . src,
1178
+ r#"
1179
+ /// Creates a new resource with the given `rep` as its representation and returning the handle to this resource.
1180
+ pub fn {name}::new(rep : Int) -> {name} {{
1181
+ {name}::{name}(wasmExportResourceNew{name}(rep))
1182
+ }}
1183
+ fn wasmExportResourceNew{name}(rep : Int) -> Int = "[export]{module}" "[resource-new]{type_name}"
1184
+
1185
+ /// Drops a resource handle.
1186
+ pub fn {name}::drop(self : {name}) -> Unit {{
1187
+ let {name}(resource) = self
1188
+ wasmExportResourceDrop{name}(resource)
1189
+ }}
1190
+ fn wasmExportResourceDrop{name}(resource : Int) = "[export]{module}" "[resource-drop]{type_name}"
1191
+
1192
+ /// Gets the `Int` representation of the resource pointed to the given handle.
1193
+ pub fn {name}::rep(self : {name}) -> Int {{
1194
+ let {name}(resource) = self
1195
+ wasmExportResourceRep{name}(resource)
1196
+ }}
1197
+ fn wasmExportResourceRep{name}(resource : Int) -> Int = "[export]{module}" "[resource-rep]{type_name}"
1198
+ "# ,
1199
+ ) ;
1200
+
1201
+ uwrite ! (
1202
+ & mut self . stub,
1203
+ r#"
1204
+ /// Destructor of the resource.
1205
+ pub fn {name}::dtor(self : {name}) -> Unit {{
1206
+ abort("todo")
1207
+ }}
1208
+ "#
1209
+ ) ;
1210
+
1211
+ let func_name = self . gen . export_ns . tmp ( & format ! ( "wasmExport{name}Dtor" ) ) ;
1212
+
1213
+ let mut gen = self
1214
+ . gen
1215
+ . interface ( self . resolve , EXPORT_DIR , "" , Direction :: Export ) ;
1216
+
1217
+ uwrite ! (
1218
+ self . ffi,
1219
+ r#"
1220
+ pub fn {func_name}(handle : Int) -> Unit {{
1221
+ {}{name}::dtor(handle)
1222
+ }}
1223
+ "# ,
1224
+ gen . qualify_package( & self . name. to_string( ) )
1225
+ ) ;
1226
+
1227
+ self . gen
1228
+ . export
1229
+ . insert ( func_name, format ! ( "{module}#[dtor]{type_name}" ) ) ;
1230
+ }
1158
1231
}
1159
1232
1160
1233
fn type_flags ( & mut self , _id : TypeId , name : & str , flags : & Flags , docs : & Docs ) {
@@ -1204,11 +1277,16 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
1204
1277
if self . gen . opts . derive_eq {
1205
1278
deriviation. push ( "Eq" )
1206
1279
}
1280
+ let declaration = if self . gen . opts . derive_error && name. contains ( "Error" ) {
1281
+ "type!"
1282
+ } else {
1283
+ "type"
1284
+ } ;
1207
1285
1208
1286
uwrite ! (
1209
1287
self . src,
1210
1288
"
1211
- pub type {name} {ty} derive({})
1289
+ pub {declaration} {name} {ty} derive({})
1212
1290
pub fn {name}::default() -> {name} {{
1213
1291
{}
1214
1292
}}
@@ -1221,13 +1299,16 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
1221
1299
}}
1222
1300
}}
1223
1301
pub fn {name}::set(self : {name}, other: {name}Flag) -> {name} {{
1224
- self.0.lor(other.value())
1302
+ let {name}(flag) = self
1303
+ flag.lor(other.value())
1225
1304
}}
1226
1305
pub fn {name}::unset(self : {name}, other: {name}Flag) -> {name} {{
1227
- self.0.land(other.value().lnot())
1306
+ let {name}(flag) = self
1307
+ flag.land(other.value().lnot())
1228
1308
}}
1229
1309
pub fn {name}::is_set(self : {name}, other: {name}Flag) -> Bool {{
1230
- (self.0.land(other.value()) == other.value())
1310
+ let {name}(flag) = self
1311
+ (flag.land(other.value()) == other.value())
1231
1312
}}
1232
1313
" ,
1233
1314
deriviation. join( ", " ) ,
@@ -1271,11 +1352,16 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
1271
1352
if self . gen . opts . derive_eq {
1272
1353
deriviation. push ( "Eq" )
1273
1354
}
1355
+ let declaration = if self . gen . opts . derive_error && name. contains ( "Error" ) {
1356
+ "type!"
1357
+ } else {
1358
+ "enum"
1359
+ } ;
1274
1360
1275
1361
uwrite ! (
1276
1362
self . src,
1277
1363
"
1278
- pub enum {name} {{
1364
+ pub {declaration} {name} {{
1279
1365
{cases}
1280
1366
}} derive({})
1281
1367
" ,
@@ -1311,11 +1397,16 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
1311
1397
if self . gen . opts . derive_eq {
1312
1398
deriviation. push ( "Eq" )
1313
1399
}
1400
+ let declaration = if self . gen . opts . derive_error && name. contains ( "Error" ) {
1401
+ "type!"
1402
+ } else {
1403
+ "enum"
1404
+ } ;
1314
1405
1315
1406
uwrite ! (
1316
1407
self . src,
1317
1408
"
1318
- pub enum {name} {{
1409
+ pub {declaration} {name} {{
1319
1410
{cases}
1320
1411
}} derive({})
1321
1412
" ,
@@ -1642,8 +1733,9 @@ impl Bindgen for FunctionBindgen<'_, '_> {
1642
1733
Instruction :: CharFromI32 => results. push ( format ! ( "Char::from_int({})" , operands[ 0 ] ) ) ,
1643
1734
Instruction :: I32FromChar => results. push ( format ! ( "({}).to_int()" , operands[ 0 ] ) ) ,
1644
1735
1645
- Instruction :: I32FromU8 | Instruction :: I32FromU16 => {
1646
- results. push ( format ! ( "({}).to_int()" , operands[ 0 ] ) )
1736
+ Instruction :: I32FromU8 => results. push ( format ! ( "({}).to_int()" , operands[ 0 ] ) ) ,
1737
+ Instruction :: I32FromU16 => {
1738
+ results. push ( format ! ( "({}).reinterpret_as_int()" , operands[ 0 ] ) )
1647
1739
}
1648
1740
Instruction :: U8FromI32 => results. push ( format ! ( "({}).to_byte()" , operands[ 0 ] ) ) ,
1649
1741
@@ -1655,11 +1747,16 @@ impl Bindgen for FunctionBindgen<'_, '_> {
1655
1747
Instruction :: I32FromS16 => {
1656
1748
results. push ( format ! ( "{ffi_qualifier}extend16({})" , operands[ 0 ] ) )
1657
1749
}
1658
- Instruction :: U16FromI32 => {
1659
- results. push ( format ! ( "({}.land(0xFFFF).to_uint())" , operands[ 0 ] ) )
1750
+ Instruction :: U16FromI32 => results. push ( format ! (
1751
+ "({}.land(0xFFFF).reinterpret_as_uint())" ,
1752
+ operands[ 0 ]
1753
+ ) ) ,
1754
+ Instruction :: U32FromI32 => {
1755
+ results. push ( format ! ( "({}).reinterpret_as_uint()" , operands[ 0 ] ) )
1756
+ }
1757
+ Instruction :: I32FromU32 => {
1758
+ results. push ( format ! ( "({}).reinterpret_as_int()" , operands[ 0 ] ) )
1660
1759
}
1661
- Instruction :: U32FromI32 => results. push ( format ! ( "({}).to_uint()" , operands[ 0 ] ) ) ,
1662
- Instruction :: I32FromU32 => results. push ( format ! ( "({}).to_int()" , operands[ 0 ] ) ) ,
1663
1760
1664
1761
Instruction :: U64FromI64 => results. push ( format ! ( "({}).to_uint64()" , operands[ 0 ] ) ) ,
1665
1762
Instruction :: I64FromU64 => results. push ( format ! ( "({}).to_int64()" , operands[ 0 ] ) ) ,
@@ -1669,14 +1766,43 @@ impl Bindgen for FunctionBindgen<'_, '_> {
1669
1766
}
1670
1767
Instruction :: BoolFromI32 => results. push ( format ! ( "({} != 0)" , operands[ 0 ] ) ) ,
1671
1768
1672
- Instruction :: FlagsLower { flags, .. } => match flags_repr ( flags) {
1673
- Int :: U8 | Int :: U16 | Int :: U32 => {
1674
- results. push ( format ! ( "({}).0.to_int()" , operands[ 0 ] ) ) ;
1769
+ Instruction :: FlagsLower { flags, ty, .. } => match flags_repr ( flags) {
1770
+ Int :: U8 => {
1771
+ let op = & operands[ 0 ] ;
1772
+ let flag = self . locals . tmp ( "flag" ) ;
1773
+ let ty = self . gen . type_name ( & Type :: Id ( * ty) , false ) ;
1774
+ uwriteln ! (
1775
+ self . src,
1776
+ r#"
1777
+ let {ty}({flag}) = {op}
1778
+ "#
1779
+ ) ;
1780
+ results. push ( format ! ( "{flag}.to_int()" ) ) ;
1781
+ }
1782
+ Int :: U16 | Int :: U32 => {
1783
+ let op = & operands[ 0 ] ;
1784
+ let flag = self . locals . tmp ( "flag" ) ;
1785
+ let ty = self . gen . type_name ( & Type :: Id ( * ty) , false ) ;
1786
+ uwriteln ! (
1787
+ self . src,
1788
+ r#"
1789
+ let {ty}({flag}) = {op}
1790
+ "#
1791
+ ) ;
1792
+ results. push ( format ! ( "{flag}.reinterpret_as_int()" ) ) ;
1675
1793
}
1676
1794
Int :: U64 => {
1677
1795
let op = & operands[ 0 ] ;
1678
- results. push ( format ! ( "(({op}).0.to_int())" ) ) ;
1679
- results. push ( format ! ( "((({op}).0.lsr(32)).to_int())" ) ) ;
1796
+ let flag = self . locals . tmp ( "flag" ) ;
1797
+ let ty = self . gen . type_name ( & Type :: Id ( * ty) , false ) ;
1798
+ uwriteln ! (
1799
+ self . src,
1800
+ r#"
1801
+ let {ty}({flag}) = {op}
1802
+ "#
1803
+ ) ;
1804
+ results. push ( format ! ( "({flag}.to_int())" ) ) ;
1805
+ results. push ( format ! ( "({flag}.lsr(32)).to_int())" ) ) ;
1680
1806
}
1681
1807
} ,
1682
1808
@@ -1690,24 +1816,32 @@ impl Bindgen for FunctionBindgen<'_, '_> {
1690
1816
}
1691
1817
Int :: U16 | Int :: U32 => {
1692
1818
results. push ( format ! (
1693
- "{}({}.to_uint ())" ,
1819
+ "{}({}.reinterpret_as_uint ())" ,
1694
1820
self . gen . type_name( & Type :: Id ( * ty) , true ) ,
1695
1821
operands[ 0 ]
1696
1822
) ) ;
1697
1823
}
1698
1824
Int :: U64 => {
1699
1825
results. push ( format ! (
1700
- "{}(({}).to_uint ().to_uint64().lor(({}).to_uint ().to_uint64.lsl(32)))" ,
1826
+ "{}(({}).reinterpret_as_uint ().to_uint64().lor(({}).reinterpret_as_uint ().to_uint64.lsl(32)))" ,
1701
1827
self . gen . type_name( & Type :: Id ( * ty) , true ) ,
1702
1828
operands[ 0 ] ,
1703
1829
operands[ 1 ]
1704
1830
) ) ;
1705
1831
}
1706
1832
} ,
1707
1833
1708
- Instruction :: HandleLower { .. } => {
1834
+ Instruction :: HandleLower { ty , .. } => {
1709
1835
let op = & operands[ 0 ] ;
1710
- results. push ( format ! ( "{op}.0" ) ) ;
1836
+ let handle = self . locals . tmp ( "handle" ) ;
1837
+ let ty = self . gen . type_name ( & Type :: Id ( * ty) , false ) ;
1838
+ uwrite ! (
1839
+ self . src,
1840
+ r#"
1841
+ let {ty}({handle}) = {op}
1842
+ "#
1843
+ ) ;
1844
+ results. push ( handle) ;
1711
1845
}
1712
1846
Instruction :: HandleLift { ty, .. } => {
1713
1847
let op = & operands[ 0 ] ;
0 commit comments