Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/VM/src/lobject.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 "lua.h"
6
#include "lcommon.h"
7
8
/*
9
** Union of all collectible objects
10
*/
11
typedef union GCObject GCObject;
12
13
/*
14
** Common Header for all collectible objects (in macro form, to be included in other objects)
15
*/
16
// clang-format off
17
#define CommonHeader \
18
uint8_t tt; uint8_t marked; uint8_t memcat
19
// clang-format on
20
21
/*
22
** Common header in struct form
23
*/
24
typedef struct GCheader
25
{
26
CommonHeader;
27
} GCheader;
28
29
/*
30
** Union of all Lua values
31
*/
32
typedef union
33
{
34
GCObject* gc;
35
void* p;
36
double n;
37
int b;
38
int64_t l;
39
float v[2]; // v[0], v[1] live here; v[2] lives in TValue::extra
40
} Value;
41
42
/*
43
** Tagged Values
44
*/
45
46
typedef struct lua_TValue
47
{
48
Value value;
49
int extra[LUA_EXTRA_SIZE];
50
int tt;
51
} TValue;
52
53
// Macros to test type
54
#define ttisnil(o) (ttype(o) == LUA_TNIL)
55
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
56
#define ttisinteger(o) (ttype(o) == LUA_TINTEGER)
57
#define ttisstring(o) (ttype(o) == LUA_TSTRING)
58
#define ttistable(o) (ttype(o) == LUA_TTABLE)
59
#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
60
#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
61
#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
62
#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
63
#define ttisbuffer(o) (ttype(o) == LUA_TBUFFER)
64
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
65
#define ttisvector(o) (ttype(o) == LUA_TVECTOR)
66
#define ttisupval(o) (ttype(o) == LUA_TUPVAL)
67
68
// Macros to access values
69
#define ttype(o) ((o)->tt)
70
#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
71
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
72
#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
73
#define lvalue(o) check_exp(ttisinteger(o), (o)->value.l)
74
#define vvalue(o) check_exp(ttisvector(o), (o)->value.v)
75
#define tsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
76
#define uvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
77
#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
78
#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
79
#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
80
#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
81
#define bufvalue(o) check_exp(ttisbuffer(o), &(o)->value.gc->buf)
82
#define upvalue(o) check_exp(ttisupval(o), &(o)->value.gc->uv)
83
84
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
85
86
#define lightuserdatatag(o) check_exp(ttislightuserdata(o), (o)->extra[0])
87
88
// Internal tags used by the VM
89
#define LU_TAG_ITERATOR LUA_UTAG_LIMIT
90
91
/*
92
** for internal debug only
93
*/
94
#define checkconsistency(obj) LUAU_ASSERT(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
95
96
#define checkliveness(g, obj) LUAU_ASSERT(!iscollectable(obj) || ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
97
98
// Macros to set values
99
#define setnilvalue(obj) ((obj)->tt = LUA_TNIL)
100
101
#define setnvalue(obj, x) \
102
{ \
103
TValue* i_o = (obj); \
104
i_o->value.n = (x); \
105
i_o->tt = LUA_TNUMBER; \
106
}
107
108
#define setlvalue(obj, x) \
109
{ \
110
TValue* i_o = (obj); \
111
i_o->value.l = (x); \
112
i_o->tt = LUA_TINTEGER; \
113
}
114
115
#if LUA_VECTOR_SIZE == 4
116
#define setvvalue(obj, x, y, z, w) \
117
{ \
118
TValue* i_o = (obj); \
119
float* i_v = i_o->value.v; \
120
i_v[0] = (x); \
121
i_v[1] = (y); \
122
i_v[2] = (z); \
123
i_v[3] = (w); \
124
i_o->tt = LUA_TVECTOR; \
125
}
126
#else
127
#define setvvalue(obj, x, y, z, w) \
128
{ \
129
TValue* i_o = (obj); \
130
float* i_v = i_o->value.v; \
131
i_v[0] = (x); \
132
i_v[1] = (y); \
133
i_v[2] = (z); \
134
i_o->tt = LUA_TVECTOR; \
135
}
136
#endif
137
138
#define setpvalue(obj, x, tag) \
139
{ \
140
TValue* i_o = (obj); \
141
i_o->value.p = (x); \
142
i_o->extra[0] = (tag); \
143
i_o->tt = LUA_TLIGHTUSERDATA; \
144
}
145
146
#define setbvalue(obj, x) \
147
{ \
148
TValue* i_o = (obj); \
149
i_o->value.b = (x); \
150
i_o->tt = LUA_TBOOLEAN; \
151
}
152
153
#define setsvalue(L, obj, x) \
154
{ \
155
TValue* i_o = (obj); \
156
i_o->value.gc = cast_to(GCObject*, (x)); \
157
i_o->tt = LUA_TSTRING; \
158
checkliveness(L->global, i_o); \
159
}
160
161
#define setuvalue(L, obj, x) \
162
{ \
163
TValue* i_o = (obj); \
164
i_o->value.gc = cast_to(GCObject*, (x)); \
165
i_o->tt = LUA_TUSERDATA; \
166
checkliveness(L->global, i_o); \
167
}
168
169
#define setthvalue(L, obj, x) \
170
{ \
171
TValue* i_o = (obj); \
172
i_o->value.gc = cast_to(GCObject*, (x)); \
173
i_o->tt = LUA_TTHREAD; \
174
checkliveness(L->global, i_o); \
175
}
176
177
#define setbufvalue(L, obj, x) \
178
{ \
179
TValue* i_o = (obj); \
180
i_o->value.gc = cast_to(GCObject*, (x)); \
181
i_o->tt = LUA_TBUFFER; \
182
checkliveness(L->global, i_o); \
183
}
184
185
#define setclvalue(L, obj, x) \
186
{ \
187
TValue* i_o = (obj); \
188
i_o->value.gc = cast_to(GCObject*, (x)); \
189
i_o->tt = LUA_TFUNCTION; \
190
checkliveness(L->global, i_o); \
191
}
192
193
#define sethvalue(L, obj, x) \
194
{ \
195
TValue* i_o = (obj); \
196
i_o->value.gc = cast_to(GCObject*, (x)); \
197
i_o->tt = LUA_TTABLE; \
198
checkliveness(L->global, i_o); \
199
}
200
201
#define setptvalue(L, obj, x) \
202
{ \
203
TValue* i_o = (obj); \
204
i_o->value.gc = cast_to(GCObject*, (x)); \
205
i_o->tt = LUA_TPROTO; \
206
checkliveness(L->global, i_o); \
207
}
208
209
#define setupvalue(L, obj, x) \
210
{ \
211
TValue* i_o = (obj); \
212
i_o->value.gc = cast_to(GCObject*, (x)); \
213
i_o->tt = LUA_TUPVAL; \
214
checkliveness(L->global, i_o); \
215
}
216
217
#define setobj(L, obj1, obj2) \
218
{ \
219
const TValue* o2 = (obj2); \
220
TValue* o1 = (obj1); \
221
*o1 = *o2; \
222
checkliveness(L->global, o1); \
223
}
224
225
/*
226
** different types of sets, according to destination
227
*/
228
229
// to stack
230
#define setobj2s setobj
231
// from table to same table (no barrier)
232
#define setobjt2t setobj
233
// to table (needs barrier)
234
#define setobj2t setobj
235
// to new object (no barrier)
236
#define setobj2n setobj
237
238
#define setttype(obj, tt) (ttype(obj) = (tt))
239
240
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
241
242
typedef TValue* StkId; // index to stack elements
243
244
/*
245
** String headers for string table
246
*/
247
typedef struct TString
248
{
249
CommonHeader;
250
// 1 byte padding
251
252
int16_t atom;
253
254
// 2 byte padding
255
256
TString* next; // next string in the hash table bucket
257
258
unsigned int hash;
259
unsigned int len;
260
261
char data[1]; // string data is allocated right after the header
262
} TString;
263
264
265
#define getstr(ts) (ts)->data
266
#define svalue(o) getstr(tsvalue(o))
267
268
typedef struct Udata
269
{
270
CommonHeader;
271
272
uint8_t tag;
273
274
int len;
275
276
struct LuaTable* metatable;
277
278
// userdata is allocated right after the header
279
// while the alignment is only 8 here, for sizes starting at 16 bytes, 16 byte alignment is provided
280
alignas(8) char data[1];
281
} Udata;
282
283
typedef struct LuauBuffer
284
{
285
CommonHeader;
286
287
unsigned int len;
288
289
alignas(8) char data[1];
290
} Buffer;
291
292
/*
293
** Function Prototypes
294
*/
295
// clang-format off
296
typedef struct Proto
297
{
298
CommonHeader;
299
300
uint8_t nups; // number of upvalues
301
uint8_t numparams;
302
uint8_t is_vararg;
303
uint8_t maxstacksize;
304
uint8_t flags;
305
306
TValue* k; // constants used by the function
307
Instruction* code; // function bytecode
308
struct Proto** p; // functions defined inside the function
309
const Instruction* codeentry;
310
311
void* execdata;
312
uintptr_t exectarget;
313
314
uint8_t* lineinfo; // for each instruction, line number as a delta from baseline
315
int* abslineinfo; // baseline line info, one entry for each 1<<linegaplog2 instructions; allocated after lineinfo
316
struct LocVar* locvars; // information about local variables
317
TString** upvalues; // upvalue names
318
TString* source;
319
320
TString* debugname;
321
uint8_t* debuginsn; // a copy of code[] array with just opcodes
322
323
uint8_t* typeinfo;
324
325
void* userdata;
326
327
GCObject* gclist;
328
329
int sizecode;
330
int sizep;
331
int sizelocvars;
332
int sizeupvalues;
333
int sizek;
334
int sizelineinfo;
335
int linegaplog2;
336
int linedefined;
337
int bytecodeid;
338
int sizetypeinfo;
339
} Proto;
340
// clang-format on
341
342
typedef struct LocVar
343
{
344
TString* varname;
345
int startpc; // first point where variable is active
346
int endpc; // first point where variable is dead
347
uint8_t reg; // register slot, relative to base, where variable is stored
348
} LocVar;
349
350
/*
351
** Upvalues
352
*/
353
354
typedef struct UpVal
355
{
356
CommonHeader;
357
uint8_t markedopen; // set if reachable from an alive thread (only valid during atomic)
358
359
// 4 byte padding (x64)
360
361
TValue* v; // points to stack or to its own value
362
union
363
{
364
TValue value; // the value (when closed)
365
struct
366
{
367
// global double linked list (when open)
368
struct UpVal* prev;
369
struct UpVal* next;
370
371
// thread linked list (when open)
372
struct UpVal* threadnext;
373
} open;
374
} u;
375
} UpVal;
376
377
#define upisopen(up) ((up)->v != &(up)->u.value)
378
379
/*
380
** Closures
381
*/
382
383
typedef struct Closure
384
{
385
CommonHeader;
386
387
uint8_t isC;
388
uint8_t nupvalues;
389
uint8_t stacksize;
390
uint8_t preload;
391
392
GCObject* gclist;
393
struct LuaTable* env;
394
395
union
396
{
397
struct
398
{
399
lua_CFunction f;
400
lua_Continuation cont;
401
const char* debugname;
402
TValue upvals[1];
403
} c;
404
405
struct
406
{
407
struct Proto* p;
408
TValue uprefs[1];
409
} l;
410
};
411
} Closure;
412
413
#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC)
414
#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->isC)
415
416
/*
417
** Tables
418
*/
419
420
typedef struct TKey
421
{
422
::Value value;
423
int extra[LUA_EXTRA_SIZE];
424
unsigned tt : 4;
425
int next : 28; // for chaining
426
} TKey;
427
428
typedef struct LuaNode
429
{
430
TValue val;
431
TKey key;
432
} LuaNode;
433
434
// copy a value into a key
435
#define setnodekey(L, node, obj) \
436
{ \
437
LuaNode* n_ = (node); \
438
const TValue* i_o = (obj); \
439
n_->key.value = i_o->value; \
440
memcpy(n_->key.extra, i_o->extra, sizeof(n_->key.extra)); \
441
n_->key.tt = i_o->tt; \
442
checkliveness(L->global, i_o); \
443
}
444
445
// copy a value from a key
446
#define getnodekey(L, obj, node) \
447
{ \
448
TValue* i_o = (obj); \
449
const LuaNode* n_ = (node); \
450
i_o->value = n_->key.value; \
451
memcpy(i_o->extra, n_->key.extra, sizeof(i_o->extra)); \
452
i_o->tt = n_->key.tt; \
453
checkliveness(L->global, i_o); \
454
}
455
456
// clang-format off
457
typedef struct LuaTable
458
{
459
CommonHeader;
460
461
uint8_t tmcache; // 1<<p means tagmethod(p) is not present
462
uint8_t readonly; // sandboxing feature to prohibit writes to table
463
uint8_t safeenv; // environment doesn't share globals with other scripts
464
uint8_t lsizenode; // log2 of size of `node' array
465
uint8_t nodemask8; // (1<<lsizenode)-1, truncated to 8 bits
466
467
int sizearray; // size of `array' array
468
union
469
{
470
int lastfree; // any free position is before this position
471
int aboundary; // negated 'boundary' of `array' array; iff aboundary < 0
472
};
473
474
struct LuaTable* metatable;
475
TValue* array; // array part
476
LuaNode* node;
477
GCObject* gclist;
478
} LuaTable;
479
// clang-format on
480
481
/*
482
** `module' operation for hashing (size is always a power of 2)
483
*/
484
#define lmod(s, size) (check_exp((size & (size - 1)) == 0, (cast_to(int, (s) & ((size)-1)))))
485
486
#define twoto(x) ((int)(1 << (x)))
487
#define sizenode(t) (twoto((t)->lsizenode))
488
489
#define luaO_nilobject (&luaO_nilobject_)
490
491
LUAI_DATA const TValue luaO_nilobject_;
492
493
#define ceillog2(x) (luaO_log2((x)-1) + 1)
494
495
LUAI_FUNC int luaO_log2(unsigned int x);
496
LUAI_FUNC int luaO_rawequalObj(const TValue* t1, const TValue* t2);
497
LUAI_FUNC int luaO_rawequalKey(const TKey* t1, const TValue* t2);
498
LUAI_FUNC int luaO_str2d(const char* s, double* result);
499
LUAI_FUNC int luaO_str2l(const char* s, int64_t* result, int base = 10);
500
LUAI_FUNC const char* luaO_pushvfstring(lua_State* L, const char* fmt, va_list argp);
501
LUAI_FUNC const char* luaO_pushfstring(lua_State* L, const char* fmt, ...);
502
LUAI_FUNC const char* luaO_chunkid(char* buf, size_t buflen, const char* source, size_t srclen);
503
504