1 /****************************************************************************
2 **
3 ** This file is part of GAP, a system for computational discrete algebra.
4 **
5 ** Copyright of GAP belongs to its developers, whose names are too numerous
6 ** to list here. Please refer to the COPYRIGHT file for details.
7 **
8 ** SPDX-License-Identifier: GPL-2.0-or-later
9 **
10 ** This file declares a struct that contains variables that are global
11 ** state in GAP, but in HPC-GAP an instance of it exists for every thread.
12 **
13 */
14
15 #ifndef GAP_GAPSTATE_H
16 #define GAP_GAPSTATE_H
17
18 #include "system.h"
19
20 #include "scanner.h"
21
22 #if defined(HPCGAP)
23 #include "hpc/tls.h"
24 #endif
25
26 enum {
27 STATE_SLOTS_SIZE = 32768,
28
29 MAX_VALUE_LEN = 1024,
30 };
31
32 typedef struct GAPState {
33 #ifdef HPCGAP
34 // TLS data -- this *must* come first, so that we can safely
35 // cast a GAPState pointer into a ThreadLocalStorage pointer
36 ThreadLocalStorage tls;
37 #endif
38
39 /* From intrprtr.c */
40 UInt IntrIgnoring;
41 UInt IntrReturning;
42 UInt IntrCoding;
43 Obj IntrState;
44 Obj StackObj;
45 Obj Tilde;
46
47 /* From gvar.c */
48 Obj CurrNamespace;
49
50 /* From vars.c */
51 Bag BottomLVars;
52 Bag CurrLVars;
53 Obj * PtrLVars;
54 Bag LVarsPool[16];
55
56 /* From read.c */
57 syJmp_buf ReadJmpError;
58
59 /* From scanner.c */
60 // TODO: eventually, ScannerState should be removed from GAPState
61 // (and then also #include "scanner.h" at the top), and instead code
62 // using a caller should dynamically allocate a ScannerState on the stack.
63 // But for now, we can't really do that.
64 ScannerState Scanner;
65 UInt NrError;
66 UInt NrErrLine;
67
68 // Used for recording the first line of the fragment of code currently
69 // begin interpreted, so the current line is outputted when profiling
70 UInt InterpreterStartLine;
71
72 const Char * Prompt;
73
74 Char * In;
75
76 /* From stats.c */
77 Obj ReturnObjStat;
78 UInt (**CurrExecStatFuncs)(Stat);
79
80 /* From code.c */
81 void * PtrBody;
82
83 /* From opers.c */
84 #if defined(HPCGAP)
85 Obj MethodCache;
86 Obj * MethodCacheItems;
87 UInt MethodCacheSize;
88 #endif
89
90 /* From gap.c */
91 Obj ThrownObject;
92 UInt UserHasQuit;
93 UInt UserHasQUIT;
94 Obj ShellContext;
95 Obj BaseShellContext;
96 Obj ErrorLVars; // ErrorLVars as modified by DownEnv / UpEnv
97 Int ErrorLLevel; // record where on the stack ErrorLVars is relative to the top, i.e. BaseShellContext
98 void (*JumpToCatchCallback)(void); // This callback is called in FuncJUMP_TO_CATCH,
99 // this is not used by GAP itself but by programs
100 // that use GAP as a library to handle errors
101
102 /* From info.c */
103 Int ShowUsedInfoClassesActive;
104
105 UInt1 StateSlots[STATE_SLOTS_SIZE];
106
107 /* Allocation */
108 #if defined(USE_BOEHM_GC)
109 #define MAX_GC_PREFIX_DESC 4
110 void ** FreeList[MAX_GC_PREFIX_DESC + 2];
111 #endif
112 } GAPState;
113
114 #if defined(HPCGAP)
115
ActiveGAPState(void)116 EXPORT_INLINE GAPState * ActiveGAPState(void)
117 {
118 return (GAPState *)GetTLS();
119 }
120
121 #else
122
123 extern GAPState MainGAPState;
124
ActiveGAPState(void)125 EXPORT_INLINE GAPState * ActiveGAPState(void)
126 {
127 return &MainGAPState;
128 }
129
130 #endif
131
132 #define STATE(x) (ActiveGAPState()->x)
133
134
135 // Offset into StateSlots
136 typedef Int ModuleStateOffset;
137
StateSlotsAtOffset(ModuleStateOffset offset)138 EXPORT_INLINE void * StateSlotsAtOffset(ModuleStateOffset offset)
139 {
140 GAP_ASSERT(0 <= offset && offset < STATE_SLOTS_SIZE);
141 return &STATE(StateSlots)[offset];
142 }
143
144 /* Access a module's registered state */
145 #define MODULE_STATE(module) \
146 (*(module ## ModuleState *)StateSlotsAtOffset(module ## StateOffset))
147
148 #endif // GAP_GAPSTATE_H
149