@@ -24,8 +24,6 @@ use wit_bindgen_core::{
2424// TODO: Export will share the type signatures with the import by using a newtype alias
2525// TODO: Export resource is not handled correctly : resource.new / resource.drop / resource.rep / dtor
2626
27- const EXPORT_DIR : & str = "gen" ;
28-
2927const FFI_DIR : & str = "ffi" ;
3028
3129const FFI : & str = r#"
@@ -90,7 +88,7 @@ pub fn malloc(size : Int) -> Int {
9088 let words = size / 4 + 1
9189 let address = malloc_inline(8 + words * 4)
9290 store32(address, 1)
93- store32(address + 4, words.lsl(8).lor( 246) )
91+ store32(address + 4, (words << 8) | 246)
9492 store8(address + words * 4 + 7, 3 - size % 4)
9593 address + 8
9694}
@@ -175,7 +173,7 @@ pub fn ptr2double_array(ptr : Int) -> FixedArray[Double] {
175173
176174fn set_64_header_ffi(offset : Int) -> Unit {
177175 let len = load32(offset)
178- store32(offset, len.lsr(1) )
176+ store32(offset, len >> 1 )
179177 store8(offset, 241)
180178}
181179
@@ -202,6 +200,9 @@ pub struct Opts {
202200 /// Whether or not to generate stub files ; useful for update after WIT change
203201 #[ cfg_attr( feature = "clap" , arg( long, default_value_t = false ) ) ]
204202 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 ,
205206}
206207
207208impl Opts {
@@ -281,7 +282,7 @@ impl WorldGenerator for MoonBit {
281282 id : InterfaceId ,
282283 files : & mut Files ,
283284 ) -> Result < ( ) > {
284- let name = interface_name ( resolve, key, Direction :: Import ) ;
285+ let name = interface_name ( resolve, key) ;
285286 let name = self . interface_ns . tmp ( & name) ;
286287 self . import_interface_names . insert ( id, name. clone ( ) ) ;
287288
@@ -331,7 +332,7 @@ impl WorldGenerator for MoonBit {
331332 id : InterfaceId ,
332333 files : & mut Files ,
333334 ) -> Result < ( ) > {
334- let name = interface_name ( resolve, key, Direction :: Export ) ;
335+ let name = format ! ( "{}.{}" , self . opts . gen_dir , interface_name( resolve, key) ) ;
335336 let name = self . interface_ns . tmp ( & name) ;
336337 self . export_interface_names . insert ( id, name. clone ( ) ) ;
337338
@@ -363,7 +364,7 @@ impl WorldGenerator for MoonBit {
363364 funcs : & [ ( & str , & Function ) ] ,
364365 _files : & mut Files ,
365366 ) -> Result < ( ) > {
366- let name = world_name ( resolve, world) ;
367+ let name = format ! ( "{}.{}" , self . opts . gen_dir , world_name( resolve, world) ) ;
367368 let mut gen = self . interface ( resolve, & name, "$root" , Direction :: Export ) ;
368369
369370 for ( _, func) in funcs {
@@ -412,7 +413,7 @@ impl WorldGenerator for MoonBit {
412413
413414 let version = env ! ( "CARGO_PKG_VERSION" ) ;
414415
415- let mut generate_pkg_definition = |name : & str , files : & mut Files | {
416+ let mut generate_pkg_definition = |name : & String , files : & mut Files | {
416417 let directory = name. replace ( '.' , "/" ) ;
417418 let imports: Option < & mut Imports > = self . package_import . get_mut ( name) ;
418419 if let Some ( imports) = imports {
@@ -472,7 +473,11 @@ impl WorldGenerator for MoonBit {
472473
473474 files. push ( & format ! ( "{directory}/top.mbt" ) , indent ( & src) . as_bytes ( ) ) ;
474475 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) ;
476481 }
477482
478483 let generate_ffi =
@@ -488,7 +493,11 @@ impl WorldGenerator for MoonBit {
488493 uwriteln ! ( & mut body, "{b}" ) ;
489494
490495 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+ ) ,
492501 indent ( & body) . as_bytes ( ) ,
493502 ) ;
494503 } ;
@@ -528,8 +537,8 @@ impl WorldGenerator for MoonBit {
528537 files. push ( & format ! ( "{directory}/top.mbt" ) , indent ( & src) . as_bytes ( ) ) ;
529538 if !self . opts . ignore_stub {
530539 files. push ( & format ! ( "{directory}/stub.mbt" ) , indent ( & stub) . as_bytes ( ) ) ;
540+ generate_pkg_definition ( & name, files) ;
531541 }
532- generate_pkg_definition ( & name, files) ;
533542 generate_ffi ( directory, fragments, files) ;
534543 }
535544
@@ -541,12 +550,16 @@ impl WorldGenerator for MoonBit {
541550 files. push ( & format ! ( "{FFI_DIR}/moon.pkg.json" ) , "{}" . as_bytes ( ) ) ;
542551
543552 // 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 ( ) ;
547560
548561 // 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 ) ;
550563 let ffi_qualifier = gen. qualify_package ( & FFI_DIR . to_string ( ) ) ;
551564
552565 let mut body = Source :: default ( ) ;
@@ -586,7 +599,10 @@ impl WorldGenerator for MoonBit {
586599 self . return_area_size,
587600 ) ;
588601 }
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+ ) ;
590606 self . export
591607 . insert ( "cabi_realloc" . into ( ) , "cabi_realloc" . into ( ) ) ;
592608
@@ -612,7 +628,7 @@ impl WorldGenerator for MoonBit {
612628 "# ,
613629 exports. join( ", " )
614630 ) ;
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 ) {
616632 let mut deps = imports
617633 . packages
618634 . iter ( )
@@ -635,7 +651,7 @@ impl WorldGenerator for MoonBit {
635651 " ,
636652 ) ;
637653 files. push (
638- & format ! ( "{EXPORT_DIR }/moon.pkg.json" ) ,
654+ & format ! ( "{}/moon.pkg.json" , self . opts . gen_dir , ) ,
639655 indent ( & body) . as_bytes ( ) ,
640656 ) ;
641657
@@ -830,9 +846,14 @@ impl InterfaceGenerator<'_> {
830846
831847 let export_name = func. legacy_core_export_name ( interface_name) ;
832848
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+ ) ;
836857
837858 let mut bindgen = FunctionBindgen :: new (
838859 & mut toplevel_generator,
@@ -1220,9 +1241,11 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
12201241
12211242 let func_name = self . gen . export_ns . tmp ( & format ! ( "wasmExport{name}Dtor" ) ) ;
12221243
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 ) ;
12261249
12271250 uwrite ! (
12281251 self . ffi,
@@ -1768,8 +1791,12 @@ impl Bindgen for FunctionBindgen<'_, '_> {
17681791 results. push ( format ! ( "({}).reinterpret_as_int()" , operands[ 0 ] ) )
17691792 }
17701793
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+ }
17731800
17741801 Instruction :: I32FromBool => {
17751802 results. push ( format ! ( "(if {} {{ 1 }} else {{ 0 }})" , operands[ 0 ] ) ) ;
@@ -1833,7 +1860,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
18331860 }
18341861 Int :: U64 => {
18351862 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 ))" ,
18371864 self . gen . type_name( & Type :: Id ( * ty) , true ) ,
18381865 operands[ 0 ] ,
18391866 operands[ 1 ]
@@ -2714,13 +2741,10 @@ fn indent(code: &str) -> Source {
27142741}
27152742
27162743fn 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( ) )
27212745}
27222746
2723- fn interface_name ( resolve : & Resolve , name : & WorldKey , direction : Direction ) -> String {
2747+ fn interface_name ( resolve : & Resolve , name : & WorldKey ) -> String {
27242748 let pkg = match name {
27252749 WorldKey :: Name ( _) => None ,
27262750 WorldKey :: Interface ( id) => {
@@ -2736,11 +2760,7 @@ fn interface_name(resolve: &Resolve, name: &WorldKey, direction: Direction) -> S
27362760 . to_lower_camel_case ( ) ;
27372761
27382762 format ! (
2739- "interface.{}.{}{name}" ,
2740- match direction {
2741- Direction :: Import => "imports" ,
2742- Direction :: Export => "exports" ,
2743- } ,
2763+ "interface.{}{name}" ,
27442764 if let Some ( name) = & pkg {
27452765 format!(
27462766 "{}.{}." ,
@@ -2764,7 +2784,7 @@ impl ToMoonBitIdent for str {
27642784 "continue" | "for" | "match" | "if" | "pub" | "priv" | "readonly" | "break"
27652785 | "raise" | "try" | "except" | "catch" | "else" | "enum" | "struct" | "type"
27662786 | "trait" | "return" | "let" | "mut" | "while" | "loop" | "extern" | "with"
2767- | "throw" | "init" | "main" | "test" | "in" | "guard" => {
2787+ | "throw" | "init" | "main" | "test" | "in" | "guard" | "typealias" => {
27682788 format ! ( "{self}_" )
27692789 }
27702790 _ => self . to_snake_case ( ) ,
@@ -2782,7 +2802,7 @@ impl ToMoonBitTypeIdent for str {
27822802 match self . to_upper_camel_case ( ) . as_str ( ) {
27832803 type_name @ ( "Bool" | "Byte" | "Int" | "Int64" | "UInt" | "UInt64" | "Float"
27842804 | "Double" | "Error" | "Buffer" | "Bytes" | "Array" | "FixedArray"
2785- | "Map" | "String" | "Option" | "Result" | "Char" ) => {
2805+ | "Map" | "String" | "Option" | "Result" | "Char" | "Json" ) => {
27862806 format ! ( "{type_name}_" )
27872807 }
27882808 type_name => type_name. to_owned ( ) ,
0 commit comments