Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The syn operation exception for JSPI #23213

Open
Perter-Zhang opened this issue Dec 18, 2024 · 4 comments
Open

The syn operation exception for JSPI #23213

Perter-Zhang opened this issue Dec 18, 2024 · 4 comments

Comments

@Perter-Zhang
Copy link

Perter-Zhang commented Dec 18, 2024

Please include the following in your bug report:

Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.74 (1092ec3)
clang version 20.0.0git (https:/github.com/llvm/llvm-project 322eb1a92e6d4266184060346616fa0dbe39e731)
Target: wasm32-unknown-emscripten
Thread model: posix

Failing command line in full:
NA

Full link command and output with -v appended:

emcc example.cpp exampleexport.cpp -o a.js -g -s JSPI -s JSPI_IMPORTS=['do_fetch'] --bind

I tried to use JSPI instead of ASYNCIFY, and wrote a demo, but I got this error:

example.cpp:31 Uncaught (in promise) RuntimeError: attempting to suspend without a WebAssembly.promising export
    at a.wasm.example::DoFetchSample() (http://127.0.0.1:5501/a.wasm:wasm-function[27]:0x1201)

2024-12-18 215034
2024-12-18 215132

//example.h

#pragma once
#include <emscripten.h>
#include <emscripten/val.h>

class example
{
private:
public:
  example();
  ~example();

  void DoFetchSample();
};

//example.cpp
#include "example.h"
#include <emscripten/html5.h>
#include <emscripten/bind.h>
#include <stdio.h>
#include <iostream>
#include <string>


example::example()
{
}

example::~example()
{
}

EM_JS(int, do_fetch, (), {
  return Asyncify.handleAsync(function () {
    out("waiting for a fetch");
    return fetch("a.html").then(function (response) {
      out("got the fetch response");
      // (normally you would do something with the fetch here)
      return 42;
    });
  });
});

void example::DoFetchSample()
{
  std::cout << "do_fetch begin: " << std::endl;
  int nResult = do_fetch();
  std::cout << "do_fetch end: " << nResult << std::endl;
}

//exampleexport.cpp
#include "example.h"
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>

EMSCRIPTEN_BINDINGS(exampleWrapper)
{
    emscripten::class_<example>("example")
        .constructor<>()
        .function("DoFetchSample", &example::DoFetchSample);
}
///TestDemo.html
<!DOCTYPE html>
<html lang="utf-8">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Test Demo</title>
</head>

<body>
</body>
<style>
  html,
  body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
  }
  
</style>
<script>
  var webReportCtrl = undefined;
  Module = {};
  Module.onRuntimeInitialized = async function () {
    webReportCtrl = new Module.example();
    webReportCtrl.DoModal();
  };

</script>
<script src="./a.js"></script>

</html>

If i use following command, the result is ok.

emcc example.cpp exampleexport.cpp -o a.js -g -s ASYNCIFY -s ASYNCIFY_IMPORTS=['do_fetch'] --bind

Am I using JSPI wrong?

@hoodmane
Copy link
Collaborator

This doesn't seem to include a full reproduction. example.h is missing and the traceback you took a screenshot of seems to involve a file called TestDemo.html which sets Module.onRuntimeInitialized.

@Perter-Zhang
Copy link
Author

This doesn't seem to include a full reproduction. example.h is missing and the traceback you took a screenshot of seems to involve a file called TestDemo.html which sets Module.onRuntimeInitialized.

I'm so sorry for this mistake, i already add the html and example.h to reproduction

@Perter-Zhang
Copy link
Author

The google chrome version is Version 131.0.6778.205 (Official Build) (64-bit)
The chrome flag "Experimental WebAssembly JavaScript Promise Integration (JSPI)" and " Experimental Web Platform features" are set to enabled

@brendandahl
Copy link
Collaborator

The example doesn't seem to actually be the full example, but I think I see what's going on. With JSPI the function that enters wasm must have be marked as async. For embind:

.function("DoFetchSample", &example::DoFetchSample, async());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants