Skip to content

Commit 7666902

Browse files
authored
[jspi] Fix returning pointers from async dyncalls. (#24316)
When dyncall calls an async function it should wait for the result of the promise to then convert the pointer. Fixes #24307
1 parent 2737dc5 commit 7666902

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

src/lib/libcore.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,14 +1818,24 @@ addToLibrary({
18181818
}
18191819
#endif
18201820
var rtn = func(...args);
1821-
#endif
1821+
#endif // DYNCALLS
1822+
1823+
function convert(rtn) {
18221824
#if MEMORY64
1823-
return sig[0] == 'p' ? Number(rtn) : rtn;
1825+
return sig[0] == 'p' ? Number(rtn) : rtn;
18241826
#elif CAN_ADDRESS_2GB
1825-
return sig[0] == 'p' ? rtn >>> 0 : rtn;
1827+
return sig[0] == 'p' ? rtn >>> 0 : rtn;
18261828
#else
1827-
return rtn;
1829+
return rtn;
1830+
#endif
1831+
}
1832+
1833+
#if JSPI
1834+
if (promising) {
1835+
return rtn.then(convert);
1836+
}
18281837
#endif
1838+
return convert(rtn);
18291839
},
18301840

18311841
$callRuntimeCallbacks__internal: true,

test/embind/embind_jspi_test.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ int stdFunction(const MyClass& target, int i) {
3939
return i + 1;
4040
}
4141

42+
MyClass* asyncGetMyClass() {
43+
emscripten_sleep(0);
44+
return new MyClass();
45+
}
46+
4247
EM_ASYNC_JS(void, jsSuspend, (), {
4348
await new Promise(resolve => {
4449
Module.unsuspendResolve = resolve;
@@ -60,6 +65,7 @@ EMSCRIPTEN_BINDINGS(xxx) {
6065
function("intFunc", &intFunc, async());
6166
function("unsuspend", &unsuspend);
6267
function("suspend", &suspend, async());
68+
function("asyncGetMyClass", &asyncGetMyClass, allow_raw_pointers(), async());
6369

6470
class_<MyClass>("MyClass")
6571
.constructor<>()
@@ -93,6 +99,9 @@ EM_ASYNC_JS(void, test, (), {
9399
await check(myClass.lambdaMethod(1), 2);
94100
await check(Module.MyClass.voidClass());
95101
await check(Module.MyClass.intClass(1), 2);
102+
var myClassAsync = await Module.asyncGetMyClass();
103+
assert(myClassAsync instanceof Module.MyClass);
104+
myClassAsync.delete();
96105

97106
setTimeout(Module.unsuspend);
98107
await Module.suspend();

0 commit comments

Comments
 (0)