Ruby  3.1.4p223 (2023-03-30 revision HEAD)
Context.h
1 #ifndef COROUTINE_ARM64_CONTEXT_H
2 #define COROUTINE_ARM64_CONTEXT_H 1
3 
4 /*
5  * This file is part of the "Coroutine" project and released under the MIT License.
6  *
7  * Created by Samuel Williams on 10/5/2018.
8  * Copyright, 2018, by Samuel Williams.
9 */
10 
11 #pragma once
12 
13 #include <assert.h>
14 #include <stddef.h>
15 #include <stdint.h>
16 #include <string.h>
17 
18 #define COROUTINE __attribute__((noreturn)) void
19 
20 enum {COROUTINE_REGISTERS = 0xb0 / 8};
21 
22 struct coroutine_context
23 {
24  void **stack_pointer;
25  void *argument;
26 };
27 
28 typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
29 
30 static inline void coroutine_initialize_main(struct coroutine_context * context) {
31  context->stack_pointer = NULL;
32 }
33 
34 static inline void coroutine_initialize(
35  struct coroutine_context *context,
36  coroutine_start start,
37  void *stack,
38  size_t size
39 ) {
40  assert(start && stack && size >= 1024);
41 
42  // Stack grows down. Force 16-byte alignment.
43  char * top = (char*)stack + size;
44  context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
45 
46  context->stack_pointer -= COROUTINE_REGISTERS;
47  memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
48 
49  context->stack_pointer[0xa0 / 8] = (void*)start;
50 }
51 
52 struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
53 
54 static inline void coroutine_destroy(struct coroutine_context * context)
55 {
56 }
57 
58 #endif /* COROUTINE_ARM64_CONTEXT_H */