Skip to content

Commit

Permalink
Handle potentially throwing getters
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Dec 5, 2024
1 parent e4f1004 commit dff35ce
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 42 deletions.
43 changes: 25 additions & 18 deletions crates/cli-support/src/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2578,6 +2578,30 @@ __wbg_set_wasm(wasm);"
Ok(name)
}

fn import_static(&mut self, import: &JsImport, optional: bool) -> Result<String, Error> {
let mut name = self.import_name(&JsImport {
name: import.name.clone(),
fields: Vec::new(),
})?;

// After we've got an actual name handle field projections
if optional {
name = format!("typeof {name} === 'undefined' ? null: {name}");

for field in import.fields.iter() {
name.push_str("?.");
name.push_str(field);
}
} else {
for field in import.fields.iter() {
name.push('.');
name.push_str(field);
}
}

Ok(name)
}

/// If a start function is present, it removes it from the `start` section
/// of the Wasm module and then moves it to an exported function, named
/// `__wbindgen_start`.
Expand Down Expand Up @@ -3269,24 +3293,7 @@ __wbg_set_wasm(wasm);"
assert!(kind == AdapterJsImportKind::Normal);
assert!(!variadic);
assert_eq!(args.len(), 0);
let js = self.import_name(js)?;

if *optional {
writeln!(
prelude,
"\
let result;
try {{
result = {js};
}} catch (_) {{
result = null;
}}",
)
.unwrap();
Ok("result".to_owned())
} else {
Ok(js)
}
self.import_static(js, *optional)
}

AuxImport::String(string) => {
Expand Down
24 changes: 3 additions & 21 deletions crates/cli/tests/reference/static.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,7 @@ export function exported() {
}

export function __wbg_static_accessor_NAMESPACE_OPTIONAL_c9a4344c544120f4() {
let result;
try {
result = test.NAMESPACE_OPTIONAL;
} catch (_) {
result = null;
}
const ret = result;
const ret = typeof test === 'undefined' ? null: test?.NAMESPACE_OPTIONAL;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};

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

export function __wbg_static_accessor_NESTED_NAMESPACE_OPTIONAL_a414abbeb018a35a() {
let result;
try {
result = test1.test2.NESTED_NAMESPACE_OPTIONAL;
} catch (_) {
result = null;
}
const ret = result;
const ret = typeof test1 === 'undefined' ? null: test1?.test2?.NESTED_NAMESPACE_OPTIONAL;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};

Expand All @@ -71,13 +59,7 @@ export function __wbg_static_accessor_NESTED_NAMESPACE_PLAIN_1121b285cb8479df()
};

export function __wbg_static_accessor_OPTIONAL_ade71b6402851d0c() {
let result;
try {
result = OPTIONAL;
} catch (_) {
result = null;
}
const ret = result;
const ret = typeof OPTIONAL === 'undefined' ? null: OPTIONAL;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};

Expand Down
5 changes: 2 additions & 3 deletions guide/src/reference/static-js-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ a named `static` in the `extern` block with an
`JsThreadLocal` for these objects, which can be cloned into a `JsValue`.

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

For example, given the following JavaScript:

Expand Down

0 comments on commit dff35ce

Please sign in to comment.