Skip to content

Commit 2a5daf6

Browse files
bnjbvrGuy Bedford
and
Guy Bedford
authored
feat: lazily generate instanceFlags (#275)
* style: use find_map() instead of filter_map().next() * feat: only generate instance flags globals when they're used * review: rename ensure_instance_flags to instance_flags --------- Co-authored-by: Guy Bedford <[email protected]>
1 parent c147ebc commit 2a5daf6

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

crates/js-component-bindgen/src/source.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ impl Source {
3939
}
4040
}
4141

42+
pub fn prepend_str(&mut self, src: &str) {
43+
// Infer the indent at start: it's the difference between the size of the first line, and
44+
// its size if trimmed at the left. That raw difference is in number of spaces, not in
45+
// units of indent; since each indent is 2 spaces, divide by 2 at the end.
46+
let indent = self
47+
.s
48+
.lines()
49+
.next()
50+
.map_or(0, |line| (line.len() - line.trim_start().len()) / 2);
51+
let mut new_start = Source {
52+
s: String::new(),
53+
indent,
54+
};
55+
new_start.push_str(src);
56+
self.s = new_start.s + &self.s;
57+
}
58+
4259
pub fn indent(&mut self, amt: usize) {
4360
self.indent += amt;
4461
}

crates/js-component-bindgen/src/transpile_bindgen.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ use crate::{uwrite, uwriteln};
1111
use base64::{engine::general_purpose, Engine as _};
1212
use heck::*;
1313
use indexmap::IndexMap;
14+
use std::cell::RefCell;
1415
use std::collections::{BTreeMap, BTreeSet, HashMap};
1516
use std::fmt::Write;
1617
use std::mem;
1718
use wasmtime_environ::component::{
18-
ComponentTypes, InterfaceType, TypeDef, TypeFuncIndex, TypeResourceTableIndex,
19+
ComponentTypes, InterfaceType, RuntimeComponentInstanceIndex, TypeDef, TypeFuncIndex,
20+
TypeResourceTableIndex,
1921
};
2022
use wasmtime_environ::{
2123
component,
@@ -141,6 +143,7 @@ pub fn transpile_bindgen(
141143
lowering_options: Default::default(),
142144
imports_resource_map: Default::default(),
143145
exports_resource_map: Default::default(),
146+
used_instance_flags: Default::default(),
144147
defined_resource_classes: Default::default(),
145148
resource_dtors: Default::default(),
146149
resource_tables_initialized: (0..component.component.num_resource_tables)
@@ -152,6 +155,7 @@ pub fn transpile_bindgen(
152155
instantiator.instantiate();
153156
instantiator.ensure_resource_tables();
154157
instantiator.destructors();
158+
instantiator.instance_flags();
155159
instantiator.gen.src.js(&instantiator.src.js);
156160
instantiator.gen.src.js_init(&instantiator.src.js_init);
157161

@@ -353,6 +357,8 @@ struct Instantiator<'a, 'b> {
353357
imports: BTreeMap<String, WorldKey>,
354358
imports_resource_map: ResourceMap,
355359
exports_resource_map: ResourceMap,
360+
/// Instance flags which references have been emitted externally at least once.
361+
used_instance_flags: RefCell<BTreeSet<RuntimeComponentInstanceIndex>>,
356362
defined_resource_classes: BTreeSet<String>,
357363
resource_dtors: BTreeMap<TypeId, CoreDef>,
358364
lowering_options:
@@ -475,10 +481,6 @@ impl<'a> Instantiator<'a, '_> {
475481
}
476482

477483
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-
482484
for (i, trampoline) in self.translation.trampolines.iter() {
483485
let Trampoline::LowerImport {
484486
index,
@@ -549,11 +551,10 @@ impl<'a> Instantiator<'a, '_> {
549551
.component
550552
.initializers
551553
.iter()
552-
.filter_map(|i| match i {
554+
.find_map(|i| match i {
553555
GlobalInitializer::Resource(r) if r.index == resource_idx => Some(r),
554556
_ => None,
555557
})
556-
.next()
557558
.unwrap();
558559

559560
if let Some(dtor) = &resource_def.dtor {
@@ -599,6 +600,20 @@ impl<'a> Instantiator<'a, '_> {
599600
}
600601
}
601602

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+
602617
fn destructors(&mut self) {
603618
for (ty, dtor) in self.resource_dtors.iter() {
604619
let dtor_name_str = self.core_def(dtor);
@@ -707,11 +722,10 @@ impl<'a> Instantiator<'a, '_> {
707722
.component
708723
.initializers
709724
.iter()
710-
.filter_map(|i| match i {
725+
.find_map(|i| match i {
711726
GlobalInitializer::Resource(r) if r.index == resource_idx => Some(r),
712727
_ => None,
713728
})
714-
.next()
715729
.unwrap();
716730

717731
if let Some(dtor) = &resource_def.dtor {
@@ -1054,11 +1068,10 @@ impl<'a> Instantiator<'a, '_> {
10541068
.component
10551069
.initializers
10561070
.iter()
1057-
.filter_map(|i| match i {
1071+
.find_map(|i| match i {
10581072
GlobalInitializer::Resource(r) if r.index == resource_idx => Some(r),
10591073
_ => None,
10601074
})
1061-
.next()
10621075
.unwrap();
10631076

10641077
if let Some(dtor) = &resource_def.dtor {
@@ -1435,7 +1448,11 @@ impl<'a> Instantiator<'a, '_> {
14351448
match def {
14361449
CoreDef::Export(e) => self.core_export(e),
14371450
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+
}
14391456
}
14401457
}
14411458

0 commit comments

Comments
 (0)