From 2fa2279d9840bc5594c7e2cb6558fa5b1ddd3649 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Fri, 25 Oct 2024 12:42:06 +0200 Subject: [PATCH 1/4] Fixed imports with late binding and `this` --- crates/cli-support/src/js/mod.rs | 15 ++++++++ crates/cli/tests/reference/import-catch.rs | 12 ------- .../{import-catch.d.ts => import.d.ts} | 0 .../reference/{import-catch.js => import.js} | 36 +++++++++++++++++-- crates/cli/tests/reference/import.rs | 27 ++++++++++++++ .../{import-catch.wat => import.wat} | 0 6 files changed, 76 insertions(+), 14 deletions(-) delete mode 100644 crates/cli/tests/reference/import-catch.rs rename crates/cli/tests/reference/{import-catch.d.ts => import.d.ts} (100%) rename crates/cli/tests/reference/{import-catch.js => import.js} (60%) create mode 100644 crates/cli/tests/reference/import.rs rename crates/cli/tests/reference/{import-catch.wat => import.wat} (100%) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 10658f37f3a..198b2464508 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -2939,6 +2939,21 @@ __wbg_set_wasm(wasm);" } } + if let JsImportName::Global { .. } | JsImportName::VendorPrefixed { .. } = js.name { + // We generally cannot import globals directly, because users can + // change most globals at runtime. + // + // An obvious example of this when the object literally changes + // (e.g. binding `foo.bar`), but polyfills can also change the + // object or fundtion. + // + // Late binding is another issue. The function might not even be + // defined when the Wasm module is instantiated. In such cases, + // there is an observable difference between a direct import and a + // JS shim calling the function. + return Ok(false); + } + self.expose_not_defined(); let name = self.import_name(js)?; let js = format!( diff --git a/crates/cli/tests/reference/import-catch.rs b/crates/cli/tests/reference/import-catch.rs deleted file mode 100644 index b6a6e58fbf9..00000000000 --- a/crates/cli/tests/reference/import-catch.rs +++ /dev/null @@ -1,12 +0,0 @@ -use wasm_bindgen::prelude::*; - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(catch)] - fn foo() -> Result<(), JsValue>; -} - -#[wasm_bindgen] -pub fn exported() -> Result<(), JsValue> { - foo() -} diff --git a/crates/cli/tests/reference/import-catch.d.ts b/crates/cli/tests/reference/import.d.ts similarity index 100% rename from crates/cli/tests/reference/import-catch.d.ts rename to crates/cli/tests/reference/import.d.ts diff --git a/crates/cli/tests/reference/import-catch.js b/crates/cli/tests/reference/import.js similarity index 60% rename from crates/cli/tests/reference/import-catch.js rename to crates/cli/tests/reference/import.js index 4c4d0284851..83cf4ec54e3 100644 --- a/crates/cli/tests/reference/import-catch.js +++ b/crates/cli/tests/reference/import.js @@ -27,6 +27,26 @@ function handleError(f, args) { } } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +let cachedUint8ArrayMemory0 = null; + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + let cachedDataViewMemory0 = null; function getDataViewMemory0() { @@ -64,7 +84,19 @@ export function exported() { } } -export function __wbg_foo_95fe1a04017077db() { return handleError(function () { - foo(); +export function __wbg_catchme_a7bca7f3d5a5f319() { return handleError(function () { + catch_me(); }, arguments) }; +export function __wbg_nocatch_62552fa42a58590b() { + no_catch(); +}; + +export function __wbg_reload_90d82b22b83c1d99() { + window.location.reload(); +}; + +export function __wbg_write_d258674ff6f0ea8d(arg0, arg1) { + window.document.write(getStringFromWasm0(arg0, arg1)); +}; + diff --git a/crates/cli/tests/reference/import.rs b/crates/cli/tests/reference/import.rs new file mode 100644 index 00000000000..27c8a3a9c27 --- /dev/null +++ b/crates/cli/tests/reference/import.rs @@ -0,0 +1,27 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +extern "C" { + // Both `catch_me` and `no_catch` should be defined in the JS and invoke + // their respective JS function inside a JS shim function. This is + // important, because these 2 function may not be defined when the WASM + // module is instantiated. + #[wasm_bindgen(catch)] + fn catch_me() -> Result<(), JsValue>; + fn no_catch(); + + // Reload needs to be passed the right `this` parameter in JS. + #[wasm_bindgen(js_namespace = ["window", "location"])] + fn reload(); + + #[wasm_bindgen(js_namespace = ["window", "document"])] + fn write(s: &str); +} + +#[wasm_bindgen] +pub fn exported() -> Result<(), JsValue> { + reload(); + write(""); + no_catch(); + catch_me() +} diff --git a/crates/cli/tests/reference/import-catch.wat b/crates/cli/tests/reference/import.wat similarity index 100% rename from crates/cli/tests/reference/import-catch.wat rename to crates/cli/tests/reference/import.wat From 70e40f779078b6d68dd056c8b37e54c9376696ce Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Fri, 25 Oct 2024 13:06:27 +0200 Subject: [PATCH 2/4] Update tests to include module and inline_js --- crates/cli/tests/reference/import.js | 9 +++++++++ crates/cli/tests/reference/import.rs | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/cli/tests/reference/import.js b/crates/cli/tests/reference/import.js index 83cf4ec54e3..879ec6c37c6 100644 --- a/crates/cli/tests/reference/import.js +++ b/crates/cli/tests/reference/import.js @@ -84,6 +84,15 @@ export function exported() { } } +export function __wbg_add_dd5307a7ca6818d5(arg0, arg1) { + const ret = add(arg0, arg1); + return ret; +}; + +export function __wbg_barfromfoo_d097f3ec35aab47c() { + bar_from_foo(); +}; + export function __wbg_catchme_a7bca7f3d5a5f319() { return handleError(function () { catch_me(); }, arguments) }; diff --git a/crates/cli/tests/reference/import.rs b/crates/cli/tests/reference/import.rs index 27c8a3a9c27..a7bea1953ed 100644 --- a/crates/cli/tests/reference/import.rs +++ b/crates/cli/tests/reference/import.rs @@ -13,13 +13,20 @@ extern "C" { // Reload needs to be passed the right `this` parameter in JS. #[wasm_bindgen(js_namespace = ["window", "location"])] fn reload(); - #[wasm_bindgen(js_namespace = ["window", "document"])] fn write(s: &str); + + // module import + #[wasm_bindgen(module = "./foo.js")] + fn bar_from_foo(); + #[wasm_bindgen(inline_js = "export function add(a,b) { return a + b; }")] + fn add(a: f64, b: f64) -> f64; } #[wasm_bindgen] pub fn exported() -> Result<(), JsValue> { + bar_from_foo(); + let _ = add(1.0, 2.0); reload(); write(""); no_catch(); From 78f50b8004e250cc99da106fe7bea44a1dcc3524 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Sat, 2 Nov 2024 18:17:37 +0100 Subject: [PATCH 3/4] Updated ref --- crates/cli/tests/reference/import.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/crates/cli/tests/reference/import.js b/crates/cli/tests/reference/import.js index 043c00f3f89..229dd246115 100644 --- a/crates/cli/tests/reference/import.js +++ b/crates/cli/tests/reference/import.js @@ -47,15 +47,6 @@ function getStringFromWasm0(ptr, len) { return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); } -let cachedDataViewMemory0 = null; - -function getDataViewMemory0() { - if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { - cachedDataViewMemory0 = new DataView(wasm.memory.buffer); - } - return cachedDataViewMemory0; -} - function getObject(idx) { return heap[idx]; } function dropObject(idx) { From c773754df5deff11eca1092503f23385f00af055 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Thu, 7 Nov 2024 22:59:19 +0100 Subject: [PATCH 4/4] Updated changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f010e99fb8f..a0327e42a33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,9 @@ * Fixed calls to `JsCast::instanceof()` not respecting JavaScript namespaces. [#4241](https://github.com/rustwasm/wasm-bindgen/pull/4241) +* Fixed imports for functions using `this` and late binding. + [#4225](https://github.com/rustwasm/wasm-bindgen/pull/4225) + -------------------------------------------------------------------------------- ## [0.2.95](https://github.com/rustwasm/wasm-bindgen/compare/0.2.94...0.2.95)