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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions