@@ -24,8 +24,6 @@ use wit_bindgen_core::{
24
24
// TODO: Export will share the type signatures with the import by using a newtype alias
25
25
// TODO: Export resource is not handled correctly : resource.new / resource.drop / resource.rep / dtor
26
26
27
- const EXPORT_DIR : & str = "gen" ;
28
-
29
27
const FFI_DIR : & str = "ffi" ;
30
28
31
29
const FFI : & str = r#"
@@ -90,7 +88,7 @@ pub fn malloc(size : Int) -> Int {
90
88
let words = size / 4 + 1
91
89
let address = malloc_inline(8 + words * 4)
92
90
store32(address, 1)
93
- store32(address + 4, words.lsl(8).lor( 246) )
91
+ store32(address + 4, (words << 8) | 246)
94
92
store8(address + words * 4 + 7, 3 - size % 4)
95
93
address + 8
96
94
}
@@ -175,7 +173,7 @@ pub fn ptr2double_array(ptr : Int) -> FixedArray[Double] {
175
173
176
174
fn set_64_header_ffi(offset : Int) -> Unit {
177
175
let len = load32(offset)
178
- store32(offset, len.lsr(1) )
176
+ store32(offset, len >> 1 )
179
177
store8(offset, 241)
180
178
}
181
179
@@ -202,6 +200,9 @@ pub struct Opts {
202
200
/// Whether or not to generate stub files ; useful for update after WIT change
203
201
#[ cfg_attr( feature = "clap" , arg( long, default_value_t = false ) ) ]
204
202
pub ignore_stub : bool ,
203
+ /// The package/dir to generate the program entrance
204
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "gen" ) ) ]
205
+ pub gen_dir : String ,
205
206
}
206
207
207
208
impl Opts {
@@ -281,7 +282,7 @@ impl WorldGenerator for MoonBit {
281
282
id : InterfaceId ,
282
283
files : & mut Files ,
283
284
) -> Result < ( ) > {
284
- let name = interface_name ( resolve, key, Direction :: Import ) ;
285
+ let name = interface_name ( resolve, key) ;
285
286
let name = self . interface_ns . tmp ( & name) ;
286
287
self . import_interface_names . insert ( id, name. clone ( ) ) ;
287
288
@@ -331,7 +332,7 @@ impl WorldGenerator for MoonBit {
331
332
id : InterfaceId ,
332
333
files : & mut Files ,
333
334
) -> Result < ( ) > {
334
- let name = interface_name ( resolve, key, Direction :: Export ) ;
335
+ let name = format ! ( "{}.{}" , self . opts . gen_dir , interface_name( resolve, key) ) ;
335
336
let name = self . interface_ns . tmp ( & name) ;
336
337
self . export_interface_names . insert ( id, name. clone ( ) ) ;
337
338
@@ -363,7 +364,7 @@ impl WorldGenerator for MoonBit {
363
364
funcs : & [ ( & str , & Function ) ] ,
364
365
_files : & mut Files ,
365
366
) -> Result < ( ) > {
366
- let name = world_name ( resolve, world) ;
367
+ let name = format ! ( "{}.{}" , self . opts . gen_dir , world_name( resolve, world) ) ;
367
368
let mut gen = self . interface ( resolve, & name, "$root" , Direction :: Export ) ;
368
369
369
370
for ( _, func) in funcs {
@@ -412,7 +413,7 @@ impl WorldGenerator for MoonBit {
412
413
413
414
let version = env ! ( "CARGO_PKG_VERSION" ) ;
414
415
415
- let mut generate_pkg_definition = |name : & str , files : & mut Files | {
416
+ let mut generate_pkg_definition = |name : & String , files : & mut Files | {
416
417
let directory = name. replace ( '.' , "/" ) ;
417
418
let imports: Option < & mut Imports > = self . package_import . get_mut ( name) ;
418
419
if let Some ( imports) = imports {
@@ -472,7 +473,11 @@ impl WorldGenerator for MoonBit {
472
473
473
474
files. push ( & format ! ( "{directory}/top.mbt" ) , indent ( & src) . as_bytes ( ) ) ;
474
475
if !self . opts . ignore_stub {
475
- files. push ( & format ! ( "{directory}/stub.mbt" ) , indent ( & stub) . as_bytes ( ) ) ;
476
+ files. push (
477
+ & format ! ( "{}/{directory}/stub.mbt" , self . opts. gen_dir) ,
478
+ indent ( & stub) . as_bytes ( ) ,
479
+ ) ;
480
+ generate_pkg_definition ( & format ! ( "{}.{}" , self . opts. gen_dir, name) , files) ;
476
481
}
477
482
478
483
let generate_ffi =
@@ -488,7 +493,11 @@ impl WorldGenerator for MoonBit {
488
493
uwriteln ! ( & mut body, "{b}" ) ;
489
494
490
495
files. push (
491
- & format ! ( "{EXPORT_DIR}/{}_export.mbt" , directory. to_snake_case( ) ) ,
496
+ & format ! (
497
+ "{}/{}_export.mbt" ,
498
+ self . opts. gen_dir,
499
+ directory. to_snake_case( )
500
+ ) ,
492
501
indent ( & body) . as_bytes ( ) ,
493
502
) ;
494
503
} ;
@@ -528,8 +537,8 @@ impl WorldGenerator for MoonBit {
528
537
files. push ( & format ! ( "{directory}/top.mbt" ) , indent ( & src) . as_bytes ( ) ) ;
529
538
if !self . opts . ignore_stub {
530
539
files. push ( & format ! ( "{directory}/stub.mbt" ) , indent ( & stub) . as_bytes ( ) ) ;
540
+ generate_pkg_definition ( & name, files) ;
531
541
}
532
- generate_pkg_definition ( & name, files) ;
533
542
generate_ffi ( directory, fragments, files) ;
534
543
}
535
544
@@ -541,12 +550,16 @@ impl WorldGenerator for MoonBit {
541
550
files. push ( & format ! ( "{FFI_DIR}/moon.pkg.json" ) , "{}" . as_bytes ( ) ) ;
542
551
543
552
// Export project files
544
- let mut body = Source :: default ( ) ;
545
- uwriteln ! ( & mut body, "{{ \" name\" : \" {project_name}\" }}" ) ;
546
- files. push ( & format ! ( "moon.mod.json" ) , body. as_bytes ( ) ) ;
553
+ if !self . opts . ignore_stub {
554
+ let mut body = Source :: default ( ) ;
555
+ uwriteln ! ( & mut body, "{{ \" name\" : \" {project_name}\" }}" ) ;
556
+ files. push ( & format ! ( "moon.mod.json" ) , body. as_bytes ( ) ) ;
557
+ }
558
+
559
+ let export_dir = self . opts . gen_dir . clone ( ) ;
547
560
548
561
// Export project entry point
549
- let mut gen = self . interface ( resolve, EXPORT_DIR , "" , Direction :: Export ) ;
562
+ let mut gen = self . interface ( resolve, & export_dir . as_str ( ) , "" , Direction :: Export ) ;
550
563
let ffi_qualifier = gen. qualify_package ( & FFI_DIR . to_string ( ) ) ;
551
564
552
565
let mut body = Source :: default ( ) ;
@@ -586,7 +599,10 @@ impl WorldGenerator for MoonBit {
586
599
self . return_area_size,
587
600
) ;
588
601
}
589
- files. push ( & format ! ( "{EXPORT_DIR}/ffi.mbt" ) , indent ( & body) . as_bytes ( ) ) ;
602
+ files. push (
603
+ & format ! ( "{}/ffi.mbt" , self . opts. gen_dir) ,
604
+ indent ( & body) . as_bytes ( ) ,
605
+ ) ;
590
606
self . export
591
607
. insert ( "cabi_realloc" . into ( ) , "cabi_realloc" . into ( ) ) ;
592
608
@@ -612,7 +628,7 @@ impl WorldGenerator for MoonBit {
612
628
"# ,
613
629
exports. join( ", " )
614
630
) ;
615
- if let Some ( imports) = self . package_import . get_mut ( EXPORT_DIR ) {
631
+ if let Some ( imports) = self . package_import . get_mut ( & self . opts . gen_dir ) {
616
632
let mut deps = imports
617
633
. packages
618
634
. iter ( )
@@ -635,7 +651,7 @@ impl WorldGenerator for MoonBit {
635
651
" ,
636
652
) ;
637
653
files. push (
638
- & format ! ( "{EXPORT_DIR }/moon.pkg.json" ) ,
654
+ & format ! ( "{}/moon.pkg.json" , self . opts . gen_dir , ) ,
639
655
indent ( & body) . as_bytes ( ) ,
640
656
) ;
641
657
@@ -830,9 +846,14 @@ impl InterfaceGenerator<'_> {
830
846
831
847
let export_name = func. legacy_core_export_name ( interface_name) ;
832
848
833
- let mut toplevel_generator =
834
- self . gen
835
- . interface ( self . resolve , EXPORT_DIR , self . module , Direction :: Export ) ;
849
+ let export_dir = self . gen . opts . gen_dir . clone ( ) ;
850
+
851
+ let mut toplevel_generator = self . gen . interface (
852
+ self . resolve ,
853
+ export_dir. as_str ( ) ,
854
+ self . module ,
855
+ Direction :: Export ,
856
+ ) ;
836
857
837
858
let mut bindgen = FunctionBindgen :: new (
838
859
& mut toplevel_generator,
@@ -1220,9 +1241,11 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
1220
1241
1221
1242
let func_name = self . gen . export_ns . tmp ( & format ! ( "wasmExport{name}Dtor" ) ) ;
1222
1243
1223
- let mut gen = self
1224
- . gen
1225
- . interface ( self . resolve , EXPORT_DIR , "" , Direction :: Export ) ;
1244
+ let export_dir = self . gen . opts . gen_dir . clone ( ) ;
1245
+
1246
+ let mut gen =
1247
+ self . gen
1248
+ . interface ( self . resolve , export_dir. as_str ( ) , "" , Direction :: Export ) ;
1226
1249
1227
1250
uwrite ! (
1228
1251
self . ffi,
@@ -1768,8 +1791,12 @@ impl Bindgen for FunctionBindgen<'_, '_> {
1768
1791
results. push ( format ! ( "({}).reinterpret_as_int()" , operands[ 0 ] ) )
1769
1792
}
1770
1793
1771
- Instruction :: U64FromI64 => results. push ( format ! ( "({}).to_uint64()" , operands[ 0 ] ) ) ,
1772
- Instruction :: I64FromU64 => results. push ( format ! ( "({}).to_int64()" , operands[ 0 ] ) ) ,
1794
+ Instruction :: U64FromI64 => {
1795
+ results. push ( format ! ( "({}).reinterpret_as_uint64()" , operands[ 0 ] ) )
1796
+ }
1797
+ Instruction :: I64FromU64 => {
1798
+ results. push ( format ! ( "({}).reinterpret_as_int64()" , operands[ 0 ] ) )
1799
+ }
1773
1800
1774
1801
Instruction :: I32FromBool => {
1775
1802
results. push ( format ! ( "(if {} {{ 1 }} else {{ 0 }})" , operands[ 0 ] ) ) ;
@@ -1833,7 +1860,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
1833
1860
}
1834
1861
Int :: U64 => {
1835
1862
results. push ( format ! (
1836
- "{}(({}).reinterpret_as_uint().to_uint64().lor (({}).reinterpret_as_uint().to_uint64.lsl(32) ))" ,
1863
+ "{}(({}).reinterpret_as_uint().to_uint64() | (({}).reinterpret_as_uint().to_uint64() << 32 ))" ,
1837
1864
self . gen . type_name( & Type :: Id ( * ty) , true ) ,
1838
1865
operands[ 0 ] ,
1839
1866
operands[ 1 ]
@@ -2714,13 +2741,10 @@ fn indent(code: &str) -> Source {
2714
2741
}
2715
2742
2716
2743
fn world_name ( resolve : & Resolve , world : WorldId ) -> String {
2717
- format ! (
2718
- "worlds.{}" ,
2719
- resolve. worlds[ world] . name. to_lower_camel_case( )
2720
- )
2744
+ format ! ( "world.{}" , resolve. worlds[ world] . name. to_lower_camel_case( ) )
2721
2745
}
2722
2746
2723
- fn interface_name ( resolve : & Resolve , name : & WorldKey , direction : Direction ) -> String {
2747
+ fn interface_name ( resolve : & Resolve , name : & WorldKey ) -> String {
2724
2748
let pkg = match name {
2725
2749
WorldKey :: Name ( _) => None ,
2726
2750
WorldKey :: Interface ( id) => {
@@ -2736,11 +2760,7 @@ fn interface_name(resolve: &Resolve, name: &WorldKey, direction: Direction) -> S
2736
2760
. to_lower_camel_case ( ) ;
2737
2761
2738
2762
format ! (
2739
- "interface.{}.{}{name}" ,
2740
- match direction {
2741
- Direction :: Import => "imports" ,
2742
- Direction :: Export => "exports" ,
2743
- } ,
2763
+ "interface.{}{name}" ,
2744
2764
if let Some ( name) = & pkg {
2745
2765
format!(
2746
2766
"{}.{}." ,
@@ -2764,7 +2784,7 @@ impl ToMoonBitIdent for str {
2764
2784
"continue" | "for" | "match" | "if" | "pub" | "priv" | "readonly" | "break"
2765
2785
| "raise" | "try" | "except" | "catch" | "else" | "enum" | "struct" | "type"
2766
2786
| "trait" | "return" | "let" | "mut" | "while" | "loop" | "extern" | "with"
2767
- | "throw" | "init" | "main" | "test" | "in" | "guard" => {
2787
+ | "throw" | "init" | "main" | "test" | "in" | "guard" | "typealias" => {
2768
2788
format ! ( "{self}_" )
2769
2789
}
2770
2790
_ => self . to_snake_case ( ) ,
@@ -2782,7 +2802,7 @@ impl ToMoonBitTypeIdent for str {
2782
2802
match self . to_upper_camel_case ( ) . as_str ( ) {
2783
2803
type_name @ ( "Bool" | "Byte" | "Int" | "Int64" | "UInt" | "UInt64" | "Float"
2784
2804
| "Double" | "Error" | "Buffer" | "Bytes" | "Array" | "FixedArray"
2785
- | "Map" | "String" | "Option" | "Result" | "Char" ) => {
2805
+ | "Map" | "String" | "Option" | "Result" | "Char" | "Json" ) => {
2786
2806
format ! ( "{type_name}_" )
2787
2807
}
2788
2808
type_name => type_name. to_owned ( ) ,
0 commit comments