Ruby 3.5.0dev (2025-01-10 revision 5fab31b15e32622c4b71d1d347a41937e9f9c212)
Context.h
1#pragma once
2
3#include <assert.h>
4#include <stddef.h>
5#include <stdint.h>
6#include <string.h>
7
8#define COROUTINE __attribute__((noreturn)) void
9
10enum {COROUTINE_REGISTERS = 0xa0 / 8};
11
13{
14 void **stack_pointer;
15 void *argument;
16};
17
18typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
19
20static inline void coroutine_initialize_main(struct coroutine_context * context) {
21 context->stack_pointer = NULL;
22}
23
24static inline void coroutine_initialize(
25 struct coroutine_context *context,
26 coroutine_start start,
27 void *stack,
28 size_t size
29) {
30 assert(start && stack && size >= 1024);
31
32 // Stack grows down. Force 16-byte alignment.
33 char * top = (char*)stack + size;
34 context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
35
36 context->stack_pointer -= COROUTINE_REGISTERS;
37 memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
38
39 context->stack_pointer[0x90 / 8] = (void*)(uintptr_t)start;
40}
41
42struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
43
44static inline void coroutine_destroy(struct coroutine_context * context)
45{
46}