Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/VM/src/lstate.h
2725 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details
3
#pragma once
4
5
#include "lobject.h"
6
#include "ltm.h"
7
8
// registry
9
#define registry(L) (&L->global->registry)
10
11
// extra stack space to handle TM calls and some other extras
12
#define EXTRA_STACK 5
13
14
#define BASIC_CI_SIZE 8
15
16
#define BASIC_STACK_SIZE (2 * LUA_MINSTACK)
17
18
// clang-format off
19
typedef struct stringtable
20
{
21
TString** hash;
22
uint32_t nuse; // number of elements
23
int size;
24
} stringtable;
25
// clang-format on
26
27
/*
28
** informations about a call
29
**
30
** the general Lua stack frame structure is as follows:
31
** - each function gets a stack frame, with function "registers" being stack slots on the frame
32
** - function arguments are associated with registers 0+
33
** - function locals and temporaries follow after; usually locals are a consecutive block per scope, and temporaries are allocated after this, but
34
*this is up to the compiler
35
**
36
** when function doesn't have varargs, the stack layout is as follows:
37
** ^ (func) ^^ [fixed args] [locals + temporaries]
38
** where ^ is the 'func' pointer in CallInfo struct, and ^^ is the 'base' pointer (which is what registers are relative to)
39
**
40
** when function *does* have varargs, the stack layout is more complex - the runtime has to copy the fixed arguments so that the 0+ addressing still
41
*works as follows:
42
** ^ (func) [fixed args] [varargs] ^^ [fixed args] [locals + temporaries]
43
**
44
** computing the sizes of these individual blocks works as follows:
45
** - the number of fixed args is always matching the `numparams` in a function's Proto object; runtime adds `nil` during the call execution as
46
*necessary
47
** - the number of variadic args can be computed by evaluating (ci->base - ci->func - 1 - numparams)
48
**
49
** the CallInfo structures are allocated as an array, with each subsequent call being *appended* to this array (so if f calls g, CallInfo for g
50
*immediately follows CallInfo for f)
51
** the `nresults` field in CallInfo is set by the caller to tell the function how many arguments the caller is expecting on the stack after the
52
*function returns
53
** the `flags` field in CallInfo contains internal execution flags that are important for pcall/etc, see LUA_CALLINFO_*
54
*/
55
// clang-format off
56
typedef struct CallInfo
57
{
58
StkId base; // base for this function
59
StkId func; // function index in the stack
60
StkId top; // top for this function
61
const Instruction* savedpc;
62
63
int nresults; // expected number of results from this function
64
unsigned int flags; // call frame flags, see LUA_CALLINFO_*
65
} CallInfo;
66
// clang-format on
67
68
#define LUA_CALLINFO_RETURN (1 << 0) // should the interpreter return after returning from this callinfo? first frame must have this set
69
#define LUA_CALLINFO_HANDLE (1 << 1) // should the error thrown during execution get handled by continuation from this callinfo? func must be C
70
#define LUA_CALLINFO_NATIVE (1 << 2) // should this function be executed using execution callback for native code
71
72
#define curr_func(L) (clvalue(L->ci->func))
73
#define ci_func(ci) (clvalue((ci)->func))
74
#define f_isLua(ci) (!ci_func(ci)->isC)
75
#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
76
77
struct GCStats
78
{
79
// data for proportional-integral controller of heap trigger value
80
int32_t triggerterms[32] = {0};
81
uint32_t triggertermpos = 0;
82
int32_t triggerintegral = 0;
83
84
size_t atomicstarttotalsizebytes = 0;
85
size_t endtotalsizebytes = 0;
86
size_t heapgoalsizebytes = 0;
87
88
double starttimestamp = 0;
89
double atomicstarttimestamp = 0;
90
double endtimestamp = 0;
91
};
92
93
#ifdef LUAI_GCMETRICS
94
struct GCCycleMetrics
95
{
96
size_t starttotalsizebytes = 0;
97
size_t heaptriggersizebytes = 0;
98
99
double pausetime = 0.0; // time from end of the last cycle to the start of a new one
100
101
double starttimestamp = 0.0;
102
double endtimestamp = 0.0;
103
104
double marktime = 0.0;
105
double markassisttime = 0.0;
106
double markmaxexplicittime = 0.0;
107
size_t markexplicitsteps = 0;
108
size_t markwork = 0;
109
110
double atomicstarttimestamp = 0.0;
111
size_t atomicstarttotalsizebytes = 0;
112
double atomictime = 0.0;
113
114
// specific atomic stage parts
115
double atomictimeupval = 0.0;
116
double atomictimeweak = 0.0;
117
double atomictimegray = 0.0;
118
double atomictimeclear = 0.0;
119
120
double sweeptime = 0.0;
121
double sweepassisttime = 0.0;
122
double sweepmaxexplicittime = 0.0;
123
size_t sweepexplicitsteps = 0;
124
size_t sweepwork = 0;
125
126
size_t assistwork = 0;
127
size_t explicitwork = 0;
128
129
size_t propagatework = 0;
130
size_t propagateagainwork = 0;
131
132
size_t endtotalsizebytes = 0;
133
};
134
135
struct GCMetrics
136
{
137
double stepexplicittimeacc = 0.0;
138
double stepassisttimeacc = 0.0;
139
140
// when cycle is completed, last cycle values are updated
141
uint64_t completedcycles = 0;
142
143
GCCycleMetrics lastcycle;
144
GCCycleMetrics currcycle;
145
};
146
#endif
147
148
// Callbacks that can be used to to redirect code execution from Luau bytecode VM to a custom implementation (AoT/JiT/sandboxing/...)
149
struct lua_ExecutionCallbacks
150
{
151
void* context;
152
void (*close)(lua_State* L); // called when global VM state is closed
153
void (*destroy)(lua_State* L, Proto* proto); // called when function is destroyed
154
int (*enter)(lua_State* L, Proto* proto); // called when function is about to start/resume (when execdata is present), return 0 to exit VM
155
void (*disable)(lua_State* L, Proto* proto); // called when function has to be switched from native to bytecode in the debugger
156
size_t (*getmemorysize)(lua_State* L, Proto* proto); // called to request the size of memory associated with native part of the Proto
157
uint8_t (*gettypemapping)(lua_State* L, const char* str, size_t len); // called to get the userdata type index
158
char* (*getcounterdata)(
159
lua_State* L,
160
Proto* proto,
161
size_t* count
162
); // called to get the execution counter data and count {uint32_t, uint32_t, uint64_t}
163
};
164
165
/*
166
** `global state', shared by all threads of this state
167
*/
168
// clang-format off
169
typedef struct global_State
170
{
171
stringtable strt; // hash table for strings
172
173
lua_Alloc frealloc; // function to reallocate memory
174
void* ud; // auxiliary data to `frealloc'
175
176
uint8_t currentwhite;
177
uint8_t gcstate; // state of garbage collector
178
179
GCObject* gray; // list of gray objects
180
GCObject* grayagain; // list of objects to be traversed atomically
181
GCObject* weak; // list of weak tables (to be cleared)
182
183
size_t GCthreshold; // when totalbytes >= GCthreshold, run GC step
184
size_t totalbytes; // number of bytes currently allocated
185
186
int gcgoal; // see LUAI_GCGOAL
187
int gcstepmul; // see LUAI_GCSTEPMUL
188
int gcstepsize; // see LUAI_GCSTEPSIZE
189
190
struct lua_Page* freepages[LUA_SIZECLASSES]; // free page linked list for each size class for non-collectable objects
191
struct lua_Page* freegcopages[LUA_SIZECLASSES]; // free page linked list for each size class for collectable objects
192
struct lua_Page* allpages; // page linked list with all pages for all non-collectable object classes (available with LUAU_ASSERTENABLED)
193
struct lua_Page* allgcopages; // page linked list with all pages for all collectable object classes
194
struct lua_Page* sweepgcopage; // position of the sweep in `allgcopages'
195
196
struct lua_State* mainthread;
197
UpVal uvhead; // head of double-linked list of all open upvalues
198
struct LuaTable* mt[LUA_T_COUNT]; // metatables for basic types
199
TString* ttname[LUA_T_COUNT]; // names for basic types
200
TString* tmname[TM_N]; // array with tag-method names
201
202
TValue pseudotemp; // storage for temporary values used in pseudo2addr
203
204
TValue registry; // registry table, used by lua_ref and LUA_REGISTRYINDEX
205
int registryfree; // next free slot in registry
206
207
struct lua_jmpbuf* errorjmp; // jump buffer data for longjmp-style error handling
208
209
uint64_t rngstate; // PCG random number generator state
210
uint64_t ptrenckey[4]; // pointer encoding key for display
211
212
lua_Callbacks cb;
213
214
lua_ExecutionCallbacks ecb;
215
216
alignas(16) uint8_t ecbdata[LUA_EXECUTION_CALLBACK_STORAGE];
217
218
size_t memcatbytes[LUA_MEMORY_CATEGORIES]; // total amount of memory used by each memory category
219
220
void (*udatagc[LUA_UTAG_LIMIT])(lua_State*, void*); // for each userdata tag, a gc callback to be called immediately before freeing memory
221
LuaTable* udatamt[LUA_UTAG_LIMIT]; // metatables for tagged userdata
222
223
TString* lightuserdataname[LUA_LUTAG_LIMIT]; // names for tagged lightuserdata
224
225
GCStats gcstats;
226
227
#ifdef LUAI_GCMETRICS
228
GCMetrics gcmetrics;
229
#endif
230
} global_State;
231
// clang-format on
232
233
/*
234
** `per thread' state
235
*/
236
// clang-format off
237
struct lua_State
238
{
239
CommonHeader;
240
uint8_t status;
241
242
uint8_t activememcat; // memory category that is used for new GC object allocations
243
244
bool isactive; // thread is currently executing, stack may be mutated without barriers
245
bool singlestep; // call debugstep hook after each instruction
246
247
StkId top; // first free slot in the stack
248
StkId base; // base of current function
249
global_State* global;
250
CallInfo* ci; // call info for current function
251
StkId stack_last; // last free slot in the stack
252
StkId stack; // stack base
253
254
CallInfo* end_ci; // points after end of ci array
255
CallInfo* base_ci; // array of CallInfo's
256
257
int stacksize;
258
int size_ci; // size of array `base_ci'
259
260
unsigned short nCcalls; // number of nested C calls
261
unsigned short baseCcalls; // nested C calls when resuming coroutine
262
263
int cachedslot; // when table operations or INDEX/NEWINDEX is invoked from Luau, what is the expected slot for lookup?
264
265
LuaTable* gt; // table of globals
266
UpVal* openupval; // list of open upvalues in this stack
267
GCObject* gclist;
268
269
TString* namecall; // when invoked from Luau using NAMECALL, what method do we need to invoke?
270
271
void* userdata;
272
};
273
// clang-format on
274
275
/*
276
** Union of all collectible objects
277
*/
278
union GCObject
279
{
280
GCheader gch;
281
struct TString ts;
282
struct Udata u;
283
struct Closure cl;
284
struct LuaTable h;
285
struct Proto p;
286
struct UpVal uv;
287
struct lua_State th; // thread
288
struct LuauBuffer buf;
289
};
290
291
// macros to convert a GCObject into a specific value
292
#define gco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
293
#define gco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
294
#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
295
#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
296
#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
297
#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
298
#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
299
#define gco2buf(o) check_exp((o)->gch.tt == LUA_TBUFFER, &((o)->buf))
300
301
// macro to convert any Lua object into a GCObject
302
#define obj2gco(v) check_exp(iscollectable(v), cast_to(GCObject*, (v) + 0))
303
304
LUAI_FUNC lua_State* luaE_newthread(lua_State* L);
305
LUAI_FUNC void luaE_freethread(lua_State* L, lua_State* L1, struct lua_Page* page);
306
307