Skip to content

Commit 050bb5c

Browse files
committed
Handle potentially throwing getters
1 parent e4f1004 commit 050bb5c

File tree

3 files changed

+38
-42
lines changed

3 files changed

+38
-42
lines changed

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

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2578,6 +2578,38 @@ __wbg_set_wasm(wasm);"
25782578
Ok(name)
25792579
}
25802580

2581+
fn import_static(&mut self, import: &JsImport, optional: bool) -> Result<String, Error> {
2582+
let mut name = if let Some(name) = self.imported_names.get(&import.name) {
2583+
name.to_owned()
2584+
} else {
2585+
let JsImportName::Global { name } = &import.name else {
2586+
unreachable!("invalid static import")
2587+
};
2588+
let unique_name = self.generate_identifier(name);
2589+
if unique_name != *name {
2590+
bail!("cannot import `{}` from two locations", name);
2591+
}
2592+
unique_name
2593+
};
2594+
2595+
// After we've got an actual name handle field projections
2596+
if optional {
2597+
name = format!("typeof {name} === 'undefined' ? null: {name}");
2598+
2599+
for field in import.fields.iter() {
2600+
name.push_str("?.");
2601+
name.push_str(field);
2602+
}
2603+
} else {
2604+
for field in import.fields.iter() {
2605+
name.push('.');
2606+
name.push_str(field);
2607+
}
2608+
}
2609+
2610+
Ok(name)
2611+
}
2612+
25812613
/// If a start function is present, it removes it from the `start` section
25822614
/// of the Wasm module and then moves it to an exported function, named
25832615
/// `__wbindgen_start`.
@@ -3269,24 +3301,7 @@ __wbg_set_wasm(wasm);"
32693301
assert!(kind == AdapterJsImportKind::Normal);
32703302
assert!(!variadic);
32713303
assert_eq!(args.len(), 0);
3272-
let js = self.import_name(js)?;
3273-
3274-
if *optional {
3275-
writeln!(
3276-
prelude,
3277-
"\
3278-
let result;
3279-
try {{
3280-
result = {js};
3281-
}} catch (_) {{
3282-
result = null;
3283-
}}",
3284-
)
3285-
.unwrap();
3286-
Ok("result".to_owned())
3287-
} else {
3288-
Ok(js)
3289-
}
3304+
self.import_static(js, *optional)
32903305
}
32913306

32923307
AuxImport::String(string) => {

crates/cli/tests/reference/static.js

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,7 @@ export function exported() {
3939
}
4040

4141
export function __wbg_static_accessor_NAMESPACE_OPTIONAL_c9a4344c544120f4() {
42-
let result;
43-
try {
44-
result = test.NAMESPACE_OPTIONAL;
45-
} catch (_) {
46-
result = null;
47-
}
48-
const ret = result;
42+
const ret = typeof test === 'undefined' ? null: test?.NAMESPACE_OPTIONAL;
4943
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
5044
};
5145

@@ -55,13 +49,7 @@ export function __wbg_static_accessor_NAMESPACE_PLAIN_784c8d7f5bbac62a() {
5549
};
5650

5751
export function __wbg_static_accessor_NESTED_NAMESPACE_OPTIONAL_a414abbeb018a35a() {
58-
let result;
59-
try {
60-
result = test1.test2.NESTED_NAMESPACE_OPTIONAL;
61-
} catch (_) {
62-
result = null;
63-
}
64-
const ret = result;
52+
const ret = typeof test1 === 'undefined' ? null: test1?.test2?.NESTED_NAMESPACE_OPTIONAL;
6553
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
6654
};
6755

@@ -71,13 +59,7 @@ export function __wbg_static_accessor_NESTED_NAMESPACE_PLAIN_1121b285cb8479df()
7159
};
7260

7361
export function __wbg_static_accessor_OPTIONAL_ade71b6402851d0c() {
74-
let result;
75-
try {
76-
result = OPTIONAL;
77-
} catch (_) {
78-
result = null;
79-
}
80-
const ret = result;
62+
const ret = typeof OPTIONAL === 'undefined' ? null: OPTIONAL;
8163
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
8264
};
8365

guide/src/reference/static-js-objects.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ a named `static` in the `extern` block with an
77
`JsThreadLocal` for these objects, which can be cloned into a `JsValue`.
88

99
These values are cached in a thread-local and are meant to bind static values
10-
or objects only. Binding getters or expecting a new value or object when
11-
changed in JS is not supported. For these use
12-
[getters](attributes/on-js-imports/getter-and-setter.md).
10+
or objects only. For getters which can change their return value or throw see
11+
[how to import getters](attributes/on-js-imports/getter-and-setter.md).
1312

1413
For example, given the following JavaScript:
1514

0 commit comments

Comments
 (0)