emscripten-core / emscripten-core/emscripten

Embind + MEMORY64: Cannot convert Promise to a BigInt

Open
#25,468 1 comment 0 reactions 0 assignees View on GitHub
embind jspi wasm64
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Embind Promise in combination with MEMORY64 fails to correctly bind Promise types.
```txt
Uncaught (in promise) SyntaxError: Cannot convert [object Promise] to a BigInt
```

**Version of emscripten/emsdk:**
emscripten 4.0.15
Chrome Canary Version 143.0.7447.0

**Failing command line in full:**
main.cpp
```c++
// cat main.cpp
#include
#include
#include

class ITestAsync {
public:
virtual ~ITestAsync() = default;
virtual void PrintValue() = 0;
};

class ITestAsyncWrapper : public emscripten::wrapper {
public:
EMSCRIPTEN_WRAPPER(ITestAsyncWrapper);
~ITestAsyncWrapper() override = default;
void PrintValue() override {
std::cout << "PrintValue resolving" << std::endl;
call("PrintValue").await().as();
std::cout << "PrintValue resolved" << std::endl;
}
};

class TestAsyncFactory {
public:
void SetFactory(emscripten::val factory) {
mFactory = [factory]() -> std::unique_ptr { return factory().as>(); };
};

void Execute() {
if (mFactory)
mFactory()->PrintValue();
};

private:
std::function()> mFactory;
};

EMSCRIPTEN_BINDINGS(AsyncWrapper) {
using namespace emscripten;
class_("ITestAsync")
.function("PrintValue", &ITestAsync::PrintValue, pure_virtual(), async())
.allow_subclass("ITestAsyncWrapper");

class_("TestAsyncFactory")
.constructor()
.function("SetFactory", &TestAsyncFactory::SetFactory)
.function("Execute", &TestAsyncFactory::Execute, async());
}
```

main.html
```HTML


Minimal HTML

async function main() {
Module = await Module();
console.log("AsyncFactory loaded",Module)

const TestAsyncClass = Module.ITestAsync.extend("ITestAsync", {
PrintValue() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('TestAsyncClass PrintValue executed');
resolve();
}, 10);
});
},

});

const factory = new Module.TestAsyncFactory();
factory.SetFactory(() => new TestAsyncClass());
await factory.Execute();
factory.delete();

}
main();

```

Build command:
```bash
emcc main.cpp -o AsyncFactory.js -fPIC -sMODULARIZE=1 -lembind -sJSPI -sMEMORY64=1
```

Image

If `-sMEMORY64=1` flag is omitted, the above example works just fine.

```bash
emcc main.cpp -o AsyncFactory.js -fPIC -sMODULARIZE=1 -lembind -sJSPI
```
Image

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.