Closed hoodmane closed 5 months ago
- Personally, I would not endorse the feature detection use of Suspender.
Why not? Do you have another suggestion? JSPI is trickier to feature-detect than most other extensions because there aren't any new core constructs such as instructions that we can run through the validator.
Well, you will get an exception if you try to create a suspending WebAssembly.function and JSPI is not enabled.
See also #2 for more discussion about Suspender
.
Francis, Above you mentioned the Supender will be used for core stack switching as well, so checking for the Suspender may feature detect both. Will that also be a problem for checking for an exception when using a function with promising/suspending or will core stack switching use something else at the boundary?
Personally, I would not endorse the feature detection use of Suspender.
I think the alternative is to use the fact that promising: "first"
transforms the type of a function from ["externref", ...rest] => result
to [...rest] => [externref]
to feature detect. So first we make a wasm module that exports a function that takes an externref argument and returns nothing and does nothing:
(module (func (export "o") (param externref)))
Then we can feature detect with:
async function supportsJSPI() {
try {
const m = new Uint8Array([
0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 1, 111, 0, 3, 2, 1, 0, 7, 5, 1,
1, 111, 0, 0, 10, 4, 1, 2, 0, 11,
]);
const { instance } = await WebAssembly.instantiate(m);
new WebAssembly.Function(
{
parameters: [],
results: ["externref"],
},
instance.exports.o,
{ promising: "first" }
);
return true;
} catch (e) {
return false;
}
}
In case JSPI is not supported, WebAssembly.Function
throws the error:
The signature of Argument 1 (a WebAssembly function) does not match the signature specified in Argument 0
We have received a fair amount of 'feedback' about the Suspender object. At first blush, it definitely appears to be superfluous. You may also remember that the original version of JSPI hid the suspender from the wasm code. The true value of Suspender objects today comes from the more unusual scenarios: combining modules in sandwich configurations. In addition to the intrinsic utility of Suspenders for JSPI applications, there is also the issue of core stack switching; specifically how core ss will integrate with the world of JS and/or hosts. This represents a 'design issue' that is not fully resolved at this time; but there is some hope that Suspender objects will be important in that scenario. This is obviously not part of JSPI itself.
Incidentally, simply implementing JSPI/core stack switching in terms of the latter fails on the shores of exception handling and traps.
The upshot is that, while Suspenders are currently part of JSPI, I would prefer to de-emphasize their role and use as much as possible. For example, currently, the only way that a JS program would ever see a Suspender is if it were leaked from the wasm module.
To be clear, I am not questioning the value of the suspender object itself, I think the point of it is clear. I was questioning specifically the purpose of the WebAssembly.Suspender
global. It seems to me that running delete WebAssembly.Suspender
causes no loss of functionality of any sort, so I was concerned that "Suspender" in WebAssembly
could be broken by the removal of WebAssembly.Suspender
.
If we delete WebAssembly.Suspender what will the type of the object be when it's passed out from wasm to js?
Well it could have a type which is just not directly accessible from the JavaScript global scope. In that case you would have to acquire a suspender, move it into JS, and then get it via someSuspender.constructor
.
My goal is to have an easy way of feature detecting stack switching, preferably easier than the code I indicated above. "Suspender" in WebAssembly
is a great way to do this feature detection from my perspective. My concern is that the text of the proposal does not say anything about the JS global WebAssembly.Suspender
so it seems to me that some other JS engine could implement the proposal without "Suspender" in WebAssembly
being true
. If this is going to be the way that https://github.com/GoogleChromeLabs/wasm-feature-detect feature detects the JSPI I think it would be preferable for there to be language in the proposal that implies that this method will return true
on a conforming implementation.
To be clear, if we delete Suspender, there will be nothing to leak out to JS.
Closing, since it has been decided that the Suspender object is no longer visible to programmers.
@brendandahl added the JSPI feature detection to wasm-feature-detect which looks like:
https://github.com/GoogleChromeLabs/wasm-feature-detect/blob/main/src/detectors/jspi/index.js
Currently this does seem to work. It is even possible to construct an instance of
WebAssembly.Suspender
. This happens four times in the v8 test suite, but in no case is the Suspender object used for anything after it is constructed. For instance inTestStackSwitchSuspendArgs
the suspender was originally used but became dead code when the API was changed: https://github.com/v8/v8/blob/6bc1b613e94016010df71ecbb89c04ce267df3b3/test/mjsunit/wasm/stack-switching.js#L303 https://chromium.googlesource.com/v8/v8/+/921135c7059a0e2c2df2e6ddad7ae5f52311f589%5E%21/test/mjsunit/wasm/stack-switching.jsA few questions:
WebAssembly.Suspender
in any way?WebAssembly.Suspender
? Seems most likely to me that they are completely useless.WebAssembly.Suspender
forinstanceof
checks? This also seems of very dubious value to me.WebAssembly.Suspender
is to allow feature detection of the JSPI without having to attempt to instantiate a webassembly module, would this not be better served by a boolean e.g.,WebAssembly.supportsJSPI
?@thibaudmichaud