From 35626eeb300b9da474c85ec59d7dc1e2afc0469f Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Wed, 29 May 2024 13:23:19 -0700 Subject: [PATCH 01/27] Blog entry for new JSPI API --- src/blog/jspi-newapi.md | 106 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/blog/jspi-newapi.md diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md new file mode 100644 index 00000000..b61778d9 --- /dev/null +++ b/src/blog/jspi-newapi.md @@ -0,0 +1,106 @@ +--- +title: 'WebAssembly JSPI has a new API' +description: 'We explain the new API for JSPI' +author: 'Francis McCabe, Thibaud Michaud, Ilya Rezvov, Brendan Dahl' +date: 2024-05-28 +tags: + - WebAssembly +--- +WebAssembly’s JavaScript Promise Integration (JSPI) API has a new API, available in Chrome release M126. We talk about what has changed, how to use it with Emscripten, and what is the roadmap for JSPI. + +JSPI is an API that allows WebAssembly applications that use *sequential* APIs to access Web APIs that are *asynchronous*. Many Web APIs are crafted in terms of JavaScript `Promise`s: instead of immediately performing the requested operation they return a `Promise` to do so. On the other hand, many applications compiled to WebAssembly come from the C/C++ universe which is dominated by APIs that block the caller until they are completed. + +JSPI hooks into the Web architecture to allow a WebAssembly application to be suspended when the `Promise` is returned and resumed when the `Promise` is resolved. + +You can find out more about JSPI and how to use it [here](https://v8.dev/blog/jspi) and the specification itself is [here](https://github.com/WebAssembly/js-promise-integration). + +## What is new? + +### The end of `Suspender`s + +In January 2024, the Stacks sub-group of the Wasm CG [voted](https://github.com/WebAssembly/meetings/blob/297ac8b5ac00e6be1fe33b1f4a146cc7481b631d/stack/2024/stack-2024-01-29.md) to amend the API for JSPI. Specifically, instead of an explicit `Suspender` object we will use the JavaScript/WebAssembly boundary as the delimiter for determining what computations are suspended. + +The difference is fairly small but potentially significant: when a computation is to be suspended it is the most recent call into a wrapped WebAssembly export that determines the 'cut point' for what is suspended. + +The implication of this is that a developer using JSPI has a little less control over that cut point. On the other hand, not having to explicitly manage `Suspender` objects makes the API significantly easier to use. + +### No more `WebAssembly.Function` + +Another change is to the style of the API. Instead of characterizing JSPI wrappers in terms of the `WebAssembly.Function` constructor, we provide specific functions and constructors. + +This has a number of benefits: + +- It removes dependency on the [*Type Reflection Proposal*](https://github.com/WebAssembly/js-types), and +- it makes tooling for JSPI simpler: the new API functions no longer need to refer explicitly to the WebAssembly types of functions. + +This change is enabled by the decision to no longer have explicitly referenced `Suspender` objects. + +### Returning without suspending + +A third change refers to the behavior of suspending calls. Instead of always suspending when calling a JavaScript function from a suspending import, we only suspend when the JavaScript function actually returns a `Promise`. + +This change, while apparently going against the [recommendations](https://www.w3.org/2001/tag/doc/promises-guide#accepting-promises) of the W3C TAG, represents a safe optimization for JSPI users. It is safe because JSPI is actually taking on the role of a *caller* to a `Promise` returning function. + +This change will likely have minimal impact on most applications; however, some applications will see a notable benefit by avoiding unnecessary trips to the browser event loop. + +### The new API + +The API is pretty simple: there is a function that takes a function exported from a WebAssembly module and converts it into a `Promise` returning function: + +```js +Function Webassembly.promising(Function wsFun) +``` + +Note that, although the argument is typed as a `Function` — i.e., a JavaScript function — it is actually restricted to WebAssembly functions. + +On the suspending side, we have a new class `WebAssembly.Suspending`, together with a constructor that takes a JavaScript function as argument. In WebIDL this is written: + +```js +interface Suspending{ + constructor (Function fun); +} +``` + +Note that this API has an asymmetric feel to it: we have a function that takes a WebAssembly function and returns a new promising (sic) function; whereas to mark a suspending function we enclose it in a `Suspending` object. This reflects a deeper reality about what is happening under the hood. + +The suspending behavior of an import is intrinsically part of the *call* to the import: i.e., some function inside the instantiated module calls the import and suspends as a result. + +On the other hand, the `promising` function takes a regular WebAssembly function and returns a new one that can respond to being suspended and which returns a `Promise`. + +### Using the new API + +If you are an Emscripten user, then using the new API will typically involve no changes to your code. You must be using a version of emscripten that is at least 3.1.61, and you must be using a version of Chrome that is at least 126.0.6478.17 (milestone 126). + +If you are rolling your own integration, then your code should be significantly simpler. In particular, it is no longer necessary to have code that stores the passed-in `Suspender` object (and retrieve it when calling the import). One can simply use regular sequential code within the WebAssembly module. + +### The old API + +The old API will continue to operate at least until 10/29/2024 (Chrome M128). After that we plan on removing the old API. + +Note that Emscripten itself will no longer support the old API as of version 3.1.61. + +## What is happening with JSPI? + +### Implementation aspects + +The biggest change to JSPI that we are working on is actually invisible to most programmers: so-called growable stacks. + +The current implementation of JSPI is based on allocating stacks of a fixed size. In fact, the allocated stacks are rather large; because we have to be able to accomodate arbitrary WebAssembly computations which may require deep stacks to handle recursion properly. + +However, this is not a sustainable strategy: we would like to support applications with millions of suspended coroutines; this is not possible if each stack is 1Mb in size. + +Growable stacks refers to a stack allocation strategy that allows a WebAssembly stack to grow as needed. That way, we can start with very small stacks for those applications that only need small stack space and grow the stack when the application runs out of room (otherwise known as stack overflow). + +There are several potential techniques for implementing growable stacks. One that we are investigating is segmented stacks. A segmented stack consists of a chain of stack regions — each of which has a fixed size, but different segments may have different sizes. + +Note that while we may be solving the stack overflow issue for coroutines we are not planning to make the main or central stack growable. Thus, if your application runs out of stack space, growable stacks will not fix your problem unless you use JSPI. + +### The standards process + +As of publication, there is an origin trial for JSPI — see [here](https://v8.dev/blog/jspi-ot) — that is active. The new API will be live during the remainder of the origin trial — available with Chrome M126. + +The previous API will also be available during the origin trial; however, it is planned to be retired shortly after Chrome M132. + +After that, the main thrust for JSPI revolves around the standardization process. JSPI is currently (at publication time) in phase 3 of the W3C Wasm CG process. The next step, moving to phase 4, marks the crucial adoption of JSPI as a standard API for the JavaScript and WebAssembly. + +We would like to know what you think about these changes to JSPI! Join the discussion at the W3C WebAssembly Community Group [repo](https://github.com/WebAssembly/js-promise-integration). From 51ecf310094ac244d287ccb92b9e77c9a08de805 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 09:41:37 -0700 Subject: [PATCH 02/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index b61778d9..e4da438c 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -8,7 +8,7 @@ tags: --- WebAssembly’s JavaScript Promise Integration (JSPI) API has a new API, available in Chrome release M126. We talk about what has changed, how to use it with Emscripten, and what is the roadmap for JSPI. -JSPI is an API that allows WebAssembly applications that use *sequential* APIs to access Web APIs that are *asynchronous*. Many Web APIs are crafted in terms of JavaScript `Promise`s: instead of immediately performing the requested operation they return a `Promise` to do so. On the other hand, many applications compiled to WebAssembly come from the C/C++ universe which is dominated by APIs that block the caller until they are completed. +JSPI is an API that allows WebAssembly applications that use *sequential* APIs to access Web APIs that are *asynchronous*. Many Web APIs are crafted in terms of JavaScript `Promise` objects: instead of immediately performing the requested operation, they return a `Promise` to do so. On the other hand, many applications compiled to WebAssembly come from the C/C++ universe, which is dominated by APIs that block the caller until they are completed. JSPI hooks into the Web architecture to allow a WebAssembly application to be suspended when the `Promise` is returned and resumed when the `Promise` is resolved. From 973d2147e09f0c2bb336bf53ab2d3acb3ab7f5c2 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 09:45:00 -0700 Subject: [PATCH 03/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index e4da438c..e72010a4 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -18,7 +18,7 @@ You can find out more about JSPI and how to use it [here](https://v8.dev/blog/js ### The end of `Suspender`s -In January 2024, the Stacks sub-group of the Wasm CG [voted](https://github.com/WebAssembly/meetings/blob/297ac8b5ac00e6be1fe33b1f4a146cc7481b631d/stack/2024/stack-2024-01-29.md) to amend the API for JSPI. Specifically, instead of an explicit `Suspender` object we will use the JavaScript/WebAssembly boundary as the delimiter for determining what computations are suspended. +In January 2024, the Stacks sub-group of the Wasm CG [voted](https://github.com/WebAssembly/meetings/blob/297ac8b5ac00e6be1fe33b1f4a146cc7481b631d/stack/2024/stack-2024-01-29.md) to amend the API for JSPI. Specifically, instead of an explicit `Suspender` object, we will use the JavaScript/WebAssembly boundary as the delimiter for determining what computations are suspended. The difference is fairly small but potentially significant: when a computation is to be suspended it is the most recent call into a wrapped WebAssembly export that determines the 'cut point' for what is suspended. From 2719d3af45e92757744226968f45e0e4c4d2c11c Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 09:45:51 -0700 Subject: [PATCH 04/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index e72010a4..058bb500 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -20,7 +20,7 @@ You can find out more about JSPI and how to use it [here](https://v8.dev/blog/js In January 2024, the Stacks sub-group of the Wasm CG [voted](https://github.com/WebAssembly/meetings/blob/297ac8b5ac00e6be1fe33b1f4a146cc7481b631d/stack/2024/stack-2024-01-29.md) to amend the API for JSPI. Specifically, instead of an explicit `Suspender` object, we will use the JavaScript/WebAssembly boundary as the delimiter for determining what computations are suspended. -The difference is fairly small but potentially significant: when a computation is to be suspended it is the most recent call into a wrapped WebAssembly export that determines the 'cut point' for what is suspended. +The difference is fairly small but potentially significant: when a computation is to be suspended, it is the most recent call into a wrapped WebAssembly export that determines the 'cut point' for what is suspended. The implication of this is that a developer using JSPI has a little less control over that cut point. On the other hand, not having to explicitly manage `Suspender` objects makes the API significantly easier to use. From aa49c7cc97253164a11d72d4e00c1d5bb7d2a733 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 09:48:07 -0700 Subject: [PATCH 05/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 058bb500..10595cd1 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -30,8 +30,8 @@ Another change is to the style of the API. Instead of characterizing JSPI wrappe This has a number of benefits: -- It removes dependency on the [*Type Reflection Proposal*](https://github.com/WebAssembly/js-types), and -- it makes tooling for JSPI simpler: the new API functions no longer need to refer explicitly to the WebAssembly types of functions. +- It removes dependency on the [*Type Reflection* Proposal](https://github.com/WebAssembly/js-types). +- It makes tooling for JSPI simpler: the new API functions no longer need to refer explicitly to the WebAssembly types of functions. This change is enabled by the decision to no longer have explicitly referenced `Suspender` objects. From 816d4693b14d712c8397ea0e9f62af66cc09060c Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 09:48:48 -0700 Subject: [PATCH 06/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 10595cd1..1f37040b 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -39,7 +39,7 @@ This change is enabled by the decision to no longer have explicitly referenced ` A third change refers to the behavior of suspending calls. Instead of always suspending when calling a JavaScript function from a suspending import, we only suspend when the JavaScript function actually returns a `Promise`. -This change, while apparently going against the [recommendations](https://www.w3.org/2001/tag/doc/promises-guide#accepting-promises) of the W3C TAG, represents a safe optimization for JSPI users. It is safe because JSPI is actually taking on the role of a *caller* to a `Promise` returning function. +This change, while apparently going against the [recommendations](https://www.w3.org/2001/tag/doc/promises-guide#accepting-promises) of the W3C TAG, represents a safe optimization for JSPI users. It is safe because JSPI is actually taking on the role of a *caller* to a function that returns a `Promise`. This change will likely have minimal impact on most applications; however, some applications will see a notable benefit by avoiding unnecessary trips to the browser event loop. From 9a4a9fee26683e52e28498169eb1767f08a9c699 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 09:49:26 -0700 Subject: [PATCH 07/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 1f37040b..76960e60 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -41,7 +41,7 @@ A third change refers to the behavior of suspending calls. Instead of always sus This change, while apparently going against the [recommendations](https://www.w3.org/2001/tag/doc/promises-guide#accepting-promises) of the W3C TAG, represents a safe optimization for JSPI users. It is safe because JSPI is actually taking on the role of a *caller* to a function that returns a `Promise`. -This change will likely have minimal impact on most applications; however, some applications will see a notable benefit by avoiding unnecessary trips to the browser event loop. +This change will likely have minimal impact on most applications; however, some applications will see a notable benefit by avoiding unnecessary trips to the browser's event loop. ### The new API From 0b73c55e2134f74ac5a0cf59ba6e208664171782 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 09:49:59 -0700 Subject: [PATCH 08/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 76960e60..de3d2444 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -45,7 +45,7 @@ This change will likely have minimal impact on most applications; however, some ### The new API -The API is pretty simple: there is a function that takes a function exported from a WebAssembly module and converts it into a `Promise` returning function: +The API is straightforward: there is a function that takes a function exported from a WebAssembly module and converts it into a function that returns a `Promise`: ```js Function Webassembly.promising(Function wsFun) From 0673e339ee9b367925e48ebd0e59033b7b928144 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 09:51:56 -0700 Subject: [PATCH 09/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index de3d2444..6966f5dc 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -51,7 +51,7 @@ The API is straightforward: there is a function that takes a function exported f Function Webassembly.promising(Function wsFun) ``` -Note that, although the argument is typed as a `Function` — i.e., a JavaScript function — it is actually restricted to WebAssembly functions. +Note that even if the argument is typed as a JavaScript `Function`, it is actually restricted to WebAssembly functions. On the suspending side, we have a new class `WebAssembly.Suspending`, together with a constructor that takes a JavaScript function as argument. In WebIDL this is written: From 1f2ac67f9b93f64177dd2659518aed0db12566cb Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:05:58 -0700 Subject: [PATCH 10/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 6966f5dc..3bedbb05 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -16,7 +16,7 @@ You can find out more about JSPI and how to use it [here](https://v8.dev/blog/js ## What is new? -### The end of `Suspender`s +### The end of `Suspender` objects In January 2024, the Stacks sub-group of the Wasm CG [voted](https://github.com/WebAssembly/meetings/blob/297ac8b5ac00e6be1fe33b1f4a146cc7481b631d/stack/2024/stack-2024-01-29.md) to amend the API for JSPI. Specifically, instead of an explicit `Suspender` object, we will use the JavaScript/WebAssembly boundary as the delimiter for determining what computations are suspended. From a06550cc3606e4ebe8ccaad19d603c1da27ac11e Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:06:57 -0700 Subject: [PATCH 11/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 3bedbb05..5ccec97f 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -53,7 +53,7 @@ Function Webassembly.promising(Function wsFun) Note that even if the argument is typed as a JavaScript `Function`, it is actually restricted to WebAssembly functions. -On the suspending side, we have a new class `WebAssembly.Suspending`, together with a constructor that takes a JavaScript function as argument. In WebIDL this is written: +On the suspending side, there's a new class `WebAssembly.Suspending`, together with a constructor that takes a JavaScript function as an argument. In WebIDL, this is written as follows: ```js interface Suspending{ From 42d7833e95cea11ab97431a00390a187d0645b14 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:07:53 -0700 Subject: [PATCH 12/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 5ccec97f..9d9ecbba 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -57,7 +57,7 @@ On the suspending side, there's a new class `WebAssembly.Suspending`, together w ```js interface Suspending{ - constructor (Function fun); + constructor (Function fun); } ``` From 604803560e41606be22c09430d6b23f99a7bb8d4 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:09:02 -0700 Subject: [PATCH 13/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 9d9ecbba..9f21ff45 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -61,7 +61,7 @@ interface Suspending{ } ``` -Note that this API has an asymmetric feel to it: we have a function that takes a WebAssembly function and returns a new promising (sic) function; whereas to mark a suspending function we enclose it in a `Suspending` object. This reflects a deeper reality about what is happening under the hood. +Note that this API has an asymmetric feel to it: there's have a function that takes a WebAssembly function and returns a new promising (_sic_) function; whereas to mark a suspending function, you enclose it in a `Suspending` object. This reflects a deeper reality about what is happening under the hood. The suspending behavior of an import is intrinsically part of the *call* to the import: i.e., some function inside the instantiated module calls the import and suspends as a result. From 762a48f864bb78c32e9d2572def61889447be83d Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:10:11 -0700 Subject: [PATCH 14/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 9f21ff45..a72bd059 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -103,4 +103,4 @@ The previous API will also be available during the origin trial; however, it is After that, the main thrust for JSPI revolves around the standardization process. JSPI is currently (at publication time) in phase 3 of the W3C Wasm CG process. The next step, moving to phase 4, marks the crucial adoption of JSPI as a standard API for the JavaScript and WebAssembly. -We would like to know what you think about these changes to JSPI! Join the discussion at the W3C WebAssembly Community Group [repo](https://github.com/WebAssembly/js-promise-integration). +We would like to know what you think about these changes to JSPI! Join the discussion at the [W3C WebAssembly Community Group repo](https://github.com/WebAssembly/js-promise-integration). From 27ed70024dc06ae050ef2e23e8fef450c3975c95 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:10:35 -0700 Subject: [PATCH 15/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index a72bd059..209b0523 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -89,7 +89,7 @@ The current implementation of JSPI is based on allocating stacks of a fixed size However, this is not a sustainable strategy: we would like to support applications with millions of suspended coroutines; this is not possible if each stack is 1Mb in size. -Growable stacks refers to a stack allocation strategy that allows a WebAssembly stack to grow as needed. That way, we can start with very small stacks for those applications that only need small stack space and grow the stack when the application runs out of room (otherwise known as stack overflow). +Growable stacks refers to a stack allocation strategy that allows a WebAssembly stack to grow as needed. That way, we can start with very small stacks for those applications that only need small stack space, and grow the stack when the application runs out of space (otherwise known as stack overflow). There are several potential techniques for implementing growable stacks. One that we are investigating is segmented stacks. A segmented stack consists of a chain of stack regions — each of which has a fixed size, but different segments may have different sizes. From 5df6492128e782a676eea09f4f2810cf1d42c0b1 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:11:04 -0700 Subject: [PATCH 16/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 209b0523..d2e4439a 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -93,7 +93,7 @@ Growable stacks refers to a stack allocation strategy that allows a WebAssembly There are several potential techniques for implementing growable stacks. One that we are investigating is segmented stacks. A segmented stack consists of a chain of stack regions — each of which has a fixed size, but different segments may have different sizes. -Note that while we may be solving the stack overflow issue for coroutines we are not planning to make the main or central stack growable. Thus, if your application runs out of stack space, growable stacks will not fix your problem unless you use JSPI. +Note that while we may be solving the stack overflow issue for coroutines, we are not planning to make the main or central stack growable. Thus, if your application runs out of stack space, growable stacks will not fix your problem unless you use JSPI. ### The standards process From ca32beac4d8805cb1f90020cb50fa749c4d6065a Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:11:37 -0700 Subject: [PATCH 17/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index d2e4439a..8252a7ce 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -97,7 +97,7 @@ Note that while we may be solving the stack overflow issue for coroutines, we ar ### The standards process -As of publication, there is an origin trial for JSPI — see [here](https://v8.dev/blog/jspi-ot) — that is active. The new API will be live during the remainder of the origin trial — available with Chrome M126. +As of publication, there is an active [origin trial for JSPI](https://v8.dev/blog/jspi-ot). The new API will be live during the remainder of the origin trial — available with Chrome M126. The previous API will also be available during the origin trial; however, it is planned to be retired shortly after Chrome M132. From 347dec2f46ce149f35f3ebbe905b5602689ffd3b Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:12:14 -0700 Subject: [PATCH 18/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 8252a7ce..415d50be 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -101,6 +101,6 @@ As of publication, there is an active [origin trial for JSPI](https://v8.dev/blo The previous API will also be available during the origin trial; however, it is planned to be retired shortly after Chrome M132. -After that, the main thrust for JSPI revolves around the standardization process. JSPI is currently (at publication time) in phase 3 of the W3C Wasm CG process. The next step, moving to phase 4, marks the crucial adoption of JSPI as a standard API for the JavaScript and WebAssembly. +After that, the main thrust for JSPI revolves around the standardization process. JSPI is currently (at publication time) in phase 3 of the W3C Wasm CG process. The next step, i.e., moving to phase 4, marks the crucial adoption of JSPI as a standard API for the JavaScript and WebAssembly ecosystems. We would like to know what you think about these changes to JSPI! Join the discussion at the [W3C WebAssembly Community Group repo](https://github.com/WebAssembly/js-promise-integration). From d5cf036335ca416d1d0976af00d80a498db16195 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:12:40 -0700 Subject: [PATCH 19/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 415d50be..8bb8a827 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -69,7 +69,7 @@ On the other hand, the `promising` function takes a regular WebAssembly function ### Using the new API -If you are an Emscripten user, then using the new API will typically involve no changes to your code. You must be using a version of emscripten that is at least 3.1.61, and you must be using a version of Chrome that is at least 126.0.6478.17 (milestone 126). +If you are an Emscripten user, then using the new API will typically involve no changes to your code. You must be using a version of Emscripten that is at least 3.1.61, and you must be using a version of Chrome that is at least 126.0.6478.17 (Milestone 126). If you are rolling your own integration, then your code should be significantly simpler. In particular, it is no longer necessary to have code that stores the passed-in `Suspender` object (and retrieve it when calling the import). One can simply use regular sequential code within the WebAssembly module. From 2f1ea11f26d58ffd38140512d992bfb8132b3e25 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:13:02 -0700 Subject: [PATCH 20/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 8bb8a827..79f62aa8 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -71,7 +71,7 @@ On the other hand, the `promising` function takes a regular WebAssembly function If you are an Emscripten user, then using the new API will typically involve no changes to your code. You must be using a version of Emscripten that is at least 3.1.61, and you must be using a version of Chrome that is at least 126.0.6478.17 (Milestone 126). -If you are rolling your own integration, then your code should be significantly simpler. In particular, it is no longer necessary to have code that stores the passed-in `Suspender` object (and retrieve it when calling the import). One can simply use regular sequential code within the WebAssembly module. +If you are rolling your own integration, then your code should be significantly simpler. In particular, it is no longer necessary to have code that stores the passed-in `Suspender` object (and retrieve it when calling the import). You can simply use regular sequential code within the WebAssembly module. ### The old API From 29b33a7f6d126d6b57a7b9d69806cf97a492d09d Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:13:27 -0700 Subject: [PATCH 21/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 79f62aa8..70ac41a2 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -75,7 +75,7 @@ If you are rolling your own integration, then your code should be significantly ### The old API -The old API will continue to operate at least until 10/29/2024 (Chrome M128). After that we plan on removing the old API. +The old API will continue to operate at least until October 29, 2024 (Chrome M128). After that, we plan on removing the old API. Note that Emscripten itself will no longer support the old API as of version 3.1.61. From 5256008e8a51e4876d60a9003d07fd3979fccd90 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:13:53 -0700 Subject: [PATCH 22/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 70ac41a2..1ff709b2 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -85,7 +85,7 @@ Note that Emscripten itself will no longer support the old API as of version 3.1 The biggest change to JSPI that we are working on is actually invisible to most programmers: so-called growable stacks. -The current implementation of JSPI is based on allocating stacks of a fixed size. In fact, the allocated stacks are rather large; because we have to be able to accomodate arbitrary WebAssembly computations which may require deep stacks to handle recursion properly. +The current implementation of JSPI is based on allocating stacks of a fixed size. In fact, the allocated stacks are rather large. This is because we have to be able to accommodate arbitrary WebAssembly computations which may require deep stacks to handle recursion properly. However, this is not a sustainable strategy: we would like to support applications with millions of suspended coroutines; this is not possible if each stack is 1Mb in size. From 84e42d371c9f52e9ff7fa70f30160e85b8df392f Mon Sep 17 00:00:00 2001 From: Thomas Steiner Date: Fri, 31 May 2024 19:17:31 +0200 Subject: [PATCH 23/27] Update src/blog/jspi-newapi.md --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 1ff709b2..5b117281 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -87,7 +87,7 @@ The biggest change to JSPI that we are working on is actually invisible to most The current implementation of JSPI is based on allocating stacks of a fixed size. In fact, the allocated stacks are rather large. This is because we have to be able to accommodate arbitrary WebAssembly computations which may require deep stacks to handle recursion properly. -However, this is not a sustainable strategy: we would like to support applications with millions of suspended coroutines; this is not possible if each stack is 1Mb in size. +However, this is not a sustainable strategy: we would like to support applications with millions of suspended coroutines; this is not possible if each stack is 1MB in size. Growable stacks refers to a stack allocation strategy that allows a WebAssembly stack to grow as needed. That way, we can start with very small stacks for those applications that only need small stack space, and grow the stack when the application runs out of space (otherwise known as stack overflow). From fe008edb565d4a3ae0485a4bbffb7b9cf9b083df Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:27:43 -0700 Subject: [PATCH 24/27] Additional change following reviewer remarks. --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 5b117281..1eaf54c2 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -12,7 +12,7 @@ JSPI is an API that allows WebAssembly applications that use *sequential* APIs t JSPI hooks into the Web architecture to allow a WebAssembly application to be suspended when the `Promise` is returned and resumed when the `Promise` is resolved. -You can find out more about JSPI and how to use it [here](https://v8.dev/blog/jspi) and the specification itself is [here](https://github.com/WebAssembly/js-promise-integration). +You can find out more about JSPI and how to use it [in this blog post](https://v8.dev/blog/jspi) and in the [specification](https://github.com/WebAssembly/js-promise-integration). ## What is new? From fb7ed1b98f211415ffa232c7ac2a7ab00c7df0b7 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 10:31:02 -0700 Subject: [PATCH 25/27] Fix chrome milestones --- src/blog/jspi-newapi.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 1eaf54c2..ebaa367f 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -69,7 +69,7 @@ On the other hand, the `promising` function takes a regular WebAssembly function ### Using the new API -If you are an Emscripten user, then using the new API will typically involve no changes to your code. You must be using a version of Emscripten that is at least 3.1.61, and you must be using a version of Chrome that is at least 126.0.6478.17 (Milestone 126). +If you are an Emscripten user, then using the new API will typically involve no changes to your code. You must be using a version of Emscripten that is at least 3.1.61, and you must be using a version of Chrome that is at least 126.0.6478.17 (Chrome M126). If you are rolling your own integration, then your code should be significantly simpler. In particular, it is no longer necessary to have code that stores the passed-in `Suspender` object (and retrieve it when calling the import). You can simply use regular sequential code within the WebAssembly module. @@ -99,7 +99,7 @@ Note that while we may be solving the stack overflow issue for coroutines, we ar As of publication, there is an active [origin trial for JSPI](https://v8.dev/blog/jspi-ot). The new API will be live during the remainder of the origin trial — available with Chrome M126. -The previous API will also be available during the origin trial; however, it is planned to be retired shortly after Chrome M132. +The previous API will also be available during the origin trial; however, it is planned to be retired shortly after Chrome M128. After that, the main thrust for JSPI revolves around the standardization process. JSPI is currently (at publication time) in phase 3 of the W3C Wasm CG process. The next step, i.e., moving to phase 4, marks the crucial adoption of JSPI as a standard API for the JavaScript and WebAssembly ecosystems. From 3c60e6d5f4727a05756a55e53e859cd76ad89402 Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Fri, 31 May 2024 11:15:49 -0700 Subject: [PATCH 26/27] Add section on detecting which JSPI is enabled. --- src/blog/jspi-newapi.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index ebaa367f..049182b6 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -79,6 +79,22 @@ The old API will continue to operate at least until October 29, 2024 (Chrome M12 Note that Emscripten itself will no longer support the old API as of version 3.1.61. +### Detecting which API is in your browser + +Changing APIs should never be taken lightly. We are able to do so in this case because JSPI itself is still provisional. There is a simple way that you can test to see which API is enabled in your browser: + +```js +function oldAPI(){ + return WebAssembly.Suspender!=undefined +} + +function newAPI(){ + return WebAssembly.Suspending!=undefined +} +``` + +The `oldAPI` function returns true if the old JSPI API is enabled in your browser, and the `newAPI` function returns true if the new JSPI API is enabled. + ## What is happening with JSPI? ### Implementation aspects From 240526d0ac9b0b72fda3a7a3cab011fdfe5528ed Mon Sep 17 00:00:00 2001 From: Francis McCabe Date: Tue, 4 Jun 2024 09:02:43 -0700 Subject: [PATCH 27/27] Update src/blog/jspi-newapi.md Co-authored-by: Thomas Steiner --- src/blog/jspi-newapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blog/jspi-newapi.md b/src/blog/jspi-newapi.md index 049182b6..e4c4cadc 100644 --- a/src/blog/jspi-newapi.md +++ b/src/blog/jspi-newapi.md @@ -1,6 +1,6 @@ --- title: 'WebAssembly JSPI has a new API' -description: 'We explain the new API for JSPI' +description: 'This article details some upcoming changes to the JavaScript Promise Integration (JSPI) API.' author: 'Francis McCabe, Thibaud Michaud, Ilya Rezvov, Brendan Dahl' date: 2024-05-28 tags: