Merge remote-tracking branch 'origin/ni/i10-js-island-requires' into tmp-merge

This commit is contained in:
Malte Ubl
2026-10-22 19:28:22 -07:00
3 changed files with 55 additions and 0 deletions
+48
View File
@@ -1664,6 +1664,54 @@ static void scr_switch(ScrCtx *from, ScrCtx *to, ScrFiber *to_fiber) {
#endif
}
#ifdef SCR_NODE_ISLANDS
/* A nested entry into Node (scr_node_island.c) runs on Node's stack in a
* context of its own while the fiber that made the call stays suspended in
* it. Runtime code that Node calls back there runs as the loop's code does:
* no current fiber, the main exception cell and ALS slot. It may resume
* other fibers, which saves the resumer's context in scr_loop_ctx (and,
* under ASan, its fake stack in the main slot); those belong to whoever
* resumed the calling fiber, so they are saved here and put back when the
* nested entry returns, or the calling fiber's next park would return to a
* context that no longer exists. */
typedef struct {
ScrFiber *current;
ScrAlsCtx **als;
ScrCtx loop_ctx;
#ifdef SCR_ASAN_FIBERS
void *main_fake;
#endif
} ScrNestedSave;
void *scr_loop_nested_enter(void) {
ScrNestedSave *s = malloc(sizeof *s);
if (s == NULL) scr_oom();
s->current = scr_current;
s->als = scr_als_active;
s->loop_ctx = scr_loop_ctx;
#ifdef SCR_ASAN_FIBERS
s->main_fake = scr_main_fake_stack;
scr_main_fake_stack = NULL;
#endif
scr_current = NULL;
scr_exc_swap_cell(NULL);
scr_als_active = &scr_als_main_slot;
return s;
}
void scr_loop_nested_leave(void *save) {
ScrNestedSave *s = save;
scr_loop_ctx = s->loop_ctx;
#ifdef SCR_ASAN_FIBERS
scr_main_fake_stack = s->main_fake;
#endif
scr_current = s->current;
scr_exc_swap_cell(s->current ? &s->current->exc : NULL);
scr_als_active = s->als;
free(s);
}
#endif
static void scr_promise_settle_wake(ScrPromise *p);
/* Copies src's settlement into a still-pending dst (payload RETAINED —
+2
View File
@@ -332,6 +332,7 @@ static void ni_on_node_stack_below_mark(void (*job)(void *), void *arg) {
ni_nested_return = &caller;
uintptr_t guard = scr_stack_guard;
SCR_STACK_GUARD_SET(scr_stack_guard_for((uintptr_t)lo, hi - (uintptr_t)lo));
void *loop_save = scr_loop_nested_enter();
#ifdef NI_ASAN
void *caller_fake = NULL;
__sanitizer_start_switch_fiber(&caller_fake, lo, hi - (uintptr_t)lo);
@@ -342,6 +343,7 @@ static void ni_on_node_stack_below_mark(void (*job)(void *), void *arg) {
size_t size;
__sanitizer_finish_switch_fiber(caller_fake, &bottom, &size);
#endif
scr_loop_nested_leave(loop_save);
SCR_STACK_GUARD_SET(guard);
}
+5
View File
@@ -39,6 +39,11 @@ void scr_loop_host(const struct ScrNodeBridge *bridge, double since_ms);
* fiber; 0: none), and the test for Node's stack it uses. */
extern uintptr_t scr_node_stack_low;
extern bool (*scr_node_stack_has)(uintptr_t sp);
/* Around a nested entry: the runtime's scheduling state of the suspended
* calling fiber, saved and put back (the SCR_NODE_ISLANDS build of
* scr_async.c). */
void *scr_loop_nested_enter(void);
void scr_loop_nested_leave(void *save);
bool scr_loop_is_hosted(void);
void scr_loop_hosted_run(uint32_t kind, uint32_t token);
void scr_loop_hosted_io_state(struct ScrNodeIoState *state);