Ruby 3.5.0dev (2025-01-10 revision 5fab31b15e32622c4b71d1d347a41937e9f9c212)
runtime.c
1#include "wasm/machine.h"
2#include "wasm/setjmp.h"
3#include "wasm/fiber.h"
4#include "wasm/asyncify.h"
5#include <stdlib.h>
6
7int rb_wasm_rt_start(int (main)(int argc, char **argv), int argc, char **argv) {
8 int result;
9 void *asyncify_buf;
10
11 bool new_fiber_started = false;
12 void *arg0 = NULL, *arg1 = NULL;
13 void (*fiber_entry_point)(void *, void *) = NULL;
14
15 while (1) {
16 if (fiber_entry_point) {
17 fiber_entry_point(arg0, arg1);
18 } else {
19 result = main(argc, argv);
20 }
21
22 extern void *rb_asyncify_unwind_buf;
23 // Exit Asyncify loop if there is no unwound buffer, which
24 // means that main function has returned normally.
25 if (rb_asyncify_unwind_buf == NULL) {
26 break;
27 }
28
29 // NOTE: it's important to call 'asyncify_stop_unwind' here instead in rb_wasm_handle_jmp_unwind
30 // because unless that, Asyncify inserts another unwind check here and it unwinds to the root frame.
31 asyncify_stop_unwind();
32
33 if ((asyncify_buf = rb_wasm_handle_jmp_unwind()) != NULL) {
34 asyncify_start_rewind(asyncify_buf);
35 continue;
36 }
37 if ((asyncify_buf = rb_wasm_handle_scan_unwind()) != NULL) {
38 asyncify_start_rewind(asyncify_buf);
39 continue;
40 }
41
42 asyncify_buf = rb_wasm_handle_fiber_unwind(&fiber_entry_point, &arg0, &arg1, &new_fiber_started);
43 // Newly starting fiber doesn't have asyncify buffer yet, so don't rewind it for the first time entry
44 if (asyncify_buf) {
45 asyncify_start_rewind(asyncify_buf);
46 continue;
47 } else if (new_fiber_started) {
48 continue;
49 }
50
51 break;
52 }
53 return result;
54}