Skip to content

Commit c8245e2

Browse files
committed
more symbols
1 parent 66ce172 commit c8245e2

1 file changed

Lines changed: 35 additions & 1 deletion

File tree

packages/cli/src/build/patch.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ pub fn create_wasm_jump_table(patch: &Path, cache: &HotpatchModuleCache) -> Resu
707707
continue;
708708
};
709709

710-
if name.contains("wasm_bindgen4__rt8wbg_cast") && !name.contains("breaks_if_inline") {
710+
if name_is_wbg_cast_symbol(name) {
711711
let name = name.to_string();
712712
let old_idx = name_to_ifunc_old
713713
.get(&name)
@@ -1526,6 +1526,21 @@ pub fn prepare_wasm_base_module(bytes: &[u8]) -> Result<Vec<u8>> {
15261526
/// backrefs (`NtB5_` etc.) routinely compress the path away. If any of these slip through, the
15271527
/// describe functions get pinned into the ifunc table, wasm-bindgen's GC can't delete them, and
15281528
/// the final module ships an unsatisfiable `__wbindgen_placeholder__.__wbindgen_describe` import.
1529+
/// Check if the name is a `wasm_bindgen::__rt::wbg_cast` instantiation (excluding its inner
1530+
/// `breaks_if_inlined` helper). These functions need their bodies rewritten to call the base
1531+
/// module's JS-bound versions via the ifunc table — if one slips through, the patch keeps its
1532+
/// local copy, which calls `breaks_if_inlined` → `describe::inform` → the stubbed
1533+
/// `__wbindgen_describe` import and traps with "null function" the first time the patched code
1534+
/// casts a value (e.g. creating an event-listener closure).
1535+
///
1536+
/// In legacy mangling the path appears as `wasm_bindgen4__rt8wbg_cast`; in v0 (default since
1537+
/// rustc 1.97) identifiers starting with `_` get a `_` separator after their length, so `__rt`
1538+
/// encodes as `4___rt`.
1539+
fn name_is_wbg_cast_symbol(name: &str) -> bool {
1540+
(name.contains("wasm_bindgen4__rt8wbg_cast") || name.contains("wasm_bindgen4___rt8wbg_cast"))
1541+
&& !name.contains("breaks_if_inline")
1542+
}
1543+
15291544
fn name_is_bindgen_symbol(name: &str) -> bool {
15301545
name.contains("__wbindgen_describe")
15311546
|| name.contains("__wbindgen_externref")
@@ -1590,6 +1605,25 @@ fn bindgen_symbol_catch() {
15901605
));
15911606
}
15921607

1608+
#[test]
1609+
fn wbg_cast_symbol_catch() {
1610+
// legacy mangling: wbg_cast instantiation matches, its breaks_if_inlined helper does not
1611+
assert!(name_is_wbg_cast_symbol(
1612+
"_ZN12wasm_bindgen4__rt8wbg_cast17h1234567890abcdefE"
1613+
));
1614+
assert!(!name_is_wbg_cast_symbol(
1615+
"_ZN12wasm_bindgen4__rt8wbg_cast17breaks_if_inlined17h1234567890abcdefE"
1616+
));
1617+
1618+
// v0 mangling: `__rt` encodes as `4___rt` (length 4, `_` separator, then `__rt`)
1619+
assert!(name_is_wbg_cast_symbol(
1620+
"_RINvNtCsa7akE1TfegA_12wasm_bindgen4___rt8wbg_castINtB4_7closure12OwnedClosureDINtNtNtCs9WN6KVdqFxk_4core3ops8function5FnMutTNtNtNtCs5qlPUvWaqlJ_7web_sys8features14gen_MouseEvent10MouseEventEEp6OutputuEL_Kb1_ENtBO_9JsClosureECsjFep1nV9Dzo_32dioxus_playwright_web_patch_test"
1621+
));
1622+
assert!(!name_is_wbg_cast_symbol(
1623+
"_RINvNvNtCsa7akE1TfegA_12wasm_bindgen4___rt8wbg_cast17breaks_if_inlinedINtNtB6_7closure12OwnedClosureDINtNtNtCs9WN6KVdqFxk_4core3ops8function5FnMutTNtNtNtCs5qlPUvWaqlJ_7web_sys8features14gen_MouseEvent10MouseEventEEp6OutputuEL_Kb1_ENtB19_9JsClosureECsjFep1nV9Dzo_32dioxus_playwright_web_patch_test"
1624+
));
1625+
}
1626+
15931627
/// Manually parse the data section from a wasm module
15941628
///
15951629
/// We need to do this for data symbols because walrus doesn't provide the right range and offset

0 commit comments

Comments
 (0)