@@ -11,11 +11,13 @@ use crate::{uwrite, uwriteln};
11
11
use base64:: { engine:: general_purpose, Engine as _} ;
12
12
use heck:: * ;
13
13
use indexmap:: IndexMap ;
14
+ use std:: cell:: RefCell ;
14
15
use std:: collections:: { BTreeMap , BTreeSet , HashMap } ;
15
16
use std:: fmt:: Write ;
16
17
use std:: mem;
17
18
use wasmtime_environ:: component:: {
18
- ComponentTypes , InterfaceType , TypeDef , TypeFuncIndex , TypeResourceTableIndex ,
19
+ ComponentTypes , InterfaceType , RuntimeComponentInstanceIndex , TypeDef , TypeFuncIndex ,
20
+ TypeResourceTableIndex ,
19
21
} ;
20
22
use wasmtime_environ:: {
21
23
component,
@@ -141,6 +143,7 @@ pub fn transpile_bindgen(
141
143
lowering_options : Default :: default ( ) ,
142
144
imports_resource_map : Default :: default ( ) ,
143
145
exports_resource_map : Default :: default ( ) ,
146
+ used_instance_flags : Default :: default ( ) ,
144
147
defined_resource_classes : Default :: default ( ) ,
145
148
resource_dtors : Default :: default ( ) ,
146
149
resource_tables_initialized : ( 0 ..component. component . num_resource_tables )
@@ -152,6 +155,7 @@ pub fn transpile_bindgen(
152
155
instantiator. instantiate ( ) ;
153
156
instantiator. ensure_resource_tables ( ) ;
154
157
instantiator. destructors ( ) ;
158
+ instantiator. instance_flags ( ) ;
155
159
instantiator. gen . src . js ( & instantiator. src . js ) ;
156
160
instantiator. gen . src . js_init ( & instantiator. src . js_init ) ;
157
161
@@ -353,6 +357,8 @@ struct Instantiator<'a, 'b> {
353
357
imports : BTreeMap < String , WorldKey > ,
354
358
imports_resource_map : ResourceMap ,
355
359
exports_resource_map : ResourceMap ,
360
+ /// Instance flags which references have been emitted externally at least once.
361
+ used_instance_flags : RefCell < BTreeSet < RuntimeComponentInstanceIndex > > ,
356
362
defined_resource_classes : BTreeSet < String > ,
357
363
resource_dtors : BTreeMap < TypeId , CoreDef > ,
358
364
lowering_options :
@@ -475,10 +481,6 @@ impl<'a> Instantiator<'a, '_> {
475
481
}
476
482
477
483
fn instantiate ( & mut self ) {
478
- for i in 0 ..self . component . num_runtime_component_instances {
479
- uwriteln ! ( self . src. js_init, "const instanceFlags{i} = new WebAssembly.Global({{ value: \" i32\" , mutable: true }}, {});" , wasmtime_environ:: component:: FLAG_MAY_LEAVE | wasmtime_environ:: component:: FLAG_MAY_ENTER ) ;
480
- }
481
-
482
484
for ( i, trampoline) in self . translation . trampolines . iter ( ) {
483
485
let Trampoline :: LowerImport {
484
486
index,
@@ -549,11 +551,10 @@ impl<'a> Instantiator<'a, '_> {
549
551
. component
550
552
. initializers
551
553
. iter ( )
552
- . filter_map ( |i| match i {
554
+ . find_map ( |i| match i {
553
555
GlobalInitializer :: Resource ( r) if r. index == resource_idx => Some ( r) ,
554
556
_ => None ,
555
557
} )
556
- . next ( )
557
558
. unwrap ( ) ;
558
559
559
560
if let Some ( dtor) = & resource_def. dtor {
@@ -599,6 +600,20 @@ impl<'a> Instantiator<'a, '_> {
599
600
}
600
601
}
601
602
603
+ fn instance_flags ( & mut self ) {
604
+ // SAFETY: short-lived borrow, and the refcell isn't mutably borrowed in the loop's body.
605
+ let mut instance_flag_defs = String :: new ( ) ;
606
+ for used in self . used_instance_flags . borrow ( ) . iter ( ) {
607
+ let i = used. as_u32 ( ) ;
608
+ uwriteln ! (
609
+ & mut instance_flag_defs,
610
+ "const instanceFlags{i} = new WebAssembly.Global({{ value: \" i32\" , mutable: true }}, {});" ,
611
+ wasmtime_environ:: component:: FLAG_MAY_LEAVE
612
+ | wasmtime_environ:: component:: FLAG_MAY_ENTER ) ;
613
+ }
614
+ self . src . js_init . prepend_str ( & instance_flag_defs) ;
615
+ }
616
+
602
617
fn destructors ( & mut self ) {
603
618
for ( ty, dtor) in self . resource_dtors . iter ( ) {
604
619
let dtor_name_str = self . core_def ( dtor) ;
@@ -707,11 +722,10 @@ impl<'a> Instantiator<'a, '_> {
707
722
. component
708
723
. initializers
709
724
. iter ( )
710
- . filter_map ( |i| match i {
725
+ . find_map ( |i| match i {
711
726
GlobalInitializer :: Resource ( r) if r. index == resource_idx => Some ( r) ,
712
727
_ => None ,
713
728
} )
714
- . next ( )
715
729
. unwrap ( ) ;
716
730
717
731
if let Some ( dtor) = & resource_def. dtor {
@@ -1054,11 +1068,10 @@ impl<'a> Instantiator<'a, '_> {
1054
1068
. component
1055
1069
. initializers
1056
1070
. iter ( )
1057
- . filter_map ( |i| match i {
1071
+ . find_map ( |i| match i {
1058
1072
GlobalInitializer :: Resource ( r) if r. index == resource_idx => Some ( r) ,
1059
1073
_ => None ,
1060
1074
} )
1061
- . next ( )
1062
1075
. unwrap ( ) ;
1063
1076
1064
1077
if let Some ( dtor) = & resource_def. dtor {
@@ -1435,7 +1448,11 @@ impl<'a> Instantiator<'a, '_> {
1435
1448
match def {
1436
1449
CoreDef :: Export ( e) => self . core_export ( e) ,
1437
1450
CoreDef :: Trampoline ( i) => format ! ( "trampoline{}" , i. as_u32( ) ) ,
1438
- CoreDef :: InstanceFlags ( i) => format ! ( "instanceFlags{}" , i. as_u32( ) ) ,
1451
+ CoreDef :: InstanceFlags ( i) => {
1452
+ // SAFETY: short-lived borrow-mut.
1453
+ self . used_instance_flags . borrow_mut ( ) . insert ( * i) ;
1454
+ format ! ( "instanceFlags{}" , i. as_u32( ) )
1455
+ }
1439
1456
}
1440
1457
}
1441
1458
0 commit comments