Skip to content

Commit dfcaabc

Browse files
authored
Merge pull request #1557 from devsnek/new-weakref
Rewrite weakrefs to use current proposal
2 parents 2a665a9 + 66ade77 commit dfcaabc

File tree

3 files changed

+29
-52
lines changed

3 files changed

+29
-52
lines changed

crates/cli-support/src/js/js2rust.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
488488
if self.cx.config.weak_refs {
489489
self.ret_expr.push_str(&format!(
490490
"\
491-
addCleanup(this, this.ptr, free{});
492-
",
491+
{}FinalizationGroup.register(this, this.ptr, this.ptr);
492+
",
493493
name
494494
));
495495
}

crates/cli-support/src/js/mod.rs

Lines changed: 26 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,35 +1103,6 @@ impl<'a> Context<'a> {
11031103
let mut dst = format!("class {} {{\n", name);
11041104
let mut ts_dst = format!("export {}", dst);
11051105

1106-
let (mkweakref, freeref) = if self.config.weak_refs {
1107-
// When weak refs are enabled we use them to automatically free the
1108-
// contents of an exported rust class when it's gc'd. Note that a
1109-
// manual `free` function still exists for deterministic
1110-
// destruction.
1111-
//
1112-
// This is implemented by using a `WeakRefGroup` to run finalizers
1113-
// for all `WeakRef` objects that it creates. Upon construction of
1114-
// a new wasm object we use `makeRef` with "holdings" of a thunk to
1115-
// free the wasm instance. Once the `this` (the instance we're
1116-
// creating) is gc'd then the finalizer will run with the
1117-
// `WeakRef`, and we'll pull out the `holdings`, our pointer.
1118-
//
1119-
// Note, though, that if manual finalization happens we want to
1120-
// cancel the `WeakRef`-generated finalization, so we retain the
1121-
// `WeakRef` in a global map. This global map is then used to
1122-
// `drop()` the `WeakRef` (cancel finalization) whenever it is
1123-
// finalized.
1124-
self.expose_cleanup_groups();
1125-
let mk = format!("addCleanup(this, this.ptr, free{});", name);
1126-
let free = "
1127-
CLEANUPS_MAP.get(ptr).drop();
1128-
CLEANUPS_MAP.delete(ptr);
1129-
";
1130-
(mk, free)
1131-
} else {
1132-
(String::new(), "")
1133-
};
1134-
11351106
if self.config.debug && !class.has_constructor {
11361107
dst.push_str(
11371108
"
@@ -1165,29 +1136,52 @@ impl<'a> Context<'a> {
11651136
}}
11661137
",
11671138
name,
1168-
mkweakref.replace("this", "obj"),
1139+
if self.config.weak_refs {
1140+
format!("{}FinalizationGroup.register(obj, obj.ptr, obj.ptr);", name)
1141+
} else {
1142+
String::new()
1143+
},
11691144
));
11701145
}
11711146

11721147
self.global(&format!(
11731148
"
11741149
function free{}(ptr) {{
1175-
{}
11761150
wasm.{}(ptr);
11771151
}}
11781152
",
11791153
name,
1180-
freeref,
11811154
wasm_bindgen_shared::free_function(&name)
11821155
));
1156+
1157+
if self.config.weak_refs {
1158+
self.global(&format!(
1159+
"
1160+
const {}FinalizationGroup = new FinalizationGroup((items) => {{
1161+
for (const ptr of items) {{
1162+
free{}(ptr);
1163+
}}
1164+
}});
1165+
",
1166+
name,
1167+
name,
1168+
));
1169+
}
1170+
11831171
dst.push_str(&format!(
11841172
"
11851173
free() {{
11861174
const ptr = this.ptr;
11871175
this.ptr = 0;
1176+
{}
11881177
free{}(ptr);
11891178
}}
11901179
",
1180+
if self.config.weak_refs {
1181+
format!("{}FinalizationGroup.unregister(ptr);", name)
1182+
} else {
1183+
String::new()
1184+
},
11911185
name,
11921186
));
11931187
ts_dst.push_str(" free(): void;");
@@ -2279,23 +2273,6 @@ impl<'a> Context<'a> {
22792273
);
22802274
}
22812275

2282-
fn expose_cleanup_groups(&mut self) {
2283-
if !self.should_write_global("cleanup_groups") {
2284-
return;
2285-
}
2286-
self.global(
2287-
"
2288-
const CLEANUPS = new WeakRefGroup(x => x.holdings());
2289-
const CLEANUPS_MAP = new Map();
2290-
2291-
function addCleanup(obj, ptr, free) {
2292-
const ref = CLEANUPS.makeRef(obj, () => free(ptr));
2293-
CLEANUPS_MAP.set(ptr, ref);
2294-
}
2295-
",
2296-
);
2297-
}
2298-
22992276
fn describe(&mut self, name: &str) -> Option<Descriptor> {
23002277
let name = format!("__wbindgen_describe_{}", name);
23012278
let descriptor = self.interpreter.interpret_descriptor(&name, self.module)?;

crates/cli-support/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub struct Bindgen {
2525
remove_name_section: bool,
2626
remove_producers_section: bool,
2727
emit_start: bool,
28-
// Experimental support for `WeakRefGroup`, an upcoming ECMAScript feature.
28+
// Experimental support for weakrefs, an upcoming ECMAScript feature.
2929
// Currently only enable-able through an env var.
3030
weak_refs: bool,
3131
// Experimental support for the wasm threads proposal, transforms the wasm

0 commit comments

Comments
 (0)