From 3934778cdfee0d5d2ae4c93b9f5568701008a628 Mon Sep 17 00:00:00 2001 From: Chris Mills Date: Thu, 9 Jul 2026 11:05:09 +0100 Subject: [PATCH 1/3] Editorial review: Document Wasm JS Promise integration (#44484) * Document Wasm JS Promise integration * Review fixes, plus add SuspendError * Update files/en-us/webassembly/reference/javascript_interface/promising_static/index.md Co-authored-by: Vadim Makeev * Update files/en-us/webassembly/reference/javascript_interface/suspending/index.md Co-authored-by: Vadim Makeev * Update files/en-us/webassembly/reference/javascript_interface/index.md Co-authored-by: Vadim Makeev * Update files/en-us/webassembly/reference/javascript_interface/promising_static/index.md Co-authored-by: Vadim Makeev * Update files/en-us/webassembly/reference/javascript_interface/suspenderror/index.md Co-authored-by: Vadim Makeev * Update files/en-us/webassembly/reference/javascript_interface/suspenderror/suspenderror/index.md Co-authored-by: Vadim Makeev * Fixes for pepelsbey review comments --------- Co-authored-by: Vadim Makeev --- .../mozilla/firefox/releases/153/index.md | 4 +- .../compileerror/compileerror/index.md | 2 +- .../compileerror/index.md | 2 +- .../reference/javascript_interface/index.md | 4 + .../javascript_interface/linkerror/index.md | 2 +- .../linkerror/linkerror/index.md | 2 +- .../promising_static/index.md | 64 ++++++++ .../suspenderror/index.md | 70 ++++++++ .../suspenderror/suspenderror/index.md | 70 ++++++++ .../javascript_interface/suspending/index.md | 151 ++++++++++++++++++ .../suspending/suspending/index.md | 64 ++++++++ files/sidebars/webassemblysidebar.yaml | 24 ++- 12 files changed, 448 insertions(+), 11 deletions(-) create mode 100644 files/en-us/webassembly/reference/javascript_interface/promising_static/index.md create mode 100644 files/en-us/webassembly/reference/javascript_interface/suspenderror/index.md create mode 100644 files/en-us/webassembly/reference/javascript_interface/suspenderror/suspenderror/index.md create mode 100644 files/en-us/webassembly/reference/javascript_interface/suspending/index.md create mode 100644 files/en-us/webassembly/reference/javascript_interface/suspending/suspending/index.md diff --git a/files/en-us/mozilla/firefox/releases/153/index.md b/files/en-us/mozilla/firefox/releases/153/index.md index 3e9b92e030cf100..f910bfa62900fb5 100644 --- a/files/en-us/mozilla/firefox/releases/153/index.md +++ b/files/en-us/mozilla/firefox/releases/153/index.md @@ -82,7 +82,9 @@ Firefox 153 is the current [Beta version of Firefox](https://www.firefox.com/en- - +### WebAssembly + +- JavaScript Promise Integration (JS-PI) is now enabled, allowing [WebAssembly](/en-US/docs/WebAssembly) modules to interoperate with asynchronous, {{jsxref("Promise")}}-based JavaScript APIs. This lets WebAssembly code suspend while waiting for a JavaScript promise and resume when the promise settles. See [`WebAssembly.Suspending`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending) for an explanation and working example. ([Firefox bug 2044809](https://bugzil.la/2044809)). diff --git a/files/en-us/webassembly/reference/javascript_interface/compileerror/compileerror/index.md b/files/en-us/webassembly/reference/javascript_interface/compileerror/compileerror/index.md index c284c3171aa8dd9..a4ac5fcbd84aa20 100644 --- a/files/en-us/webassembly/reference/javascript_interface/compileerror/compileerror/index.md +++ b/files/en-us/webassembly/reference/javascript_interface/compileerror/compileerror/index.md @@ -45,7 +45,7 @@ details to the console: try { throw new WebAssembly.CompileError("Hello", "someFile", 10); } catch (e) { - console.log(e instanceof CompileError); // true + console.log(e instanceof WebAssembly.CompileError); // true console.log(e.message); // "Hello" console.log(e.name); // "CompileError" console.log(e.fileName); // "someFile" diff --git a/files/en-us/webassembly/reference/javascript_interface/compileerror/index.md b/files/en-us/webassembly/reference/javascript_interface/compileerror/index.md index 1f4cdeec105eb0c..423c9428ed6030a 100644 --- a/files/en-us/webassembly/reference/javascript_interface/compileerror/index.md +++ b/files/en-us/webassembly/reference/javascript_interface/compileerror/index.md @@ -45,7 +45,7 @@ The following snippet creates a new `CompileError` instance, and logs its detail try { throw new WebAssembly.CompileError("Hello", "someFile", 10); } catch (e) { - console.log(e instanceof CompileError); // true + console.log(e instanceof WebAssembly.CompileError); // true console.log(e.message); // "Hello" console.log(e.name); // "CompileError" console.log(e.fileName); // "someFile" diff --git a/files/en-us/webassembly/reference/javascript_interface/index.md b/files/en-us/webassembly/reference/javascript_interface/index.md index 162a519081c8781..32be18d633e52eb 100644 --- a/files/en-us/webassembly/reference/javascript_interface/index.md +++ b/files/en-us/webassembly/reference/javascript_interface/index.md @@ -34,6 +34,8 @@ The primary uses for the `WebAssembly` object are: - : Contains stateless WebAssembly code that has already been compiled by the browser and can be efficiently [shared with Workers](/en-US/docs/Web/API/Worker/postMessage), and instantiated multiple times. - [`WebAssembly.RuntimeError`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/RuntimeError) - : Error type that is thrown whenever WebAssembly specifies a [trap](https://webassembly.github.io/simd/core/intro/overview.html#trap). +- [`WebAssembly.Suspending`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending) + - : Represents a suspending function — an asynchronous ({{jsxref("Promise")}}-based) JavaScript function that, when imported into a Wasm module and called from inside, will result in execution being suspended until the promise resolves. - [`WebAssembly.Table`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Table) - : An array-like structure representing a WebAssembly Table, which stores [references](https://webassembly.github.io/spec/core/syntax/types.html#syntax-reftype), such as function references. - [`WebAssembly.Tag`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Tag) @@ -56,6 +58,8 @@ The primary uses for the `WebAssembly` object are: - : The primary API for compiling and instantiating WebAssembly code, returning both a `Module` and its first `Instance`. - [`WebAssembly.instantiateStreaming()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/instantiateStreaming_static) - : Compiles and instantiates a WebAssembly module directly from a streamed underlying source, returning both a `Module` and its first `Instance`. +- [`WebAssembly.promising()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/promising_static) + - : Wraps an exported Wasm function that relies on an asynchronous operation (that is, an imported suspending function created via the [`WebAssembly.Suspending()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending/Suspending) constructor), turning it into a {{jsxref("Promise")}}. - [`WebAssembly.validate()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/validate_static) - : Validates a given typed array of WebAssembly binary code, returning whether the bytes are valid WebAssembly code (`true`) or not (`false`). diff --git a/files/en-us/webassembly/reference/javascript_interface/linkerror/index.md b/files/en-us/webassembly/reference/javascript_interface/linkerror/index.md index 16901b05876b252..c05fa0484f9af4b 100644 --- a/files/en-us/webassembly/reference/javascript_interface/linkerror/index.md +++ b/files/en-us/webassembly/reference/javascript_interface/linkerror/index.md @@ -45,7 +45,7 @@ The following snippet creates a new `LinkError` instance, and logs its details t try { throw new WebAssembly.LinkError("Hello", "someFile", 10); } catch (e) { - console.log(e instanceof LinkError); // true + console.log(e instanceof WebAssembly.LinkError); // true console.log(e.message); // "Hello" console.log(e.name); // "LinkError" console.log(e.fileName); // "someFile" diff --git a/files/en-us/webassembly/reference/javascript_interface/linkerror/linkerror/index.md b/files/en-us/webassembly/reference/javascript_interface/linkerror/linkerror/index.md index 3a4d30a02f1d0eb..4181cd449798d72 100644 --- a/files/en-us/webassembly/reference/javascript_interface/linkerror/linkerror/index.md +++ b/files/en-us/webassembly/reference/javascript_interface/linkerror/linkerror/index.md @@ -46,7 +46,7 @@ details to the console: try { throw new WebAssembly.LinkError("Hello", "someFile", 10); } catch (e) { - console.log(e instanceof LinkError); // true + console.log(e instanceof WebAssembly.LinkError); // true console.log(e.message); // "Hello" console.log(e.name); // "LinkError" console.log(e.fileName); // "someFile" diff --git a/files/en-us/webassembly/reference/javascript_interface/promising_static/index.md b/files/en-us/webassembly/reference/javascript_interface/promising_static/index.md new file mode 100644 index 000000000000000..93954af96b263fb --- /dev/null +++ b/files/en-us/webassembly/reference/javascript_interface/promising_static/index.md @@ -0,0 +1,64 @@ +--- +title: WebAssembly.promising() +slug: WebAssembly/Reference/JavaScript_interface/promising_static +page-type: webassembly-function +browser-compat: webassembly.api.promising_static +sidebar: webassemblysidebar +--- + +The **`WebAssembly.promising()`** static method is used to wrap an exported Wasm function that relies on an asynchronous operation (that is, an imported suspending function created via the [`WebAssembly.Suspending()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending/Suspending) constructor), turning it into a {{jsxref("Promise")}}. + +See [`WebAssembly.Suspending`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending) for an explanation of how this functionality works. + +## Syntax + +```js-nolint +WebAssembly.promising(function) +``` + +### Parameters + +- `function` + - : A reference to an exported Wasm function, typically available on the [`exports`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Instance/exports) object available in the fulfilled value of a method such as [`WebAssembly.instantiateStreaming()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/instantiateStreaming_static). + +### Return value + +A function that wraps the original function passed into the `promising()` call, and can itself be called. The wrapper function takes the same arguments as the wrapped function, and returns a promise that fulfills with the wrapped function's results. + +### Exceptions + +- {{jsxref("TypeError")}} + - : The referenced `function` is not callable. + +## Examples + +### Basic usage + +```js +WebAssembly.instantiateStreaming(fetch("module.wasm"), { importObj }).then( + (result) => { + const fromWasm = WebAssembly.promising( + result.instance.exports.exportedFunc, + ); + fromWasm().then((result) => { + // ... + }); + }, +); +``` + +See [`WebAssembly.Suspending`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending) for a full working example. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [`WebAssembly.Suspending`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending) +- [`WebAssembly.Suspending()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending/Suspending) constructor +- [WebAssembly](/en-US/docs/WebAssembly) overview diff --git a/files/en-us/webassembly/reference/javascript_interface/suspenderror/index.md b/files/en-us/webassembly/reference/javascript_interface/suspenderror/index.md new file mode 100644 index 000000000000000..0e37468425520ed --- /dev/null +++ b/files/en-us/webassembly/reference/javascript_interface/suspenderror/index.md @@ -0,0 +1,70 @@ +--- +title: WebAssembly.SuspendError +slug: WebAssembly/Reference/JavaScript_interface/SuspendError +page-type: webassembly-interface +browser-compat: webassembly.api.SuspendError +sidebar: webassemblysidebar +--- + +The **`WebAssembly.SuspendError`** object indicates an error during WebAssembly [function suspension](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending). + +## Constructor + +- [`WebAssembly.SuspendError()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/SuspendError/SuspendError) + - : Creates a new `WebAssembly.SuspendError` object. + +## Instance properties + +- {{jsxref("Error.prototype.message", "WebAssembly.SuspendError.prototype.message")}} + - : Error message. Inherited from {{jsxref("Error")}}. +- {{jsxref("Error.prototype.name", "WebAssembly.SuspendError.prototype.name")}} + - : Error name. Inherited from {{jsxref("Error")}}. +- {{jsxref("Error.prototype.cause", "WebAssembly.SuspendError.prototype.cause")}} + - : Error cause. Inherited from {{jsxref("Error")}}. +- {{jsxref("Error.prototype.fileName", "WebAssembly.SuspendError.prototype.fileName")}} {{non-standard_inline}} + - : Path to file that raised this error. Inherited from {{jsxref("Error")}}. +- {{jsxref("Error.prototype.lineNumber", "WebAssembly.SuspendError.prototype.lineNumber")}} {{non-standard_inline}} + - : Line number in file that raised this error. Inherited from {{jsxref("Error")}}. +- {{jsxref("Error.prototype.columnNumber", "WebAssembly.SuspendError.prototype.columnNumber")}} {{non-standard_inline}} + - : Column number in line that raised this error. Inherited from {{jsxref("Error")}}. +- {{jsxref("Error.prototype.stack", "WebAssembly.SuspendError.prototype.stack")}} {{non-standard_inline}} + - : Stack trace. Inherited from {{jsxref("Error")}}. + +## Instance methods + +- {{jsxref("Error.prototype.toString", "WebAssembly.SuspendError.prototype.toString()")}} + - : Returns a string representing the specified `Error` object. Inherited from {{jsxref("Error")}}. + +## Examples + +### Creating a new SuspendError instance + +The following snippet creates a new `SuspendError` instance, and logs its details to the console: + +```js +try { + throw new WebAssembly.SuspendError("Hello", "someFile", 10); +} catch (e) { + console.log(e instanceof WebAssembly.SuspendError); // true + console.log(e.message); // "Hello" + console.log(e.name); // "SuspendError" + console.log(e.fileName); // "someFile" + console.log(e.lineNumber); // 10 + console.log(e.columnNumber); // 0 + console.log(e.stack); // The location where the code was run +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [`WebAssembly.Suspending`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending) +- [WebAssembly](/en-US/docs/WebAssembly) overview +- [WebAssembly concepts](/en-US/docs/WebAssembly/Guides/Concepts) diff --git a/files/en-us/webassembly/reference/javascript_interface/suspenderror/suspenderror/index.md b/files/en-us/webassembly/reference/javascript_interface/suspenderror/suspenderror/index.md new file mode 100644 index 000000000000000..46005d8ea6715f6 --- /dev/null +++ b/files/en-us/webassembly/reference/javascript_interface/suspenderror/suspenderror/index.md @@ -0,0 +1,70 @@ +--- +title: WebAssembly.SuspendError() constructor +slug: WebAssembly/Reference/JavaScript_interface/SuspendError/SuspendError +page-type: webassembly-constructor +browser-compat: webassembly.api.SuspendError.SuspendError +sidebar: webassemblysidebar +--- + +The **`WebAssembly.SuspendError()`** constructor creates a new +WebAssembly `SuspendError` object, which indicates an error during +WebAssembly [function suspension](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending). + +## Syntax + +```js-nolint +new WebAssembly.SuspendError() +new WebAssembly.SuspendError(message) +new WebAssembly.SuspendError(message, options) +new WebAssembly.SuspendError(message, fileName) +new WebAssembly.SuspendError(message, fileName, lineNumber) +``` + +### Parameters + +- `message` {{optional_inline}} + - : Human-readable description of the error. +- `options` {{optional_inline}} + - : An object that has the following properties: + - `cause` {{optional_inline}} + - : A property indicating the specific cause of the error. + When catching and re-throwing an error with a more-specific or useful error message, this property can be used to pass the original error. +- `fileName` {{optional_inline}} {{non-standard_inline}} + - : The name of the file containing the code that caused the exception. +- `lineNumber` {{optional_inline}} {{non-standard_inline}} + - : The line number of the code that caused the exception. + +## Examples + +### Creating a new SuspendError instance + +The following snippet creates a new `SuspendError` instance, and logs its +details to the console: + +```js +try { + throw new WebAssembly.SuspendError("Hello", "someFile", 10); +} catch (e) { + console.log(e instanceof WebAssembly.SuspendError); // true + console.log(e.message); // "Hello" + console.log(e.name); // "SuspendError" + console.log(e.fileName); // "someFile" + console.log(e.lineNumber); // 10 + console.log(e.columnNumber); // 0 + console.log(e.stack); // The location where the code was run +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [`WebAssembly.Suspending`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending) +- [WebAssembly](/en-US/docs/WebAssembly) overview +- [WebAssembly concepts](/en-US/docs/WebAssembly/Guides/Concepts) diff --git a/files/en-us/webassembly/reference/javascript_interface/suspending/index.md b/files/en-us/webassembly/reference/javascript_interface/suspending/index.md new file mode 100644 index 000000000000000..1ee844927703943 --- /dev/null +++ b/files/en-us/webassembly/reference/javascript_interface/suspending/index.md @@ -0,0 +1,151 @@ +--- +title: WebAssembly.Suspending +slug: WebAssembly/Reference/JavaScript_interface/Suspending +page-type: webassembly-interface +browser-compat: webassembly.api.Suspending +sidebar: webassemblysidebar +--- + +The **`WebAssembly.Suspending`** object represents a suspending function — an asynchronous ({{jsxref("Promise")}}-based) JavaScript function that, when imported into a Wasm module and called from inside, will result in execution being suspended until the promise resolves. + +> [!NOTE] +> The only purpose of `WebAssembly.Suspending` is to mark which imported functions are suspending functions when passing them into a Wasm module imports object. + +## Constructor + +- [`WebAssembly.Suspending()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending/Suspending) + - : Creates a new `Suspending` object instance. + +## Description + +The `Suspending` interface — along with its counterpart [`WebAssembly.promising()`](/en-US/docs/WebAssembly/Reference/JavaScript_interface/promising_static) method — enables WebAssembly modules to interact with asynchronous JavaScript host functions. + +To use this functionality, you first need to wrap `Promise`-based functions inside a `WebAssembly.Suspending()` constructor call when importing them: + +```js +function someAsyncFunction() { + return fetch("https://example.com").then((result) => { + // ... + }); +} + +const importObj = { + someAsyncFunction: new WebAssembly.Suspending(someAsyncFunction), +}; +``` + +This creates a suspending function. No changes are necessary to use it inside the Wasm module: when it is called, execution is suspended until the `Promise` resolves, then resumed with the resolving value available on the stack. However, when exporting a Wasm function that relies on the suspending imported function back to the JavaScript host, you need to wrap the export in a `WebAssembly.promising()` call: + +```js +WebAssembly.instantiateStreaming(fetch("module.wasm"), { importObj }).then( + (result) => { + const fromWasm = WebAssembly.promising( + result.instance.exports.exportedFunc, + ); + fromWasm().then((result) => { + // ... + }); + }, +); +``` + +This effectively turns the export into a promise, which resolves once the imported JavaScript function resolves and allows the exported Wasm function's execution to complete. + +## Examples + +### Integrating a promise into a Wasm application + +This example shows how to import a JavaScript `Promise`-based function into a Wasm module, call it inside an exported Wasm function, and then call the exported function from the JavaScript host to obtain a result. + +#### HTML + +In our markup we include a {{htmlelement("button")}} element to start the application, and a {{htmlelement("p")}} element to output the obtained result into. + +```html live-sample___jspi + +
+

+``` + +#### Wasm + +Our Wasm module first imports a `double()` function, which takes an [`i32`](/en-US/docs/WebAssembly/Reference/Value_types/i32) parameter and returns an `i32` result. It then defines an exported `add()` function, which also takes and returns an `i32`. The `add()` function pushes a constant onto the stack and feeds that into the imported `double()` function, then [adds](/en-US/docs/WebAssembly/Reference/Numeric/add) the result to its parameter. + +```wat live-sample___jspi +(module + (import "importObj" "double" (func $double (param i32) (result i32))) + (func (export "add") (param i32) (result i32) + (i32.const 20) + call $double + (local.get 0) + + i32.add ;; add the two values + ) +) +``` + +#### JavaScript + +In our script, we first grab references to the `

` and `