Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/VM/src/ltm.cpp
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
#include "ltm.h"
4
5
#include "lstate.h"
6
#include "lstring.h"
7
#include "ludata.h"
8
#include "ltable.h"
9
#include "lgc.h"
10
11
#include <string.h>
12
13
// clang-format off
14
const char* const luaT_typenames[] = {
15
// ORDER TYPE
16
"nil",
17
"boolean",
18
19
"userdata",
20
"number",
21
"integer",
22
"vector",
23
24
"string",
25
26
"table",
27
"function",
28
"userdata",
29
"thread",
30
"buffer",
31
};
32
33
const char* const luaT_eventname[] = {
34
// ORDER TM
35
"__index",
36
"__newindex",
37
"__mode",
38
"__namecall",
39
"__call",
40
"__iter",
41
"__len",
42
43
"__eq",
44
45
"__add",
46
"__sub",
47
"__mul",
48
"__div",
49
"__idiv",
50
"__mod",
51
"__pow",
52
"__unm",
53
54
"__lt",
55
"__le",
56
"__concat",
57
"__type",
58
"__metatable",
59
};
60
// clang-format on
61
62
static_assert(sizeof(luaT_typenames) / sizeof(luaT_typenames[0]) == LUA_T_COUNT, "luaT_typenames size mismatch");
63
static_assert(sizeof(luaT_eventname) / sizeof(luaT_eventname[0]) == TM_N, "luaT_eventname size mismatch");
64
static_assert(TM_EQ < 8, "fasttm optimization stores a bitfield with metamethods in a byte");
65
66
void luaT_init(lua_State* L)
67
{
68
int i;
69
for (i = 0; i < LUA_T_COUNT; i++)
70
{
71
L->global->ttname[i] = luaS_new(L, luaT_typenames[i]);
72
luaS_fix(L->global->ttname[i]); // never collect these names
73
}
74
for (i = 0; i < TM_N; i++)
75
{
76
L->global->tmname[i] = luaS_new(L, luaT_eventname[i]);
77
luaS_fix(L->global->tmname[i]); // never collect these names
78
}
79
}
80
81
/*
82
** function to be used with macro "fasttm": optimized for absence of
83
** tag methods.
84
*/
85
const TValue* luaT_gettm(LuaTable* events, TMS event, TString* ename)
86
{
87
const TValue* tm = luaH_getstr(events, ename);
88
LUAU_ASSERT(event <= TM_EQ);
89
if (ttisnil(tm))
90
{ // no tag method?
91
events->tmcache |= cast_byte(1u << event); // cache this fact
92
return NULL;
93
}
94
else
95
return tm;
96
}
97
98
const TValue* luaT_gettmbyobj(lua_State* L, const TValue* o, TMS event)
99
{
100
/*
101
NB: Tag-methods were replaced by meta-methods in Lua 5.0, but the
102
old names are still around (this function, for example).
103
*/
104
LuaTable* mt;
105
switch (ttype(o))
106
{
107
case LUA_TTABLE:
108
mt = hvalue(o)->metatable;
109
break;
110
case LUA_TUSERDATA:
111
mt = uvalue(o)->metatable;
112
break;
113
default:
114
mt = L->global->mt[ttype(o)];
115
}
116
return (mt ? luaH_getstr(mt, L->global->tmname[event]) : luaO_nilobject);
117
}
118
119
const TString* luaT_objtypenamestr(lua_State* L, const TValue* o)
120
{
121
// Userdata created by the environment can have a custom type name set in the individual metatable
122
// If there is no custom name, 'userdata' is returned
123
if (ttisuserdata(o) && uvalue(o)->tag != UTAG_PROXY && uvalue(o)->metatable)
124
{
125
const TValue* type = luaH_getstr(uvalue(o)->metatable, L->global->tmname[TM_TYPE]);
126
127
if (ttisstring(type))
128
return tsvalue(type);
129
130
return L->global->ttname[ttype(o)];
131
}
132
133
// Tagged lightuserdata can be named using lua_setlightuserdataname
134
if (ttislightuserdata(o))
135
{
136
int tag = lightuserdatatag(o);
137
138
if (unsigned(tag) < LUA_LUTAG_LIMIT)
139
{
140
if (const TString* name = L->global->lightuserdataname[tag])
141
return name;
142
}
143
}
144
145
// For all types except userdata and table, a global metatable can be set with a global name override
146
if (LuaTable* mt = L->global->mt[ttype(o)])
147
{
148
const TValue* type = luaH_getstr(mt, L->global->tmname[TM_TYPE]);
149
150
if (ttisstring(type))
151
return tsvalue(type);
152
}
153
154
return L->global->ttname[ttype(o)];
155
}
156
157
const char* luaT_objtypename(lua_State* L, const TValue* o)
158
{
159
return getstr(luaT_objtypenamestr(L, o));
160
}
161
162