Ruby  3.1.4p223 (2023-03-30 revision HEAD)
Context.h
1 #ifndef COROUTINE_WIN32_CONTEXT_H
2 #define COROUTINE_WIN32_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 __declspec(noreturn) void __fastcall
19 #define COROUTINE_LIMITED_ADDRESS_SPACE
20 
21 /* This doesn't include thread information block */
22 enum {COROUTINE_REGISTERS = 4};
23 
24 struct coroutine_context
25 {
26  void **stack_pointer;
27  void *argument;
28 };
29 
30 typedef void(__fastcall * coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
31 
32 static inline void coroutine_initialize_main(struct coroutine_context * context) {
33  context->stack_pointer = NULL;
34 }
35 
36 static inline void coroutine_initialize(
37  struct coroutine_context *context,
38  coroutine_start start,
39  void *stack,
40  size_t size
41 ) {
42  assert(start && stack && size >= 1024);
43 
44  // Stack grows down. Force 16-byte alignment.
45  char * top = (char*)stack + size;
46  context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
47 
48  *--context->stack_pointer = (void*)start;
49 
50  /* Windows Thread Information Block */
51  *--context->stack_pointer = (void*)0xFFFFFFFF; /* fs:[0] */
52  *--context->stack_pointer = (void*)top; /* fs:[4] */
53  *--context->stack_pointer = (void*)stack; /* fs:[8] */
54 
55  context->stack_pointer -= COROUTINE_REGISTERS;
56  memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
57 }
58 
59 struct coroutine_context * __fastcall coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
60 
61 static inline void coroutine_destroy(struct coroutine_context * context)
62 {
63 }
64 
65 #endif /* COROUTINE_WIN32_CONTEXT_H */