ceifa / wasmoon

A real lua 5.4 VM with JS bindings made with webassembly
MIT License
462 stars 27 forks source link

Cannot use Asyncify #68

Closed sunzhuo closed 8 months ago

sunzhuo commented 1 year ago

I want to use Asyncify. I wrote the following code and added -s ASYNCIFY in the build.sh. When I use this Sleep function in Lua, the process can print 1 and 2 with the right interval in the console, but gets stuck and doesn't return to proceed.

int Sleep(lua_State *L)
{
    double ms = lua_tonumber(L,1);
    printf("1\n");
    emscripten_sleep(ms);
    printf("2\n");
    return 0;
}
ceifa commented 1 year ago

How are you calling it on JS?

You can also bind a JS sleep function on Lua:

lua.global.set('sleep', (ms) => new Promise(resolve => setTimeout(resolve, ms)))
sleep(1000):await()
sunzhuo commented 1 year ago

How are you calling it on JS?

I tried engine.doString and engine.doStringSync in a web worker to call my lua code.

You can also bind a JS sleep function on Lua:

I just use the sleep function to demonstrate the async functionality. I have a batch of legacy Lua code with many embedded c functions in which I want to use async for nonblocking js executions.

sleep(1000):await()

I also tried your sleep in the browser. If I use engine.doStringSync, I got:

Error: cannot await in the main thread

If I use engine.doString, I got :

glue.wasm:0x2d719 

       Uncaught (in promise) RuntimeError: memory access out of bounds
    at glue.wasm:0x2d719
    at glue.wasm:0x3770b
    at A (glue.min.js:1:59815)
    at glue.wasm:0xbe71
    at glue.wasm:0x1a3eb
    at t._lua_resume [as lua_resume] (glue.min.js:1:66218)
    at h.resume (glue.min.js:1:2055)
    at h.run (glue.min.js:1:2921)
    at async T.callByteCode (glue.min.js:1:22190)
ceifa commented 1 year ago

Can you make a minimal repro? Tested on codesandbox and no errors: https://codesandbox.io/s/upbeat-sea-ippeee?file=/src/index.js

sunzhuo commented 1 year ago

I will make a repro later. From your code, I just wonder if I can modify your code as the following and remove the ":await()" in the Lua code?

  engine.global.set(
    "sleep",
    async (ms) => await new Promise((resolve) => setTimeout(resolve, ms))
  );
sleep(1000)
ceifa commented 1 year ago

Nop, if you remove the await it will hold a promise and will never sleep in fact. The only way to do this without promises is using Asyncify.