Skip to content

Interaction between JSPI and WebAssembly.Function? #50

@hoodmane

Description

@hoodmane

I'm concerned about the interaction between this proposal and the JSPI, in particular about the behavior of new WebAssembly.Function(sig, new WebAssembly.Suspending(jsFunc)). I believe the two specs as they currently exist says this should throw an error, because IsCallable(new WebAssembly.Suspending(jsFunc)) should return false and then new Webassembly.Function should fail step 1 "Assert: =IsCallable=".

In v8 the current implementation seems to just delete the new WebAssembly.Suspending(jsFunc).

What I would like is for new WebAssembly.Function(sig, func) to behave like reexporting the function, basically the following pseudocode from #16:

function wasmFunctionPolyfill({ parameters, results }, f) {
  const builder = new WasmModuleBuilder();
  const functionIndex = builder.addImport("env", "f", { parameters, results });
  builder.addExport("exportedFunction", functionIndex);
  const buffer = builder.toBuffer();

  const module = new WebAssembly.Module(buffer);
  const instance = new WebAssembly.Instance(module, {"env": { f } });
  return instance.exports.exportedFunction;
}

To update the spec so that new WebAssembly.Function behaves like the above wasmFunctionPolyfill when passed a suspendable object I think we would need something like the following diff:

--- a/document/js-api/index.bs
+++ b/document/js-api/index.bs
@@ -1319,8 +1319,13 @@ The <dfn method for="Function">type()</dfn> method steps are:
 </div>
 
 <div algorithm>
-  To <dfn>construct a new WebAssembly Function</dfn> from a JavaScript [=callable=] object |callable| and {{FunctionType}} |signature|, perform the following steps:
+  To <dfn>construct a new WebAssembly Function</dfn> from a JavaScript [=callable=] or [=suspendable=] object |callable| and {{FunctionType}} |signature|, perform the following steps:
 
+    1. If |callable| has a \[[wrappedFunction]] internal slot:
+        1. Let |func| be |callable|'s \[[wrappedFunction]] slot.
+        1. Assert [=IsCallable=](|func|).
+        1. Create [=a new suspending function=] from |func| and |functype|, and let |funcaddr| be the result.
+        1. Return the result of creating [=a new Exported Function=] from |funcaddr|.
     1. Assert: [=IsCallable=](|callable|).
     1. Let |store| be the [=surrounding agent=]'s [=associated store=].
     1. Let |signature| be «[ "{{FunctionType/parameters}}" → |parameters|, "{{FunctionType/results}}" → |results| ]».

xrefs:
the jspi issue
the v8 issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions