mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 22:35:43 +08:00
551a43c424
- Updated Roblox copyright to 2023 - Floor division operator `//` (implements #832) - Autocomplete now shows `end` within `do` blocks - Restore BraceType when using `Lexer::lookahead` (fixes #1019) # New typechecker - Subtyping tests between metatables and tables - Subtyping tests between string singletons and tables - Subtyping tests for class types # Native codegen - Fixed macOS test failure (wrong spill restore offset) - Fixed clobbering of non-volatile xmm registers on Windows - Fixed wrong storage location of SSA reg spills - Implemented A64 support for add/sub extended - Eliminated zextReg from A64 lowering - Remove identical table slot lookups - Propagate values from predecessor into the linear block - Disabled reuse slot optimization - Keep `LuaNode::val` check for nil when optimizing `CHECK_SLOT_MATCH` - Implemented IR translation of `table.insert` builtin - Fixed mmap error handling on macOS/Linux # Tooling - Used `|` as a column separator instead of `+` in `bench.py` - Added a `table.sort` micro-benchmark - Switched `libprotobuf-mutator` to a less problematic version
146 lines
3.3 KiB
C++
146 lines
3.3 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details
|
|
#include "ltm.h"
|
|
|
|
#include "lstate.h"
|
|
#include "lstring.h"
|
|
#include "ludata.h"
|
|
#include "ltable.h"
|
|
#include "lgc.h"
|
|
|
|
#include <string.h>
|
|
|
|
// clang-format off
|
|
const char* const luaT_typenames[] = {
|
|
// ORDER TYPE
|
|
"nil",
|
|
"boolean",
|
|
|
|
|
|
"userdata",
|
|
"number",
|
|
"vector",
|
|
|
|
"string",
|
|
|
|
|
|
"table",
|
|
"function",
|
|
"userdata",
|
|
"thread",
|
|
};
|
|
|
|
const char* const luaT_eventname[] = {
|
|
// ORDER TM
|
|
|
|
"__index",
|
|
"__newindex",
|
|
"__mode",
|
|
"__namecall",
|
|
"__call",
|
|
"__iter",
|
|
"__len",
|
|
|
|
"__eq",
|
|
|
|
|
|
"__add",
|
|
"__sub",
|
|
"__mul",
|
|
"__div",
|
|
"__idiv",
|
|
"__mod",
|
|
"__pow",
|
|
"__unm",
|
|
|
|
|
|
"__lt",
|
|
"__le",
|
|
"__concat",
|
|
"__type",
|
|
"__metatable",
|
|
};
|
|
// clang-format on
|
|
|
|
static_assert(sizeof(luaT_typenames) / sizeof(luaT_typenames[0]) == LUA_T_COUNT, "luaT_typenames size mismatch");
|
|
static_assert(sizeof(luaT_eventname) / sizeof(luaT_eventname[0]) == TM_N, "luaT_eventname size mismatch");
|
|
static_assert(TM_EQ < 8, "fasttm optimization stores a bitfield with metamethods in a byte");
|
|
|
|
void luaT_init(lua_State* L)
|
|
{
|
|
int i;
|
|
for (i = 0; i < LUA_T_COUNT; i++)
|
|
{
|
|
L->global->ttname[i] = luaS_new(L, luaT_typenames[i]);
|
|
luaS_fix(L->global->ttname[i]); // never collect these names
|
|
}
|
|
for (i = 0; i < TM_N; i++)
|
|
{
|
|
L->global->tmname[i] = luaS_new(L, luaT_eventname[i]);
|
|
luaS_fix(L->global->tmname[i]); // never collect these names
|
|
}
|
|
}
|
|
|
|
/*
|
|
** function to be used with macro "fasttm": optimized for absence of
|
|
** tag methods.
|
|
*/
|
|
const TValue* luaT_gettm(Table* events, TMS event, TString* ename)
|
|
{
|
|
const TValue* tm = luaH_getstr(events, ename);
|
|
LUAU_ASSERT(event <= TM_EQ);
|
|
if (ttisnil(tm))
|
|
{ // no tag method?
|
|
events->tmcache |= cast_byte(1u << event); // cache this fact
|
|
return NULL;
|
|
}
|
|
else
|
|
return tm;
|
|
}
|
|
|
|
const TValue* luaT_gettmbyobj(lua_State* L, const TValue* o, TMS event)
|
|
{
|
|
/*
|
|
NB: Tag-methods were replaced by meta-methods in Lua 5.0, but the
|
|
old names are still around (this function, for example).
|
|
*/
|
|
Table* mt;
|
|
switch (ttype(o))
|
|
{
|
|
case LUA_TTABLE:
|
|
mt = hvalue(o)->metatable;
|
|
break;
|
|
case LUA_TUSERDATA:
|
|
mt = uvalue(o)->metatable;
|
|
break;
|
|
default:
|
|
mt = L->global->mt[ttype(o)];
|
|
}
|
|
return (mt ? luaH_getstr(mt, L->global->tmname[event]) : luaO_nilobject);
|
|
}
|
|
|
|
const TString* luaT_objtypenamestr(lua_State* L, const TValue* o)
|
|
{
|
|
if (ttisuserdata(o) && uvalue(o)->tag != UTAG_PROXY && uvalue(o)->metatable)
|
|
{
|
|
const TValue* type = luaH_getstr(uvalue(o)->metatable, L->global->tmname[TM_TYPE]);
|
|
|
|
if (ttisstring(type))
|
|
return tsvalue(type);
|
|
}
|
|
else if (Table* mt = L->global->mt[ttype(o)])
|
|
{
|
|
const TValue* type = luaH_getstr(mt, L->global->tmname[TM_TYPE]);
|
|
|
|
if (ttisstring(type))
|
|
return tsvalue(type);
|
|
}
|
|
|
|
return L->global->ttname[ttype(o)];
|
|
}
|
|
|
|
const char* luaT_objtypename(lua_State* L, const TValue* o)
|
|
{
|
|
return getstr(luaT_objtypenamestr(L, o));
|
|
}
|