Ruby  3.1.4p223 (2023-03-30 revision HEAD)
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 
10 enum {COROUTINE_REGISTERS = 0xd0 / 8};
11 
12 struct coroutine_context
13 {
14  void **stack_pointer;
15  void *argument;
16 };
17 
18 typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
19 
20 static inline void coroutine_initialize_main(struct coroutine_context * context) {
21  context->stack_pointer = NULL;
22 }
23 
24 static 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[0xc0 / 8] = (void*)start;
40 }
41 
42 struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
43 
44 static inline void coroutine_destroy(struct coroutine_context * context)
45 {
46 }