-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Open
Description
Embind Promise in combination with MEMORY64 fails to correctly bind Promise types.
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
// cat main.cpp
#include <iostream>
#include <functional>
#include <emscripten/bind.h>
class ITestAsync {
public:
virtual ~ITestAsync() = default;
virtual void PrintValue() = 0;
};
class ITestAsyncWrapper : public emscripten::wrapper<ITestAsync> {
public:
EMSCRIPTEN_WRAPPER(ITestAsyncWrapper);
~ITestAsyncWrapper() override = default;
void PrintValue() override {
std::cout << "PrintValue resolving" << std::endl;
call<emscripten::val>("PrintValue").await().as<void>();
std::cout << "PrintValue resolved" << std::endl;
}
};
class TestAsyncFactory {
public:
void SetFactory(emscripten::val factory) {
mFactory = [factory]() -> std::unique_ptr<ITestAsync> { return factory().as<std::unique_ptr<ITestAsync>>(); };
};
void Execute() {
if (mFactory)
mFactory()->PrintValue();
};
private:
std::function<std::unique_ptr<ITestAsync>()> mFactory;
};
EMSCRIPTEN_BINDINGS(AsyncWrapper) {
using namespace emscripten;
class_<ITestAsync>("ITestAsync")
.function("PrintValue", &ITestAsync::PrintValue, pure_virtual(), async())
.allow_subclass<ITestAsyncWrapper>("ITestAsyncWrapper");
class_<TestAsyncFactory>("TestAsyncFactory")
.constructor()
.function("SetFactory", &TestAsyncFactory::SetFactory)
.function("Execute", &TestAsyncFactory::Execute, async());
}
main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Minimal HTML</title>
</head>
<body>
<script lang="ts" src="AsyncFactory.js"></script>
<script>
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();
</script>
</body>
</html>
Build command:
emcc main.cpp -o AsyncFactory.js -fPIC -sMODULARIZE=1 -lembind -sJSPI -sMEMORY64=1

If -sMEMORY64=1
flag is omitted, the above example works just fine.
emcc main.cpp -o AsyncFactory.js -fPIC -sMODULARIZE=1 -lembind -sJSPI
