@@ -325,7 +325,7 @@ impl<'a> Context<'a> {
325
325
326
326
wasm_import_object. push_str ( & format ! ( " {}: {{\n " , crate :: PLACEHOLDER_MODULE ) ) ;
327
327
328
- for ( id, js) in crate :: sorted_iter ( & self . wasm_import_definitions ) {
328
+ for ( id, js) in iter_by_import ( & self . wasm_import_definitions , self . module ) {
329
329
let import = self . module . imports . get ( * id) ;
330
330
wasm_import_object. push_str ( & format ! ( "{}: {},\n " , & import. name, js. trim( ) ) ) ;
331
331
}
@@ -424,8 +424,8 @@ impl<'a> Context<'a> {
424
424
425
425
js. push_str ( "let wasm;\n " ) ;
426
426
427
- for ( id, js) in crate :: sorted_iter ( & self . wasm_import_definitions ) {
428
- let import = self . module . imports . get_mut ( * id) ;
427
+ for ( id, js) in iter_by_import ( & self . wasm_import_definitions , self . module ) {
428
+ let import = self . module . imports . get ( * id) ;
429
429
footer. push_str ( "\n module.exports." ) ;
430
430
footer. push_str ( & import. name ) ;
431
431
footer. push_str ( " = " ) ;
@@ -463,7 +463,7 @@ impl<'a> Context<'a> {
463
463
// and let the bundler/runtime take care of it.
464
464
// With Node we manually read the Wasm file from the filesystem and instantiate it.
465
465
OutputMode :: Bundler { .. } | OutputMode :: Node { module : true } => {
466
- for ( id, js) in crate :: sorted_iter ( & self . wasm_import_definitions ) {
466
+ for ( id, js) in iter_by_import ( & self . wasm_import_definitions , self . module ) {
467
467
let import = self . module . imports . get_mut ( * id) ;
468
468
import. module = format ! ( "./{}_bg.js" , module_name) ;
469
469
if let Some ( body) = js. strip_prefix ( "function" ) {
@@ -791,7 +791,7 @@ __wbg_set_wasm(wasm);"
791
791
imports_init. push_str ( module_name) ;
792
792
imports_init. push_str ( " = {};\n " ) ;
793
793
794
- for ( id, js) in crate :: sorted_iter ( & self . wasm_import_definitions ) {
794
+ for ( id, js) in iter_by_import ( & self . wasm_import_definitions , self . module ) {
795
795
let import = self . module . imports . get_mut ( * id) ;
796
796
import. module = module_name. to_string ( ) ;
797
797
imports_init. push_str ( "imports." ) ;
@@ -2531,12 +2531,13 @@ __wbg_set_wasm(wasm);"
2531
2531
if self . config . symbol_dispose && !self . aux . structs . is_empty ( ) {
2532
2532
self . expose_symbol_dispose ( ) ?;
2533
2533
}
2534
- for ( id, adapter) in crate :: sorted_iter ( & self . wit . adapters ) {
2534
+
2535
+ for ( id, adapter, kind) in iter_adapeter ( self . aux , self . wit , self . module ) {
2535
2536
let instrs = match & adapter. kind {
2536
2537
AdapterKind :: Import { .. } => continue ,
2537
2538
AdapterKind :: Local { instructions } => instructions,
2538
2539
} ;
2539
- self . generate_adapter ( * id, adapter, instrs) ?;
2540
+ self . generate_adapter ( id, adapter, instrs, kind ) ?;
2540
2541
}
2541
2542
2542
2543
let mut pairs = self . aux . export_map . iter ( ) . collect :: < Vec < _ > > ( ) ;
@@ -2614,26 +2615,10 @@ __wbg_set_wasm(wasm);"
2614
2615
id : AdapterId ,
2615
2616
adapter : & Adapter ,
2616
2617
instrs : & [ InstructionData ] ,
2618
+ kind : ContextAdapterKind ,
2617
2619
) -> Result < ( ) , Error > {
2618
- enum Kind < ' a > {
2619
- Export ( & ' a AuxExport ) ,
2620
- Import ( walrus:: ImportId ) ,
2621
- Adapter ,
2622
- }
2623
-
2624
- let kind = match self . aux . export_map . get ( & id) {
2625
- Some ( export) => Kind :: Export ( export) ,
2626
- None => {
2627
- let core = self . wit . implements . iter ( ) . find ( |pair| pair. 2 == id) ;
2628
- match core {
2629
- Some ( ( core, _, _) ) => Kind :: Import ( * core) ,
2630
- None => Kind :: Adapter ,
2631
- }
2632
- }
2633
- } ;
2634
-
2635
2620
let catch = self . aux . imports_with_catch . contains ( & id) ;
2636
- if let Kind :: Import ( core) = kind {
2621
+ if let ContextAdapterKind :: Import ( core) = kind {
2637
2622
if !catch && self . attempt_direct_import ( core, instrs) ? {
2638
2623
return Ok ( ( ) ) ;
2639
2624
}
@@ -2643,16 +2628,16 @@ __wbg_set_wasm(wasm);"
2643
2628
// export that we're generating.
2644
2629
let mut builder = binding:: Builder :: new ( self ) ;
2645
2630
builder. log_error ( match kind {
2646
- Kind :: Export ( _) | Kind :: Adapter => false ,
2647
- Kind :: Import ( _) => builder. cx . config . debug ,
2631
+ ContextAdapterKind :: Export ( _) | ContextAdapterKind :: Adapter => false ,
2632
+ ContextAdapterKind :: Import ( _) => builder. cx . config . debug ,
2648
2633
} ) ;
2649
2634
builder. catch ( catch) ;
2650
2635
let mut arg_names = & None ;
2651
2636
let mut asyncness = false ;
2652
2637
let mut variadic = false ;
2653
2638
let mut generate_jsdoc = false ;
2654
2639
match kind {
2655
- Kind :: Export ( export) => {
2640
+ ContextAdapterKind :: Export ( export) => {
2656
2641
arg_names = & export. arg_names ;
2657
2642
asyncness = export. asyncness ;
2658
2643
variadic = export. variadic ;
@@ -2667,8 +2652,8 @@ __wbg_set_wasm(wasm);"
2667
2652
} ,
2668
2653
}
2669
2654
}
2670
- Kind :: Import ( _) => { }
2671
- Kind :: Adapter => { }
2655
+ ContextAdapterKind :: Import ( _) => { }
2656
+ ContextAdapterKind :: Adapter => { }
2672
2657
}
2673
2658
2674
2659
// Process the `binding` and generate a bunch of JS/TypeScript/etc.
@@ -2692,23 +2677,27 @@ __wbg_set_wasm(wasm);"
2692
2677
generate_jsdoc,
2693
2678
)
2694
2679
. with_context ( || match kind {
2695
- Kind :: Export ( e) => format ! ( "failed to generate bindings for `{}`" , e. debug_name) ,
2696
- Kind :: Import ( i) => {
2680
+ ContextAdapterKind :: Export ( e) => {
2681
+ format ! ( "failed to generate bindings for `{}`" , e. debug_name)
2682
+ }
2683
+ ContextAdapterKind :: Import ( i) => {
2697
2684
let i = builder. cx . module . imports . get ( i) ;
2698
2685
format ! (
2699
2686
"failed to generate bindings for import of `{}::{}`" ,
2700
2687
i. module, i. name
2701
2688
)
2702
2689
}
2703
- Kind :: Adapter => "failed to generates bindings for adapter" . to_string ( ) ,
2690
+ ContextAdapterKind :: Adapter => {
2691
+ "failed to generates bindings for adapter" . to_string ( )
2692
+ }
2704
2693
} ) ?;
2705
2694
2706
2695
self . typescript_refs . extend ( ts_refs) ;
2707
2696
2708
2697
// Once we've got all the JS then put it in the right location depending
2709
2698
// on what's being exported.
2710
2699
match kind {
2711
- Kind :: Export ( export) => {
2700
+ ContextAdapterKind :: Export ( export) => {
2712
2701
assert ! ( !catch) ;
2713
2702
assert ! ( !log_error) ;
2714
2703
@@ -2795,7 +2784,7 @@ __wbg_set_wasm(wasm);"
2795
2784
}
2796
2785
}
2797
2786
}
2798
- Kind :: Import ( core) => {
2787
+ ContextAdapterKind :: Import ( core) => {
2799
2788
let code = if catch {
2800
2789
format ! (
2801
2790
"function() {{ return handleError(function {}, arguments) }}" ,
@@ -2812,7 +2801,7 @@ __wbg_set_wasm(wasm);"
2812
2801
2813
2802
self . wasm_import_definitions . insert ( core, code) ;
2814
2803
}
2815
- Kind :: Adapter => {
2804
+ ContextAdapterKind :: Adapter => {
2816
2805
assert ! ( !catch) ;
2817
2806
assert ! ( !log_error) ;
2818
2807
@@ -4137,6 +4126,102 @@ __wbg_set_wasm(wasm);"
4137
4126
}
4138
4127
}
4139
4128
4129
+ /// A categorization of adapters for the purpose of code generation.
4130
+ ///
4131
+ /// This is different from [`AdapterKind`] and is only used internally in the
4132
+ /// code generation process.
4133
+ enum ContextAdapterKind < ' a > {
4134
+ /// An exported function, method, constrctor, or getter/setter.
4135
+ Export ( & ' a AuxExport ) ,
4136
+ /// An imported function or intrinsic.
4137
+ Import ( walrus:: ImportId ) ,
4138
+ Adapter ,
4139
+ }
4140
+ impl < ' a > ContextAdapterKind < ' a > {
4141
+ fn get ( id : AdapterId , aux : & ' a WasmBindgenAux , wit : & ' a NonstandardWitSection ) -> Self {
4142
+ match aux. export_map . get ( & id) {
4143
+ Some ( export) => ContextAdapterKind :: Export ( export) ,
4144
+ None => {
4145
+ let core = wit. implements . iter ( ) . find ( |pair| pair. 2 == id) ;
4146
+ match core {
4147
+ Some ( ( core, _, _) ) => ContextAdapterKind :: Import ( * core) ,
4148
+ None => ContextAdapterKind :: Adapter ,
4149
+ }
4150
+ }
4151
+ }
4152
+ }
4153
+ }
4154
+
4155
+ /// Iterate over the adapters in a deterministic order.
4156
+ fn iter_adapeter < ' a > (
4157
+ aux : & ' a WasmBindgenAux ,
4158
+ wit : & ' a NonstandardWitSection ,
4159
+ module : & Module ,
4160
+ ) -> Vec < ( AdapterId , & ' a Adapter , ContextAdapterKind < ' a > ) > {
4161
+ let mut adapters: Vec < _ > = wit
4162
+ . adapters
4163
+ . iter ( )
4164
+ . map ( |( id, adapter) | {
4165
+ // we need the kind of the adapter to properly sort them
4166
+ let kind = ContextAdapterKind :: get ( * id, aux, wit) ;
4167
+ ( * id, adapter, kind)
4168
+ } )
4169
+ . collect ( ) ;
4170
+
4171
+ // Since `wit.adapters` is a BTreeMap, the adapters are already sorted by
4172
+ // their ID. This is good enough for exports and adapters, but imports need
4173
+ // to be sorted by their name.
4174
+ //
4175
+ // Note: we do *NOT* want to sort exports by name. By default, exports are
4176
+ // the order in which they were defined in the Rust code. Sorting them by
4177
+ // name would break that order and take away control from the user.
4178
+
4179
+ adapters. sort_by ( |( _, _, a) , ( _, _, b) | {
4180
+ fn get_kind_order ( kind : & ContextAdapterKind ) -> u8 {
4181
+ match kind {
4182
+ ContextAdapterKind :: Import ( _) => 0 ,
4183
+ ContextAdapterKind :: Export ( _) => 1 ,
4184
+ ContextAdapterKind :: Adapter => 2 ,
4185
+ }
4186
+ }
4187
+
4188
+ match ( a, b) {
4189
+ ( ContextAdapterKind :: Import ( a) , ContextAdapterKind :: Import ( b) ) => {
4190
+ let a = module. imports . get ( * a) ;
4191
+ let b = module. imports . get ( * b) ;
4192
+ a. name . cmp ( & b. name )
4193
+ }
4194
+ _ => get_kind_order ( a) . cmp ( & get_kind_order ( b) ) ,
4195
+ }
4196
+ } ) ;
4197
+
4198
+ adapters
4199
+ }
4200
+
4201
+ /// Iterate over the imports in a deterministic order.
4202
+ fn iter_by_import < ' a , T > (
4203
+ map : & ' a HashMap < ImportId , T > ,
4204
+ module : & Module ,
4205
+ ) -> Vec < ( & ' a ImportId , & ' a T ) > {
4206
+ let mut items: Vec < _ > = map. iter ( ) . collect ( ) ;
4207
+
4208
+ // Sort by import name.
4209
+ //
4210
+ // Imports have a name and a module, and it's important that we *ignore*
4211
+ // the module. The module of an import is set to its final value *during*
4212
+ // code generation, so using it here would cause the imports to be sorted
4213
+ // differently depending on which part of the code generation process we're
4214
+ // in.
4215
+ items. sort_by ( |& ( a, _) , & ( b, _) | {
4216
+ let a = module. imports . get ( * a) ;
4217
+ let b = module. imports . get ( * b) ;
4218
+
4219
+ a. name . cmp ( & b. name )
4220
+ } ) ;
4221
+
4222
+ items
4223
+ }
4224
+
4140
4225
fn check_duplicated_getter_and_setter_names (
4141
4226
exports : & [ ( & AdapterId , & AuxExport ) ] ,
4142
4227
) -> Result < ( ) , Error > {
0 commit comments