diff --git a/stubs/machine.c b/stubs/machine.c index aafb0ec..e73f644 100644 --- a/stubs/machine.c +++ b/stubs/machine.c @@ -22,6 +22,10 @@ static void init_asyncify_buf(struct asyncify_buf *buf) static void *_asyncjmp_active_scan_buf = NULL; +// Separate buffer for async web API operations (isolated from setjmp) +static struct asyncify_buf _async_web_api_buf; +static int _async_web_api_in_unwind = 0; + void asyncjmp_scan_locals(asyncjmp_scan_func scan) { static struct asyncify_buf buf; @@ -42,6 +46,33 @@ void asyncjmp_scan_locals(asyncjmp_scan_func scan) } } +// Start async web API unwind - saves setjmp state if active +void async_web_api_unwind(void) +{ + if (!_async_web_api_in_unwind) + { + _async_web_api_in_unwind = 1; + init_asyncify_buf(&_async_web_api_buf); + asyncify_start_unwind(&_async_web_api_buf); + } +} + +// Stop async web API unwind and restore setjmp context +void async_web_api_stop(void) +{ + if (_async_web_api_in_unwind) + { + asyncify_stop_rewind(); + _async_web_api_in_unwind = 0; + } +} + +// Handle async web API unwind - called from runtime.c +void *async_web_api_handle_unwind(void) +{ + return (_async_web_api_in_unwind) ? &_async_web_api_buf : NULL; +} + static void *asyncjmp_stack_base = NULL; __attribute__((constructor)) int asyncjmp_record_stack_base(void) diff --git a/stubs/machine.h b/stubs/machine.h index d4fcc9c..576cfb5 100644 --- a/stubs/machine.h +++ b/stubs/machine.h @@ -21,4 +21,13 @@ void asyncjmp_set_stack_pointer(void *sp); // Used by the top level Asyncify handling in wasm/runtime.c void *asyncjmp_handle_scan_unwind(void); +// Start async web API unwind - uses separate buffer from setjmp +void async_web_api_unwind(void); + +// Stop async web API unwind +void async_web_api_stop(void); + +// Handle async web API unwind +void *async_web_api_handle_unwind(void); + #endif \ No newline at end of file diff --git a/stubs/runtime.c b/stubs/runtime.c index b1a0f7d..b5506e4 100644 --- a/stubs/runtime.c +++ b/stubs/runtime.c @@ -34,6 +34,12 @@ int asyncjmp_rt_start(int(main)(int argc, char **argv), int argc, char **argv) asyncify_start_rewind(asyncify_buf); continue; } + // Handle async web API unwind - uses separate buffer from setjmp + if ((asyncify_buf = async_web_api_handle_unwind()) != NULL) + { + asyncify_start_rewind(asyncify_buf); + continue; + } break; }