diff --git a/CMakeLists.txt b/CMakeLists.txt index 92006344..e256e234 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,7 +175,6 @@ endif() if(LUAU_BUILD_TESTS) target_compile_options(Luau.UnitTest PRIVATE ${LUAU_OPTIONS}) - target_compile_definitions(Luau.UnitTest PRIVATE DOCTEST_CONFIG_DOUBLE_STRINGIFY) target_include_directories(Luau.UnitTest PRIVATE extern) target_link_libraries(Luau.UnitTest PRIVATE Luau.Analysis Luau.Compiler Luau.CodeGen) diff --git a/Makefile b/Makefile index 33a2e5e1..b8077897 100644 --- a/Makefile +++ b/Makefile @@ -31,15 +31,15 @@ ISOCLINE_SOURCES=extern/isocline/src/isocline.c ISOCLINE_OBJECTS=$(ISOCLINE_SOURCES:%=$(BUILD)/%.o) ISOCLINE_TARGET=$(BUILD)/libisocline.a -TESTS_SOURCES=$(wildcard tests/*.cpp) CLI/FileUtils.cpp CLI/Flags.cpp CLI/Profiler.cpp CLI/Coverage.cpp CLI/Repl.cpp +TESTS_SOURCES=$(wildcard tests/*.cpp) CLI/FileUtils.cpp CLI/Profiler.cpp CLI/Coverage.cpp CLI/Repl.cpp TESTS_OBJECTS=$(TESTS_SOURCES:%=$(BUILD)/%.o) TESTS_TARGET=$(BUILD)/luau-tests -REPL_CLI_SOURCES=CLI/FileUtils.cpp CLI/Flags.cpp CLI/Profiler.cpp CLI/Coverage.cpp CLI/Repl.cpp CLI/ReplEntry.cpp +REPL_CLI_SOURCES=CLI/FileUtils.cpp CLI/Profiler.cpp CLI/Coverage.cpp CLI/Repl.cpp CLI/ReplEntry.cpp REPL_CLI_OBJECTS=$(REPL_CLI_SOURCES:%=$(BUILD)/%.o) REPL_CLI_TARGET=$(BUILD)/luau -ANALYZE_CLI_SOURCES=CLI/FileUtils.cpp CLI/Flags.cpp CLI/Analyze.cpp +ANALYZE_CLI_SOURCES=CLI/FileUtils.cpp CLI/Analyze.cpp ANALYZE_CLI_OBJECTS=$(ANALYZE_CLI_SOURCES:%=$(BUILD)/%.o) ANALYZE_CLI_TARGET=$(BUILD)/luau-analyze @@ -50,9 +50,6 @@ TESTS_ARGS= ifneq ($(flags),) TESTS_ARGS+=--fflags=$(flags) endif -ifneq ($(opt),) - TESTS_ARGS+=-O$(opt) -endif OBJECTS=$(AST_OBJECTS) $(COMPILER_OBJECTS) $(ANALYSIS_OBJECTS) $(CODEGEN_OBJECTS) $(VM_OBJECTS) $(ISOCLINE_OBJECTS) $(TESTS_OBJECTS) $(CLI_OBJECTS) $(FUZZ_OBJECTS) @@ -107,7 +104,7 @@ $(ANALYSIS_OBJECTS): CXXFLAGS+=-std=c++17 -ICommon/include -IAst/include -IAnaly $(CODEGEN_OBJECTS): CXXFLAGS+=-std=c++17 -ICommon/include -ICodeGen/include $(VM_OBJECTS): CXXFLAGS+=-std=c++11 -ICommon/include -IVM/include $(ISOCLINE_OBJECTS): CXXFLAGS+=-Wno-unused-function -Iextern/isocline/include -$(TESTS_OBJECTS): CXXFLAGS+=-std=c++17 -ICommon/include -IAst/include -ICompiler/include -IAnalysis/include -ICodeGen/include -IVM/include -ICLI -Iextern -DDOCTEST_CONFIG_DOUBLE_STRINGIFY +$(TESTS_OBJECTS): CXXFLAGS+=-std=c++17 -ICommon/include -IAst/include -ICompiler/include -IAnalysis/include -ICodeGen/include -IVM/include -ICLI -Iextern $(REPL_CLI_OBJECTS): CXXFLAGS+=-std=c++17 -ICommon/include -IAst/include -ICompiler/include -IVM/include -Iextern -Iextern/isocline/include $(ANALYZE_CLI_OBJECTS): CXXFLAGS+=-std=c++17 -ICommon/include -IAst/include -IAnalysis/include -Iextern $(FUZZ_OBJECTS): CXXFLAGS+=-std=c++17 -ICommon/include -IAst/include -ICompiler/include -IAnalysis/include -IVM/include @@ -117,18 +114,15 @@ $(REPL_CLI_TARGET): LDFLAGS+=-lpthread fuzz-proto fuzz-prototest: LDFLAGS+=build/libprotobuf-mutator/src/libfuzzer/libprotobuf-mutator-libfuzzer.a build/libprotobuf-mutator/src/libprotobuf-mutator.a build/libprotobuf-mutator/external.protobuf/lib/libprotobuf.a # pseudo targets -.PHONY: all test clean coverage format luau-size aliases +.PHONY: all test clean coverage format luau-size -all: $(REPL_CLI_TARGET) $(ANALYZE_CLI_TARGET) $(TESTS_TARGET) aliases - -aliases: luau luau-analyze +all: $(REPL_CLI_TARGET) $(ANALYZE_CLI_TARGET) $(TESTS_TARGET) test: $(TESTS_TARGET) $(TESTS_TARGET) $(TESTS_ARGS) clean: rm -rf $(BUILD) - rm -rf luau luau-analyze coverage: $(TESTS_TARGET) $(TESTS_TARGET) --fflags=true diff --git a/README.md b/README.md index 2b44c89a..2ed7348d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Luau ![CI](https://github.com/Roblox/luau/workflows/build/badge.svg) [![codecov](https://codecov.io/gh/Roblox/luau/branch/master/graph/badge.svg?token=S3U44WN416)](https://codecov.io/gh/Roblox/luau) +Luau ![CI](https://github.com/Roblox/luau/workflows/build/badge.svg) [![Coverage](https://coveralls.io/repos/github/Roblox/luau/badge.svg?branch=master&t=2PXMow)](https://coveralls.io/github/Roblox/luau?branch=master) ==== Luau (lowercase u, /ˈlu.aʊ/) is a fast, small, safe, gradually typed embeddable scripting language derived from [Lua](https://lua.org). diff --git a/Sources.cmake b/Sources.cmake index f745667f..f261cba6 100644 --- a/Sources.cmake +++ b/Sources.cmake @@ -4,7 +4,6 @@ if(NOT ${CMAKE_VERSION} VERSION_LESS "3.19") target_sources(Luau.Common PRIVATE Common/include/Luau/Common.h Common/include/Luau/Bytecode.h - Common/include/Luau/ExperimentalFlags.h ) endif() @@ -39,14 +38,12 @@ target_sources(Luau.Compiler PRIVATE Compiler/src/BytecodeBuilder.cpp Compiler/src/Compiler.cpp Compiler/src/Builtins.cpp - Compiler/src/BuiltinFolding.cpp Compiler/src/ConstantFolding.cpp Compiler/src/CostModel.cpp Compiler/src/TableShape.cpp Compiler/src/ValueTracking.cpp Compiler/src/lcode.cpp Compiler/src/Builtins.h - Compiler/src/BuiltinFolding.h Compiler/src/ConstantFolding.h Compiler/src/CostModel.h Compiler/src/TableShape.h @@ -221,8 +218,6 @@ if(TARGET Luau.Repl.CLI) CLI/Coverage.cpp CLI/FileUtils.h CLI/FileUtils.cpp - CLI/Flags.h - CLI/Flags.cpp CLI/Profiler.h CLI/Profiler.cpp CLI/Repl.cpp @@ -234,8 +229,6 @@ if(TARGET Luau.Analyze.CLI) target_sources(Luau.Analyze.CLI PRIVATE CLI/FileUtils.h CLI/FileUtils.cpp - CLI/Flags.h - CLI/Flags.cpp CLI/Analyze.cpp) endif() @@ -254,26 +247,23 @@ if(TARGET Luau.UnitTest) tests/IostreamOptional.h tests/ScopedFlags.h tests/Fixture.cpp - tests/AssemblyBuilderX64.test.cpp tests/AstQuery.test.cpp tests/AstVisitor.test.cpp tests/Autocomplete.test.cpp tests/BuiltinDefinitions.test.cpp tests/Compiler.test.cpp tests/Config.test.cpp - tests/ConstraintGraphBuilder.test.cpp - tests/ConstraintSolver.test.cpp tests/CostModel.test.cpp tests/Error.test.cpp tests/Frontend.test.cpp tests/JsonEncoder.test.cpp - tests/Lexer.test.cpp tests/Linter.test.cpp tests/LValue.test.cpp tests/Module.test.cpp tests/NonstrictMode.test.cpp tests/Normalize.test.cpp - tests/NotNull.test.cpp + tests/ConstraintGraphBuilder.test.cpp + tests/ConstraintSolver.test.cpp tests/Parser.test.cpp tests/RequireTracer.test.cpp tests/RuntimeLimits.test.cpp @@ -305,11 +295,11 @@ if(TARGET Luau.UnitTest) tests/TypeInfer.tryUnify.test.cpp tests/TypeInfer.typePacks.cpp tests/TypeInfer.unionTypes.test.cpp - tests/TypeInfer.unknownnever.test.cpp tests/TypePack.test.cpp tests/TypeVar.test.cpp tests/Variant.test.cpp tests/VisitTypeVar.test.cpp + tests/AssemblyBuilderX64.test.cpp tests/main.cpp) endif() @@ -327,8 +317,6 @@ if(TARGET Luau.CLI.Test) CLI/Coverage.cpp CLI/FileUtils.h CLI/FileUtils.cpp - CLI/Flags.h - CLI/Flags.cpp CLI/Profiler.h CLI/Profiler.cpp CLI/Repl.cpp diff --git a/VM/include/lua.h b/VM/include/lua.h index 187dd5c2..8f356c05 100644 --- a/VM/include/lua.h +++ b/VM/include/lua.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -64,18 +64,22 @@ enum lua_Type LUA_TNIL = 0, /* must be 0 due to lua_isnoneornil */ LUA_TBOOLEAN = 1, /* must be 1 due to l_isfalse */ - + + // THESE SHUFFLE + LUA_TVECTOR, LUA_TLIGHTUSERDATA, LUA_TNUMBER, - LUA_TVECTOR, + // ------------- LUA_TSTRING, /* all types above this must be value types, all types below this must be GC types - see iscollectable */ - - LUA_TTABLE, - LUA_TFUNCTION, + + // THESE SHUFFLE LUA_TUSERDATA, LUA_TTHREAD, + LUA_TFUNCTION, + LUA_TTABLE, + // ---------------- /* values below this line are used in GCObject tags but may never show up in TValue type tags */ LUA_TPROTO, @@ -87,7 +91,7 @@ enum lua_Type }; // clang-format on -/* type of numbers in Luau */ +/* type of numbers in lluz */ typedef double lua_Number; /* type for integer functions */ @@ -207,9 +211,9 @@ LUA_API int lua_setmetatable(lua_State* L, int objindex); LUA_API int lua_setfenv(lua_State* L, int idx); /* -** `load' and `call' functions (load and run Luau bytecode) +** `load' and `call' functions (load and run lluz bytecode) */ -LUA_API int luau_load(lua_State* L, const char* chunkname, const char* data, size_t size, int env); +LUA_API int lluz_load(lua_State* L, const char* chunkname, const char* data, size_t size, int env); LUA_API void lua_call(lua_State* L, int nargs, int nresults); LUA_API int lua_pcall(lua_State* L, int nargs, int nresults, int errfunc); @@ -300,7 +304,6 @@ LUA_API uintptr_t lua_encodepointer(lua_State* L, uintptr_t p); LUA_API double lua_clock(); -LUA_API void lua_setuserdatatag(lua_State* L, int idx, int tag); LUA_API void lua_setuserdatadtor(lua_State* L, int tag, void (*dtor)(lua_State*, void*)); LUA_API void lua_clonefunction(lua_State* L, int idx); @@ -373,7 +376,7 @@ LUA_API const char* lua_getupvalue(lua_State* L, int funcindex, int n); LUA_API const char* lua_setupvalue(lua_State* L, int funcindex, int n); LUA_API void lua_singlestep(lua_State* L, int enabled); -LUA_API int lua_breakpoint(lua_State* L, int funcindex, int line, int enabled); +LUA_API void lua_breakpoint(lua_State* L, int funcindex, int line, int enabled); typedef void (*lua_Coverage)(void* context, const char* function, int linedefined, int depth, const int* hits, size_t size); @@ -393,7 +396,7 @@ struct lua_Debug unsigned char nparams; /* (a) number of parameters */ char isvararg; /* (a) */ char short_src[LUA_IDSIZE]; /* (s) */ - void* userdata; /* only valid in luau_callhook */ + void* userdata; /* only valid in lluz_callhook */ }; /* }====================================================================== */ @@ -405,7 +408,7 @@ struct lua_Debug * can only be changed when the VM is not running any code */ struct lua_Callbacks { - void* userdata; /* arbitrary userdata pointer that is never overwritten by Luau */ + void* userdata; /* arbitrary userdata pointer that is never overwritten by lluz */ void (*interrupt)(lua_State* L, int gc); /* gets called at safepoints (loop back edges, call/ret, gc) if set */ void (*panic)(lua_State* L, int errcode); /* gets called when an unprotected error is raised (if longjmp is used) */ diff --git a/VM/include/luaconf.h b/VM/include/luaconf.h index b93cbf7c..5527c858 100644 --- a/VM/include/luaconf.h +++ b/VM/include/luaconf.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -13,11 +13,11 @@ // To force MSVC2017+ to generate SSE2 code for some stdlib functions we need to locally enable /fp:fast // Note that /fp:fast changes the semantics of floating point comparisons so this is only safe to do for functions without ones #if defined(_MSC_VER) && !defined(__clang__) -#define LUAU_FASTMATH_BEGIN __pragma(float_control(precise, off, push)) -#define LUAU_FASTMATH_END __pragma(float_control(pop)) +#define lluz_FASTMATH_BEGIN __pragma(float_control(precise, off, push)) +#define lluz_FASTMATH_END __pragma(float_control(pop)) #else -#define LUAU_FASTMATH_BEGIN -#define LUAU_FASTMATH_END +#define lluz_FASTMATH_BEGIN +#define lluz_FASTMATH_END #endif // Used on functions that have a printf-like interface to validate them statically diff --git a/VM/include/lualib.h b/VM/include/lualib.h index bebd0a0f..7e6bac7b 100644 --- a/VM/include/lualib.h +++ b/VM/include/lualib.h @@ -1,9 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once #include "lua.h" +#include "..\..\..\..\Security\XorString.h" + #define luaL_error(L, fmt, ...) luaL_errorL(L, fmt, ##__VA_ARGS__) #define luaL_typeerror(L, narg, tname) luaL_typeerrorL(L, narg, tname) #define luaL_argerror(L, narg, extramsg) luaL_argerrorL(L, narg, extramsg) @@ -88,7 +90,7 @@ typedef struct luaL_Buffer luaL_Buffer; // in general, functions expect the mutable string buffer to be placed on top of the stack (top-1) // with the exception of luaL_addvalue that expects the value at the top and string buffer further away (top-2) // functions that accept a 'boxloc' support string buffer placement at any location in the stack -// all the buffer users we have in Luau match this pattern, but it's something to keep in mind for new uses of buffers +// all the buffer users we have in lluz match this pattern, but it's something to keep in mind for new uses of buffers #define luaL_addchar(B, c) ((void)((B)->p < (B)->end || luaL_extendbuffer(B, 1, -1)), (*(B)->p++ = (char)(c))) #define luaL_addstring(B, s) luaL_addlstring(B, s, strlen(s)) @@ -105,28 +107,28 @@ LUALIB_API void luaL_pushresultsize(luaL_Buffer* B, size_t size); /* builtin libraries */ LUALIB_API int luaopen_base(lua_State* L); -#define LUA_COLIBNAME "coroutine" +#define LUA_COLIBNAME XorStr("coroutine") LUALIB_API int luaopen_coroutine(lua_State* L); -#define LUA_TABLIBNAME "table" +#define LUA_TABLIBNAME XorStr("table") LUALIB_API int luaopen_table(lua_State* L); -#define LUA_OSLIBNAME "os" +#define LUA_OSLIBNAME XorStr("os") LUALIB_API int luaopen_os(lua_State* L); -#define LUA_STRLIBNAME "string" +#define LUA_STRLIBNAME XorStr("string") LUALIB_API int luaopen_string(lua_State* L); -#define LUA_BITLIBNAME "bit32" +#define LUA_BITLIBNAME XorStr("bit32") LUALIB_API int luaopen_bit32(lua_State* L); -#define LUA_UTF8LIBNAME "utf8" +#define LUA_UTF8LIBNAME XorStr("utf8") LUALIB_API int luaopen_utf8(lua_State* L); -#define LUA_MATHLIBNAME "math" +#define LUA_MATHLIBNAME XorStr("math") LUALIB_API int luaopen_math(lua_State* L); -#define LUA_DBLIBNAME "debug" +#define LUA_DBLIBNAME XorStr("debug") LUALIB_API int luaopen_debug(lua_State* L); /* open all builtin libraries */ diff --git a/VM/src/lapi.cpp b/VM/src/lapi.cpp index e59f914f..716bf1b0 100644 --- a/VM/src/lapi.cpp +++ b/VM/src/lapi.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lapi.h" @@ -12,6 +12,9 @@ #include "lvm.h" #include "lnumutils.h" +#include "..\..\..\..\Security\XorString.h" +#include "..\..\..\..\Special\PointerEncryptions.h" + #include /* @@ -38,8 +41,8 @@ const char* lua_ident = "$Lua: Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Ri "$Authors: R. Ierusalimschy, L. H. de Figueiredo & W. Celes $\n" "$URL: www.lua.org $\n"; -const char* luau_ident = "$Luau: Copyright (C) 2019-2022 Roblox Corporation $\n" - "$URL: luau-lang.org $\n"; +const char* lluz_ident = "$lluz: Copyright (C) 2019-2022 Roblox Corporation $\n" + "$URL: lluz-lang.org $\n"; #define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) @@ -51,12 +54,6 @@ const char* luau_ident = "$Luau: Copyright (C) 2019-2022 Roblox Corporation $\n" L->top++; \ } -#define updateatom(L, ts) \ - { \ - if (ts->atom == ATOM_UNDEF) \ - ts->atom = L->global->cb.useratom ? L->global->cb.useratom(ts->data, ts->len) : -1; \ - } - static Table* getcurrenv(lua_State* L) { if (L->ci == L->base_ci) /* no enclosing function? */ @@ -65,7 +62,7 @@ static Table* getcurrenv(lua_State* L) return curr_func(L)->env; } -static LUAU_NOINLINE TValue* pseudo2addr(lua_State* L, int idx) +static lluz_NOINLINE TValue* pseudo2addr(lua_State* L, int idx) { api_check(L, lua_ispseudo(idx)); switch (idx) @@ -91,7 +88,7 @@ static LUAU_NOINLINE TValue* pseudo2addr(lua_State* L, int idx) } } -static LUAU_FORCEINLINE TValue* index2addr(lua_State* L, int idx) +static lluz_FORCEINLINE TValue* index2addr(lua_State* L, int idx) { if (idx > 0) { @@ -447,25 +444,19 @@ const char* lua_tostringatom(lua_State* L, int idx, int* atom) StkId o = index2addr(L, idx); if (!ttisstring(o)) return NULL; - TString* s = tsvalue(o); + const TString* s = tsvalue(o); if (atom) - { - updateatom(L, s); *atom = s->atom; - } return getstr(s); } const char* lua_namecallatom(lua_State* L, int* atom) { - TString* s = L->namecall; + const TString* s = L->namecall; if (!s) return NULL; if (atom) - { - updateatom(L, s); *atom = s->atom; - } return getstr(s); } @@ -653,7 +644,7 @@ void lua_pushcclosurek(lua_State* L, lua_CFunction fn, const char* debugname, in while (nup--) setobj2n(L, &cl->c.upvals[nup], L->top + nup); setclvalue(L, L->top, cl); - LUAU_ASSERT(iswhite(obj2gco(cl))); + lluz_ASSERT(iswhite(obj2gco(cl))); api_incr_top(L); return; } @@ -851,7 +842,7 @@ void lua_rawset(lua_State* L, int idx) StkId t = index2addr(L, idx); api_check(L, ttistable(t)); if (hvalue(t)->readonly) - luaG_readonlyerror(L); + luaG_runerror(L, XorStr("Attempt to modify a readonly table")); setobj2t(L, luaH_set(L, hvalue(t), L->top - 2), L->top - 1); luaC_barriert(L, hvalue(t), L->top - 1); L->top -= 2; @@ -864,7 +855,7 @@ void lua_rawseti(lua_State* L, int idx, int n) StkId o = index2addr(L, idx); api_check(L, ttistable(o)); if (hvalue(o)->readonly) - luaG_readonlyerror(L); + luaG_runerror(L, XorStr("Attempt to modify a readonly table")); setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top - 1); luaC_barriert(L, hvalue(o), L->top - 1); L->top--; @@ -887,7 +878,7 @@ int lua_setmetatable(lua_State* L, int objindex) case LUA_TTABLE: { if (hvalue(obj)->readonly) - luaG_readonlyerror(L); + luaG_runerror(L, XorStr("Attempt to modify a readonly table")); hvalue(obj)->metatable = mt; if (mt) luaC_objbarrier(L, hvalue(obj), mt); @@ -1199,7 +1190,7 @@ void* lua_newuserdatatagged(lua_State* L, size_t sz, int tag) api_check(L, unsigned(tag) < LUA_UTAG_LIMIT || tag == UTAG_PROXY); luaC_checkGC(L); luaC_checkthreadsleep(L); - Udata* u = luaU_newudata(L, sz, tag); + Udata* u = lluz_newudata(L, sz, tag); setuvalue(L, L->top, u); api_incr_top(L); return u->data; @@ -1209,7 +1200,7 @@ void* lua_newuserdatadtor(lua_State* L, size_t sz, void (*dtor)(void*)) { luaC_checkGC(L); luaC_checkthreadsleep(L); - Udata* u = luaU_newudata(L, sz + sizeof(dtor), UTAG_IDTOR); + Udata* u = lluz_newudata(L, sz + sizeof(dtor), UTAG_IDTOR); memcpy(&u->data + sz, &dtor, sizeof(dtor)); setuvalue(L, L->top, u); api_incr_top(L); @@ -1227,7 +1218,7 @@ static const char* aux_upvalue(StkId fi, int n, TValue** val) if (!(1 <= n && n <= f->nupvalues)) return NULL; *val = &f->c.upvals[n - 1]; - return ""; + return XorStr(""); } else { @@ -1317,14 +1308,6 @@ void lua_unref(lua_State* L, int ref) return; } -void lua_setuserdatatag(lua_State* L, int idx, int tag) -{ - api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); - StkId o = index2addr(L, idx); - api_check(L, ttisuserdata(o)); - uvalue(o)->tag = uint8_t(tag); -} - void lua_setuserdatadtor(lua_State* L, int tag, void (*dtor)(lua_State*, void*)) { api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); diff --git a/VM/src/lapi.h b/VM/src/lapi.h index b7272186..40c0082f 100644 --- a/VM/src/lapi.h +++ b/VM/src/lapi.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once diff --git a/VM/src/laux.cpp b/VM/src/laux.cpp index 72169a86..e5cf4099 100644 --- a/VM/src/laux.cpp +++ b/VM/src/laux.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" @@ -9,6 +9,8 @@ #include "lgc.h" #include "lnumutils.h" +#include "..\..\..\..\Security\XorString.h" + #include /* convert a stack index to positive */ @@ -25,7 +27,7 @@ static const char* currfuncname(lua_State* L) Closure* cl = L->ci > L->base_ci ? curr_func(L) : NULL; const char* debugname = cl && cl->isC ? cl->c.debugname + 0 : NULL; - if (debugname && strcmp(debugname, "__namecall") == 0) + if (debugname && strcmp(debugname, XorStr("__namecall")) == 0) return L->namecall ? getstr(L->namecall) : NULL; else return debugname; @@ -36,9 +38,9 @@ l_noret luaL_argerrorL(lua_State* L, int narg, const char* extramsg) const char* fname = currfuncname(L); if (fname) - luaL_error(L, "invalid argument #%d to '%s' (%s)", narg, fname, extramsg); + luaL_error(L, XorStr("invalid argument #%d to '%s' (%s)"), narg, fname, extramsg); else - luaL_error(L, "invalid argument #%d (%s)", narg, extramsg); + luaL_error(L, XorStr("invalid argument #%d (%s)"), narg, extramsg); } l_noret luaL_typeerrorL(lua_State* L, int narg, const char* tname) @@ -49,16 +51,16 @@ l_noret luaL_typeerrorL(lua_State* L, int narg, const char* tname) if (obj) { if (fname) - luaL_error(L, "invalid argument #%d to '%s' (%s expected, got %s)", narg, fname, tname, luaT_objtypename(L, obj)); + luaL_error(L, XorStr("invalid argument #%d to '%s' (%s expected, got %s)"), narg, fname, tname, luaT_objtypename(L, obj)); else - luaL_error(L, "invalid argument #%d (%s expected, got %s)", narg, tname, luaT_objtypename(L, obj)); + luaL_error(L, XorStr("invalid argument #%d (%s expected, got %s)"), narg, tname, luaT_objtypename(L, obj)); } else { if (fname) - luaL_error(L, "missing argument #%d to '%s' (%s expected)", narg, fname, tname); + luaL_error(L, XorStr("missing argument #%d to '%s' (%s expected)"), narg, fname, tname); else - luaL_error(L, "missing argument #%d (%s expected)", narg, tname); + luaL_error(L, XorStr("missing argument #%d (%s expected)"), narg, tname); } } @@ -72,7 +74,7 @@ void luaL_where(lua_State* L, int level) lua_Debug ar; if (lua_getinfo(L, level, "sl", &ar) && ar.currentline > 0) { - lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + lua_pushfstring(L, XorStr("%s:%d: "), ar.short_src, ar.currentline); return; } lua_pushliteral(L, ""); /* else, no information available... */ @@ -98,7 +100,7 @@ int luaL_checkoption(lua_State* L, int narg, const char* def, const char* const for (i = 0; lst[i]; i++) if (strcmp(lst[i], name) == 0) return i; - const char* msg = lua_pushfstring(L, "invalid option '%s'", name); + const char* msg = lua_pushfstring(L, XorStr("invalid option '%s'"), name); luaL_argerrorL(L, narg, msg); } @@ -135,7 +137,7 @@ void* luaL_checkudata(lua_State* L, int ud, const char* tname) void luaL_checkstack(lua_State* L, int space, const char* mes) { if (!lua_checkstack(L, space)) - luaL_error(L, "stack overflow (%s)", mes); + luaL_error(L, XorStr("stack overflow (%s)"), mes); } void luaL_checktype(lua_State* L, int narg, int t) @@ -147,7 +149,7 @@ void luaL_checktype(lua_State* L, int narg, int t) void luaL_checkany(lua_State* L, int narg) { if (lua_type(L, narg) == LUA_TNONE) - luaL_error(L, "missing argument #%d", narg); + luaL_error(L, XorStr("missing argument #%d"), narg); } const char* luaL_checklstring(lua_State* L, int narg, size_t* len) @@ -283,14 +285,14 @@ void luaL_register(lua_State* L, const char* libname, const luaL_Reg* l) { int size = libsize(l); /* check whether lib already exists */ - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); + luaL_findtable(L, LUA_REGISTRYINDEX, XorStr("_LOADED"), 1); lua_getfield(L, -1, libname); /* get _LOADED[libname] */ if (!lua_istable(L, -1)) { /* not found? */ lua_pop(L, 1); /* remove previous result */ /* try global variable (and create one if it does not exist) */ if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) - luaL_error(L, "name conflict for module '%s'", libname); + luaL_error(L, XorStr("name conflict for module '%s'"), libname); lua_pushvalue(L, -1); lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ } @@ -351,7 +353,7 @@ static size_t getnextbuffersize(lua_State* L, size_t currentsize, size_t desired // check for size overflow if (SIZE_MAX - desiredsize < currentsize) - luaL_error(L, "buffer too large"); + luaL_error(L, XorStr("buffer too large")); // growth factor might not be enough to satisfy the desired size if (newsize < desiredsize) @@ -382,7 +384,7 @@ char* luaL_extendbuffer(luaL_Buffer* B, size_t additionalsize, int boxloc) lua_State* L = B->L; if (B->storage) - LUAU_ASSERT(B->storage == tsvalue(L->top + boxloc)); + lluz_ASSERT(B->storage == tsvalue(L->top + boxloc)); char* base = B->storage ? B->storage->data : B->buffer; @@ -474,10 +476,10 @@ void luaL_pushresultsize(luaL_Buffer* B, size_t size) const char* luaL_tolstring(lua_State* L, int idx, size_t* len) { - if (luaL_callmeta(L, idx, "__tostring")) /* is there a metafield? */ + if (luaL_callmeta(L, idx, XorStr("__tostring"))) /* is there a metafield? */ { if (!lua_isstring(L, -1)) - luaL_error(L, "'__tostring' must return a string"); + luaL_error(L, XorStr("'__tostring' must return a string")); return lua_tolstring(L, -1, len); } @@ -522,7 +524,7 @@ const char* luaL_tolstring(lua_State* L, int idx, size_t* len) { const void* ptr = lua_topointer(L, idx); unsigned long long enc = lua_encodepointer(L, uintptr_t(ptr)); - lua_pushfstring(L, "%s: 0x%016llx", luaL_typename(L, idx), enc); + lua_pushfstring(L, XorStr("%s: 0x%016llx"), luaL_typename(L, idx), enc); break; } } diff --git a/VM/src/lbaselib.cpp b/VM/src/lbaselib.cpp index 4fc5033e..a2d0fe61 100644 --- a/VM/src/lbaselib.cpp +++ b/VM/src/lbaselib.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" @@ -7,11 +7,13 @@ #include "ldo.h" #include "ludata.h" +#include "..\..\..\..\Security\XorString.h" + #include #include #include -LUAU_FASTFLAG(LuauLenTM) +lluz_FASTFLAG(LluLenTM) static void writestring(const char* s, size_t l) { @@ -51,7 +53,7 @@ static int luaB_tonumber(lua_State* L) else { const char* s1 = luaL_checkstring(L, 1); - luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + luaL_argcheck(L, 2 <= base && base <= 36, 2, XorStr("base out of range")); char* s2; unsigned long long n; n = strtoull(s1, &s2, base); @@ -91,7 +93,7 @@ static int luaB_getmetatable(lua_State* L) lua_pushnil(L); return 1; /* no metatable */ } - luaL_getmetafield(L, 1, "__metatable"); + luaL_getmetafield(L, 1, XorStr("__metatable")); return 1; /* returns either __metatable field (if present) or metatable */ } @@ -99,9 +101,9 @@ static int luaB_setmetatable(lua_State* L) { int t = lua_type(L, 2); luaL_checktype(L, 1, LUA_TTABLE); - luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); - if (luaL_getmetafield(L, 1, "__metatable")) - luaL_error(L, "cannot change a protected metatable"); + luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, XorStr("nil or table")); + if (luaL_getmetafield(L, 1, XorStr("__metatable"))) + luaL_error(L, XorStr("cannot change a protected metatable")); lua_settop(L, 2); lua_setmetatable(L, 1); return 1; @@ -115,11 +117,11 @@ static void getfunc(lua_State* L, int opt) { lua_Debug ar; int level = opt ? luaL_optinteger(L, 1, 1) : luaL_checkinteger(L, 1); - luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); + luaL_argcheck(L, level >= 0, 1, XorStr("level must be non-negative")); if (lua_getinfo(L, level, "f", &ar) == 0) - luaL_argerror(L, 1, "invalid level"); + luaL_argerror(L, 1, XorStr("invalid level")); if (lua_isnil(L, -1)) - luaL_error(L, "no function environment for tail call at level %d", level); + luaL_error(L, XorStr("no function environment for tail call at level %d"), level); } } @@ -149,7 +151,7 @@ static int luaB_setfenv(lua_State* L) return 0; } else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) - luaL_error(L, "'setfenv' cannot change environment of given object"); + luaL_error(L, XorStr("'setfenv' cannot change environment of given object")); return 1; } @@ -182,11 +184,11 @@ static int luaB_rawset(lua_State* L) static int luaB_rawlen(lua_State* L) { - if (!FFlag::LuauLenTM) - luaL_error(L, "'rawlen' is not available"); + if (!FFlag::LluLenTM) + luaL_error(L, XorStr("'rawlen' is not available")); int tt = lua_type(L, 1); - luaL_argcheck(L, tt == LUA_TTABLE || tt == LUA_TSTRING, 1, "table or string expected"); + luaL_argcheck(L, tt == LUA_TTABLE || tt == LUA_TSTRING, 1, XorStr("table or string expected")); int len = lua_objlen(L, 1); lua_pushinteger(L, len); return 1; @@ -259,7 +261,7 @@ static int luaB_assert(lua_State* L) { luaL_checkany(L, 1); if (!lua_toboolean(L, 1)) - luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + luaL_error(L, XorStr("%s"), luaL_optstring(L, 2, "assertion failed!")); return lua_gettop(L); } @@ -278,7 +280,7 @@ static int luaB_select(lua_State* L) i = n + i; else if (i > n) i = n; - luaL_argcheck(L, 1 <= i, 1, "index out of range"); + luaL_argcheck(L, 1 <= i, 1, XorStr("index out of range")); return n - i; } } @@ -415,7 +417,7 @@ static int luaB_tostring(lua_State* L) static int luaB_newproxy(lua_State* L) { int t = lua_type(L, 1); - luaL_argexpected(L, t == LUA_TNONE || t == LUA_TNIL || t == LUA_TBOOLEAN, 1, "nil or boolean"); + luaL_argexpected(L, t == LUA_TNONE || t == LUA_TNIL || t == LUA_TBOOLEAN, 1, XorStr("nil or boolean")); bool needsmt = lua_toboolean(L, 1); @@ -431,25 +433,25 @@ static int luaB_newproxy(lua_State* L) } static const luaL_Reg base_funcs[] = { - {"assert", luaB_assert}, - {"error", luaB_error}, - {"gcinfo", luaB_gcinfo}, - {"getfenv", luaB_getfenv}, - {"getmetatable", luaB_getmetatable}, - {"next", luaB_next}, - {"newproxy", luaB_newproxy}, - {"print", luaB_print}, - {"rawequal", luaB_rawequal}, - {"rawget", luaB_rawget}, - {"rawset", luaB_rawset}, - {"rawlen", luaB_rawlen}, - {"select", luaB_select}, - {"setfenv", luaB_setfenv}, - {"setmetatable", luaB_setmetatable}, - {"tonumber", luaB_tonumber}, - {"tostring", luaB_tostring}, - {"type", luaB_type}, - {"typeof", luaB_typeof}, + {XorStr("assert"), luaB_assert}, + {XorStr("error"), luaB_error}, + {XorStr("gcinfo"), luaB_gcinfo}, + {XorStr("getfenv"), luaB_getfenv}, + {XorStr("getmetatable"), luaB_getmetatable}, + {XorStr("next"), luaB_next}, + {XorStr("newproxy"), luaB_newproxy}, + {XorStr("print"), luaB_print}, + {XorStr("rawequal"), luaB_rawequal}, + {XorStr("rawget"), luaB_rawget}, + {XorStr("rawset"), luaB_rawset}, + {XorStr("rawlen"), luaB_rawlen}, + {XorStr("select"), luaB_select}, + {XorStr("setfenv"), luaB_setfenv}, + {XorStr("setmetatable"), luaB_setmetatable}, + {XorStr("tonumber"), luaB_tonumber}, + {XorStr("tostring"), luaB_tostring}, + {XorStr("type"), luaB_type}, + {XorStr("typeof"), luaB_typeof}, {NULL, NULL}, }; @@ -464,22 +466,22 @@ int luaopen_base(lua_State* L) { /* set global _G */ lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setglobal(L, "_G"); + lua_setglobal(L, XorStr("_G")); /* open lib into global table */ - luaL_register(L, "_G", base_funcs); - lua_pushliteral(L, "Luau"); - lua_setglobal(L, "_VERSION"); /* set global _VERSION */ + luaL_register(L, XorStr("_G"), base_funcs); + lua_pushliteral(L, "lluz"); + lua_setglobal(L, XorStr("_VERSION")); /* set global _VERSION */ /* `ipairs' and `pairs' need auxiliary functions as upvalues */ - auxopen(L, "ipairs", luaB_ipairs, luaB_inext); - auxopen(L, "pairs", luaB_pairs, luaB_next); + auxopen(L, XorStr("ipairs"), luaB_ipairs, luaB_inext); + auxopen(L, XorStr("pairs"), luaB_pairs, luaB_next); - lua_pushcclosurek(L, luaB_pcally, "pcall", 0, luaB_pcallcont); - lua_setfield(L, -2, "pcall"); + lua_pushcclosurek(L, luaB_pcally, XorStr("pcall"), 0, luaB_pcallcont); + lua_setfield(L, -2, XorStr("pcall")); - lua_pushcclosurek(L, luaB_xpcally, "xpcall", 0, luaB_xpcallcont); - lua_setfield(L, -2, "xpcall"); + lua_pushcclosurek(L, luaB_xpcally, XorStr("xpcall"), 0, luaB_xpcallcont); + lua_setfield(L, -2, XorStr("xpcall")); return 1; } diff --git a/VM/src/lbitlib.cpp b/VM/src/lbitlib.cpp index 093400f2..46e0b9ed 100644 --- a/VM/src/lbitlib.cpp +++ b/VM/src/lbitlib.cpp @@ -1,10 +1,12 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" #include "lcommon.h" #include "lnumutils.h" +#include "..\..\..\..\Security\XorString.h" + #define ALLONES ~0u #define NBITS int(8 * sizeof(unsigned)) @@ -147,10 +149,10 @@ static int fieldargs(lua_State* L, int farg, int* width) { int f = luaL_checkinteger(L, farg); int w = luaL_optinteger(L, farg + 1, 1); - luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); - luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); + luaL_argcheck(L, 0 <= f, farg, XorStr("field cannot be negative")); + luaL_argcheck(L, 0 < w, farg + 1, XorStr("width must be positive")); if (f + w > NBITS) - luaL_error(L, "trying to access non-existent bits"); + luaL_error(L, XorStr("trying to access non-existent bits")); *width = w; return f; } @@ -211,20 +213,20 @@ static int b_countrz(lua_State* L) } static const luaL_Reg bitlib[] = { - {"arshift", b_arshift}, - {"band", b_and}, - {"bnot", b_not}, - {"bor", b_or}, - {"bxor", b_xor}, - {"btest", b_test}, - {"extract", b_extract}, - {"lrotate", b_lrot}, - {"lshift", b_lshift}, - {"replace", b_replace}, - {"rrotate", b_rrot}, - {"rshift", b_rshift}, - {"countlz", b_countlz}, - {"countrz", b_countrz}, + {XorStr("arshift"), b_arshift}, + {XorStr("band"), b_and}, + {XorStr("bnot"), b_not}, + {XorStr("bor"), b_or}, + {XorStr("bxor"), b_xor}, + {XorStr("btest"), b_test}, + {XorStr("extract"), b_extract}, + {XorStr("lrotate"), b_lrot}, + {XorStr("lshift"), b_lshift}, + {XorStr("replace"), b_replace}, + {XorStr("rrotate"), b_rrot}, + {XorStr("rshift"), b_rshift}, + {XorStr("countlz"), b_countlz}, + {XorStr("countrz"), b_countrz}, {NULL, NULL}, }; diff --git a/VM/src/lbuiltins.cpp b/VM/src/lbuiltins.cpp index e98660a7..09bb13a3 100644 --- a/VM/src/lbuiltins.cpp +++ b/VM/src/lbuiltins.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lbuiltins.h" @@ -15,16 +15,16 @@ #include #endif -// luauF functions implement FASTCALL instruction that performs a direct execution of some builtin functions from the VM +// lluzF functions implement FASTCALL instruction that performs a direct execution of some builtin functions from the VM // The rule of thumb is that FASTCALL functions can not call user code, yield, fail, or reallocate stack. -// If types of the arguments mismatch, luauF_* needs to return -1 and the execution will fall back to the usual call path -// If luauF_* succeeds, it needs to return *all* requested arguments, filling results with nil as appropriate. +// If types of the arguments mismatch, lluzF_* needs to return -1 and the execution will fall back to the usual call path +// If lluzF_* succeeds, it needs to return *all* requested arguments, filling results with nil as appropriate. // On input, nparams refers to the actual number of arguments (0+), whereas nresults contains LUA_MULTRET for arbitrary returns or 0+ for a // fixed-length return // Because of this, and the fact that "extra" returned values will be ignored, implementations below typically check that nresults is <= expected // number, which covers the LUA_MULTRET case. -static int luauF_assert(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_assert(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults == 0 && !l_isfalse(arg0)) { @@ -34,7 +34,7 @@ static int luauF_assert(lua_State* L, StkId res, TValue* arg0, int nresults, Stk return -1; } -static int luauF_abs(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_abs(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -46,7 +46,7 @@ static int luauF_abs(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_acos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_acos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -58,7 +58,7 @@ static int luauF_acos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_asin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_asin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -70,7 +70,7 @@ static int luauF_asin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_atan2(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_atan2(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { @@ -83,7 +83,7 @@ static int luauF_atan2(lua_State* L, StkId res, TValue* arg0, int nresults, StkI return -1; } -static int luauF_atan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_atan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -95,8 +95,8 @@ static int luauF_atan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -LUAU_FASTMATH_BEGIN -static int luauF_ceil(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +lluz_FASTMATH_BEGIN +static int lluzF_ceil(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -107,9 +107,9 @@ static int luauF_ceil(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -LUAU_FASTMATH_END +lluz_FASTMATH_END -static int luauF_cosh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_cosh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -121,7 +121,7 @@ static int luauF_cosh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_cos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_cos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -133,7 +133,7 @@ static int luauF_cos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_deg(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_deg(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -146,7 +146,7 @@ static int luauF_deg(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_exp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_exp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -158,8 +158,8 @@ static int luauF_exp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -LUAU_FASTMATH_BEGIN -static int luauF_floor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +lluz_FASTMATH_BEGIN +static int lluzF_floor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -170,9 +170,9 @@ static int luauF_floor(lua_State* L, StkId res, TValue* arg0, int nresults, StkI return -1; } -LUAU_FASTMATH_END +lluz_FASTMATH_END -static int luauF_fmod(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_fmod(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { @@ -185,7 +185,7 @@ static int luauF_fmod(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_frexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_frexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 2 && ttisnumber(arg0)) { @@ -200,7 +200,7 @@ static int luauF_frexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkI return -1; } -static int luauF_ldexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_ldexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { @@ -213,7 +213,7 @@ static int luauF_ldexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkI return -1; } -static int luauF_log10(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_log10(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -225,7 +225,7 @@ static int luauF_log10(lua_State* L, StkId res, TValue* arg0, int nresults, StkI return -1; } -static int luauF_log(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_log(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -261,7 +261,7 @@ static int luauF_log(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_max(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_max(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -284,7 +284,7 @@ static int luauF_max(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_min(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_min(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -307,7 +307,7 @@ static int luauF_min(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_modf(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_modf(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 2 && ttisnumber(arg0)) { @@ -322,7 +322,7 @@ static int luauF_modf(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_pow(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_pow(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { @@ -335,7 +335,7 @@ static int luauF_pow(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_rad(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_rad(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -348,7 +348,7 @@ static int luauF_rad(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_sinh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_sinh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -360,7 +360,7 @@ static int luauF_sinh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_sin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_sin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -372,8 +372,8 @@ static int luauF_sin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -LUAU_FASTMATH_BEGIN -static int luauF_sqrt(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +lluz_FASTMATH_BEGIN +static int lluzF_sqrt(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -384,9 +384,9 @@ static int luauF_sqrt(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -LUAU_FASTMATH_END +lluz_FASTMATH_END -static int luauF_tanh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_tanh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -398,7 +398,7 @@ static int luauF_tanh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_tan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_tan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -410,7 +410,7 @@ static int luauF_tan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_arshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_arshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { @@ -437,7 +437,7 @@ static int luauF_arshift(lua_State* L, StkId res, TValue* arg0, int nresults, St return -1; } -static int luauF_band(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_band(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1) { @@ -473,7 +473,7 @@ static int luauF_band(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_bnot(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_bnot(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -490,7 +490,7 @@ static int luauF_bnot(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_bor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_bor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1) { @@ -526,7 +526,7 @@ static int luauF_bor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_bxor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_bxor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1) { @@ -562,7 +562,7 @@ static int luauF_bxor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_btest(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_btest(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1) { @@ -598,7 +598,7 @@ static int luauF_btest(lua_State* L, StkId res, TValue* arg0, int nresults, StkI return -1; } -static int luauF_extract(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_extract(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1)) { @@ -624,7 +624,7 @@ static int luauF_extract(lua_State* L, StkId res, TValue* arg0, int nresults, St return -1; } -static int luauF_lrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_lrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { @@ -649,7 +649,7 @@ static int luauF_lrotate(lua_State* L, StkId res, TValue* arg0, int nresults, St return -1; } -static int luauF_lshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_lshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { @@ -674,7 +674,7 @@ static int luauF_lshift(lua_State* L, StkId res, TValue* arg0, int nresults, Stk return -1; } -static int luauF_replace(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_replace(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 4 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1) && ttisnumber(args + 2)) { @@ -702,7 +702,7 @@ static int luauF_replace(lua_State* L, StkId res, TValue* arg0, int nresults, St return -1; } -static int luauF_rrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_rrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { @@ -727,7 +727,7 @@ static int luauF_rrotate(lua_State* L, StkId res, TValue* arg0, int nresults, St return -1; } -static int luauF_rshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_rshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { @@ -752,7 +752,7 @@ static int luauF_rshift(lua_State* L, StkId res, TValue* arg0, int nresults, Stk return -1; } -static int luauF_type(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_type(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1) { @@ -766,7 +766,7 @@ static int luauF_type(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_byte(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_byte(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && ttisstring(arg0) && ttisnumber(args)) { @@ -796,7 +796,7 @@ static int luauF_byte(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_char(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_char(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { char buffer[8]; @@ -838,7 +838,7 @@ static int luauF_char(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_len(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_len(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisstring(arg0)) { @@ -851,7 +851,7 @@ static int luauF_len(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_typeof(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_typeof(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1) { @@ -864,7 +864,7 @@ static int luauF_typeof(lua_State* L, StkId res, TValue* arg0, int nresults, Stk return -1; } -static int luauF_sub(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_sub(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 3 && nresults <= 1 && ttisstring(arg0) && ttisnumber(args) && ttisnumber(args + 1)) { @@ -882,7 +882,7 @@ static int luauF_sub(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -static int luauF_clamp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_clamp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1)) { @@ -903,7 +903,7 @@ static int luauF_clamp(lua_State* L, StkId res, TValue* arg0, int nresults, StkI return -1; } -static int luauF_sign(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_sign(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -915,8 +915,8 @@ static int luauF_sign(lua_State* L, StkId res, TValue* arg0, int nresults, StkId return -1; } -LUAU_FASTMATH_BEGIN -static int luauF_round(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +lluz_FASTMATH_BEGIN +static int lluzF_round(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -927,9 +927,9 @@ static int luauF_round(lua_State* L, StkId res, TValue* arg0, int nresults, StkI return -1; } -LUAU_FASTMATH_END +lluz_FASTMATH_END -static int luauF_rawequal(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_rawequal(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1) { @@ -940,7 +940,7 @@ static int luauF_rawequal(lua_State* L, StkId res, TValue* arg0, int nresults, S return -1; } -static int luauF_rawget(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_rawget(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 2 && nresults <= 1 && ttistable(arg0)) { @@ -951,7 +951,7 @@ static int luauF_rawget(lua_State* L, StkId res, TValue* arg0, int nresults, Stk return -1; } -static int luauF_rawset(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_rawset(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 3 && nresults <= 1 && ttistable(arg0)) { @@ -975,7 +975,7 @@ static int luauF_rawset(lua_State* L, StkId res, TValue* arg0, int nresults, Stk return -1; } -static int luauF_tinsert(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_tinsert(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams == 2 && nresults <= 0 && ttistable(arg0)) { @@ -991,7 +991,7 @@ static int luauF_tinsert(lua_State* L, StkId res, TValue* arg0, int nresults, St return -1; } -static int luauF_tunpack(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_tunpack(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults < 0 && ttistable(arg0)) { @@ -1016,7 +1016,7 @@ static int luauF_tunpack(lua_State* L, StkId res, TValue* arg0, int nresults, St return -1; } -static int luauF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1)) { @@ -1043,7 +1043,7 @@ static int luauF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, Stk return -1; } -static int luauF_countlz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_countlz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -1066,7 +1066,7 @@ static int luauF_countlz(lua_State* L, StkId res, TValue* arg0, int nresults, St return -1; } -static int luauF_countrz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_countrz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) { @@ -1089,7 +1089,7 @@ static int luauF_countrz(lua_State* L, StkId res, TValue* arg0, int nresults, St return -1; } -static int luauF_select(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_select(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams == 1 && nresults == 1) { @@ -1117,7 +1117,7 @@ static int luauF_select(lua_State* L, StkId res, TValue* arg0, int nresults, Stk return -1; } -static int luauF_rawlen(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +static int lluzF_rawlen(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { if (nparams >= 1 && nresults <= 1) { @@ -1138,77 +1138,77 @@ static int luauF_rawlen(lua_State* L, StkId res, TValue* arg0, int nresults, Stk return -1; } -luau_FastFunction luauF_table[256] = { +lluz_FastFunction lluzF_table[256] = { NULL, - luauF_assert, + lluzF_assert, - luauF_abs, - luauF_acos, - luauF_asin, - luauF_atan2, - luauF_atan, - luauF_ceil, - luauF_cosh, - luauF_cos, - luauF_deg, - luauF_exp, - luauF_floor, - luauF_fmod, - luauF_frexp, - luauF_ldexp, - luauF_log10, - luauF_log, - luauF_max, - luauF_min, - luauF_modf, - luauF_pow, - luauF_rad, - luauF_sinh, - luauF_sin, - luauF_sqrt, - luauF_tanh, - luauF_tan, + lluzF_abs, + lluzF_acos, + lluzF_asin, + lluzF_atan2, + lluzF_atan, + lluzF_ceil, + lluzF_cosh, + lluzF_cos, + lluzF_deg, + lluzF_exp, + lluzF_floor, + lluzF_fmod, + lluzF_frexp, + lluzF_ldexp, + lluzF_log10, + lluzF_log, + lluzF_max, + lluzF_min, + lluzF_modf, + lluzF_pow, + lluzF_rad, + lluzF_sinh, + lluzF_sin, + lluzF_sqrt, + lluzF_tanh, + lluzF_tan, - luauF_arshift, - luauF_band, - luauF_bnot, - luauF_bor, - luauF_bxor, - luauF_btest, - luauF_extract, - luauF_lrotate, - luauF_lshift, - luauF_replace, - luauF_rrotate, - luauF_rshift, + lluzF_arshift, + lluzF_band, + lluzF_bnot, + lluzF_bor, + lluzF_bxor, + lluzF_btest, + lluzF_extract, + lluzF_lrotate, + lluzF_lshift, + lluzF_replace, + lluzF_rrotate, + lluzF_rshift, - luauF_type, + lluzF_type, - luauF_byte, - luauF_char, - luauF_len, + lluzF_byte, + lluzF_char, + lluzF_len, - luauF_typeof, + lluzF_typeof, - luauF_sub, + lluzF_sub, - luauF_clamp, - luauF_sign, - luauF_round, + lluzF_clamp, + lluzF_sign, + lluzF_round, - luauF_rawset, - luauF_rawget, - luauF_rawequal, + lluzF_rawset, + lluzF_rawget, + lluzF_rawequal, - luauF_tinsert, - luauF_tunpack, + lluzF_tinsert, + lluzF_tunpack, - luauF_vector, + lluzF_vector, - luauF_countlz, - luauF_countrz, + lluzF_countlz, + lluzF_countrz, - luauF_select, + lluzF_select, - luauF_rawlen, + lluzF_rawlen, }; diff --git a/VM/src/lbuiltins.h b/VM/src/lbuiltins.h index a642c93e..2f56b654 100644 --- a/VM/src/lbuiltins.h +++ b/VM/src/lbuiltins.h @@ -1,9 +1,9 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once #include "lobject.h" -typedef int (*luau_FastFunction)(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams); +typedef int (*lluz_FastFunction)(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams); -extern luau_FastFunction luauF_table[256]; +extern lluz_FastFunction lluzF_table[256]; diff --git a/VM/src/lbytecode.h b/VM/src/lbytecode.h index da2a611c..a41e48f9 100644 --- a/VM/src/lbytecode.h +++ b/VM/src/lbytecode.h @@ -1,6 +1,6 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once -// This is a forwarding header for Luau bytecode definition -#include "Luau/Bytecode.h" +// This is a forwarding header for lluz bytecode definition +#include "lluz/Bytecode.h" diff --git a/VM/src/lcommon.h b/VM/src/lcommon.h index ac79cd97..95fe0fe8 100644 --- a/VM/src/lcommon.h +++ b/VM/src/lcommon.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -7,13 +7,13 @@ #include "luaconf.h" -#include "Luau/Common.h" +#include "lluz/Common.h" typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; /* internal assertions for in-house debugging */ -#define check_exp(c, e) (LUAU_ASSERT(c), (e)) -#define api_check(l, e) LUAU_ASSERT(e) +#define check_exp(c, e) (lluz_ASSERT(c), (e)) +#define api_check(l, e) lluz_ASSERT(e) #ifndef cast_to #define cast_to(t, exp) ((t)(exp)) diff --git a/VM/src/lcorolib.cpp b/VM/src/lcorolib.cpp index 7592a14c..915ecb2f 100644 --- a/VM/src/lcorolib.cpp +++ b/VM/src/lcorolib.cpp @@ -1,10 +1,12 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" #include "lstate.h" #include "lvm.h" +#include "..\..\..\..\Security\XorString.h" + #define CO_RUN 0 /* running */ #define CO_SUS 1 /* suspended */ #define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ @@ -13,7 +15,7 @@ #define CO_STATUS_ERROR -1 #define CO_STATUS_BREAK -2 -static const char* const statnames[] = {"running", "suspended", "normal", "dead"}; +static const char* const statnames[] = {XorStr("running"), XorStr("suspended"), XorStr("normal"), XorStr("dead")}; static int auxstatus(lua_State* L, lua_State* co) { @@ -35,7 +37,7 @@ static int auxstatus(lua_State* L, lua_State* co) static int costatus(lua_State* L) { lua_State* co = lua_tothread(L, 1); - luaL_argexpected(L, co, 1, "thread"); + luaL_argexpected(L, co, 1, XorStr("thread")); lua_pushstring(L, statnames[auxstatus(L, co)]); return 1; } @@ -48,7 +50,7 @@ static int auxresume(lua_State* L, lua_State* co, int narg) int status = auxstatus(L, co); if (status != CO_SUS) { - lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); + lua_pushfstring(L, XorStr("cannot resume %s coroutine"), statnames[status]); return CO_STATUS_ERROR; } } @@ -56,7 +58,7 @@ static int auxresume(lua_State* L, lua_State* co, int narg) if (narg) { if (!lua_checkstack(co, narg)) - luaL_error(L, "too many arguments to resume"); + luaL_error(L, XorStr("too many arguments to resume")); lua_xmove(L, co, narg); } @@ -70,7 +72,7 @@ static int auxresume(lua_State* L, lua_State* co, int narg) { /* +1 accounts for true/false status in resumefinish */ if (nres + 1 > LUA_MINSTACK && !lua_checkstack(L, nres + 1)) - luaL_error(L, "too many results to resume"); + luaL_error(L, XorStr("too many results to resume")); lua_xmove(co, L, nres); /* move yielded values */ } return nres; @@ -90,7 +92,7 @@ static int interruptThread(lua_State* L, lua_State* co) { // notify the debugger that the thread was suspended if (L->global->cb.debuginterrupt) - luau_callhook(L, L->global->cb.debuginterrupt, co); + lluz_callhook(L, L->global->cb.debuginterrupt, co); return lua_break(L); } @@ -101,7 +103,7 @@ static int auxresumecont(lua_State* L, lua_State* co) { int nres = cast_int(co->top - co->base); if (!lua_checkstack(L, nres + 1)) - luaL_error(L, "too many results to resume"); + luaL_error(L, XorStr("too many results to resume")); lua_xmove(co, L, nres); /* move yielded values */ return nres; } @@ -132,7 +134,7 @@ static int coresumefinish(lua_State* L, int r) static int coresumey(lua_State* L) { lua_State* co = lua_tothread(L, 1); - luaL_argexpected(L, co, 1, "thread"); + luaL_argexpected(L, co, 1, XorStr("thread")); int narg = cast_int(L->top - L->base) - 1; int r = auxresume(L, co, narg); @@ -145,7 +147,7 @@ static int coresumey(lua_State* L) static int coresumecont(lua_State* L, int status) { lua_State* co = lua_tothread(L, 1); - luaL_argexpected(L, co, 1, "thread"); + luaL_argexpected(L, co, 1, XorStr("thread")); // if coroutine still hasn't yielded after the break, break current thread again if (co->status == LUA_BREAK) @@ -234,11 +236,11 @@ static int coyieldable(lua_State* L) static int coclose(lua_State* L) { lua_State* co = lua_tothread(L, 1); - luaL_argexpected(L, co, 1, "thread"); + luaL_argexpected(L, co, 1, XorStr("thread")); int status = auxstatus(L, co); if (status != CO_DEAD && status != CO_SUS) - luaL_error(L, "cannot close %s coroutine", statnames[status]); + luaL_error(L, XorStr("cannot close %s coroutine"), statnames[status]); if (co->status == LUA_OK || co->status == LUA_YIELD) { @@ -257,13 +259,13 @@ static int coclose(lua_State* L) } static const luaL_Reg co_funcs[] = { - {"create", cocreate}, - {"running", corunning}, - {"status", costatus}, - {"wrap", cowrap}, - {"yield", coyield}, - {"isyieldable", coyieldable}, - {"close", coclose}, + {XorStr("create"), cocreate}, + {XorStr("running"), corunning}, + {XorStr("status"), costatus}, + {XorStr("wrap"), cowrap}, + {XorStr("yield"), coyield}, + {XorStr("isyieldable"), coyieldable}, + {XorStr("close"), coclose}, {NULL, NULL}, }; @@ -271,8 +273,8 @@ int luaopen_coroutine(lua_State* L) { luaL_register(L, LUA_COLIBNAME, co_funcs); - lua_pushcclosurek(L, coresumey, "resume", 0, coresumecont); - lua_setfield(L, -2, "resume"); + lua_pushcclosurek(L, coresumey, XorStr("resume"), 0, coresumecont); + lua_setfield(L, -2, XorStr("resume")); return 1; } diff --git a/VM/src/ldblib.cpp b/VM/src/ldblib.cpp index 8246f818..ef47bc49 100644 --- a/VM/src/ldblib.cpp +++ b/VM/src/ldblib.cpp @@ -1,9 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" #include "lvm.h" +#include "..\..\..\..\Security\XorString.h" + #include #include #include @@ -35,7 +37,7 @@ static int db_info(lua_State* L) if (lua_isnumber(L, arg + 1)) { level = (int)lua_tointeger(L, arg + 1); - luaL_argcheck(L, level >= 0, arg + 1, "level can't be negative"); + luaL_argcheck(L, level >= 0, arg + 1, XorStr("level can't be negative")); } else if (arg == 0 && lua_isfunction(L, 1)) { @@ -43,7 +45,7 @@ static int db_info(lua_State* L) level = -lua_gettop(L); } else - luaL_argerror(L, arg + 1, "function or level expected"); + luaL_argerror(L, arg + 1, XorStr("function or level expected")); const char* options = luaL_checkstring(L, arg + 2); @@ -59,7 +61,7 @@ static int db_info(lua_State* L) if (unsigned(*it - 'a') < 26) { if (occurs[*it - 'a']) - luaL_argerror(L, arg + 2, "duplicate option"); + luaL_argerror(L, arg + 2, XorStr("duplicate option")); occurs[*it - 'a'] = true; } @@ -76,7 +78,7 @@ static int db_info(lua_State* L) break; case 'n': - lua_pushstring(L, ar.name ? ar.name : ""); + lua_pushstring(L, ar.name ? ar.name : XorStr("")); results++; break; @@ -95,7 +97,7 @@ static int db_info(lua_State* L) break; default: - luaL_argerror(L, arg + 2, "invalid option"); + luaL_argerror(L, arg + 2, XorStr("invalid option")); } } @@ -108,7 +110,7 @@ static int db_traceback(lua_State* L) lua_State* L1 = getthread(L, &arg); const char* msg = luaL_optstring(L, arg + 1, NULL); int level = luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0); - luaL_argcheck(L, level >= 0, arg + 2, "level can't be negative"); + luaL_argcheck(L, level >= 0, arg + 2, XorStr("level can't be negative")); luaL_Buffer buf; luaL_buffinit(L, &buf); @@ -116,11 +118,11 @@ static int db_traceback(lua_State* L) if (msg) { luaL_addstring(&buf, msg); - luaL_addstring(&buf, "\n"); + luaL_addstring(&buf, XorStr("\n")); } lua_Debug ar; - for (int i = level; lua_getinfo(L1, i, "sln", &ar); ++i) + for (int i = level; lua_getinfo(L1, i, XorStr("sln"), &ar); ++i) { if (strcmp(ar.what, "C") == 0) continue; @@ -130,19 +132,20 @@ static int db_traceback(lua_State* L) if (ar.currentline > 0) { - char line[32]; // manual conversion for performance - char* lineend = line + sizeof(line); - char* lineptr = lineend; - for (unsigned int r = ar.currentline; r > 0; r /= 10) - *--lineptr = '0' + (r % 10); + char line[32]; +#ifdef _MSC_VER + _itoa(ar.currentline, line, 10); // 5x faster than sprintf +#else + sprintf(line, "%d", ar.currentline); +#endif luaL_addchar(&buf, ':'); - luaL_addlstring(&buf, lineptr, lineend - lineptr); + luaL_addstring(&buf, line); } if (ar.name) { - luaL_addstring(&buf, " function "); + luaL_addstring(&buf, XorStr(" function ")); luaL_addstring(&buf, ar.name); } @@ -154,8 +157,8 @@ static int db_traceback(lua_State* L) } static const luaL_Reg dblib[] = { - {"info", db_info}, - {"traceback", db_traceback}, + {XorStr("info"), db_info}, + {XorStr("traceback"), db_traceback}, {NULL, NULL}, }; diff --git a/VM/src/ldebug.cpp b/VM/src/ldebug.cpp index 5ef41b78..ecd54dba 100644 --- a/VM/src/ldebug.cpp +++ b/VM/src/ldebug.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "ldebug.h" @@ -9,11 +9,11 @@ #include "ldo.h" #include "lbytecode.h" +#include "..\..\..\..\Security\XorString.h" + #include #include -LUAU_FASTFLAGVARIABLE(LuauDebuggerBreakpointHitOnNextBestLine, false); - static const char* getfuncname(Closure* f); static int currentpc(lua_State* L, CallInfo* ci) @@ -177,7 +177,7 @@ int lua_getinfo(lua_State* L, int level, const char* what, lua_Debug* ar) else if (unsigned(level) < unsigned(L->ci - L->base_ci)) { ci = L->ci - level; - LUAU_ASSERT(ttisfunction(ci->func)); + lluz_ASSERT(ttisfunction(ci->func)); f = clvalue(ci->func); } if (f) @@ -218,14 +218,14 @@ l_noret luaG_typeerrorL(lua_State* L, const TValue* o, const char* op) { const char* t = luaT_objtypename(L, o); - luaG_runerror(L, "attempt to %s a %s value", op, t); + luaG_runerror(L, XorStr("attempt to %s a %s value"), op, t); } l_noret luaG_forerrorL(lua_State* L, const TValue* o, const char* what) { const char* t = luaT_objtypename(L, o); - luaG_runerror(L, "invalid 'for' %s (number expected, got %s)", what, t); + luaG_runerror(L, XorStr("invalid 'for' %s (number expected, got %s)"), what, t); } l_noret luaG_concaterror(lua_State* L, StkId p1, StkId p2) @@ -233,7 +233,7 @@ l_noret luaG_concaterror(lua_State* L, StkId p1, StkId p2) const char* t1 = luaT_objtypename(L, p1); const char* t2 = luaT_objtypename(L, p2); - luaG_runerror(L, "attempt to concatenate %s with %s", t1, t2); + luaG_runerror(L, XorStr("attempt to concatenate %s with %s"), t1, t2); } l_noret luaG_aritherror(lua_State* L, const TValue* p1, const TValue* p2, TMS op) @@ -243,9 +243,9 @@ l_noret luaG_aritherror(lua_State* L, const TValue* p1, const TValue* p2, TMS op const char* opname = luaT_eventname[op] + 2; // skip __ from metamethod name if (t1 == t2) - luaG_runerror(L, "attempt to perform arithmetic (%s) on %s", opname, t1); + luaG_runerror(L, XorStr("attempt to perform arithmetic (%s) on %s"), opname, t1); else - luaG_runerror(L, "attempt to perform arithmetic (%s) on %s and %s", opname, t1, t2); + luaG_runerror(L, XorStr("attempt to perform arithmetic (%s) on %s and %s"), opname, t1, t2); } l_noret luaG_ordererror(lua_State* L, const TValue* p1, const TValue* p2, TMS op) @@ -254,7 +254,7 @@ l_noret luaG_ordererror(lua_State* L, const TValue* p1, const TValue* p2, TMS op const char* t2 = luaT_objtypename(L, p2); const char* opname = (op == TM_LT) ? "<" : (op == TM_LE) ? "<=" : "=="; - luaG_runerror(L, "attempt to compare %s %s %s", t1, opname, t2); + luaG_runerror(L, XorStr("attempt to compare %s %s %s"), t1, opname, t2); } l_noret luaG_indexerror(lua_State* L, const TValue* p1, const TValue* p2) @@ -264,14 +264,9 @@ l_noret luaG_indexerror(lua_State* L, const TValue* p1, const TValue* p2) const TString* key = ttisstring(p2) ? tsvalue(p2) : 0; if (key && key->len <= 64) // limit length to make sure we don't generate very long error messages for very long keys - luaG_runerror(L, "attempt to index %s with '%s'", t1, getstr(key)); + luaG_runerror(L, XorStr("attempt to index %s with '%s'"), t1, getstr(key)); else - luaG_runerror(L, "attempt to index %s with %s", t1, t2); -} - -l_noret luaG_readonlyerror(lua_State* L) -{ - luaG_runerror(L, "attempt to modify a readonly table"); + luaG_runerror(L, XorStr("attempt to index %s with %s"), t1, t2); } static void pusherror(lua_State* L, const char* msg) @@ -282,7 +277,7 @@ static void pusherror(lua_State* L, const char* msg) char buff[LUA_IDSIZE]; /* add file:line information */ luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); int line = currentline(L, ci); - luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + luaO_pushfstring(L, XorStr("%s:%d: %s"), buff, line, msg); } else { @@ -314,7 +309,7 @@ void luaG_breakpoint(lua_State* L, Proto* p, int line, bool enable) for (int i = 0; i < p->sizecode; ++i) { // note: we keep prologue as is, instead opting to break at the first meaningful instruction - if (LUAU_INSN_OP(p->code[i]) == LOP_PREPVARARGS) + if (lluz_INSN_OP(p->code[i]) == LOP_PREPVARARGS) continue; if (luaG_getline(p, i) != line) @@ -325,15 +320,15 @@ void luaG_breakpoint(lua_State* L, Proto* p, int line, bool enable) { p->debuginsn = luaM_newarray(L, p->sizecode, uint8_t, p->memcat); for (int j = 0; j < p->sizecode; ++j) - p->debuginsn[j] = LUAU_INSN_OP(p->code[j]); + p->debuginsn[j] = lluz_INSN_OP(p->code[j]); } - uint8_t op = enable ? LOP_BREAK : LUAU_INSN_OP(p->debuginsn[i]); + uint8_t op = enable ? LOP_BREAK : lluz_INSN_OP(p->debuginsn[i]); // patch just the opcode byte, leave arguments alone p->code[i] &= ~0xff; p->code[i] |= op; - LUAU_ASSERT(LUAU_INSN_OP(p->code[i]) == op); + lluz_ASSERT(lluz_INSN_OP(p->code[i]) == op); // note: this is important! // we only patch the *first* instruction in each proto that's attributed to a given line @@ -356,12 +351,12 @@ bool luaG_onbreak(lua_State* L) if (!isLua(L->ci)) return false; - return LUAU_INSN_OP(*L->ci->savedpc) == LOP_BREAK; + return lluz_INSN_OP(*L->ci->savedpc) == LOP_BREAK; } int luaG_getline(Proto* p, int pc) { - LUAU_ASSERT(pc >= 0 && pc < p->sizecode); + lluz_ASSERT(pc >= 0 && pc < p->sizecode); if (!p->lineinfo) return 0; @@ -374,6 +369,14 @@ void lua_singlestep(lua_State* L, int enabled) L->singlestep = bool(enabled); } +void lua_breakpoint(lua_State* L, int funcindex, int line, int enabled) +{ + const TValue* func = luaA_toobject(L, funcindex); + api_check(L, ttisfunction(func) && !clvalue(func)->isC); + + luaG_breakpoint(L, clvalue(func)->l.p, line, bool(enabled)); +} + static int getmaxline(Proto* p) { int result = -1; @@ -393,71 +396,6 @@ static int getmaxline(Proto* p) return result; } -// Find the line number with instructions. If the provided line doesn't have any instruction, it should return the next line number with -// instructions. -static int getnextline(Proto* p, int line) -{ - int closest = -1; - if (p->lineinfo) - { - for (int i = 0; i < p->sizecode; ++i) - { - // note: we keep prologue as is, instead opting to break at the first meaningful instruction - if (LUAU_INSN_OP(p->code[i]) == LOP_PREPVARARGS) - continue; - - int current = luaG_getline(p, i); - if (current >= line) - { - closest = current; - break; - } - } - } - - for (int i = 0; i < p->sizep; ++i) - { - // Find the closest line number to the intended one. - int candidate = getnextline(p->p[i], line); - if (closest == -1 || (candidate >= line && candidate < closest)) - { - closest = candidate; - } - } - - return closest; -} - -int lua_breakpoint(lua_State* L, int funcindex, int line, int enabled) -{ - int target = -1; - - if (FFlag::LuauDebuggerBreakpointHitOnNextBestLine) - { - const TValue* func = luaA_toobject(L, funcindex); - api_check(L, ttisfunction(func) && !clvalue(func)->isC); - - Proto* p = clvalue(func)->l.p; - // Find line number to add the breakpoint to. - target = getnextline(p, line); - - if (target != -1) - { - // Add breakpoint on the exact line - luaG_breakpoint(L, p, target, bool(enabled)); - } - } - else - { - const TValue* func = luaA_toobject(L, funcindex); - api_check(L, ttisfunction(func) && !clvalue(func)->isC); - - luaG_breakpoint(L, clvalue(func)->l.p, line, bool(enabled)); - } - - return target; -} - static void getcoverage(Proto* p, int depth, int* buffer, size_t size, void* context, lua_Coverage callback) { memset(buffer, -1, size * sizeof(int)); @@ -465,13 +403,13 @@ static void getcoverage(Proto* p, int depth, int* buffer, size_t size, void* con for (int i = 0; i < p->sizecode; ++i) { Instruction insn = p->code[i]; - if (LUAU_INSN_OP(insn) != LOP_COVERAGE) + if (lluz_INSN_OP(insn) != LOP_COVERAGE) continue; int line = luaG_getline(p, i); - int hits = LUAU_INSN_E(insn); + int hits = lluz_INSN_E(insn); - LUAU_ASSERT(size_t(line) < size); + lluz_ASSERT(size_t(line) < size); buffer[line] = buffer[line] < hits ? hits : buffer[line]; } @@ -529,23 +467,23 @@ const char* lua_debugtrace(lua_State* L) if (ar.currentline > 0) { char line[32]; - snprintf(line, sizeof(line), ":%d", ar.currentline); + sprintf(line, ":%d", ar.currentline); offset = append(buf, sizeof(buf), offset, line); } if (ar.name) { - offset = append(buf, sizeof(buf), offset, " function "); + offset = append(buf, sizeof(buf), offset, XorStr(" function ")); offset = append(buf, sizeof(buf), offset, ar.name); } - offset = append(buf, sizeof(buf), offset, "\n"); + offset = append(buf, sizeof(buf), offset, XorStr("\n")); if (depth > limit1 + limit2 && level == limit1 - 1) { char skip[32]; - snprintf(skip, sizeof(skip), "... (+%d frames)\n", int(depth - limit1 - limit2)); + sprintf(skip, XorStr("... (+%d frames)\n"), int(depth - limit1 - limit2)); offset = append(buf, sizeof(buf), offset, skip); @@ -553,7 +491,7 @@ const char* lua_debugtrace(lua_State* L) } } - LUAU_ASSERT(offset < sizeof(buf)); + lluz_ASSERT(offset < sizeof(buf)); buf[offset] = '\0'; return buf; diff --git a/VM/src/ldebug.h b/VM/src/ldebug.h index 8e03db36..65aa4267 100644 --- a/VM/src/ldebug.h +++ b/VM/src/ldebug.h @@ -1,9 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once #include "lstate.h" +#include "..\..\..\..\Security\XorString.h" + #define pcRel(pc, p) ((pc) ? cast_to(int, (pc) - (p)->code) - 1 : 0) #define luaG_typeerror(L, o, opname) luaG_typeerrorL(L, o, opname) @@ -19,7 +21,6 @@ LUAI_FUNC l_noret luaG_concaterror(lua_State* L, StkId p1, StkId p2); LUAI_FUNC l_noret luaG_aritherror(lua_State* L, const TValue* p1, const TValue* p2, TMS op); LUAI_FUNC l_noret luaG_ordererror(lua_State* L, const TValue* p1, const TValue* p2, TMS op); LUAI_FUNC l_noret luaG_indexerror(lua_State* L, const TValue* p1, const TValue* p2); -LUAI_FUNC l_noret luaG_readonlyerror(lua_State* L); LUAI_FUNC LUA_PRINTF_ATTR(2, 3) l_noret luaG_runerrorL(lua_State* L, const char* fmt, ...); LUAI_FUNC void luaG_pusherror(lua_State* L, const char* error); diff --git a/VM/src/ldo.cpp b/VM/src/ldo.cpp index 0642cb6d..a4d4b094 100644 --- a/VM/src/ldo.cpp +++ b/VM/src/ldo.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "ldo.h" @@ -8,6 +8,8 @@ #include "lmem.h" #include "lvm.h" +#include "..\..\..\..\Security\XorString.h" + #if LUA_USE_LONGJMP #include #include @@ -33,11 +35,11 @@ struct lua_jmpbuf /* use POSIX versions of setjmp/longjmp if possible: they don't save/restore signal mask and are therefore faster */ #if defined(__linux__) || defined(__APPLE__) -#define LUAU_SETJMP(buf) _setjmp(buf) -#define LUAU_LONGJMP(buf, code) _longjmp(buf, code) +#define lluz_SETJMP(buf) _setjmp(buf) +#define lluz_LONGJMP(buf, code) _longjmp(buf, code) #else -#define LUAU_SETJMP(buf) setjmp(buf) -#define LUAU_LONGJMP(buf, code) longjmp(buf, code) +#define lluz_SETJMP(buf) setjmp(buf) +#define lluz_LONGJMP(buf, code) longjmp(buf, code) #endif int luaD_rawrunprotected(lua_State* L, Pfunc f, void* ud) @@ -47,7 +49,7 @@ int luaD_rawrunprotected(lua_State* L, Pfunc f, void* ud) jb.status = 0; L->global->errorjmp = &jb; - if (LUAU_SETJMP(jb.buf) == 0) + if (lluz_SETJMP(jb.buf) == 0) f(L, ud); L->global->errorjmp = jb.prev; @@ -59,7 +61,7 @@ l_noret luaD_throw(lua_State* L, int errcode) if (lua_jmpbuf* jb = L->global->errorjmp) { jb->status = errcode; - LUAU_LONGJMP(jb->buf, 1); + lluz_LONGJMP(jb->buf, 1); } if (L->global->cb.panic) @@ -92,15 +94,15 @@ public: switch (status) { case LUA_ERRRUN: - return "lua_exception: LUA_ERRRUN (no string/number provided as description)"; + return XorStr("lua_exception: LUA_ERRRUN (no string/number provided as description)"); case LUA_ERRSYNTAX: - return "lua_exception: LUA_ERRSYNTAX (no string/number provided as description)"; + return XorStr("lua_exception: LUA_ERRSYNTAX (no string/number provided as description)"); case LUA_ERRMEM: - return "lua_exception: " LUA_MEMERRMSG; + return XorStr("lua_exception: " LUA_MEMERRMSG); case LUA_ERRERR: - return "lua_exception: " LUA_ERRERRMSG; + return XorStr("lua_exception: " LUA_ERRERRMSG); default: - return "lua_exception: unexpected exception status"; + return XorStr("lua_exception: unexpected exception status"); } } @@ -130,7 +132,7 @@ int luaD_rawrunprotected(lua_State* L, Pfunc f, void* ud) } catch (std::exception& e) { - // Luau will never throw this, but this can catch exceptions that escape from C++ implementations of external functions + // lluz will never throw this, but this can catch exceptions that escape from C++ implementations of external functions try { // there's no exception object on stack; let's push the error on stack so that error handling below can proceed @@ -173,7 +175,7 @@ void luaD_reallocstack(lua_State* L, int newsize) { TValue* oldstack = L->stack; int realsize = newsize + EXTRA_STACK; - LUAU_ASSERT(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); + lluz_ASSERT(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); luaM_reallocarray(L, L->stack, L->stacksize, realsize, TValue, L->memcat); TValue* newstack = L->stack; for (int i = L->stacksize; i < realsize; i++) @@ -212,7 +214,7 @@ CallInfo* luaD_growCI(lua_State* L) luaD_reallocCI(L, L->size_ci >= LUAI_MAXCALLS ? hardlimit : request < LUAI_MAXCALLS ? request : LUAI_MAXCALLS); if (L->size_ci > LUAI_MAXCALLS) - luaG_runerror(L, "stack overflow"); + luaG_runerror(L, XorStr("stack overflow")); return ++L->ci; } @@ -223,7 +225,7 @@ void luaD_checkCstack(lua_State* L) const int hardlimit = LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3); if (L->nCcalls == LUAI_MAXCCALLS) - luaG_runerror(L, "C stack overflow"); + luaG_runerror(L, XorStr("C stack overflow")); else if (L->nCcalls >= hardlimit) luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ } @@ -239,15 +241,15 @@ void luaD_call(lua_State* L, StkId func, int nResults) if (++L->nCcalls >= LUAI_MAXCCALLS) luaD_checkCstack(L); - if (luau_precall(L, func, nResults) == PCRLUA) + if (lluz_precall(L, func, nResults) == PCRLUA) { /* is a Lua function? */ - L->ci->flags |= LUA_CALLINFO_RETURN; /* luau_execute will stop after returning from the stack frame */ + L->ci->flags |= LUA_CALLINFO_RETURN; /* lluz_execute will stop after returning from the stack frame */ int oldactive = luaC_threadactive(L); l_setbit(L->stackstate, THREAD_ACTIVEBIT); luaC_checkthreadsleep(L); - luau_execute(L); /* call it */ + lluz_execute(L); /* call it */ if (!oldactive) resetbit(L->stackstate, THREAD_ACTIVEBIT); @@ -286,13 +288,13 @@ static void resume_continue(lua_State* L) // unroll Lua/C combined stack, processing continuations while (L->status == 0 && L->ci > L->base_ci) { - LUAU_ASSERT(L->baseCcalls == L->nCcalls); + lluz_ASSERT(L->baseCcalls == L->nCcalls); Closure* cl = curr_func(L); if (cl->isC) { - LUAU_ASSERT(cl->c.cont); + lluz_ASSERT(cl->c.cont); // C continuation; we expect this to be followed by Lua continuations int n = cl->c.cont(L, 0); @@ -301,12 +303,12 @@ static void resume_continue(lua_State* L) if (L->status == LUA_BREAK) break; - luau_poscall(L, L->top - n); + lluz_poscall(L, L->top - n); } else { // Lua continuation; it terminates at the end of the stack or at another C continuation - luau_execute(L); + lluz_execute(L); } } } @@ -318,11 +320,11 @@ static void resume(lua_State* L, void* ud) if (L->status == 0) { // start coroutine - LUAU_ASSERT(L->ci == L->base_ci && firstArg >= L->base); + lluz_ASSERT(L->ci == L->base_ci && firstArg >= L->base); if (firstArg == L->base) - luaG_runerror(L, "cannot resume dead coroutine"); + luaG_runerror(L, XorStr("cannot resume dead coroutine")); - if (luau_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) + if (lluz_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) return; L->ci->flags |= LUA_CALLINFO_RETURN; @@ -330,7 +332,7 @@ static void resume(lua_State* L, void* ud) else { // resume from previous yield or break - LUAU_ASSERT(L->status == LUA_YIELD || L->status == LUA_BREAK); + lluz_ASSERT(L->status == LUA_YIELD || L->status == LUA_BREAK); L->status = 0; Closure* cl = curr_func(L); @@ -341,7 +343,7 @@ static void resume(lua_State* L, void* ud) if (!cl->c.cont) { // finish interrupted execution of `OP_CALL' - luau_poscall(L, firstArg); + lluz_poscall(L, firstArg); } } else @@ -375,9 +377,9 @@ static void resume_handle(lua_State* L, void* ud) CallInfo* ci = (CallInfo*)ud; Closure* cl = ci_func(ci); - LUAU_ASSERT(ci->flags & LUA_CALLINFO_HANDLE); - LUAU_ASSERT(cl->isC && cl->c.cont); - LUAU_ASSERT(L->status != 0); + lluz_ASSERT(ci->flags & LUA_CALLINFO_HANDLE); + lluz_ASSERT(cl->isC && cl->c.cont); + lluz_ASSERT(L->status != 0); // restore nCcalls back to base since this might not have happened during error handling L->nCcalls = L->baseCcalls; @@ -410,7 +412,7 @@ static void resume_handle(lua_State* L, void* ud) luaF_close(L, L->base); // finish cont call and restore stack to previous ci top - luau_poscall(L, L->top - n); + lluz_poscall(L, L->top - n); // run remaining continuations from the stack; typically resumes pcalls resume_continue(L); @@ -445,11 +447,11 @@ int lua_resume(lua_State* L, lua_State* from, int nargs) { int status; if (L->status != LUA_YIELD && L->status != LUA_BREAK && (L->status != 0 || L->ci != L->base_ci)) - return resume_error(L, "cannot resume non-suspended coroutine"); + return resume_error(L, XorStr("cannot resume non-suspended coroutine")); L->nCcalls = from ? from->nCcalls : 0; if (L->nCcalls >= LUAI_MAXCCALLS) - return resume_error(L, "C stack overflow"); + return resume_error(L, XorStr("C stack overflow")); L->baseCcalls = ++L->nCcalls; l_setbit(L->stackstate, THREAD_ACTIVEBIT); @@ -474,11 +476,11 @@ int lua_resumeerror(lua_State* L, lua_State* from) { int status; if (L->status != LUA_YIELD && L->status != LUA_BREAK && (L->status != 0 || L->ci != L->base_ci)) - return resume_error(L, "cannot resume non-suspended coroutine"); + return resume_error(L, XorStr("cannot resume non-suspended coroutine")); L->nCcalls = from ? from->nCcalls : 0; if (L->nCcalls >= LUAI_MAXCCALLS) - return resume_error(L, "C stack overflow"); + return resume_error(L, XorStr("C stack overflow")); L->baseCcalls = ++L->nCcalls; l_setbit(L->stackstate, THREAD_ACTIVEBIT); @@ -502,7 +504,7 @@ int lua_resumeerror(lua_State* L, lua_State* from) int lua_yield(lua_State* L, int nresults) { if (L->nCcalls > L->baseCcalls) - luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); + luaG_runerror(L, XorStr("attempt to yield across metamethod/C-call boundary")); L->base = L->top - nresults; /* protect stack slots below */ L->status = LUA_YIELD; return -1; @@ -511,7 +513,7 @@ int lua_yield(lua_State* L, int nresults) int lua_break(lua_State* L) { if (L->nCcalls > L->baseCcalls) - luaG_runerror(L, "attempt to break across metamethod/C-call boundary"); + luaG_runerror(L, XorStr("attempt to break across metamethod/C-call boundary")); L->status = LUA_BREAK; return -1; } @@ -533,7 +535,7 @@ static void callerrfunc(lua_State* L, void* ud) static void restore_stack_limit(lua_State* L) { - LUAU_ASSERT(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); + lluz_ASSERT(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ int inuse = cast_int(L->ci - L->base_ci); diff --git a/VM/src/ldo.h b/VM/src/ldo.h index 5e9472bf..c2c74dc0 100644 --- a/VM/src/ldo.h +++ b/VM/src/ldo.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -24,7 +24,7 @@ #define expandstacklimit(L, p) \ { \ - LUAU_ASSERT((p) <= (L)->stack_last); \ + lluz_ASSERT((p) <= (L)->stack_last); \ if ((L)->ci->top < (p)) \ (L)->ci->top = (p); \ } diff --git a/VM/src/lfunc.cpp b/VM/src/lfunc.cpp index 66447a95..6e7a256b 100644 --- a/VM/src/lfunc.cpp +++ b/VM/src/lfunc.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lfunc.h" @@ -71,7 +71,7 @@ UpVal* luaF_findupval(lua_State* L, StkId level) UpVal* p; while (*pp != NULL && (p = *pp)->v >= level) { - LUAU_ASSERT(p->v != &p->u.value); + lluz_ASSERT(p->v != &p->u.value); if (p->v == level) { /* found a corresponding upvalue? */ if (isdead(g, obj2gco(p))) /* is it dead? */ @@ -102,13 +102,13 @@ UpVal* luaF_findupval(lua_State* L, StkId level) uv->u.l.next = g->uvhead.u.l.next; uv->u.l.next->u.l.prev = uv; g->uvhead.u.l.next = uv; - LUAU_ASSERT(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + lluz_ASSERT(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); return uv; } void luaF_unlinkupval(UpVal* uv) { // unlink upvalue from the global open upvalue list - LUAU_ASSERT(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + lluz_ASSERT(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); uv->u.l.next->u.l.prev = uv->u.l.prev; uv->u.l.prev->u.l.next = uv->u.l.next; @@ -133,7 +133,7 @@ void luaF_close(lua_State* L, StkId level) while (L->openupval != NULL && (uv = L->openupval)->v >= level) { GCObject* o = obj2gco(uv); - LUAU_ASSERT(!isblack(o) && uv->v != &uv->u.value); + lluz_ASSERT(!isblack(o) && uv->v != &uv->u.value); // by removing the upvalue from global/thread open upvalue lists, L->openupval will be pointing to the next upvalue luaF_unlinkupval(uv); diff --git a/VM/src/lfunc.h b/VM/src/lfunc.h index a260d00a..7e63d01d 100644 --- a/VM/src/lfunc.h +++ b/VM/src/lfunc.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once diff --git a/VM/src/lgc.cpp b/VM/src/lgc.cpp index 70b4dbf9..280def11 100644 --- a/VM/src/lgc.cpp +++ b/VM/src/lgc.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lgc.h" @@ -11,6 +11,8 @@ #include "lmem.h" #include "ludata.h" +#include "..\..\..\..\Security\XorString.h" + #include #define GC_SWEEPPAGESTEPCOST 16 @@ -18,7 +20,7 @@ #define GC_INTERRUPT(state) \ { \ void (*interrupt)(lua_State*, int) = g->cb.interrupt; \ - if (LUAU_UNLIKELY(!!interrupt)) \ + if (lluz_UNLIKELY(!!interrupt)) \ interrupt(L, state); \ } @@ -78,7 +80,7 @@ static void recordGcStateStep(global_State* g, int startgcstate, double seconds, g->gcmetrics.currcycle.sweepassisttime += seconds; break; default: - LUAU_ASSERT(!"Unexpected GC state"); + lluz_ASSERT(!XorStr("Unexpected GC state")); } if (assist) @@ -123,14 +125,14 @@ static void finishGcCycleMetrics(global_State* g) static void removeentry(LuaNode* n) { - LUAU_ASSERT(ttisnil(gval(n))); + lluz_ASSERT(ttisnil(gval(n))); if (iscollectable(gkey(n))) setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ } static void reallymarkobject(global_State* g, GCObject* o) { - LUAU_ASSERT(iswhite(o) && !isdead(g, o)); + lluz_ASSERT(iswhite(o) && !isdead(g, o)); white2gray(o); switch (o->gch.tt) { @@ -179,7 +181,7 @@ static void reallymarkobject(global_State* g, GCObject* o) break; } default: - LUAU_ASSERT(0); + lluz_ASSERT(0); } } @@ -225,12 +227,12 @@ static int traversetable(global_State* g, Table* h) while (i--) { LuaNode* n = gnode(h, i); - LUAU_ASSERT(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + lluz_ASSERT(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); if (ttisnil(gval(n))) removeentry(n); /* remove empty entries */ else { - LUAU_ASSERT(!ttisnil(gkey(n))); + lluz_ASSERT(!ttisnil(gkey(n))); if (!weakkey) markvalue(g, gkey(n)); if (!weakvalue) @@ -282,7 +284,7 @@ static void traverseclosure(global_State* g, Closure* cl) else { int i; - LUAU_ASSERT(cl->nupvalues == cl->l.p->nups); + lluz_ASSERT(cl->nupvalues == cl->l.p->nups); markobject(g, cast_to(Proto*, cl->l.p)); for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ markvalue(g, &cl->l.uprefs[i]); @@ -312,7 +314,7 @@ static void traversestack(global_State* g, lua_State* l, bool clearstack) static size_t propagatemark(global_State* g) { GCObject* o = g->gray; - LUAU_ASSERT(isgray(o)); + lluz_ASSERT(isgray(o)); gray2black(o); switch (o->gch.tt) { @@ -336,7 +338,7 @@ static size_t propagatemark(global_State* g) lua_State* th = gco2th(o); g->gray = th->gclist; - LUAU_ASSERT(!luaC_threadsleeping(th)); + lluz_ASSERT(!luaC_threadsleeping(th)); // threads that are executing and the main thread are not deactivated bool active = luaC_threadactive(th) || th == th->global->mainthread; @@ -368,7 +370,7 @@ static size_t propagatemark(global_State* g) sizeof(LocVar) * p->sizelocvars + sizeof(TString*) * p->sizeupvalues; } default: - LUAU_ASSERT(0); + lluz_ASSERT(0); return 0; } } @@ -464,7 +466,7 @@ static void shrinkstack(lua_State* L) StkId lim = L->top; for (CallInfo* ci = L->base_ci; ci <= L->ci; ci++) { - LUAU_ASSERT(ci->top <= L->stack_last); + lluz_ASSERT(ci->top <= L->stack_last); if (lim < ci->top) lim = ci->top; } @@ -499,17 +501,17 @@ static void freeobj(lua_State* L, GCObject* o, lua_Page* page) luaH_free(L, gco2h(o), page); break; case LUA_TTHREAD: - LUAU_ASSERT(gco2th(o) != L && gco2th(o) != L->global->mainthread); + lluz_ASSERT(gco2th(o) != L && gco2th(o) != L->global->mainthread); luaE_freethread(L, gco2th(o), page); break; case LUA_TSTRING: luaS_free(L, gco2ts(o), page); break; case LUA_TUSERDATA: - luaU_freeudata(L, gco2u(o), page); + lluz_freeudata(L, gco2u(o), page); break; default: - LUAU_ASSERT(0); + lluz_ASSERT(0); } } @@ -558,15 +560,15 @@ void luaC_freeall(lua_State* L) { global_State* g = L->global; - LUAU_ASSERT(L == g->mainthread); + lluz_ASSERT(L == g->mainthread); luaM_visitgco(L, L, deletegco); - for (int i = 0; i < g->strt.size; i++) /* free all string lists */ - LUAU_ASSERT(g->strt.hash[i] == NULL); + for (int i = 0; i < g->strt.size; i++) // free all string lists + lluz_ASSERT(g->strt.hash[i] == NULL); - LUAU_ASSERT(L->global->strt.nuse == 0); - LUAU_ASSERT(g->strbufgc == NULL); + lluz_ASSERT(L->global->strt.nuse == 0); + lluz_ASSERT(g->strbufgc == NULL); } static void markmt(global_State* g) @@ -585,7 +587,7 @@ static void markroot(lua_State* L) g->grayagain = NULL; g->weak = NULL; markobject(g, g->mainthread); - /* make global table be traversed before main stack */ + // make global table be traversed before main stack markobject(g, g->mainthread->gt); markvalue(g, registry(L)); markmt(g); @@ -598,7 +600,7 @@ static size_t remarkupvals(global_State* g) for (UpVal* uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { work += sizeof(UpVal); - LUAU_ASSERT(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + lluz_ASSERT(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); if (isgray(obj2gco(uv))) markvalue(g, uv->v); } @@ -608,7 +610,7 @@ static size_t remarkupvals(global_State* g) static size_t atomic(lua_State* L) { global_State* g = L->global; - LUAU_ASSERT(g->gcstate == GCSatomic); + lluz_ASSERT(g->gcstate == GCSatomic); size_t work = 0; @@ -628,7 +630,7 @@ static size_t atomic(lua_State* L) /* remark weak tables */ g->gray = g->weak; g->weak = NULL; - LUAU_ASSERT(!iswhite(obj2gco(g->mainthread))); + lluz_ASSERT(!iswhite(obj2gco(g->mainthread))); markobject(g, L); /* mark running thread */ markmt(g); /* mark basic metatables (again) */ work += propagateall(g); @@ -667,7 +669,7 @@ static bool sweepgco(lua_State* L, lua_Page* page, GCObject* gco) global_State* g = L->global; int deadmask = otherwhite(g); - LUAU_ASSERT(testbit(deadmask, FIXEDBIT)); // make sure we never sweep fixed objects + lluz_ASSERT(testbit(deadmask, FIXEDBIT)); // make sure we never sweep fixed objects int alive = (gco->gch.marked ^ WHITEBITS) & deadmask; @@ -684,12 +686,12 @@ static bool sweepgco(lua_State* L, lua_Page* page, GCObject* gco) if (alive) { - LUAU_ASSERT(!isdead(g, gco)); + lluz_ASSERT(!isdead(g, gco)); makewhite(g, gco); // make it white (for next cycle) return false; } - LUAU_ASSERT(isdead(g, gco)); + lluz_ASSERT(isdead(g, gco)); freeobj(L, gco, page); return true; } @@ -714,7 +716,7 @@ static int sweepgcopage(lua_State* L, lua_Page* page) // when true is returned it means that the element was deleted if (sweepgco(L, page, gco)) { - LUAU_ASSERT(busyBlocks > 0); + lluz_ASSERT(busyBlocks > 0); // if the last block was removed, page would be removed as well if (--busyBlocks == 0) @@ -734,7 +736,7 @@ static size_t gcstep(lua_State* L, size_t limit) case GCSpause: { markroot(L); /* start a new collection */ - LUAU_ASSERT(g->gcstate == GCSpropagate); + lluz_ASSERT(g->gcstate == GCSpropagate); break; } case GCSpropagate: @@ -788,7 +790,7 @@ static size_t gcstep(lua_State* L, size_t limit) cost = atomic(L); /* finish mark phase */ - LUAU_ASSERT(g->gcstate == GCSsweep); + lluz_ASSERT(g->gcstate == GCSsweep); break; } case GCSsweep: @@ -815,7 +817,7 @@ static size_t gcstep(lua_State* L, size_t limit) break; } default: - LUAU_ASSERT(!"Unexpected GC state"); + lluz_ASSERT(!"Unexpected GC state"); } return cost; } @@ -876,64 +878,7 @@ static size_t getheaptrigger(global_State* g, size_t heapgoal) size_t luaC_step(lua_State* L, bool assist) { - global_State* g = L->global; - - int lim = g->gcstepsize * g->gcstepmul / 100; /* how much to work */ - LUAU_ASSERT(g->totalbytes >= g->GCthreshold); - size_t debt = g->totalbytes - g->GCthreshold; - - GC_INTERRUPT(0); - - // at the start of the new cycle - if (g->gcstate == GCSpause) - g->gcstats.starttimestamp = lua_clock(); - -#ifdef LUAI_GCMETRICS - if (g->gcstate == GCSpause) - startGcCycleMetrics(g); - - double lasttimestamp = lua_clock(); -#endif - - int lastgcstate = g->gcstate; - - size_t work = gcstep(L, lim); - -#ifdef LUAI_GCMETRICS - recordGcStateStep(g, lastgcstate, lua_clock() - lasttimestamp, assist, work); -#endif - - size_t actualstepsize = work * 100 / g->gcstepmul; - - // at the end of the last cycle - if (g->gcstate == GCSpause) - { - // at the end of a collection cycle, set goal based on gcgoal setting - size_t heapgoal = (g->totalbytes / 100) * g->gcgoal; - size_t heaptrigger = getheaptrigger(g, heapgoal); - - g->GCthreshold = heaptrigger; - - g->gcstats.heapgoalsizebytes = heapgoal; - g->gcstats.endtimestamp = lua_clock(); - g->gcstats.endtotalsizebytes = g->totalbytes; - -#ifdef LUAI_GCMETRICS - finishGcCycleMetrics(g); -#endif - } - else - { - g->GCthreshold = g->totalbytes + actualstepsize; - - // compensate if GC is "behind schedule" (has some debt to pay) - if (g->GCthreshold >= debt) - g->GCthreshold -= debt; - } - - GC_INTERRUPT(lastgcstate); - - return actualstepsize; + return 0; } void luaC_fullgc(lua_State* L) @@ -955,11 +900,11 @@ void luaC_fullgc(lua_State* L) g->weak = NULL; g->gcstate = GCSsweep; } - LUAU_ASSERT(g->gcstate == GCSsweep); + lluz_ASSERT(g->gcstate == GCSsweep); /* finish any pending sweep phase */ while (g->gcstate != GCSpause) { - LUAU_ASSERT(g->gcstate == GCSsweep); + lluz_ASSERT(g->gcstate == GCSsweep); gcstep(L, SIZE_MAX); } @@ -1000,7 +945,7 @@ void luaC_fullgc(lua_State* L) void luaC_barrierupval(lua_State* L, GCObject* v) { global_State* g = L->global; - LUAU_ASSERT(iswhite(v) && !isdead(g, v)); + lluz_ASSERT(iswhite(v) && !isdead(g, v)); if (keepinvariant(g)) reallymarkobject(g, v); @@ -1009,8 +954,8 @@ void luaC_barrierupval(lua_State* L, GCObject* v) void luaC_barrierf(lua_State* L, GCObject* o, GCObject* v) { global_State* g = L->global; - LUAU_ASSERT(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); - LUAU_ASSERT(g->gcstate != GCSpause); + lluz_ASSERT(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lluz_ASSERT(g->gcstate != GCSpause); /* must keep invariant? */ if (keepinvariant(g)) reallymarkobject(g, v); /* restore invariant */ @@ -1026,13 +971,13 @@ void luaC_barriertable(lua_State* L, Table* t, GCObject* v) // in the second propagation stage, table assignment barrier works as a forward barrier if (g->gcstate == GCSpropagateagain) { - LUAU_ASSERT(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lluz_ASSERT(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); reallymarkobject(g, v); return; } - LUAU_ASSERT(isblack(o) && !isdead(g, o)); - LUAU_ASSERT(g->gcstate != GCSpause); + lluz_ASSERT(isblack(o) && !isdead(g, o)); + lluz_ASSERT(g->gcstate != GCSpause); black2gray(o); /* make table gray (again) */ t->gclist = g->grayagain; g->grayagain = o; @@ -1042,8 +987,8 @@ void luaC_barrierback(lua_State* L, Table* t) { global_State* g = L->global; GCObject* o = obj2gco(t); - LUAU_ASSERT(isblack(o) && !isdead(g, o)); - LUAU_ASSERT(g->gcstate != GCSpause); + lluz_ASSERT(isblack(o) && !isdead(g, o)); + lluz_ASSERT(g->gcstate != GCSpause); black2gray(o); /* make table gray (again) */ t->gclist = g->grayagain; g->grayagain = o; @@ -1072,7 +1017,7 @@ void luaC_initupval(lua_State* L, UpVal* uv) else { /* sweep phase: sweep it (turning it into white) */ makewhite(g, o); - LUAU_ASSERT(g->gcstate != GCSpause); + lluz_ASSERT(g->gcstate != GCSpause); } } } @@ -1128,19 +1073,19 @@ const char* luaC_statename(int state) switch (state) { case GCSpause: - return "pause"; + return XorStr("pause"); case GCSpropagate: - return "mark"; + return XorStr("mark"); case GCSpropagateagain: - return "remark"; + return XorStr("remark"); case GCSatomic: - return "atomic"; + return XorStr("atomic"); case GCSsweep: - return "sweep"; + return XorStr("sweep"); default: return NULL; diff --git a/VM/src/lgc.h b/VM/src/lgc.h index 797284a2..c3e62638 100644 --- a/VM/src/lgc.h +++ b/VM/src/lgc.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once diff --git a/VM/src/lgcdebug.cpp b/VM/src/lgcdebug.cpp index 2b38619b..fb051877 100644 --- a/VM/src/lgcdebug.cpp +++ b/VM/src/lgcdebug.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lgc.h" @@ -10,17 +10,19 @@ #include "ltable.h" #include "ludata.h" +#include "..\..\..\..\Security\XorString.h" + #include #include static void validateobjref(global_State* g, GCObject* f, GCObject* t) { - LUAU_ASSERT(!isdead(g, t)); + lluz_ASSERT(!isdead(g, t)); if (keepinvariant(g)) { /* basic incremental invariant: black can't point to white */ - LUAU_ASSERT(!(isblack(f) && iswhite(t))); + lluz_ASSERT(!(isblack(f) && iswhite(t))); } } @@ -28,7 +30,7 @@ static void validateref(global_State* g, GCObject* f, TValue* v) { if (iscollectable(v)) { - LUAU_ASSERT(ttype(v) == gcvalue(v)->gch.tt); + lluz_ASSERT(ttype(v) == gcvalue(v)->gch.tt); validateobjref(g, f, gcvalue(v)); } } @@ -37,7 +39,7 @@ static void validatetable(global_State* g, Table* h) { int sizenode = 1 << h->lsizenode; - LUAU_ASSERT(h->lastfree <= sizenode); + lluz_ASSERT(h->lastfree <= sizenode); if (h->metatable) validateobjref(g, obj2gco(h), obj2gco(h->metatable)); @@ -49,8 +51,8 @@ static void validatetable(global_State* g, Table* h) { LuaNode* n = &h->node[i]; - LUAU_ASSERT(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); - LUAU_ASSERT(i + gnext(n) >= 0 && i + gnext(n) < sizenode); + lluz_ASSERT(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + lluz_ASSERT(i + gnext(n) >= 0 && i + gnext(n) < sizenode); if (!ttisnil(gval(n))) { @@ -75,7 +77,7 @@ static void validateclosure(global_State* g, Closure* cl) } else { - LUAU_ASSERT(cl->nupvalues == cl->l.p->nups); + lluz_ASSERT(cl->nupvalues == cl->l.p->nups); validateobjref(g, obj2gco(cl), obj2gco(cl->l.p)); @@ -90,9 +92,9 @@ static void validatestack(global_State* g, lua_State* l) for (CallInfo* ci = l->base_ci; ci <= l->ci; ++ci) { - LUAU_ASSERT(l->stack <= ci->base); - LUAU_ASSERT(ci->func <= ci->base && ci->base <= ci->top); - LUAU_ASSERT(ci->top <= l->stack_last); + lluz_ASSERT(l->stack <= ci->base); + lluz_ASSERT(ci->func <= ci->base && ci->base <= ci->top); + lluz_ASSERT(ci->top <= l->stack_last); } // note: stack refs can violate gc invariant so we only check for liveness @@ -104,8 +106,8 @@ static void validatestack(global_State* g, lua_State* l) for (UpVal* uv = l->openupval; uv; uv = uv->u.l.threadnext) { - LUAU_ASSERT(uv->tt == LUA_TUPVAL); - LUAU_ASSERT(uv->v != &uv->u.value); + lluz_ASSERT(uv->tt == LUA_TUPVAL); + lluz_ASSERT(uv->v != &uv->u.value); } } @@ -138,7 +140,7 @@ static void validateobj(global_State* g, GCObject* o) /* dead objects can only occur during sweep */ if (isdead(g, o)) { - LUAU_ASSERT(g->gcstate == GCSsweep); + lluz_ASSERT(g->gcstate == GCSsweep); return; } @@ -173,7 +175,7 @@ static void validateobj(global_State* g, GCObject* o) break; default: - LUAU_ASSERT(!"unexpected object type"); + lluz_ASSERT(!"unexpected object type"); } } @@ -184,7 +186,7 @@ static void validategraylist(global_State* g, GCObject* o) while (o) { - LUAU_ASSERT(isgray(o)); + lluz_ASSERT(isgray(o)); switch (o->gch.tt) { @@ -201,7 +203,7 @@ static void validategraylist(global_State* g, GCObject* o) o = gco2p(o)->gclist; break; default: - LUAU_ASSERT(!"unknown object in gray list"); + lluz_ASSERT(!"unknown object in gray list"); return; } } @@ -220,12 +222,12 @@ void luaC_validate(lua_State* L) { global_State* g = L->global; - LUAU_ASSERT(!isdead(g, obj2gco(g->mainthread))); + lluz_ASSERT(!isdead(g, obj2gco(g->mainthread))); checkliveness(g, &g->registry); for (int i = 0; i < LUA_T_COUNT; ++i) if (g->mt[i]) - LUAU_ASSERT(!isdead(g, obj2gco(g->mt[i]))); + lluz_ASSERT(!isdead(g, obj2gco(g->mt[i]))); validategraylist(g, g->weak); validategraylist(g, g->gray); @@ -237,9 +239,9 @@ void luaC_validate(lua_State* L) for (UpVal* uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { - LUAU_ASSERT(uv->tt == LUA_TUPVAL); - LUAU_ASSERT(uv->v != &uv->u.value); - LUAU_ASSERT(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + lluz_ASSERT(uv->tt == LUA_TUPVAL); + lluz_ASSERT(uv->v != &uv->u.value); + lluz_ASSERT(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); } } @@ -280,7 +282,7 @@ static void dumpstring(FILE* f, TString* ts) { fprintf(f, "{\"type\":\"string\",\"cat\":%d,\"size\":%d,\"data\":\"", ts->memcat, int(sizestring(ts->len))); dumpstringdata(f, ts->data, ts->len); - fprintf(f, "\"}"); + fprintf(f, XorStr("\"}")); } static void dumptable(FILE* f, Table* h) @@ -291,7 +293,7 @@ static void dumptable(FILE* f, Table* h) if (h->node != &luaH_dummynode) { - fprintf(f, ",\"pairs\":["); + fprintf(f, XorStr(",\"pairs\":[")); bool first = true; @@ -308,31 +310,31 @@ static void dumptable(FILE* f, Table* h) if (iscollectable(&n.key)) dumpref(f, gcvalue(&n.key)); else - fprintf(f, "null"); + fprintf(f, XorStr("null")); fputc(',', f); if (iscollectable(&n.val)) dumpref(f, gcvalue(&n.val)); else - fprintf(f, "null"); + fprintf(f, XorStr("null")); } } - fprintf(f, "]"); + fprintf(f, XorStr("]")); } if (h->sizearray) { - fprintf(f, ",\"array\":["); + fprintf(f, XorStr(",\"array\":[")); dumprefs(f, h->array, h->sizearray); - fprintf(f, "]"); + fprintf(f, XorStr("]")); } if (h->metatable) { - fprintf(f, ",\"metatable\":"); + fprintf(f, XorStr(",\"metatable\":")); dumpref(f, obj2gco(h->metatable)); } - fprintf(f, "}"); + fprintf(f, XorStr("}")); } static void dumpclosure(FILE* f, Closure* cl) @@ -340,30 +342,30 @@ static void dumpclosure(FILE* f, Closure* cl) fprintf(f, "{\"type\":\"function\",\"cat\":%d,\"size\":%d", cl->memcat, cl->isC ? int(sizeCclosure(cl->nupvalues)) : int(sizeLclosure(cl->nupvalues))); - fprintf(f, ",\"env\":"); + fprintf(f, XorStr(",\"env\":")); dumpref(f, obj2gco(cl->env)); if (cl->isC) { if (cl->nupvalues) { - fprintf(f, ",\"upvalues\":["); + fprintf(f, XorStr(",\"upvalues\":[")); dumprefs(f, cl->c.upvals, cl->nupvalues); - fprintf(f, "]"); + fprintf(f, XorStr("]")); } } else { - fprintf(f, ",\"proto\":"); + fprintf(f, XorStr(",\"proto\":")); dumpref(f, obj2gco(cl->l.p)); if (cl->nupvalues) { - fprintf(f, ",\"upvalues\":["); + fprintf(f, XorStr(",\"upvalues\":[")); dumprefs(f, cl->l.uprefs, cl->nupvalues); - fprintf(f, "]"); + fprintf(f, XorStr("]")); } } - fprintf(f, "}"); + fprintf(f, XorStr("}")); } static void dumpudata(FILE* f, Udata* u) @@ -372,10 +374,10 @@ static void dumpudata(FILE* f, Udata* u) if (u->metatable) { - fprintf(f, ",\"metatable\":"); + fprintf(f, XorStr(",\"metatable\":")); dumpref(f, obj2gco(u->metatable)); } - fprintf(f, "}"); + fprintf(f, XorStr("}")); } static void dumpthread(FILE* f, lua_State* th) @@ -384,7 +386,7 @@ static void dumpthread(FILE* f, lua_State* th) fprintf(f, "{\"type\":\"thread\",\"cat\":%d,\"size\":%d", th->memcat, int(size)); - fprintf(f, ",\"env\":"); + fprintf(f, XorStr(",\"env\":")); dumpref(f, obj2gco(th->gt)); Closure* tcl = 0; @@ -401,18 +403,18 @@ static void dumpthread(FILE* f, lua_State* th) { Proto* p = tcl->l.p; - fprintf(f, ",\"source\":\""); + fprintf(f, XorStr(",\"source\":\"")); dumpstringdata(f, p->source->data, p->source->len); fprintf(f, "\",\"line\":%d", p->abslineinfo ? p->abslineinfo[0] : 0); } if (th->top > th->stack) { - fprintf(f, ",\"stack\":["); + fprintf(f, XorStr(",\"stack\":[")); dumprefs(f, th->stack, th->top - th->stack); - fprintf(f, "]"); + fprintf(f, XorStr("]")); } - fprintf(f, "}"); + fprintf(f, XorStr("}")); } static void dumpproto(FILE* f, Proto* p) @@ -424,31 +426,31 @@ static void dumpproto(FILE* f, Proto* p) if (p->source) { - fprintf(f, ",\"source\":\""); + fprintf(f, XorStr(",\"source\":\"")); dumpstringdata(f, p->source->data, p->source->len); fprintf(f, "\",\"line\":%d", p->abslineinfo ? p->abslineinfo[0] : 0); } if (p->sizek) { - fprintf(f, ",\"constants\":["); + fprintf(f, XorStr(",\"constants\":[")); dumprefs(f, p->k, p->sizek); - fprintf(f, "]"); + fprintf(f, XorStr("]")); } if (p->sizep) { - fprintf(f, ",\"protos\":["); + fprintf(f, XorStr(",\"protos\":[")); for (int i = 0; i < p->sizep; ++i) { if (i != 0) fputc(',', f); dumpref(f, obj2gco(p->p[i])); } - fprintf(f, "]"); + fprintf(f, XorStr("]")); } - fprintf(f, "}"); + fprintf(f, XorStr("}")); } static void dumpupval(FILE* f, UpVal* uv) @@ -457,10 +459,10 @@ static void dumpupval(FILE* f, UpVal* uv) if (iscollectable(uv->v)) { - fprintf(f, ",\"object\":"); + fprintf(f, XorStr(",\"object\":")); dumpref(f, gcvalue(uv->v)); } - fprintf(f, "}"); + fprintf(f, XorStr("}")); } static void dumpobj(FILE* f, GCObject* o) @@ -489,7 +491,7 @@ static void dumpobj(FILE* f, GCObject* o) return dumpupval(f, gco2uv(o)); default: - LUAU_ASSERT(0); + lluz_ASSERT(0); } } @@ -511,24 +513,24 @@ void luaC_dump(lua_State* L, void* file, const char* (*categoryName)(lua_State* global_State* g = L->global; FILE* f = static_cast(file); - fprintf(f, "{\"objects\":{\n"); + fprintf(f, XorStr("{\"objects\":{\n")); dumpgco(f, NULL, obj2gco(g->mainthread)); luaM_visitgco(L, f, dumpgco); - fprintf(f, "\"0\":{\"type\":\"userdata\",\"cat\":0,\"size\":0}\n"); // to avoid issues with trailing , - fprintf(f, "},\"roots\":{\n"); - fprintf(f, "\"mainthread\":"); + fprintf(f, XorStr("\"0\":{\"type\":\"userdata\",\"cat\":0,\"size\":0}\n")); // to avoid issues with trailing , + fprintf(f, XorStr("},\"roots\":{\n")); + fprintf(f, XorStr("\"mainthread\":")); dumpref(f, obj2gco(g->mainthread)); - fprintf(f, ",\"registry\":"); + fprintf(f, XorStr(",\"registry\":")); dumpref(f, gcvalue(&g->registry)); - fprintf(f, "},\"stats\":{\n"); + fprintf(f, XorStr("},\"stats\":{\n")); fprintf(f, "\"size\":%d,\n", int(g->totalbytes)); - fprintf(f, "\"categories\":{\n"); + fprintf(f, XorStr("\"categories\":{\n")); for (int i = 0; i < LUA_MEMORY_CATEGORIES; i++) { if (size_t bytes = g->memcatbytes[i]) @@ -539,7 +541,7 @@ void luaC_dump(lua_State* L, void* file, const char* (*categoryName)(lua_State* fprintf(f, "\"%d\":{\"size\":%d},\n", i, int(bytes)); } } - fprintf(f, "\"none\":{}\n"); // to avoid issues with trailing , - fprintf(f, "}\n"); - fprintf(f, "}}\n"); + fprintf(f, XorStr("\"none\":{}\n")); // to avoid issues with trailing , + fprintf(f, XorStr("}\n")); + fprintf(f, XorStr("}}\n")); } diff --git a/VM/src/linit.cpp b/VM/src/linit.cpp index fd95f596..ec137527 100644 --- a/VM/src/linit.cpp +++ b/VM/src/linit.cpp @@ -1,7 +1,9 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" +#include "..\..\..\..\Security\XorString.h" + #include static const luaL_Reg lualibs[] = { @@ -58,7 +60,7 @@ void luaL_sandboxthread(lua_State* L) lua_newtable(L); lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setfield(L, -2, "__index"); + lua_setfield(L, -2, XorStr("__index")); lua_setreadonly(L, -1, true); lua_setmetatable(L, -2); diff --git a/VM/src/lmathlib.cpp b/VM/src/lmathlib.cpp index a6e7b494..7b480dfb 100644 --- a/VM/src/lmathlib.cpp +++ b/VM/src/lmathlib.cpp @@ -1,9 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" #include "lstate.h" +#include "..\..\..\..\Security\XorString.h" + #include #include @@ -241,7 +243,7 @@ static int math_random(lua_State* L) case 1: { /* only upper limit */ int u = luaL_checkinteger(L, 1); - luaL_argcheck(L, 1 <= u, 1, "interval is empty"); + luaL_argcheck(L, 1 <= u, 1, XorStr("interval is empty")); uint64_t x = uint64_t(u) * pcg32_random(&g->rngstate); int r = int(1 + (x >> 32)); @@ -252,17 +254,17 @@ static int math_random(lua_State* L) { /* lower and upper limits */ int l = luaL_checkinteger(L, 1); int u = luaL_checkinteger(L, 2); - luaL_argcheck(L, l <= u, 2, "interval is empty"); + luaL_argcheck(L, l <= u, 2, XorStr("interval is empty")); uint32_t ul = uint32_t(u) - uint32_t(l); - luaL_argcheck(L, ul < UINT_MAX, 2, "interval is too large"); // -INT_MIN..INT_MAX interval can result in integer overflow + luaL_argcheck(L, ul < UINT_MAX, 2, XorStr("interval is too large")); // -INT_MIN..INT_MAX interval can result in integer overflow uint64_t x = uint64_t(ul + 1) * pcg32_random(&g->rngstate); int r = int(l + (x >> 32)); lua_pushinteger(L, r); /* int between `l' and `u' */ break; } default: - luaL_error(L, "wrong number of arguments"); + luaL_error(L, XorStr("wrong number of arguments")); } return 1; } @@ -367,7 +369,7 @@ static int math_clamp(lua_State* L) double min = luaL_checknumber(L, 2); double max = luaL_checknumber(L, 3); - luaL_argcheck(L, min <= max, 3, "max must be greater than or equal to min"); + luaL_argcheck(L, min <= max, 3, XorStr("max must be greater than or equal to min")); double r = v < min ? min : v; r = r > max ? max : r; @@ -390,38 +392,38 @@ static int math_round(lua_State* L) } static const luaL_Reg mathlib[] = { - {"abs", math_abs}, - {"acos", math_acos}, - {"asin", math_asin}, - {"atan2", math_atan2}, - {"atan", math_atan}, - {"ceil", math_ceil}, - {"cosh", math_cosh}, - {"cos", math_cos}, - {"deg", math_deg}, - {"exp", math_exp}, - {"floor", math_floor}, - {"fmod", math_fmod}, - {"frexp", math_frexp}, - {"ldexp", math_ldexp}, - {"log10", math_log10}, - {"log", math_log}, - {"max", math_max}, - {"min", math_min}, - {"modf", math_modf}, - {"pow", math_pow}, - {"rad", math_rad}, - {"random", math_random}, - {"randomseed", math_randomseed}, - {"sinh", math_sinh}, - {"sin", math_sin}, - {"sqrt", math_sqrt}, - {"tanh", math_tanh}, - {"tan", math_tan}, - {"noise", math_noise}, - {"clamp", math_clamp}, - {"sign", math_sign}, - {"round", math_round}, + {XorStr("abs"), math_abs}, + {XorStr("acos"), math_acos}, + {XorStr("asin"), math_asin}, + {XorStr("atan2"), math_atan2}, + {XorStr("atan"), math_atan}, + {XorStr("ceil"), math_ceil}, + {XorStr("cosh"), math_cosh}, + {XorStr("cos"), math_cos}, + {XorStr("deg"), math_deg}, + {XorStr("exp"), math_exp}, + {XorStr("floor"), math_floor}, + {XorStr("fmod"), math_fmod}, + {XorStr("frexp"), math_frexp}, + {XorStr("ldexp"), math_ldexp}, + {XorStr("log10"), math_log10}, + {XorStr("log"), math_log}, + {XorStr("max"), math_max}, + {XorStr("min"), math_min}, + {XorStr("modf"), math_modf}, + {XorStr("pow"), math_pow}, + {XorStr("rad"), math_rad}, + {XorStr("random"), math_random}, + {XorStr("randomseed"), math_randomseed}, + {XorStr("sinh"), math_sinh}, + {XorStr("sin"), math_sin}, + {XorStr("sqrt"), math_sqrt}, + {XorStr("tanh"), math_tanh}, + {XorStr("tan"), math_tan}, + {XorStr("noise"), math_noise}, + {XorStr("clamp"), math_clamp}, + {XorStr("sign"), math_sign}, + {XorStr("round"), math_round}, {NULL, NULL}, }; @@ -438,8 +440,8 @@ int luaopen_math(lua_State* L) luaL_register(L, LUA_MATHLIBNAME, mathlib); lua_pushnumber(L, PI); - lua_setfield(L, -2, "pi"); + lua_setfield(L, -2, XorStr("pi")); lua_pushnumber(L, HUGE_VAL); - lua_setfield(L, -2, "huge"); + lua_setfield(L, -2, XorStr("huge")); return 1; } diff --git a/VM/src/lmem.cpp b/VM/src/lmem.cpp index 3cbdafff..6bf6c4eb 100644 --- a/VM/src/lmem.cpp +++ b/VM/src/lmem.cpp @@ -1,88 +1,28 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lmem.h" +#pragma once #include "lstate.h" #include "ldo.h" #include "ldebug.h" +//#include "..\..\..\..\Security\XorString.h" +#include #include -/* - * Luau heap uses a size-segregated page structure, with individual pages and large allocations - * allocated using system heap (via frealloc callback). - * - * frealloc callback serves as a general, if slow, allocation callback that can allocate, free or - * resize allocations: - * - * void* frealloc(void* ud, void* ptr, size_t oldsize, size_t newsize); - * - * frealloc(ud, NULL, 0, x) creates a new block of size x - * frealloc(ud, p, x, 0) frees the block p (must return NULL) - * frealloc(ud, NULL, 0, 0) does nothing, equivalent to free(NULL) - * - * frealloc returns NULL if it cannot create or reallocate the area - * (any reallocation to an equal or smaller size cannot fail!) - * - * On top of this, Luau implements heap storage which is split into two types of allocations: - * - * - GCO, short for "garbage collected objects" - * - other objects (for example, arrays stored inside table objects) - * - * The heap layout for these two allocation types is a bit different. - * - * All GCO are allocated in pages, which is a block of memory of ~16K in size that has a page header - * (lua_Page). Each page contains 1..N blocks of the same size, where N is selected to fill the page - * completely. This amortizes the allocation cost and increases locality. Each GCO block starts with - * the GC header (GCheader) which contains the object type, mark bits and other GC metadata. If the - * GCO block is free (not used), then it must have the type set to TNIL; in this case the block can - * be part of the per-page free list, the link for that list is stored after the header (freegcolink). - * - * Importantly, the GCO block doesn't have any back references to the page it's allocated in, so it's - * impossible to free it in isolation - GCO blocks are freed by sweeping the pages they belong to, - * using luaM_freegco which must specify the page; this is called by page sweeper that traverses the - * entire page's worth of objects. For this reason it's also important that freed GCO blocks keep the - * GC header intact and accessible (with type = NIL) so that the sweeper can access it. - * - * Some GCOs are too large to fit in a 16K page without excessive fragmentation (the size threshold is - * currently 512 bytes); in this case, we allocate a dedicated small page with just a single block's worth - * storage space, but that requires allocating an extra page header. In effect large GCOs are a little bit - * less memory efficient, but this allows us to uniformly sweep small and large GCOs using page lists. - * - * All GCO pages are linked in a large intrusive linked list (global_State::allgcopages). Additionally, - * for each block size there's a page free list that contains pages that have at least one free block - * (global_State::freegcopages). This free list is used to make sure object allocation is O(1). - * - * Compared to GCOs, regular allocations have two important differences: they can be freed in isolation, - * and they don't start with a GC header. Because of this, each allocation is prefixed with block metadata, - * which contains the pointer to the page for allocated blocks, and the pointer to the next free block - * inside the page for freed blocks. - * For regular allocations that are too large to fit in a page (using the same threshold of 512 bytes), - * we don't allocate a separate page, instead simply using frealloc to allocate a vanilla block of memory. - * - * Just like GCO pages, we store a page free list (global_State::freepages) that allows O(1) allocation; - * there is no global list for non-GCO pages since we never need to traverse them directly. - * - * In both cases, we pick the page by computing the size class from the block size which rounds the block - * size up to reduce the chance that we'll allocate pages that have very few allocated blocks. The size - * class strategy is determined by SizeClassConfig constructor. - * - * Note that when the last block in a page is freed, we immediately free the page with frealloc - the - * memory manager doesn't currently attempt to keep unused memory around. This can result in excessive - * allocation traffic and can be mitigated by adding a page cache in the future. - * - * For both GCO and non-GCO pages, the per-page block allocation combines bump pointer style allocation - * (lua_Page::freeNext) and per-page free list (lua_Page::freeList). We use the bump allocator to allocate - * the contents of the page, and the free list for further reuse; this allows shorter page setup times - * which results in less variance between allocation cost, as well as tighter sweep bounds for newly - * allocated pages. - */ +uintptr_t unbaseaddr(uintptr_t address) +{ + return address - 0x400000 + reinterpret_cast(GetModuleHandleA(NULL)); +} + +uintptr_t sizeofclass_address = 0x40E3F38; +uintptr_t SizeOfClassMod = *(uintptr_t*)unbaseaddr(sizeofclass_address); #ifndef __has_feature #define __has_feature(x) 0 #endif -#if __has_feature(address_sanitizer) || defined(LUAU_ENABLE_ASAN) +#if __has_feature(address_sanitizer) || defined(lluz_ENABLE_ASAN) #include #define ASAN_POISON_MEMORY_REGION(addr, size) __asan_poison_memory_region((addr), (size)) #define ASAN_UNPOISON_MEMORY_REGION(addr, size) __asan_unpoison_memory_region((addr), (size)) @@ -92,7 +32,7 @@ #endif /* - * The sizes of Luau objects aren't crucial for code correctness, but they are crucial for memory efficiency + * The sizes of lluz objects aren't crucial for code correctness, but they are crucial for memory efficiency * To prevent some of them accidentally growing and us losing memory without realizing it, we're going to lock * the sizes of all critical structures down. */ @@ -126,44 +66,17 @@ const size_t kGCOLinkOffset = (sizeof(GCheader) + sizeof(void*) - 1) & ~(sizeof( struct SizeClassConfig { - int sizeOfClass[kSizeClasses]; - int8_t classForSize[kMaxSmallSize + 1]; - int classCount = 0; - - SizeClassConfig() - { - memset(sizeOfClass, 0, sizeof(sizeOfClass)); - memset(classForSize, -1, sizeof(classForSize)); - - // we use a progressive size class scheme: - // - all size classes are aligned by 8b to satisfy pointer alignment requirements - // - we first allocate sizes classes in multiples of 8 - // - after the first cutoff we allocate size classes in multiples of 16 - // - after the second cutoff we allocate size classes in multiples of 32 - // this balances internal fragmentation vs external fragmentation - for (int size = 8; size < 64; size += 8) - sizeOfClass[classCount++] = size; - - for (int size = 64; size < 256; size += 16) - sizeOfClass[classCount++] = size; - - for (int size = 256; size <= 512; size += 32) - sizeOfClass[classCount++] = size; - - LUAU_ASSERT(size_t(classCount) <= kSizeClasses); - - // fill the lookup table for all classes - for (int klass = 0; klass < classCount; ++klass) - classForSize[sizeOfClass[klass]] = int8_t(klass); - - // fill the gaps in lookup table - for (int size = kMaxSmallSize - 1; size >= 0; --size) - if (classForSize[size] < 0) - classForSize[size] = classForSize[size + 1]; - } + int* sizeOfClass; + int8_t* classForSize; }; -const SizeClassConfig kSizeClassConfig; +SizeClassConfig kSizeClassConfig; + +void setup_luau_mem() +{ + *(uintptr_t*)&kSizeClassConfig.sizeOfClass = SizeOfClassMod - (sizeof(int) * 32); // int NOT void* + *(uintptr_t*)&kSizeClassConfig.classForSize = SizeOfClassMod; +} // size class for a block of size sz; returns -1 for size=0 because empty allocations take no space #define sizeclass(sz) (size_t((sz)-1) < kMaxSmallSize ? kSizeClassConfig.classForSize[sz] : -1) @@ -199,14 +112,14 @@ struct lua_Page l_noret luaM_toobig(lua_State* L) { - luaG_runerror(L, "memory allocation error: block too big"); + luaG_runerror(L, XorStr("memory allocation error: block too big")); } static lua_Page* newpage(lua_State* L, lua_Page** gcopageset, int pageSize, int blockSize, int blockCount) { global_State* g = L->global; - LUAU_ASSERT(pageSize - int(offsetof(lua_Page, data)) >= blockSize * blockCount); + lluz_ASSERT(pageSize - int(offsetof(lua_Page, data)) >= blockSize * blockCount); lua_Page* page = (lua_Page*)(*g->frealloc)(g->ud, NULL, 0, pageSize); if (!page) @@ -250,7 +163,7 @@ static lua_Page* newclasspage(lua_State* L, lua_Page** freepageset, lua_Page** g lua_Page* page = newpage(L, gcopageset, kPageSize, blockSize, blockCount); // prepend a page to page freelist (which is empty because we only ever allocate a new page when it is!) - LUAU_ASSERT(!freepageset[sizeClass]); + lluz_ASSERT(!freepageset[sizeClass]); freepageset[sizeClass] = page; return page; @@ -299,9 +212,9 @@ static void* newblock(lua_State* L, int sizeClass) if (!page) page = newclasspage(L, g->freepages, NULL, sizeClass, true); - LUAU_ASSERT(!page->prev); - LUAU_ASSERT(page->freeList || page->freeNext >= 0); - LUAU_ASSERT(size_t(page->blockSize) == kSizeClassConfig.sizeOfClass[sizeClass] + kBlockHeader); + lluz_ASSERT(!page->prev); + lluz_ASSERT(page->freeList || page->freeNext >= 0); + lluz_ASSERT(size_t(page->blockSize) == kSizeClassConfig.sizeOfClass[sizeClass] + kBlockHeader); void* block; @@ -347,9 +260,9 @@ static void* newgcoblock(lua_State* L, int sizeClass) if (!page) page = newclasspage(L, g->freegcopages, &g->allgcopages, sizeClass, false); - LUAU_ASSERT(!page->prev); - LUAU_ASSERT(page->freeList || page->freeNext >= 0); - LUAU_ASSERT(page->blockSize == kSizeClassConfig.sizeOfClass[sizeClass]); + lluz_ASSERT(!page->prev); + lluz_ASSERT(page->freeList || page->freeNext >= 0); + lluz_ASSERT(page->blockSize == kSizeClassConfig.sizeOfClass[sizeClass]); void* block; @@ -388,19 +301,19 @@ static void freeblock(lua_State* L, int sizeClass, void* block) global_State* g = L->global; // the user data is right after the metadata - LUAU_ASSERT(block); + lluz_ASSERT(block); block = (char*)block - kBlockHeader; lua_Page* page = (lua_Page*)metadata(block); - LUAU_ASSERT(page && page->busyBlocks > 0); - LUAU_ASSERT(size_t(page->blockSize) == kSizeClassConfig.sizeOfClass[sizeClass] + kBlockHeader); - LUAU_ASSERT(block >= page->data && block < (char*)page + page->pageSize); + lluz_ASSERT(page && page->busyBlocks > 0); + lluz_ASSERT(size_t(page->blockSize) == kSizeClassConfig.sizeOfClass[sizeClass] + kBlockHeader); + lluz_ASSERT(block >= page->data && block < (char*)page + page->pageSize); // if the page wasn't in the page free list, it should be now since it got a block! if (!page->freeList && page->freeNext < 0) { - LUAU_ASSERT(!page->prev); - LUAU_ASSERT(!page->next); + lluz_ASSERT(!page->prev); + lluz_ASSERT(!page->next); page->next = g->freepages[sizeClass]; if (page->next) @@ -423,17 +336,17 @@ static void freeblock(lua_State* L, int sizeClass, void* block) static void freegcoblock(lua_State* L, int sizeClass, void* block, lua_Page* page) { - LUAU_ASSERT(page && page->busyBlocks > 0); - LUAU_ASSERT(page->blockSize == kSizeClassConfig.sizeOfClass[sizeClass]); - LUAU_ASSERT(block >= page->data && block < (char*)page + page->pageSize); + lluz_ASSERT(page && page->busyBlocks > 0); + lluz_ASSERT(page->blockSize == kSizeClassConfig.sizeOfClass[sizeClass]); + lluz_ASSERT(block >= page->data && block < (char*)page + page->pageSize); global_State* g = L->global; // if the page wasn't in the page free list, it should be now since it got a block! if (!page->freeList && page->freeNext < 0) { - LUAU_ASSERT(!page->prev); - LUAU_ASSERT(!page->next); + lluz_ASSERT(!page->prev); + lluz_ASSERT(!page->next); page->next = g->freegcopages[sizeClass]; if (page->next) @@ -473,7 +386,7 @@ void* luaM_new_(lua_State* L, size_t nsize, uint8_t memcat) GCObject* luaM_newgco_(lua_State* L, size_t nsize, uint8_t memcat) { // we need to accommodate space for link for free blocks (freegcolink) - LUAU_ASSERT(nsize >= kGCOLinkOffset + sizeof(void*)); + lluz_ASSERT(nsize >= kGCOLinkOffset + sizeof(void*)); global_State* g = L->global; @@ -508,7 +421,7 @@ GCObject* luaM_newgco_(lua_State* L, size_t nsize, uint8_t memcat) void luaM_free_(lua_State* L, void* block, size_t osize, uint8_t memcat) { global_State* g = L->global; - LUAU_ASSERT((osize == 0) == (block == NULL)); + lluz_ASSERT((osize == 0) == (block == NULL)); int oclass = sizeclass(osize); @@ -524,7 +437,7 @@ void luaM_free_(lua_State* L, void* block, size_t osize, uint8_t memcat) void luaM_freegco_(lua_State* L, GCObject* block, size_t osize, uint8_t memcat, lua_Page* page) { global_State* g = L->global; - LUAU_ASSERT((osize == 0) == (block == NULL)); + lluz_ASSERT((osize == 0) == (block == NULL)); int oclass = sizeclass(osize); @@ -536,9 +449,9 @@ void luaM_freegco_(lua_State* L, GCObject* block, size_t osize, uint8_t memcat, } else { - LUAU_ASSERT(page->busyBlocks == 1); - LUAU_ASSERT(size_t(page->blockSize) == osize); - LUAU_ASSERT((void*)block == page->data); + lluz_ASSERT(page->busyBlocks == 1); + lluz_ASSERT(size_t(page->blockSize) == osize); + lluz_ASSERT((void*)block == page->data); freepage(L, &g->allgcopages, page); } @@ -550,7 +463,7 @@ void luaM_freegco_(lua_State* L, GCObject* block, size_t osize, uint8_t memcat, void* luaM_realloc_(lua_State* L, void* block, size_t osize, size_t nsize, uint8_t memcat) { global_State* g = L->global; - LUAU_ASSERT((osize == 0) == (block == NULL)); + lluz_ASSERT((osize == 0) == (block == NULL)); int nclass = sizeclass(nsize); int oclass = sizeclass(osize); @@ -578,7 +491,7 @@ void* luaM_realloc_(lua_State* L, void* block, size_t osize, size_t nsize, uint8 luaD_throw(L, LUA_ERRMEM); } - LUAU_ASSERT((nsize == 0) == (result == NULL)); + lluz_ASSERT((nsize == 0) == (result == NULL)); g->totalbytes = (g->totalbytes - osize) + nsize; g->memcatbytes[memcat] += nsize - osize; return result; @@ -588,7 +501,7 @@ void luaM_getpagewalkinfo(lua_Page* page, char** start, char** end, int* busyBlo { int blockCount = (page->pageSize - offsetof(lua_Page, data)) / page->blockSize; - LUAU_ASSERT(page->freeNext >= -page->blockSize && page->freeNext <= (blockCount - 1) * page->blockSize); + lluz_ASSERT(page->freeNext >= -page->blockSize && page->freeNext <= (blockCount - 1) * page->blockSize); char* data = page->data; // silences ubsan when indexing page->data @@ -622,7 +535,7 @@ void luaM_visitpage(lua_Page* page, void* context, bool (*visitor)(void* context // when true is returned it means that the element was deleted if (visitor(context, page, gco)) { - LUAU_ASSERT(busyBlocks > 0); + lluz_ASSERT(busyBlocks > 0); // if the last block was removed, page would be removed as well if (--busyBlocks == 0) diff --git a/VM/src/lmem.h b/VM/src/lmem.h index e552d739..5468d7d1 100644 --- a/VM/src/lmem.h +++ b/VM/src/lmem.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -7,6 +7,8 @@ struct lua_Page; union GCObject; +void setup_luau_mem(); + #define luaM_newgco(L, t, size, memcat) cast_to(t*, luaM_newgco_(L, size, memcat)) #define luaM_freegco(L, p, size, memcat, page) luaM_freegco_(L, obj2gco(p), size, memcat, page) diff --git a/VM/src/lnumprint.cpp b/VM/src/lnumprint.cpp index d64e3ca4..249b57d3 100644 --- a/VM/src/lnumprint.cpp +++ b/VM/src/lnumprint.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "luaconf.h" #include "lnumutils.h" @@ -152,7 +152,7 @@ static Decimal schubfach(int exponent, uint64_t fraction) // 9.8.2. Overestimates of powers of 10 // Recover 10^-k fraction using compact tables generated by tools/numutils.py // The 128-bit fraction is encoded as 128-bit baseline * power-of-5 * scale + offset - LUAU_ASSERT(-k >= kPow10TableMin && -k <= kPow10TableMax); + lluz_ASSERT(-k >= kPow10TableMin && -k <= kPow10TableMax); int gtoff = -k - kPow10TableMin; const uint64_t* gt = kPow10Table[gtoff >> 4]; @@ -283,7 +283,7 @@ char* luai_num2str(char* buf, double n) uint64_t fraction = v.bits & ((1ull << 52) - 1); // specials - if (LUAU_UNLIKELY(exponent == 0x7ff)) + if (lluz_UNLIKELY(exponent == 0x7ff)) return printspecial(buf, sign, fraction); // sign bit @@ -299,7 +299,7 @@ char* luai_num2str(char* buf, double n) // convert binary to decimal using Schubfach Decimal d = schubfach(exponent, fraction); - LUAU_ASSERT(d.s < uint64_t(1e17)); + lluz_ASSERT(d.s < uint64_t(1e17)); // print the decimal to a temporary buffer; we'll need to insert the decimal point and figure out the format char decbuf[40]; @@ -307,7 +307,7 @@ char* luai_num2str(char* buf, double n) char* dec = printunsignedrev(decend, d.s); int declen = int(decend - dec); - LUAU_ASSERT(declen <= 17); + lluz_ASSERT(declen <= 17); int dot = declen + d.k; diff --git a/VM/src/lnumutils.h b/VM/src/lnumutils.h index 549b4630..f8b7f296 100644 --- a/VM/src/lnumutils.h +++ b/VM/src/lnumutils.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -33,12 +33,12 @@ inline bool luai_vecisnan(const float* a) #endif } -LUAU_FASTMATH_BEGIN +lluz_FASTMATH_BEGIN inline double luai_nummod(double a, double b) { return a - floor(a / b) * b; } -LUAU_FASTMATH_END +lluz_FASTMATH_END #define luai_num2int(i, d) ((i) = (int)(d)) diff --git a/VM/src/lobject.cpp b/VM/src/lobject.cpp index d5bd76a8..8148ea39 100644 --- a/VM/src/lobject.cpp +++ b/VM/src/lobject.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lobject.h" @@ -8,6 +8,8 @@ #include "ldo.h" #include "lnumutils.h" +#include "..\..\..\..\Security\XorString.h" + #include #include #include @@ -52,7 +54,7 @@ int luaO_rawequalObj(const TValue* t1, const TValue* t2) case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); default: - LUAU_ASSERT(iscollectable(t1)); + lluz_ASSERT(iscollectable(t1)); return gcvalue(t1) == gcvalue(t2); } } @@ -75,7 +77,7 @@ int luaO_rawequalKey(const TKey* t1, const TValue* t2) case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); default: - LUAU_ASSERT(iscollectable(t1)); + lluz_ASSERT(iscollectable(t1)); return gcvalue(t1) == gcvalue(t2); } } @@ -133,28 +135,28 @@ void luaO_chunkid(char* out, const char* source, size_t bufflen) source++; /* skip the `@' */ bufflen -= sizeof("..."); l = strlen(source); - strcpy(out, ""); + strcpy(out, XorStr("")); if (l > bufflen) { source += (l - bufflen); /* get last part of file name */ - strcat(out, "..."); + strcat(out, XorStr("...")); } strcat(out, source); } else { /* out = [string "string"] */ - size_t len = strcspn(source, "\n\r"); /* stop at first newline */ + size_t len = strcspn(source, XorStr("\n\r")); /* stop at first newline */ bufflen -= sizeof("[string \"...\"]"); if (len > bufflen) len = bufflen; - strcpy(out, "[string \""); + strcpy(out, XorStr("[string \"")); if (source[len] != '\0') { /* must truncate? */ strncat(out, source, len); - strcat(out, "..."); + strcat(out, XorStr("...")); } else strcat(out, source); - strcat(out, "\"]"); + strcat(out, XorStr("\"]")); } } diff --git a/VM/src/lobject.h b/VM/src/lobject.h index bdcb85cb..80c8b63f 100644 --- a/VM/src/lobject.h +++ b/VM/src/lobject.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -15,7 +15,7 @@ typedef union GCObject GCObject; */ // clang-format off #define CommonHeader \ - uint8_t tt; uint8_t marked; uint8_t memcat + uint8_t memcat; uint8_t tt; uint8_t marked // clang-format on /* @@ -81,9 +81,9 @@ typedef struct lua_TValue /* ** for internal debug only */ -#define checkconsistency(obj) LUAU_ASSERT(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) +#define checkconsistency(obj) lluz_ASSERT(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) -#define checkliveness(g, obj) LUAU_ASSERT(!iscollectable(obj) || ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) +#define checkliveness(g, obj) lluz_ASSERT(!iscollectable(obj) || ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) /* Macros to set values */ #define setnilvalue(obj) ((obj)->tt = LUA_TNIL) @@ -294,7 +294,7 @@ typedef struct Proto int linedefined; - uint8_t nups; /* number of upvalues */ + uint8_t nups; uint8_t numparams; uint8_t is_vararg; uint8_t maxstacksize; diff --git a/VM/src/loslib.cpp b/VM/src/loslib.cpp index b5901865..633daa5b 100644 --- a/VM/src/loslib.cpp +++ b/VM/src/loslib.cpp @@ -1,7 +1,9 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" +#include "..\..\..\..\Security\XorString.h" + #include #include @@ -70,7 +72,7 @@ static int getfield(lua_State* L, const char* key, int d) else { if (d < 0) - luaL_error(L, "field '%s' missing in date table", key); + luaL_error(L, XorStr("field '%s' missing in date table"), key); res = d; } lua_pop(L, 1); @@ -79,7 +81,7 @@ static int getfield(lua_State* L, const char* key, int d) static int os_date(lua_State* L) { - const char* s = luaL_optstring(L, 1, "%c"); + const char* s = luaL_optstring(L, 1, XorStr("%c")); time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); struct tm tm; @@ -128,7 +130,7 @@ static int os_date(lua_State* L) } else if (strchr(LUA_STRFTIMEOPTIONS, *(s + 1)) == 0) { - luaL_argerror(L, 1, "invalid conversion specifier"); + luaL_argerror(L, 1, XorStr("invalid conversion specifier")); } else { @@ -160,7 +162,7 @@ static int os_time(lua_State* L) ts.tm_mday = getfield(L, "day", -1); ts.tm_mon = getfield(L, "month", -1) - 1; ts.tm_year = getfield(L, "year", -1) - 1900; - ts.tm_isdst = getboolfield(L, "isdst"); + ts.tm_isdst = getboolfield(L, XorStr("isdst")); // Note: upstream Lua uses mktime() here which assumes input is local time, but we prefer UTC for consistency t = timegm(&ts); @@ -179,10 +181,10 @@ static int os_difftime(lua_State* L) } static const luaL_Reg syslib[] = { - {"clock", os_clock}, - {"date", os_date}, - {"difftime", os_difftime}, - {"time", os_time}, + {XorStr("clock"), os_clock}, + {XorStr("date"), os_date}, + {XorStr("difftime"), os_difftime}, + {XorStr("time"), os_time}, {NULL, NULL}, }; diff --git a/VM/src/lperf.cpp b/VM/src/lperf.cpp index da68e376..750d6dc1 100644 --- a/VM/src/lperf.cpp +++ b/VM/src/lperf.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lua.h" @@ -18,12 +18,13 @@ #endif #include +#include "../../../../Security/Lazy_Importer.h" static double clock_period() { #if defined(_WIN32) LARGE_INTEGER result = {}; - QueryPerformanceFrequency(&result); + LI_FN(QueryPerformanceFrequency).in(LI_MODULE("kernel32.dll").cached())(&result); return 1.0 / double(result.QuadPart); #elif defined(__APPLE__) mach_timebase_info_data_t result = {}; @@ -40,7 +41,7 @@ static double clock_timestamp() { #if defined(_WIN32) LARGE_INTEGER result = {}; - QueryPerformanceCounter(&result); + LI_FN(QueryPerformanceCounter).in(LI_MODULE("kernel32.dll").cached())(&result); return double(result.QuadPart); #elif defined(__APPLE__) return double(mach_absolute_time()); diff --git a/VM/src/lstate.cpp b/VM/src/lstate.cpp index fbc6fb1e..a634f736 100644 --- a/VM/src/lstate.cpp +++ b/VM/src/lstate.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lstate.h" @@ -65,6 +65,7 @@ static void f_luaopen(lua_State* L, void* ud) static void preinit_state(lua_State* L, global_State* g) { + std::string ajadk = "preinit"; L->global = g; L->stack = NULL; L->stacksize = 0; @@ -87,20 +88,20 @@ static void close_state(lua_State* L) global_State* g = L->global; luaF_close(L, L->stack); /* close all upvalues for this thread */ luaC_freeall(L); /* collect all objects */ - LUAU_ASSERT(g->strbufgc == NULL); - LUAU_ASSERT(g->strt.nuse == 0); + lluz_ASSERT(g->strbufgc == NULL); + lluz_ASSERT(g->strt.nuse == 0); luaM_freearray(L, L->global->strt.hash, L->global->strt.size, TString*, 0); freestack(L, L); for (int i = 0; i < LUA_SIZECLASSES; i++) { - LUAU_ASSERT(g->freepages[i] == NULL); - LUAU_ASSERT(g->freegcopages[i] == NULL); + lluz_ASSERT(g->freepages[i] == NULL); + lluz_ASSERT(g->freegcopages[i] == NULL); } - LUAU_ASSERT(g->allgcopages == NULL); - LUAU_ASSERT(g->totalbytes == sizeof(LG)); - LUAU_ASSERT(g->memcatbytes[0] == sizeof(LG)); + lluz_ASSERT(g->allgcopages == NULL); + lluz_ASSERT(g->totalbytes == sizeof(LG)); + lluz_ASSERT(g->memcatbytes[0] == sizeof(LG)); for (int i = 1; i < LUA_MEMORY_CATEGORIES; i++) - LUAU_ASSERT(g->memcatbytes[i] == 0); + lluz_ASSERT(g->memcatbytes[i] == 0); (*g->frealloc)(g->ud, L, sizeof(LG), 0); } @@ -113,14 +114,14 @@ lua_State* luaE_newthread(lua_State* L) stack_init(L1, L); /* init stack */ L1->gt = L->gt; /* share table of globals */ L1->singlestep = L->singlestep; - LUAU_ASSERT(iswhite(obj2gco(L1))); + lluz_ASSERT(iswhite(obj2gco(L1))); return L1; } void luaE_freethread(lua_State* L, lua_State* L1, lua_Page* page) { luaF_close(L1, L1->stack); /* close all upvalues for this thread */ - LUAU_ASSERT(L1->openupval == NULL); + lluz_ASSERT(L1->openupval == NULL); global_State* g = L->global; if (g->cb.userthread) g->cb.userthread(NULL, L1); diff --git a/VM/src/lstate.h b/VM/src/lstate.h index 423514a7..8c41d2bc 100644 --- a/VM/src/lstate.h +++ b/VM/src/lstate.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -226,13 +226,15 @@ struct lua_State bool singlestep; /* call debugstep hook after each instruction */ - - StkId top; /* first free slot in the stack */ - StkId base; /* base of current function */ + // THESE SHUFFLE --------------------- global_State* global; - CallInfo* ci; /* call info for current function */ - StkId stack_last; /* last free slot in the stack */ - StkId stack; /* stack base */ + StkId top; + StkId base; + + CallInfo* ci; + StkId stack; + StkId stack_last; + //---------------------------------------------------- CallInfo* end_ci; /* points after end of ci array*/ @@ -246,14 +248,14 @@ struct lua_State unsigned short nCcalls; /* number of nested C calls */ unsigned short baseCcalls; /* nested C calls when resuming coroutine */ - int cachedslot; /* when table operations or INDEX/NEWINDEX is invoked from Luau, what is the expected slot for lookup? */ + int cachedslot; /* when table operations or INDEX/NEWINDEX is invoked from lluz, what is the expected slot for lookup? */ - - Table* gt; /* table of globals */ - UpVal* openupval; /* list of open upvalues in this stack */ + // THESE SHUFFLE --------------------- + Table* gt; + UpVal* openupval; GCObject* gclist; - - TString* namecall; /* when invoked from Luau using NAMECALL, what method do we need to invoke? */ + TString* namecall; + //---------------------------------------------------- void* userdata; }; diff --git a/VM/src/lstring.cpp b/VM/src/lstring.cpp index d454308c..05b5f2a3 100644 --- a/VM/src/lstring.cpp +++ b/VM/src/lstring.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lstring.h" @@ -57,7 +57,7 @@ void luaS_resize(lua_State* L, int newsize) TString* next = p->next; /* save next */ unsigned int h = p->hash; int h1 = lmod(h, newsize); /* new position */ - LUAU_ASSERT(cast_int(h % newsize) == lmod(h, newsize)); + lluz_ASSERT(cast_int(h % newsize) == lmod(h, newsize)); p->next = newhash[h1]; /* chain it */ newhash[h1] = p; p = next; @@ -82,7 +82,7 @@ static TString* newlstr(lua_State* L, const char* str, size_t l, unsigned int h) ts->memcat = L->activememcat; memcpy(ts->data, str, l); ts->data[l] = '\0'; /* ending 0 */ - ts->atom = ATOM_UNDEF; + ts->atom = L->global->cb.useratom ? L->global->cb.useratom(ts->data, l) : -1; tb = &L->global->strt; h = lmod(h, tb->size); ts->next = tb->hash[h]; /* chain new entry */ @@ -121,7 +121,7 @@ static void unlinkstrbuf(lua_State* L, TString* ts) } } - LUAU_ASSERT(!"failed to find string buffer"); + lluz_ASSERT(!"failed to find string buffer"); } TString* luaS_bufstart(lua_State* L, size_t size) @@ -163,7 +163,9 @@ TString* luaS_buffinish(lua_State* L, TString* ts) ts->hash = h; ts->data[ts->len] = '\0'; // ending 0 - ts->atom = ATOM_UNDEF; + + // Complete string object + ts->atom = L->global->cb.useratom ? L->global->cb.useratom(ts->data, ts->len) : -1; ts->next = tb->hash[bucket]; // chain new entry tb->hash[bucket] = ts; diff --git a/VM/src/lstring.h b/VM/src/lstring.h index acdf9a1e..6889966e 100644 --- a/VM/src/lstring.h +++ b/VM/src/lstring.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -8,9 +8,6 @@ /* string size limit */ #define MAXSSIZE (1 << 30) -/* string atoms are not defined by default; the storage is 16-bit integer */ -#define ATOM_UNDEF -32768 - #define sizestring(len) (offsetof(TString, data) + len + 1) #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) diff --git a/VM/src/lstrlib.cpp b/VM/src/lstrlib.cpp index b0cd4dc2..bf6f3476 100644 --- a/VM/src/lstrlib.cpp +++ b/VM/src/lstrlib.cpp @@ -1,9 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" #include "lstring.h" +#include "..\..\..\..\Security\XorString.h" + #include #include #include @@ -93,7 +95,7 @@ static int str_rep(lua_State* L) } if (l > MAXSSIZE / (size_t)n) // may overflow? - luaL_error(L, "resulting string too large"); + luaL_error(L, XorStr("resulting string too large")); luaL_Buffer b; char* ptr = luaL_buffinitsize(L, &b, l * n); @@ -140,8 +142,8 @@ static int str_byte(lua_State* L) return 0; /* empty interval; return no values */ n = (int)(pose - posi + 1); if (posi + n <= pose) /* overflow? */ - luaL_error(L, "string slice too long"); - luaL_checkstack(L, n, "string slice too long"); + luaL_error(L, XorStr("string slice too long")); + luaL_checkstack(L, n, XorStr("string slice too long")); for (i = 0; i < n; i++) lua_pushinteger(L, uchar(s[posi + i - 1])); return n; @@ -157,7 +159,7 @@ static int str_char(lua_State* L) for (int i = 1; i <= n; i++) { int c = luaL_checkinteger(L, i); - luaL_argcheck(L, uchar(c) == c, i, "invalid value"); + luaL_argcheck(L, uchar(c) == c, i, XorStr("invalid value")); *ptr++ = uchar(c); } @@ -193,13 +195,13 @@ typedef struct MatchState static const char* match(MatchState* ms, const char* s, const char* p); #define L_ESC '%' -#define SPECIALS "^$*+?.([%-" +#define SPECIALS XorStr("^$*+?.([%-") static int check_capture(MatchState* ms, int l) { l -= '1'; if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) - luaL_error(ms->L, "invalid capture index %%%d", l + 1); + luaL_error(ms->L, XorStr("invalid capture index %%%d"), l + 1); return l; } @@ -209,7 +211,7 @@ static int capture_to_close(MatchState* ms) for (level--; level >= 0; level--) if (ms->capture[level].len == CAP_UNFINISHED) return level; - luaL_error(ms->L, "invalid pattern capture"); + luaL_error(ms->L, XorStr("invalid pattern capture")); } static const char* classend(MatchState* ms, const char* p) @@ -219,7 +221,7 @@ static const char* classend(MatchState* ms, const char* p) case L_ESC: { if (p == ms->p_end) - luaL_error(ms->L, "malformed pattern (ends with '%%')"); + luaL_error(ms->L, XorStr("malformed pattern (ends with '%%')")); return p + 1; } case '[': @@ -229,7 +231,7 @@ static const char* classend(MatchState* ms, const char* p) do { /* look for a `]' */ if (p == ms->p_end) - luaL_error(ms->L, "malformed pattern (missing ']')"); + luaL_error(ms->L, XorStr("malformed pattern (missing ']')")); if (*(p++) == L_ESC && p < ms->p_end) p++; /* skip escapes (e.g. `%]') */ } while (*p != ']'); @@ -338,7 +340,7 @@ static int singlematch(MatchState* ms, const char* s, const char* p, const char* static const char* matchbalance(MatchState* ms, const char* s, const char* p) { if (p >= ms->p_end - 1) - luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); + luaL_error(ms->L, XorStr("malformed pattern (missing arguments to '%%b')")); if (*s != *p) return NULL; else @@ -395,7 +397,7 @@ static const char* start_capture(MatchState* ms, const char* s, const char* p, i const char* res; int level = ms->level; if (level >= LUA_MAXCAPTURES) - luaL_error(ms->L, "too many captures"); + luaL_error(ms->L, XorStr("too many captures")); ms->capture[level].init = s; ms->capture[level].len = what; ms->level = level + 1; @@ -428,7 +430,7 @@ static const char* match_capture(MatchState* ms, const char* s, int l) static const char* match(MatchState* ms, const char* s, const char* p) { if (ms->matchdepth-- == 0) - luaL_error(ms->L, "pattern too complex"); + luaL_error(ms->L, XorStr("pattern too complex")); init: /* using goto's to optimize tail recursion */ if (p != ms->p_end) { /* end of pattern? */ @@ -474,7 +476,7 @@ init: /* using goto's to optimize tail recursion */ char previous; p += 2; if (*p != '[') - luaL_error(ms->L, "missing '[' after '%%f' in pattern"); + luaL_error(ms->L, XorStr("missing '[' after '%%f' in pattern")); ep = classend(ms, p); /* points to what is next */ previous = (s == ms->src_init) ? '\0' : *(s - 1); if (!matchbracketclass(uchar(previous), p, ep - 1) && matchbracketclass(uchar(*s), p, ep - 1)) @@ -596,13 +598,13 @@ static void push_onecapture(MatchState* ms, int i, const char* s, const char* e) if (i == 0) /* ms->level == 0, too */ lua_pushlstring(ms->L, s, e - s); /* add whole match */ else - luaL_error(ms->L, "invalid capture index"); + luaL_error(ms->L, XorStr("invalid capture index")); } else { ptrdiff_t l = ms->capture[i].len; if (l == CAP_UNFINISHED) - luaL_error(ms->L, "unfinished capture"); + luaL_error(ms->L, XorStr("unfinished capture")); if (l == CAP_POSITION) lua_pushinteger(ms->L, (int)(ms->capture[i].init - ms->src_init) + 1); else @@ -614,7 +616,7 @@ static int push_captures(MatchState* ms, const char* s, const char* e) { int i; int nlevels = (ms->level == 0 && s) ? 1 : ms->level; - luaL_checkstack(ms->L, nlevels, "too many captures"); + luaL_checkstack(ms->L, nlevels, XorStr("too many captures")); for (i = 0; i < nlevels; i++) push_onecapture(ms, i, s, e); return nlevels; /* number of strings pushed */ @@ -645,7 +647,7 @@ static void prepstate(MatchState* ms, lua_State* L, const char* s, size_t ls, co static void reprepstate(MatchState* ms) { ms->level = 0; - LUAU_ASSERT(ms->matchdepth == LUAI_MAXCCALLS); + lluz_ASSERT(ms->matchdepth == LUAI_MAXCCALLS); } static int str_find_aux(lua_State* L, int find) @@ -767,7 +769,7 @@ static void add_s(MatchState* ms, luaL_Buffer* b, const char* s, const char* e) if (!isdigit(uchar(news[i]))) { if (news[i] != L_ESC) - luaL_error(ms->L, "invalid use of '%c' in replacement string", L_ESC); + luaL_error(ms->L, XorStr("invalid use of '%c' in replacement string"), L_ESC); luaL_addchar(b, news[i]); } else if (news[i] == '0') @@ -812,7 +814,7 @@ static void add_value(MatchState* ms, luaL_Buffer* b, const char* s, const char* lua_pushlstring(L, s, e - s); /* keep original text */ } else if (!lua_isstring(L, -1)) - luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_error(L, XorStr("invalid replacement value (a %s)"), luaL_typename(L, -1)); luaL_addvalue(b); /* add result to accumulator */ } @@ -827,7 +829,7 @@ static int str_gsub(lua_State* L) int n = 0; MatchState ms; luaL_Buffer b; - luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, "string/function/table"); + luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, XorStr("string/function/table")); luaL_buffinit(L, &b); if (anchor) { @@ -916,7 +918,7 @@ static const char* scanformat(lua_State* L, const char* strfrmt, char* form, siz while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) - luaL_error(L, "invalid format (repeated flags)"); + luaL_error(L, XorStr("invalid format (repeated flags)")); if (isdigit(uchar(*p))) p++; /* skip width */ if (isdigit(uchar(*p))) @@ -930,7 +932,7 @@ static const char* scanformat(lua_State* L, const char* strfrmt, char* form, siz p++; /* (2 digits at most) */ } if (isdigit(uchar(*p))) - luaL_error(L, "invalid format (width or precision too long)"); + luaL_error(L, XorStr("invalid format (width or precision too long)")); *(form++) = '%'; *size = p - strfrmt + 1; strncpy(form, strfrmt, *size); @@ -941,10 +943,10 @@ static const char* scanformat(lua_State* L, const char* strfrmt, char* form, siz static void addInt64Format(char form[MAX_FORMAT], char formatIndicator, size_t formatItemSize) { - LUAU_ASSERT((formatItemSize + 3) <= MAX_FORMAT); - LUAU_ASSERT(form[0] == '%'); - LUAU_ASSERT(form[formatItemSize] != 0); - LUAU_ASSERT(form[formatItemSize + 1] == 0); + lluz_ASSERT((formatItemSize + 3) <= MAX_FORMAT); + lluz_ASSERT(form[0] == '%'); + lluz_ASSERT(form[formatItemSize] != 0); + lluz_ASSERT(form[formatItemSize + 1] == 0); form[formatItemSize + 0] = 'l'; form[formatItemSize + 1] = 'l'; form[formatItemSize + 2] = formatIndicator; @@ -971,7 +973,7 @@ static int str_format(lua_State* L) char form[MAX_FORMAT]; /* to store the format (`%...') */ char buff[MAX_ITEM]; /* to store the formatted item */ if (++arg > top) - luaL_error(L, "missing argument #%d", arg); + luaL_error(L, XorStr("missing argument #%d"), arg); size_t formatItemSize = 0; strfrmt = scanformat(L, strfrmt, form, &formatItemSize); char formatIndicator = *strfrmt++; @@ -979,14 +981,14 @@ static int str_format(lua_State* L) { case 'c': { - snprintf(buff, sizeof(buff), form, (int)luaL_checknumber(L, arg)); + sprintf(buff, form, (int)luaL_checknumber(L, arg)); break; } case 'd': case 'i': { addInt64Format(form, formatIndicator, formatItemSize); - snprintf(buff, sizeof(buff), form, (long long)luaL_checknumber(L, arg)); + sprintf(buff, form, (long long)luaL_checknumber(L, arg)); break; } case 'o': @@ -997,7 +999,7 @@ static int str_format(lua_State* L) double argValue = luaL_checknumber(L, arg); addInt64Format(form, formatIndicator, formatItemSize); unsigned long long v = (argValue < 0) ? (unsigned long long)(long long)argValue : (unsigned long long)argValue; - snprintf(buff, sizeof(buff), form, v); + sprintf(buff, form, v); break; } case 'e': @@ -1006,7 +1008,7 @@ static int str_format(lua_State* L) case 'g': case 'G': { - snprintf(buff, sizeof(buff), form, (double)luaL_checknumber(L, arg)); + sprintf(buff, form, (double)luaL_checknumber(L, arg)); break; } case 'q': @@ -1028,13 +1030,13 @@ static int str_format(lua_State* L) } else { - snprintf(buff, sizeof(buff), form, s); + sprintf(buff, form, s); break; } } default: { /* also treat cases `pnLlh' */ - luaL_error(L, "invalid option '%%%c' to 'format'", *(strfrmt - 1)); + luaL_error(L, XorStr("invalid option '%%%c' to 'format'"), *(strfrmt - 1)); } } luaL_addlstring(&b, buff, strlen(buff)); @@ -1183,7 +1185,7 @@ static int getnum(Header* h, const char** fmt, int df) a = a * 10 + (*((*fmt)++) - '0'); } while (digit(**fmt) && a <= (INT_MAX - 9) / 10); if (a > MAXSSIZE || digit(**fmt)) - luaL_error(h->L, "size specifier is too large"); + luaL_error(h->L, XorStr("size specifier is too large")); return a; } } @@ -1267,7 +1269,7 @@ static KOption getoption(Header* h, const char** fmt, int* size) case 'c': *size = getnum(h, fmt, -1); if (*size == -1) - luaL_error(h->L, "missing size for format option 'c'"); + luaL_error(h->L, XorStr("missing size for format option 'c'")); return Kchar; case 'z': return Kzstr; @@ -1312,7 +1314,7 @@ static KOption getdetails(Header* h, size_t totalsize, const char** fmt, int* ps if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) - luaL_argerror(h->L, 1, "invalid next option for option 'X'"); + luaL_argerror(h->L, 1, XorStr("invalid next option for option 'X'")); } if (align <= 1 || opt == Kchar) /* need no alignment? */ *ntoalign = 0; @@ -1321,7 +1323,7 @@ static KOption getdetails(Header* h, size_t totalsize, const char** fmt, int* ps if (align > h->maxalign) /* enforce maximum alignment */ align = h->maxalign; if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ - luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); + luaL_argerror(h->L, 1, XorStr("format asks for alignment not power of 2")); *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); } return opt; @@ -1335,7 +1337,7 @@ static KOption getdetails(Header* h, size_t totalsize, const char** fmt, int* ps */ static void packint(luaL_Buffer* b, unsigned long long n, int islittle, int size, int neg) { - LUAU_ASSERT(size <= MAXINTSIZE); + lluz_ASSERT(size <= MAXINTSIZE); char buff[MAXINTSIZE]; int i; buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ @@ -1397,7 +1399,7 @@ static int str_pack(lua_State* L) if (size < SZINT) { /* need overflow check? */ long long lim = (long long)1 << ((size * NB) - 1); - luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); + luaL_argcheck(L, -lim <= n && n < lim, arg, XorStr("integer overflow")); } packint(&b, n, h.islittle, size, (n < 0)); break; @@ -1406,7 +1408,7 @@ static int str_pack(lua_State* L) { /* unsigned integers */ long long n = (long long)luaL_checknumber(L, arg); if (size < SZINT) /* need overflow check? */ - luaL_argcheck(L, (unsigned long long)n < ((unsigned long long)1 << (size * NB)), arg, "unsigned overflow"); + luaL_argcheck(L, (unsigned long long)n < ((unsigned long long)1 << (size * NB)), arg, XorStr("unsigned overflow")); packint(&b, (unsigned long long)n, h.islittle, size, 0); break; } @@ -1430,7 +1432,7 @@ static int str_pack(lua_State* L) { /* fixed-size string */ size_t len; const char* s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, len <= (size_t)size, arg, "string longer than given size"); + luaL_argcheck(L, len <= (size_t)size, arg, XorStr("string longer than given size")); luaL_addlstring(&b, s, len); /* add string */ while (len++ < (size_t)size) /* pad extra space */ luaL_addchar(&b, LUAL_PACKPADBYTE); @@ -1440,7 +1442,7 @@ static int str_pack(lua_State* L) { /* strings with length count */ size_t len; const char* s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, size >= (int)sizeof(size_t) || len < ((size_t)1 << (size * NB)), arg, "string length does not fit in given size"); + luaL_argcheck(L, size >= (int)sizeof(size_t) || len < ((size_t)1 << (size * NB)), arg, XorStr("string length does not fit in given size")); packint(&b, len, h.islittle, size, 0); /* pack length */ luaL_addlstring(&b, s, len); totalsize += len; @@ -1450,7 +1452,7 @@ static int str_pack(lua_State* L) { /* zero-terminated string */ size_t len; const char* s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); + luaL_argcheck(L, strlen(s) == len, arg, XorStr("string contains zeros")); luaL_addlstring(&b, s, len); luaL_addchar(&b, '\0'); /* add zero at the end */ totalsize += len + 1; @@ -1478,9 +1480,9 @@ static int str_packsize(lua_State* L) { int size, ntoalign; KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); - luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1, "variable-length format"); + luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1, XorStr("variable-length format")); size += ntoalign; /* total space used by option */ - luaL_argcheck(L, totalsize <= MAXSSIZE - size, 1, "format result too large"); + luaL_argcheck(L, totalsize <= MAXSSIZE - size, 1, XorStr("format result too large")); totalsize += size; } lua_pushinteger(L, totalsize); @@ -1519,7 +1521,7 @@ static long long unpackint(lua_State* L, const char* str, int islittle, int size for (i = limit; i < size; i++) { if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) - luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); + luaL_error(L, XorStr("%d-byte integer does not fit into Lua Integer"), size); } } return (long long)res; @@ -1535,16 +1537,16 @@ static int str_unpack(lua_State* L) if (pos < 0) pos = 0; int n = 0; /* number of results */ - luaL_argcheck(L, size_t(pos) <= ld, 3, "initial position out of string"); + luaL_argcheck(L, size_t(pos) <= ld, 3, XorStr("initial position out of string")); initheader(L, &h); while (*fmt != '\0') { int size, ntoalign; KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); - luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, "data string too short"); + luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, XorStr("data string too short")); pos += ntoalign; /* skip alignment */ /* stack space for item + next position */ - luaL_checkstack(L, 2, "too many results"); + luaL_checkstack(L, 2, XorStr("too many results")); n++; switch (opt) { @@ -1582,7 +1584,7 @@ static int str_unpack(lua_State* L) case Kstring: { size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); - luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); + luaL_argcheck(L, len <= ld - pos - size, 2, XorStr("data string too short")); lua_pushlstring(L, data + pos + size, len); pos += (int)len; /* skip string */ break; @@ -1590,7 +1592,7 @@ static int str_unpack(lua_State* L) case Kzstr: { size_t len = strlen(data + pos); - luaL_argcheck(L, pos + len < ld, 2, "unfinished string for format 'z'"); + luaL_argcheck(L, pos + len < ld, 2, XorStr("unfinished string for format 'z'")); lua_pushlstring(L, data + pos, len); pos += (int)len + 1; /* skip string plus final '\0' */ break; @@ -1610,23 +1612,23 @@ static int str_unpack(lua_State* L) /* }====================================================== */ static const luaL_Reg strlib[] = { - {"byte", str_byte}, - {"char", str_char}, - {"find", str_find}, - {"format", str_format}, - {"gmatch", gmatch}, - {"gsub", str_gsub}, - {"len", str_len}, - {"lower", str_lower}, - {"match", str_match}, - {"rep", str_rep}, - {"reverse", str_reverse}, - {"sub", str_sub}, - {"upper", str_upper}, - {"split", str_split}, - {"pack", str_pack}, - {"packsize", str_packsize}, - {"unpack", str_unpack}, + {XorStr("byte"), str_byte}, + {XorStr("char"), str_char}, + {XorStr("find"), str_find}, + {XorStr("format"), str_format}, + {XorStr("gmatch"), gmatch}, + {XorStr("gsub"), str_gsub}, + {XorStr("len"), str_len}, + {XorStr("lower"), str_lower}, + {XorStr("match"), str_match}, + {XorStr("rep"), str_rep}, + {XorStr("reverse"), str_reverse}, + {XorStr("sub"), str_sub}, + {XorStr("upper"), str_upper}, + {XorStr("split"), str_split}, + {XorStr("pack"), str_pack}, + {XorStr("packsize"), str_packsize}, + {XorStr("unpack"), str_unpack}, {NULL, NULL}, }; @@ -1638,7 +1640,7 @@ static void createmetatable(lua_State* L) lua_setmetatable(L, -2); /* set string metatable */ lua_pop(L, 1); /* pop dummy string */ lua_pushvalue(L, -2); /* string library... */ - lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ + lua_setfield(L, -2, XorStr("__index")); /* ...is the __index metamethod */ lua_pop(L, 1); /* pop metatable */ } diff --git a/VM/src/ltable.cpp b/VM/src/ltable.cpp index 38693156..dd10b4e9 100644 --- a/VM/src/ltable.cpp +++ b/VM/src/ltable.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 /* @@ -17,7 +17,7 @@ * so even if the key is a userdata with an overridden __eq, it's not used during hash lookups. * * Each table has a "boundary", defined as the index k where t[k] ~= nil and t[k+1] == nil. The boundary can be - * computed using a binary search and can be adjusted when the table is modified; crucially, Luau enforces an + * computed using a binary search and can be adjusted when the table is modified; crucially, lluz enforces an * invariant where the boundary must be in the array part - this enforces a consistent iteration order through the * prefix of the table when using pairs(), and allows to implement algorithms that access elements in 1..#t range * more efficiently. @@ -31,6 +31,8 @@ #include "lmem.h" #include "lnumutils.h" +#include "..\..\..\..\Security\XorString.h" + #include // max size of both array and hash part is 2^MAXBITS @@ -44,6 +46,9 @@ static_assert(TKey{{NULL}, {0}, LUA_TDEADKEY, 0}.tt == LUA_TDEADKEY, "not enough static_assert(TKey{{NULL}, {0}, LUA_TNIL, MAXSIZE - 1}.next == MAXSIZE - 1, "not enough bits for next"); static_assert(TKey{{NULL}, {0}, LUA_TNIL, -(MAXSIZE - 1)}.next == -(MAXSIZE - 1), "not enough bits for next"); +// reset cache of absent metamethods, cache is updated in luaT_gettm +#define invalidateTMcache(t) t->tmcache = 0 + // empty hash data points to dummynode so that we can always dereference it const LuaNode luaH_dummynode = { {{NULL}, {0}, LUA_TNIL}, /* value */ @@ -105,9 +110,9 @@ static LuaNode* hashvec(const Table* t, const float* v) memcpy(i, v, sizeof(i)); // convert -0 to 0 to make sure they hash to the same value - i[0] = (i[0] == 0x80000000) ? 0 : i[0]; - i[1] = (i[1] == 0x80000000) ? 0 : i[1]; - i[2] = (i[2] == 0x80000000) ? 0 : i[2]; + i[0] = (i[0] == 0x8000000) ? 0 : i[0]; + i[1] = (i[1] == 0x8000000) ? 0 : i[1]; + i[2] = (i[2] == 0x8000000) ? 0 : i[2]; // scramble bits to make sure that integer coordinates have entropy in lower bits i[0] ^= i[0] >> 17; @@ -118,7 +123,7 @@ static LuaNode* hashvec(const Table* t, const float* v) unsigned int h = (i[0] * 73856093) ^ (i[1] * 19349663) ^ (i[2] * 83492791); #if LUA_VECTOR_SIZE == 4 - i[3] = (i[3] == 0x80000000) ? 0 : i[3]; + i[3] = (i[3] == 0x8000000) ? 0 : i[3]; i[3] ^= i[3] >> 17; h ^= i[3] * 39916801; #endif @@ -190,7 +195,7 @@ static int findindex(lua_State* L, Table* t, StkId key) break; n += gnext(n); } - luaG_runerror(L, "invalid key to 'next'"); /* key not found */ + luaG_runerror(L, XorStr("invalid key to 'next'")); /* key not found */ } } @@ -254,7 +259,7 @@ static int computesizes(int nums[], int* narray) break; /* all elements already counted */ } *narray = n; - LUAU_ASSERT(*narray / 2 <= na && na <= *narray); + lluz_ASSERT(*narray / 2 <= na && na <= *narray); return na; } @@ -320,7 +325,7 @@ static int numusehash(const Table* t, int* nums, int* pnasize) static void setarrayvector(lua_State* L, Table* t, int size) { if (size > MAXSIZE) - luaG_runerror(L, "table overflow"); + luaG_runerror(L, XorStr("table overflow")); luaM_reallocarray(L, t->array, t->sizearray, size, TValue, t->memcat); TValue* array = t->array; for (int i = t->sizearray; i < size; i++) @@ -341,7 +346,7 @@ static void setnodevector(lua_State* L, Table* t, int size) int i; lsize = ceillog2(size); if (lsize > MAXBITS) - luaG_runerror(L, "table overflow"); + luaG_runerror(L, XorStr("table overflow")); size = twoto(lsize); t->node = luaM_newarray(L, size, LuaNode, t->memcat); for (i = 0; i < size; i++) @@ -376,7 +381,7 @@ static TValue* arrayornewkey(lua_State* L, Table* t, const TValue* key) static void resize(lua_State* L, Table* t, int nasize, int nhsize) { if (nasize > MAXSIZE || nhsize > MAXSIZE) - luaG_runerror(L, "table overflow"); + luaG_runerror(L, XorStr("table overflow")); int oldasize = t->sizearray; int oldhsize = t->lsizenode; LuaNode* nold = t->node; /* save old hash ... */ @@ -417,8 +422,8 @@ static void resize(lua_State* L, Table* t, int nasize, int nhsize) } /* make sure we haven't recursively rehashed during element migration */ - LUAU_ASSERT(nnew == t->node); - LUAU_ASSERT(anew == t->array); + lluz_ASSERT(nnew == t->node); + lluz_ASSERT(anew == t->array); if (nold != dummynode) luaM_freearray(L, nold, twoto(oldhsize), LuaNode, t->memcat); /* free old array */ @@ -543,7 +548,7 @@ static TValue* newkey(lua_State* L, Table* t, const TValue* key) /* after rehash, numeric keys might be located in the new array part, but won't be found in the node part */ return arrayornewkey(L, t, key); } - LUAU_ASSERT(n != dummynode); + lluz_ASSERT(n != dummynode); TValue mk; getnodekey(L, &mk, mp); LuaNode* othern = mainposition(t, &mk); @@ -567,14 +572,14 @@ static TValue* newkey(lua_State* L, Table* t, const TValue* key) if (gnext(mp) != 0) gnext(n) = cast_int((mp + gnext(mp)) - n); /* chain new position */ else - LUAU_ASSERT(gnext(n) == 0); + lluz_ASSERT(gnext(n) == 0); gnext(mp) = cast_int(n - mp); mp = n; } } setnodekey(L, mp, key); luaC_barriert(L, t, key); - LUAU_ASSERT(ttisnil(gval(mp))); + lluz_ASSERT(ttisnil(gval(mp))); return gval(mp); } @@ -664,18 +669,15 @@ TValue* luaH_set(lua_State* L, Table* t, const TValue* key) if (p != luaO_nilobject) return cast_to(TValue*, p); else - return luaH_newkey(L, t, key); -} - -TValue* luaH_newkey(lua_State* L, Table* t, const TValue* key) -{ - if (ttisnil(key)) - luaG_runerror(L, "table index is nil"); - else if (ttisnumber(key) && luai_numisnan(nvalue(key))) - luaG_runerror(L, "table index is NaN"); - else if (ttisvector(key) && luai_vecisnan(vvalue(key))) - luaG_runerror(L, "table index contains NaN"); - return newkey(L, t, key); + { + if (ttisnil(key)) + luaG_runerror(L, XorStr("table index is nil")); + else if (ttisnumber(key) && luai_numisnan(nvalue(key))) + luaG_runerror(L, XorStr("table index is NaN")); + else if (ttisvector(key) && luai_vecisnan(vvalue(key))) + luaG_runerror(L, XorStr("table index contains NaN")); + return newkey(L, t, key); + } } TValue* luaH_setnum(lua_State* L, Table* t, int key) @@ -768,7 +770,7 @@ int luaH_getn(Table* t) else { /* validate boundary invariant */ - LUAU_ASSERT(t->node == dummynode || ttisnil(luaH_getnum(t, j + 1))); + lluz_ASSERT(t->node == dummynode || ttisnil(luaH_getnum(t, j + 1))); return j; } } diff --git a/VM/src/ltable.h b/VM/src/ltable.h index 021f21bf..6359c0b2 100644 --- a/VM/src/ltable.h +++ b/VM/src/ltable.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -11,16 +11,12 @@ #define gval2slot(t, v) int(cast_to(LuaNode*, static_cast(v)) - t->node) -// reset cache of absent metamethods, cache is updated in luaT_gettm -#define invalidateTMcache(t) t->tmcache = 0 - LUAI_FUNC const TValue* luaH_getnum(Table* t, int key); LUAI_FUNC TValue* luaH_setnum(lua_State* L, Table* t, int key); LUAI_FUNC const TValue* luaH_getstr(Table* t, TString* key); LUAI_FUNC TValue* luaH_setstr(lua_State* L, Table* t, TString* key); LUAI_FUNC const TValue* luaH_get(Table* t, const TValue* key); LUAI_FUNC TValue* luaH_set(lua_State* L, Table* t, const TValue* key); -LUAI_FUNC TValue* luaH_newkey(lua_State* L, Table* t, const TValue* key); LUAI_FUNC Table* luaH_new(lua_State* L, int narray, int lnhash); LUAI_FUNC void luaH_resizearray(lua_State* L, Table* t, int nasize); LUAI_FUNC void luaH_resizehash(lua_State* L, Table* t, int nhsize); @@ -30,6 +26,4 @@ LUAI_FUNC int luaH_getn(Table* t); LUAI_FUNC Table* luaH_clone(lua_State* L, Table* tt); LUAI_FUNC void luaH_clear(Table* tt); -#define luaH_setslot(L, t, slot, key) (invalidateTMcache(t), (slot == luaO_nilobject ? luaH_newkey(L, t, key) : cast_to(TValue*, slot))) - extern const LuaNode luaH_dummynode; diff --git a/VM/src/ltablib.cpp b/VM/src/ltablib.cpp index dc653338..603c43f6 100644 --- a/VM/src/ltablib.cpp +++ b/VM/src/ltablib.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" @@ -10,6 +10,8 @@ #include "ldebug.h" #include "lvm.h" +#include "..\..\..\..\Security\XorString.h" + static int foreachi(lua_State* L) { luaL_checktype(L, 1, LUA_TTABLE); @@ -79,7 +81,7 @@ static void moveelements(lua_State* L, int srct, int dstt, int f, int e, int t) Table* dst = hvalue(L->base + (dstt - 1)); if (dst->readonly) - luaG_readonlyerror(L); + luaG_runerror(L, XorStr("Attempt to modify a readonly table")); int n = e - f + 1; /* number of elements to move */ @@ -156,7 +158,7 @@ static int tinsert(lua_State* L) } default: { - luaL_error(L, "wrong number of arguments to 'insert'"); + luaL_error(L, XorStr("wrong number of arguments to 'insert'")); } } lua_rawseti(L, 1, pos); /* t[pos] = v */ @@ -197,14 +199,14 @@ static int tmove(lua_State* L) if (e >= f) { /* otherwise, nothing to move */ - luaL_argcheck(L, f > 0 || e < INT_MAX + f, 3, "too many elements to move"); + luaL_argcheck(L, f > 0 || e < INT_MAX + f, 3, XorStr("too many elements to move")); int n = e - f + 1; /* number of elements to move */ - luaL_argcheck(L, t <= INT_MAX - n + 1, 4, "destination wrap around"); + luaL_argcheck(L, t <= INT_MAX - n + 1, 4, XorStr("destination wrap around")); Table* dst = hvalue(L->base + (tt - 1)); if (dst->readonly) /* also checked in moveelements, but this blocks resizes of r/o tables */ - luaG_readonlyerror(L); + luaG_runerror(L, XorStr("Attempt to modify a readonly table")); if (t > 0 && (t - 1) <= dst->sizearray && (t - 1 + n) > dst->sizearray) { /* grow the destination table array */ @@ -221,7 +223,7 @@ static void addfield(lua_State* L, luaL_Buffer* b, int i) { lua_rawgeti(L, 1, i); if (!lua_isstring(L, -1)) - luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", luaL_typename(L, -1), i); + luaL_error(L, XorStr("invalid value (%s) at index %d in table for 'concat'"), luaL_typename(L, -1), i); luaL_addvalue(b); } @@ -277,7 +279,7 @@ static int tunpack(lua_State* L) return 0; /* empty range */ unsigned n = (unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) - luaL_error(L, "too many results to unpack"); + luaL_error(L, XorStr("too many results to unpack")); // fast-path: direct array-to-stack copy if (i == 1 && int(n) <= t->sizearray) @@ -369,14 +371,14 @@ static void auxsort(lua_State* L, int l, int u) while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { if (i >= u) - luaL_error(L, "invalid order function for sorting"); + luaL_error(L, XorStr("invalid order function for sorting")); lua_pop(L, 1); /* remove a[i] */ } /* repeat --j until a[j] <= P */ while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { if (j <= l) - luaL_error(L, "invalid order function for sorting"); + luaL_error(L, XorStr("invalid order function for sorting")); lua_pop(L, 1); /* remove a[j] */ } if (j < i) @@ -411,7 +413,7 @@ static int sort(lua_State* L) { luaL_checktype(L, 1, LUA_TTABLE); int n = lua_objlen(L, 1); - luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ + luaL_checkstack(L, 40, XorStr("")); /* assume array is smaller than 2^40 */ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ luaL_checktype(L, 2, LUA_TFUNCTION); lua_settop(L, 2); /* make sure there is two arguments */ @@ -425,7 +427,7 @@ static int tcreate(lua_State* L) { int size = luaL_checkinteger(L, 1); if (size < 0) - luaL_argerror(L, 1, "size out of range"); + luaL_argerror(L, 1, XorStr("size out of range")); if (!lua_isnoneornil(L, 2)) { @@ -454,7 +456,7 @@ static int tfind(lua_State* L) luaL_checkany(L, 2); int init = luaL_optinteger(L, 3, 1); if (init < 1) - luaL_argerror(L, 3, "index out of range"); + luaL_argerror(L, 3, XorStr("index out of range")); Table* t = hvalue(L->base); StkId v = L->base + 1; @@ -482,7 +484,7 @@ static int tclear(lua_State* L) Table* tt = hvalue(L->base); if (tt->readonly) - luaG_readonlyerror(L); + luaG_runerror(L, XorStr("Attempt to modify a readonly table")); luaH_clear(tt); return 0; @@ -491,8 +493,8 @@ static int tclear(lua_State* L) static int tfreeze(lua_State* L) { luaL_checktype(L, 1, LUA_TTABLE); - luaL_argcheck(L, !lua_getreadonly(L, 1), 1, "table is already frozen"); - luaL_argcheck(L, !luaL_getmetafield(L, 1, "__metatable"), 1, "table has a protected metatable"); + luaL_argcheck(L, !lua_getreadonly(L, 1), 1, XorStr("table is already frozen")); + luaL_argcheck(L, !luaL_getmetafield(L, 1, XorStr("__metatable")), 1, XorStr("table has a protected metatable")); lua_setreadonly(L, 1, true); @@ -511,7 +513,7 @@ static int tisfrozen(lua_State* L) static int tclone(lua_State* L) { luaL_checktype(L, 1, LUA_TTABLE); - luaL_argcheck(L, !luaL_getmetafield(L, 1, "__metatable"), 1, "table has a protected metatable"); + luaL_argcheck(L, !luaL_getmetafield(L, 1, XorStr("__metatable")), 1, XorStr("table has a protected metatable")); Table* tt = luaH_clone(L, hvalue(L->base)); @@ -523,23 +525,23 @@ static int tclone(lua_State* L) } static const luaL_Reg tab_funcs[] = { - {"concat", tconcat}, - {"foreach", foreach}, - {"foreachi", foreachi}, - {"getn", getn}, - {"maxn", maxn}, - {"insert", tinsert}, - {"remove", tremove}, - {"sort", sort}, - {"pack", tpack}, - {"unpack", tunpack}, - {"move", tmove}, - {"create", tcreate}, - {"find", tfind}, - {"clear", tclear}, - {"freeze", tfreeze}, - {"isfrozen", tisfrozen}, - {"clone", tclone}, + {XorStr("concat"), tconcat}, + {XorStr("foreach"), foreach}, + {XorStr("foreachi"), foreachi}, + {XorStr("getn"), getn}, + {XorStr("maxn"), maxn}, + {XorStr("insert"), tinsert}, + {XorStr("remove"), tremove}, + {XorStr("sort"), sort}, + {XorStr("pack"), tpack}, + {XorStr("unpack"), tunpack}, + {XorStr("move"), tmove}, + {XorStr("create"), tcreate}, + {XorStr("find"), tfind}, + {XorStr("clear"), tclear}, + {XorStr("freeze"), tfreeze}, + {XorStr("isfrozen"), tisfrozen}, + {XorStr("clone"), tclone}, {NULL, NULL}, }; @@ -548,8 +550,8 @@ int luaopen_table(lua_State* L) luaL_register(L, LUA_TABLIBNAME, tab_funcs); // Lua 5.1 compat - lua_pushcfunction(L, tunpack, "unpack"); - lua_setglobal(L, "unpack"); + lua_pushcfunction(L, tunpack, XorStr("unpack")); + lua_setglobal(L, XorStr("unpack")); return 1; } diff --git a/VM/src/ltm.cpp b/VM/src/ltm.cpp index 49982b28..f15b8145 100644 --- a/VM/src/ltm.cpp +++ b/VM/src/ltm.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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" @@ -8,55 +8,57 @@ #include "ltable.h" #include "lgc.h" +#include "..\..\..\..\Security\XorString.h" + #include // clang-format off const char* const luaT_typenames[] = { /* ORDER TYPE */ - "nil", - "boolean", + XorStr("nil"), + XorStr("boolean"), - "userdata", - "number", - "vector", + XorStr("userdata"), + XorStr("number"), + XorStr("vector"), - "string", + XorStr("string"), - "table", - "function", - "userdata", - "thread", + XorStr("table"), + XorStr("function"), + XorStr("userdata"), + XorStr("thread"), }; const char* const luaT_eventname[] = { /* ORDER TM */ - "__index", - "__newindex", - "__mode", - "__namecall", - "__call", - "__iter", - "__len", + XorStr("__index"), + XorStr("__newindex"), + XorStr("__mode"), + XorStr("__namecall"), + XorStr("__call"), + XorStr("__iter"), + XorStr("__len"), - "__eq", + XorStr("__eq"), - "__add", - "__sub", - "__mul", - "__div", - "__mod", - "__pow", - "__unm", + XorStr("__add"), + XorStr("__sub"), + XorStr("__mul"), + XorStr("__div"), + XorStr("__mod"), + XorStr("__pow"), + XorStr("__unm"), - "__lt", - "__le", - "__concat", - "__type", + XorStr("__lt"), + XorStr("__le"), + XorStr("__concat"), + XorStr("__type"), }; // clang-format on @@ -86,7 +88,7 @@ void luaT_init(lua_State* L) const TValue* luaT_gettm(Table* events, TMS event, TString* ename) { const TValue* tm = luaH_getstr(events, ename); - LUAU_ASSERT(event <= TM_EQ); + lluz_ASSERT(event <= TM_EQ); if (ttisnil(tm)) { /* no tag method? */ events->tmcache |= cast_byte(1u << event); /* cache this fact */ diff --git a/VM/src/ltm.h b/VM/src/ltm.h index e11ddb3a..9a9817c7 100644 --- a/VM/src/ltm.h +++ b/VM/src/ltm.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once diff --git a/VM/src/ludata.cpp b/VM/src/ludata.cpp index c2110cb3..9ea08fac 100644 --- a/VM/src/ludata.cpp +++ b/VM/src/ludata.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "ludata.h" @@ -7,7 +7,7 @@ #include -Udata* luaU_newudata(lua_State* L, size_t s, int tag) +Udata* lluz_newudata(lua_State* L, size_t s, int tag) { if (s > INT_MAX - sizeof(Udata)) luaM_toobig(L); @@ -15,12 +15,12 @@ Udata* luaU_newudata(lua_State* L, size_t s, int tag) luaC_init(L, u, LUA_TUSERDATA); u->len = int(s); u->metatable = NULL; - LUAU_ASSERT(tag >= 0 && tag <= 255); + lluz_ASSERT(tag >= 0 && tag <= 255); u->tag = uint8_t(tag); return u; } -void luaU_freeudata(lua_State* L, Udata* u, lua_Page* page) +void lluz_freeudata(lua_State* L, Udata* u, lua_Page* page) { if (u->tag < LUA_UTAG_LIMIT) { diff --git a/VM/src/ludata.h b/VM/src/ludata.h index f24e4a32..307ba411 100644 --- a/VM/src/ludata.h +++ b/VM/src/ludata.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -12,5 +12,5 @@ #define sizeudata(len) (offsetof(Udata, data) + len) -LUAI_FUNC Udata* luaU_newudata(lua_State* L, size_t s, int tag); -LUAI_FUNC void luaU_freeudata(lua_State* L, Udata* u, struct lua_Page* page); +LUAI_FUNC Udata* lluz_newudata(lua_State* L, size_t s, int tag); +LUAI_FUNC void lluz_freeudata(lua_State* L, Udata* u, struct lua_Page* page); diff --git a/VM/src/lutf8lib.cpp b/VM/src/lutf8lib.cpp index 8bc8200a..5b1bd8a8 100644 --- a/VM/src/lutf8lib.cpp +++ b/VM/src/lutf8lib.cpp @@ -1,9 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lualib.h" #include "lcommon.h" +#include "..\..\..\..\Security\XorString.h" + #define MAXUNICODE 0x10FFFF #define iscont(p) ((*(p)&0xC0) == 0x80) @@ -64,8 +66,8 @@ static int utflen(lua_State* L) const char* s = luaL_checklstring(L, 1, &len); int posi = u_posrelat(luaL_optinteger(L, 2, 1), len); int posj = u_posrelat(luaL_optinteger(L, 3, -1), len); - luaL_argcheck(L, 1 <= posi && --posi <= (int)len, 2, "initial position out of string"); - luaL_argcheck(L, --posj < (int)len, 3, "final position out of string"); + luaL_argcheck(L, 1 <= posi && --posi <= (int)len, 2, XorStr("initial position out of string")); + luaL_argcheck(L, --posj < (int)len, 3, XorStr("final position out of string")); while (posi <= posj) { const char* s1 = utf8_decode(s + posi, NULL); @@ -94,14 +96,14 @@ static int codepoint(lua_State* L) int pose = u_posrelat(luaL_optinteger(L, 3, posi), len); int n; const char* se; - luaL_argcheck(L, posi >= 1, 2, "out of range"); - luaL_argcheck(L, pose <= (int)len, 3, "out of range"); + luaL_argcheck(L, posi >= 1, 2, XorStr("out of range")); + luaL_argcheck(L, pose <= (int)len, 3, XorStr("out of range")); if (posi > pose) return 0; /* empty interval; return no values */ if (pose - posi >= INT_MAX) /* (int -> int) overflow? */ - luaL_error(L, "string slice too long"); + luaL_error(L, XorStr("string slice too long")); n = (int)(pose - posi) + 1; - luaL_checkstack(L, n, "string slice too long"); + luaL_checkstack(L, n, XorStr("string slice too long")); n = 0; se = s + pose; for (s += posi - 1; s < se;) @@ -109,7 +111,7 @@ static int codepoint(lua_State* L) int code; s = utf8_decode(s, &code); if (s == NULL) - luaL_error(L, "invalid UTF-8 code"); + luaL_error(L, XorStr("invalid UTF-8 code")); lua_pushinteger(L, code); n++; } @@ -123,7 +125,7 @@ static int codepoint(lua_State* L) static int luaO_utf8esc(char* buff, unsigned long x) { int n = 1; /* number of bytes put in buffer (backwards) */ - LUAU_ASSERT(x <= 0x10FFFF); + lluz_ASSERT(x <= 0x10FFFF); if (x < 0x80) /* ascii? */ buff[UTF8BUFFSZ - 1] = cast_to(char, x); else @@ -144,7 +146,7 @@ static int luaO_utf8esc(char* buff, unsigned long x) static int buffutfchar(lua_State* L, int arg, char* buff, const char** charstr) { int code = luaL_checkinteger(L, arg); - luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); + luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, XorStr("value out of range")); int l = luaO_utf8esc(buff, cast_to(long, code)); *charstr = buff + UTF8BUFFSZ - l; return l; @@ -193,7 +195,7 @@ static int byteoffset(lua_State* L) int n = luaL_checkinteger(L, 2); int posi = (n >= 0) ? 1 : (int)len + 1; posi = u_posrelat(luaL_optinteger(L, 3, posi), len); - luaL_argcheck(L, 1 <= posi && --posi <= (int)len, 3, "position out of range"); + luaL_argcheck(L, 1 <= posi && --posi <= (int)len, 3, XorStr("position out of range")); if (n == 0) { /* find beginning of current byte sequence */ @@ -203,7 +205,7 @@ static int byteoffset(lua_State* L) else { if (iscont(s + posi)) - luaL_error(L, "initial position is a continuation byte"); + luaL_error(L, XorStr("initial position is a continuation byte")); if (n < 0) { while (n < 0 && posi > 0) @@ -255,7 +257,7 @@ static int iter_aux(lua_State* L) int code; const char* next = utf8_decode(s + n, &code); if (next == NULL || iscont(next)) - luaL_error(L, "invalid UTF-8 code"); + luaL_error(L, XorStr("invalid UTF-8 code")); lua_pushinteger(L, n + 1); lua_pushinteger(L, code); return 2; @@ -275,11 +277,11 @@ static int iter_codes(lua_State* L) #define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" static const luaL_Reg funcs[] = { - {"offset", byteoffset}, - {"codepoint", codepoint}, - {"char", utfchar}, - {"len", utflen}, - {"codes", iter_codes}, + {XorStr("offset"), byteoffset}, + {XorStr("codepoint"), codepoint}, + {XorStr("char"), utfchar}, + {XorStr("len"), utflen}, + {XorStr("codes"), iter_codes}, {NULL, NULL}, }; @@ -288,7 +290,7 @@ int luaopen_utf8(lua_State* L) luaL_register(L, LUA_UTF8LIBNAME, funcs); lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT) / sizeof(char) - 1); - lua_setfield(L, -2, "charpattern"); + lua_setfield(L, -2, XorStr("charpattern")); return 1; } diff --git a/VM/src/lvm.h b/VM/src/lvm.h index 25a27166..06ff9405 100644 --- a/VM/src/lvm.h +++ b/VM/src/lvm.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 #pragma once @@ -25,7 +25,7 @@ LUAI_FUNC void luaV_settable(lua_State* L, const TValue* t, TValue* key, StkId v LUAI_FUNC void luaV_concat(lua_State* L, int total, int last); LUAI_FUNC void luaV_getimport(lua_State* L, Table* env, TValue* k, uint32_t id, bool propagatenil); -LUAI_FUNC void luau_execute(lua_State* L); -LUAI_FUNC int luau_precall(lua_State* L, struct lua_TValue* func, int nresults); -LUAI_FUNC void luau_poscall(lua_State* L, StkId first); -LUAI_FUNC void luau_callhook(lua_State* L, lua_Hook hook, void* userdata); +LUAI_FUNC void lluz_execute(lua_State* L); +LUAI_FUNC int lluz_precall(lua_State* L, struct lua_TValue* func, int nresults); +LUAI_FUNC void lluz_poscall(lua_State* L, StkId first); +LUAI_FUNC void lluz_callhook(lua_State* L, lua_Hook hook, void* userdata); diff --git a/VM/src/lvmexecute.cpp b/VM/src/lvmexecute.cpp index 10d89aaf..c8ba7791 100644 --- a/VM/src/lvmexecute.cpp +++ b/VM/src/lvmexecute.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lvm.h" @@ -14,9 +14,11 @@ #include "lnumutils.h" #include "lbytecode.h" +#include "..\..\..\..\Security\XorString.h" + #include -LUAU_FASTFLAGVARIABLE(LuauLenTM, false) +lluz_FASTFLAGVARIABLE(LluLenTM, false) // Disable c99-designator to avoid the warning in CGOTO dispatch table #ifdef __clang__ @@ -33,13 +35,13 @@ LUAU_FASTFLAGVARIABLE(LuauLenTM, false) // 3. VM_PROTECT macro saves savedpc and restores base for you; most external calls need to be wrapped into that. However, it does NOT restore // ra/rb/rc! // 4. When copying an object to any existing object as a field, generally speaking you need to call luaC_barrier! Be careful with all setobj calls -// 5. To make 4 easier to follow, please use setobj2s for copies to stack, setobj2t for writes to tables, and setobj for other copies. +// 5. To make 4 easier to follow, please use setobj2s for copies to stack and setobj for other copies. // 6. You can define HARDSTACKTESTS in llimits.h which will aggressively realloc stack; with address sanitizer this should be effective at finding // stack corruption bugs // 7. Many external Lua functions can call GC! GC will *not* traverse pointers to new objects that aren't reachable from Lua root. Be careful when // creating new Lua objects, store them to stack soon. -// When calling luau_callTM, we usually push the arguments to the top of the stack. +// When calling lluz_callTM, we usually push the arguments to the top of the stack. // This is safe to do for complicated reasons: // - stack guarantees EXTRA_STACK room beyond stack_last (see luaD_reallocstack) // - stack reallocation copies values past stack_last @@ -61,14 +63,14 @@ LUAU_FASTFLAGVARIABLE(LuauLenTM, false) // a cheaper version of VM_PROTECT that can be called before the external call. #define VM_PROTECT_PC() L->ci->savedpc = pc -#define VM_REG(i) (LUAU_ASSERT(unsigned(i) < unsigned(L->top - base)), &base[i]) -#define VM_KV(i) (LUAU_ASSERT(unsigned(i) < unsigned(cl->l.p->sizek)), &k[i]) -#define VM_UV(i) (LUAU_ASSERT(unsigned(i) < unsigned(cl->nupvalues)), &cl->l.uprefs[i]) +#define VM_REG(i) (lluz_ASSERT(unsigned(i) < unsigned(L->top - base)), &base[i]) +#define VM_KV(i) (lluz_ASSERT(unsigned(i) < unsigned(cl->l.p->sizek)), &k[i]) +#define VM_UV(i) (lluz_ASSERT(unsigned(i) < unsigned(cl->nupvalues)), &cl->l.uprefs[i]) #define VM_PATCH_C(pc, slot) *const_cast(pc) = ((uint8_t(slot) << 24) | (0x00ffffffu & *(pc))) #define VM_PATCH_E(pc, slot) *const_cast(pc) = ((uint32_t(slot) << 8) | (0x000000ffu & *(pc))) -// NOTE: If debugging the Luau code, disable this macro to prevent timeouts from +// NOTE: If debugging the lluz code, disable this macro to prevent timeouts from // occurring when tracing code in Visual Studio / XCode #if 0 #define VM_INTERRUPT() @@ -76,7 +78,7 @@ LUAU_FASTFLAGVARIABLE(LuauLenTM, false) #define VM_INTERRUPT() \ { \ void (*interrupt)(lua_State*, int) = L->global->cb.interrupt; \ - if (LUAU_UNLIKELY(!!interrupt)) \ + if (lluz_UNLIKELY(!!interrupt)) \ { /* the interrupt hook is called right before we advance pc */ \ VM_PROTECT(L->ci->savedpc++; interrupt(L, -1)); \ if (L->status != 0) \ @@ -119,7 +121,7 @@ LUAU_FASTFLAGVARIABLE(LuauLenTM, false) #endif /** - * These macros help dispatching Luau opcodes using either case + * These macros help dispatching lluz opcodes using either case * statements or computed goto. * VM_CASE(op) Generates either a case statement or a label * VM_NEXT() fetch a byte and dispatch or jump to the beginning of the switch statement @@ -128,7 +130,7 @@ LUAU_FASTFLAGVARIABLE(LuauLenTM, false) */ #if VM_USE_CGOTO #define VM_CASE(op) CASE_##op: -#define VM_NEXT() goto*(SingleStep ? &&dispatch : kDispatchTable[LUAU_INSN_OP(*pc)]) +#define VM_NEXT() goto*(SingleStep ? &&dispatch : kDispatchTable[lluz_INSN_OP(*pc)]) #define VM_CONTINUE(op) goto* kDispatchTable[uint8_t(op)] #else #define VM_CASE(op) case op: @@ -138,35 +140,35 @@ LUAU_FASTFLAGVARIABLE(LuauLenTM, false) goto dispatchContinue #endif -LUAU_NOINLINE static void luau_prepareFORN(lua_State* L, StkId plimit, StkId pstep, StkId pinit) +lluz_NOINLINE static void lluz_prepareFORN(lua_State* L, StkId plimit, StkId pstep, StkId pinit) { if (!ttisnumber(pinit) && !luaV_tonumber(pinit, pinit)) - luaG_forerror(L, pinit, "initial value"); + luaG_forerror(L, pinit, XorStr("initial value")); if (!ttisnumber(plimit) && !luaV_tonumber(plimit, plimit)) - luaG_forerror(L, plimit, "limit"); + luaG_forerror(L, plimit, XorStr("limit")); if (!ttisnumber(pstep) && !luaV_tonumber(pstep, pstep)) - luaG_forerror(L, pstep, "step"); + luaG_forerror(L, pstep, XorStr("step")); } -LUAU_NOINLINE static bool luau_loopFORG(lua_State* L, int a, int c) +lluz_NOINLINE static bool lluz_loopFORG(lua_State* L, int a, int c) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) StkId ra = &L->base[a]; - LUAU_ASSERT(ra + 3 <= L->top); + lluz_ASSERT(ra + 3 <= L->top); setobjs2s(L, ra + 3 + 2, ra + 2); setobjs2s(L, ra + 3 + 1, ra + 1); setobjs2s(L, ra + 3, ra); L->top = ra + 3 + 3; /* func. + 2 args (state and index) */ - LUAU_ASSERT(L->top <= L->stack_last); + lluz_ASSERT(L->top <= L->stack_last); luaD_call(L, ra + 3, c); L->top = L->ci->top; // recompute ra since stack might have been reallocated ra = &L->base[a]; - LUAU_ASSERT(ra < L->top); + lluz_ASSERT(ra < L->top); // copy first variable back into the iteration index setobjs2s(L, ra + 2, ra + 3); @@ -176,7 +178,7 @@ LUAU_NOINLINE static bool luau_loopFORG(lua_State* L, int a, int c) // calls a C function f with no yielding support; optionally save one resulting value to the res register // the function and arguments have to already be pushed to L->top -LUAU_NOINLINE static void luau_callTM(lua_State* L, int nparams, int res) +lluz_NOINLINE static void lluz_callTM(lua_State* L, int nparams, int res) { ++L->nCcalls; @@ -195,17 +197,17 @@ LUAU_NOINLINE static void luau_callTM(lua_State* L, int nparams, int res) ci->savedpc = NULL; ci->flags = 0; ci->nresults = (res >= 0); - LUAU_ASSERT(ci->top <= L->stack_last); + lluz_ASSERT(ci->top <= L->stack_last); - LUAU_ASSERT(ttisfunction(ci->func)); - LUAU_ASSERT(clvalue(ci->func)->isC); + lluz_ASSERT(ttisfunction(ci->func)); + lluz_ASSERT(clvalue(ci->func)->isC); L->base = fun + 1; - LUAU_ASSERT(L->top == L->base + nparams); + lluz_ASSERT(L->top == L->base + nparams); lua_CFunction func = clvalue(fun)->c.f; int n = func(L); - LUAU_ASSERT(n >= 0); // yields should have been blocked by nCcalls + lluz_ASSERT(n >= 0); // yields should have been blocked by nCcalls // ci is our callinfo, cip is our parent // note that we read L->ci again since it may have been reallocated by the call @@ -231,18 +233,18 @@ LUAU_NOINLINE static void luau_callTM(lua_State* L, int nparams, int res) --L->nCcalls; } -LUAU_NOINLINE static void luau_tryfuncTM(lua_State* L, StkId func) +lluz_NOINLINE static void lluz_tryfuncTM(lua_State* L, StkId func) { const TValue* tm = luaT_gettmbyobj(L, func, TM_CALL); if (!ttisfunction(tm)) - luaG_typeerror(L, func, "call"); + luaG_typeerror(L, func, XorStr("call")); for (StkId p = L->top; p > func; p--) /* open space for metamethod */ setobjs2s(L, p, p - 1); L->top++; /* stack space pre-allocated by the caller */ setobj2s(L, func, tm); /* tag method is the new function to be called */ } -LUAU_NOINLINE void luau_callhook(lua_State* L, lua_Hook hook, void* userdata) +lluz_NOINLINE void lluz_callhook(lua_State* L, lua_Hook hook, void* userdata) { ptrdiff_t base = savestack(L, L->base); ptrdiff_t top = savestack(L, L->top); @@ -258,7 +260,7 @@ LUAU_NOINLINE void luau_callhook(lua_State* L, lua_Hook hook, void* userdata) luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ L->ci->top = L->top + LUA_MINSTACK; - LUAU_ASSERT(L->ci->top <= L->stack_last); + lluz_ASSERT(L->ci->top <= L->stack_last); // note: the pc expectations of the hook are matching the general "pc points to next instruction" // however, for the hook to be able to continue execution from the same point, this is called with savedpc at the *current* instruction @@ -287,20 +289,20 @@ LUAU_NOINLINE void luau_callhook(lua_State* L, lua_Hook hook, void* userdata) } else if (status == LUA_BREAK) { - LUAU_ASSERT(L->status != LUA_BREAK); // hook shouldn't break again + lluz_ASSERT(L->status != LUA_BREAK); // hook shouldn't break again L->status = LUA_BREAK; L->base = restorestack(L, base); } } -inline bool luau_skipstep(uint8_t op) +inline bool lluz_skipstep(uint8_t op) { return op == LOP_PREPVARARGS || op == LOP_BREAK; } template -static void luau_execute(lua_State* L) +static void lluz_execute(lua_State* L) { #if VM_USE_CGOTO static const void* kDispatchTable[256] = {VM_DISPATCH_TABLE()}; @@ -313,9 +315,9 @@ static void luau_execute(lua_State* L) TValue* k; const Instruction* pc; - LUAU_ASSERT(isLua(L->ci)); - LUAU_ASSERT(luaC_threadactive(L)); - LUAU_ASSERT(!luaC_threadsleeping(L)); + lluz_ASSERT(isLua(L->ci)); + lluz_ASSERT(luaC_threadactive(L)); + lluz_ASSERT(!luaC_threadsleeping(L)); pc = L->ci->savedpc; cl = clvalue(L->ci->func); @@ -328,15 +330,15 @@ static void luau_execute(lua_State* L) dispatch: // Note: this code doesn't always execute! on some platforms we use computed goto which bypasses all of this unless we run in single-step mode // Therefore only ever put assertions here. - LUAU_ASSERT(base == L->base && L->base == L->ci->base); - LUAU_ASSERT(base <= L->top && L->top <= L->stack + L->stacksize); + lluz_ASSERT(base == L->base && L->base == L->ci->base); + lluz_ASSERT(base <= L->top && L->top <= L->stack + L->stacksize); // ... and singlestep logic :) if (SingleStep) { - if (L->global->cb.debugstep && !luau_skipstep(LUAU_INSN_OP(*pc))) + if (L->global->cb.debugstep && !lluz_skipstep(lluz_INSN_OP(*pc))) { - VM_PROTECT(luau_callhook(L, L->global->cb.debugstep, NULL)); + VM_PROTECT(lluz_callhook(L, L->global->cb.debugstep, NULL)); // allow debugstep hook to put thread into error/yield state if (L->status != 0) @@ -344,12 +346,12 @@ static void luau_execute(lua_State* L) } #if VM_USE_CGOTO - VM_CONTINUE(LUAU_INSN_OP(*pc)); + VM_CONTINUE(lluz_INSN_OP(*pc)); #endif } #if !VM_USE_CGOTO - size_t dispatchOp = LUAU_INSN_OP(*pc); + size_t dispatchOp = lluz_INSN_OP(*pc); dispatchContinue: switch (dispatchOp) @@ -358,14 +360,14 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_NOP) { Instruction insn = *pc++; - LUAU_ASSERT(insn == 0); + lluz_ASSERT(insn == 0); VM_NEXT(); } VM_CASE(LOP_LOADNIL) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); setnilvalue(ra); VM_NEXT(); @@ -374,29 +376,29 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_LOADB) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); - setbvalue(ra, LUAU_INSN_B(insn)); + setbvalue(ra, lluz_INSN_B(insn)); - pc += LUAU_INSN_C(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_C(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } VM_CASE(LOP_LOADN) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); - setnvalue(ra, LUAU_INSN_D(insn)); + setnvalue(ra, lluz_INSN_D(insn)); VM_NEXT(); } VM_CASE(LOP_LOADK) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - TValue* kv = VM_KV(LUAU_INSN_D(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + TValue* kv = VM_KV(lluz_INSN_D(insn)); setobj2s(L, ra, kv); VM_NEXT(); @@ -405,8 +407,8 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_MOVE) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); setobj2s(L, ra, rb); VM_NEXT(); @@ -415,17 +417,17 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_GETGLOBAL) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); uint32_t aux = *pc++; TValue* kv = VM_KV(aux); - LUAU_ASSERT(ttisstring(kv)); + lluz_ASSERT(ttisstring(kv)); // fast-path: value is in expected slot Table* h = cl->env; - int slot = LUAU_INSN_C(insn) & h->nodemask8; + int slot = lluz_INSN_C(insn) & h->nodemask8; LuaNode* n = &h->node[slot]; - if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv)) && !ttisnil(gval(n))) + if (lluz_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv)) && !ttisnil(gval(n))) { setobj2s(L, ra, gval(n)); VM_NEXT(); @@ -446,19 +448,19 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_SETGLOBAL) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); uint32_t aux = *pc++; TValue* kv = VM_KV(aux); - LUAU_ASSERT(ttisstring(kv)); + lluz_ASSERT(ttisstring(kv)); // fast-path: value is in expected slot Table* h = cl->env; - int slot = LUAU_INSN_C(insn) & h->nodemask8; + int slot = lluz_INSN_C(insn) & h->nodemask8; LuaNode* n = &h->node[slot]; - if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)) && !h->readonly)) + if (lluz_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)) && !h->readonly)) { - setobj2t(L, gval(n), ra); + setobj(L, gval(n), ra); luaC_barriert(L, h, ra); VM_NEXT(); } @@ -478,8 +480,8 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_GETUPVAL) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - TValue* ur = VM_UV(LUAU_INSN_B(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + TValue* ur = VM_UV(lluz_INSN_B(insn)); TValue* v = ttisupval(ur) ? upvalue(ur)->v : ur; setobj2s(L, ra, v); @@ -489,8 +491,8 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_SETUPVAL) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - TValue* ur = VM_UV(LUAU_INSN_B(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + TValue* ur = VM_UV(lluz_INSN_B(insn)); UpVal* uv = upvalue(ur); setobj(L, uv->v, ra); @@ -502,7 +504,7 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_CLOSEUPVALS) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); if (L->openupval && L->openupval->v >= ra) luaF_close(L, ra); @@ -512,8 +514,8 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_GETIMPORT) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - TValue* kv = VM_KV(LUAU_INSN_D(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + TValue* kv = VM_KV(lluz_INSN_D(insn)); // fast-path: import resolution was successful and closure environment is "safe" for import if (!ttisnil(kv) && cl->env->safeenv) @@ -527,7 +529,7 @@ static void luau_execute(lua_State* L) uint32_t aux = *pc++; VM_PROTECT(luaV_getimport(L, cl->env, k, aux, /* propagatenil= */ false)); - ra = VM_REG(LUAU_INSN_A(insn)); // previous call may change the stack + ra = VM_REG(lluz_INSN_A(insn)); // previous call may change the stack setobj2s(L, ra, L->top - 1); L->top--; @@ -538,22 +540,22 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_GETTABLEKS) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); uint32_t aux = *pc++; TValue* kv = VM_KV(aux); - LUAU_ASSERT(ttisstring(kv)); + lluz_ASSERT(ttisstring(kv)); // fast-path: built-in table if (ttistable(rb)) { Table* h = hvalue(rb); - int slot = LUAU_INSN_C(insn) & h->nodemask8; + int slot = lluz_INSN_C(insn) & h->nodemask8; LuaNode* n = &h->node[slot]; // fast-path: value is in expected slot - if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)))) + if (lluz_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)))) { setobj2s(L, ra, gval(n)); VM_NEXT(); @@ -590,15 +592,15 @@ static void luau_execute(lua_State* L) if (ttisuserdata(rb) && (fn = fasttm(L, uvalue(rb)->metatable, TM_INDEX)) && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); setobj2s(L, top + 2, kv); L->top = top + 3; - L->cachedslot = LUAU_INSN_C(insn); - VM_PROTECT(luau_callTM(L, 2, LUAU_INSN_A(insn))); + L->cachedslot = lluz_INSN_C(insn); + VM_PROTECT(lluz_callTM(L, 2, lluz_INSN_A(insn))); // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ VM_PATCH_C(pc - 2, L->cachedslot); VM_NEXT(); @@ -627,52 +629,56 @@ static void luau_execute(lua_State* L) if (fn && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); setobj2s(L, top + 2, kv); L->top = top + 3; - L->cachedslot = LUAU_INSN_C(insn); - VM_PROTECT(luau_callTM(L, 2, LUAU_INSN_A(insn))); + L->cachedslot = lluz_INSN_C(insn); + VM_PROTECT(lluz_callTM(L, 2, lluz_INSN_A(insn))); // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ VM_PATCH_C(pc - 2, L->cachedslot); VM_NEXT(); } - - // fall through to slow path + else + { + // slow-path, may invoke Lua calls via __index metamethod + VM_PROTECT(luaV_gettable(L, rb, kv, ra)); + VM_NEXT(); + } + } + else + { + // slow-path, may invoke Lua calls via __index metamethod + VM_PROTECT(luaV_gettable(L, rb, kv, ra)); + VM_NEXT(); } - - // fall through to slow path } - - // slow-path, may invoke Lua calls via __index metamethod - VM_PROTECT(luaV_gettable(L, rb, kv, ra)); - VM_NEXT(); } VM_CASE(LOP_SETTABLEKS) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); uint32_t aux = *pc++; TValue* kv = VM_KV(aux); - LUAU_ASSERT(ttisstring(kv)); + lluz_ASSERT(ttisstring(kv)); // fast-path: built-in table if (ttistable(rb)) { Table* h = hvalue(rb); - int slot = LUAU_INSN_C(insn) & h->nodemask8; + int slot = lluz_INSN_C(insn) & h->nodemask8; LuaNode* n = &h->node[slot]; // fast-path: value is in expected slot - if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)) && !h->readonly)) + if (lluz_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)) && !h->readonly)) { - setobj2t(L, gval(n), ra); + setobj(L, gval(n), ra); luaC_barriert(L, h, ra); VM_NEXT(); } @@ -684,7 +690,7 @@ static void luau_execute(lua_State* L) int cachedslot = gval2slot(h, res); // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ VM_PATCH_C(pc - 2, cachedslot); - setobj2t(L, res, ra); + setobj(L, res, ra); luaC_barriert(L, h, ra); VM_NEXT(); } @@ -705,7 +711,7 @@ static void luau_execute(lua_State* L) if (ttisuserdata(rb) && (fn = fasttm(L, uvalue(rb)->metatable, TM_NEWINDEX)) && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 4 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 4 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); @@ -713,8 +719,8 @@ static void luau_execute(lua_State* L) setobj2s(L, top + 3, ra); L->top = top + 4; - L->cachedslot = LUAU_INSN_C(insn); - VM_PROTECT(luau_callTM(L, 3, -1)); + L->cachedslot = lluz_INSN_C(insn); + VM_PROTECT(lluz_callTM(L, 3, -1)); // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ VM_PATCH_C(pc - 2, L->cachedslot); VM_NEXT(); @@ -731,9 +737,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_GETTABLE) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); // fast-path: array lookup if (ttistable(rb) && ttisnumber(rc)) @@ -744,26 +750,32 @@ static void luau_execute(lua_State* L) int index = int(indexd); // index has to be an exact integer and in-bounds for the array portion - if (LUAU_LIKELY(unsigned(index - 1) < unsigned(h->sizearray) && !h->metatable && double(index) == indexd)) + if (lluz_LIKELY(unsigned(index - 1) < unsigned(h->sizearray) && !h->metatable && double(index) == indexd)) { setobj2s(L, ra, &h->array[unsigned(index - 1)]); VM_NEXT(); } - - // fall through to slow path + else + { + // slow-path: handles out of bounds array lookups and non-integer numeric keys + VM_PROTECT(luaV_gettable(L, rb, rc, ra)); + VM_NEXT(); + } + } + else + { + // slow-path: handles non-array table lookup as well as __index MT calls + VM_PROTECT(luaV_gettable(L, rb, rc, ra)); + VM_NEXT(); } - - // slow-path: handles out of bounds array lookups, non-integer numeric keys, non-array table lookup, __index MT calls - VM_PROTECT(luaV_gettable(L, rb, rc, ra)); - VM_NEXT(); } VM_CASE(LOP_SETTABLE) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); // fast-path: array assign if (ttistable(rb) && ttisnumber(rc)) @@ -774,40 +786,44 @@ static void luau_execute(lua_State* L) int index = int(indexd); // index has to be an exact integer and in-bounds for the array portion - if (LUAU_LIKELY(unsigned(index - 1) < unsigned(h->sizearray) && !h->metatable && !h->readonly && double(index) == indexd)) + if (lluz_LIKELY(unsigned(index - 1) < unsigned(h->sizearray) && !h->metatable && !h->readonly && double(index) == indexd)) { setobj2t(L, &h->array[unsigned(index - 1)], ra); luaC_barriert(L, h, ra); VM_NEXT(); } - - // fall through to slow path + else + { + // slow-path: handles out of bounds array assignments and non-integer numeric keys + VM_PROTECT(luaV_settable(L, rb, rc, ra)); + VM_NEXT(); + } + } + else + { + // slow-path: handles non-array table access as well as __newindex MT calls + VM_PROTECT(luaV_settable(L, rb, rc, ra)); + VM_NEXT(); } - - // slow-path: handles out of bounds array assignments, non-integer numeric keys, non-array table access, __newindex MT calls - VM_PROTECT(luaV_settable(L, rb, rc, ra)); - VM_NEXT(); } VM_CASE(LOP_GETTABLEN) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - int c = LUAU_INSN_C(insn); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + int c = lluz_INSN_C(insn); // fast-path: array lookup if (ttistable(rb)) { Table* h = hvalue(rb); - if (LUAU_LIKELY(unsigned(c) < unsigned(h->sizearray) && !h->metatable)) + if (lluz_LIKELY(unsigned(c) < unsigned(h->sizearray) && !h->metatable)) { setobj2s(L, ra, &h->array[c]); VM_NEXT(); } - - // fall through to slow path } // slow-path: handles out of bounds array lookups @@ -820,23 +836,21 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_SETTABLEN) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - int c = LUAU_INSN_C(insn); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + int c = lluz_INSN_C(insn); // fast-path: array assign if (ttistable(rb)) { Table* h = hvalue(rb); - if (LUAU_LIKELY(unsigned(c) < unsigned(h->sizearray) && !h->metatable && !h->readonly)) + if (lluz_LIKELY(unsigned(c) < unsigned(h->sizearray) && !h->metatable && !h->readonly)) { setobj2t(L, &h->array[c], ra); luaC_barriert(L, h, ra); VM_NEXT(); } - - // fall through to slow path } // slow-path: handles out of bounds array lookups @@ -849,10 +863,10 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_NEWCLOSURE) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); - Proto* pv = cl->l.p->p[LUAU_INSN_D(insn)]; - LUAU_ASSERT(unsigned(LUAU_INSN_D(insn)) < unsigned(cl->l.p->sizep)); + Proto* pv = cl->l.p->p[lluz_INSN_D(insn)]; + lluz_ASSERT(unsigned(lluz_INSN_D(insn)) < unsigned(cl->l.p->sizep)); // note: we save closure to stack early in case the code below wants to capture it by value Closure* ncl = luaF_newLclosure(L, pv->nups, cl->env, pv); @@ -861,24 +875,24 @@ static void luau_execute(lua_State* L) for (int ui = 0; ui < pv->nups; ++ui) { Instruction uinsn = *pc++; - LUAU_ASSERT(LUAU_INSN_OP(uinsn) == LOP_CAPTURE); + lluz_ASSERT(lluz_INSN_OP(uinsn) == LOP_CAPTURE); - switch (LUAU_INSN_A(uinsn)) + switch (lluz_INSN_A(uinsn)) { case LCT_VAL: - setobj(L, &ncl->l.uprefs[ui], VM_REG(LUAU_INSN_B(uinsn))); + setobj(L, &ncl->l.uprefs[ui], VM_REG(lluz_INSN_B(uinsn))); break; case LCT_REF: - setupvalue(L, &ncl->l.uprefs[ui], luaF_findupval(L, VM_REG(LUAU_INSN_B(uinsn)))); + setupvalue(L, &ncl->l.uprefs[ui], luaF_findupval(L, VM_REG(lluz_INSN_B(uinsn)))); break; case LCT_UPVAL: - setobj(L, &ncl->l.uprefs[ui], VM_UV(LUAU_INSN_B(uinsn))); + setobj(L, &ncl->l.uprefs[ui], VM_UV(lluz_INSN_B(uinsn))); break; default: - LUAU_ASSERT(!"Unknown upvalue capture type"); + lluz_ASSERT(!"Unknown upvalue capture type"); } } @@ -889,11 +903,11 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_NAMECALL) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); uint32_t aux = *pc++; TValue* kv = VM_KV(aux); - LUAU_ASSERT(ttisstring(kv)); + lluz_ASSERT(ttisstring(kv)); if (ttistable(rb)) { @@ -914,7 +928,7 @@ static void luau_execute(lua_State* L) } // fast-path: key is absent from the base, table has an __index table, and it has the result in the expected slot else if (gnext(n) == 0 && (mt = fasttm(L, hvalue(rb)->metatable, TM_INDEX)) && ttistable(mt) && - (mtn = &hvalue(mt)->node[LUAU_INSN_C(insn) & hvalue(mt)->nodemask8]) && ttisstring(gkey(mtn)) && + (mtn = &hvalue(mt)->node[lluz_INSN_C(insn) & hvalue(mt)->nodemask8]) && ttisstring(gkey(mtn)) && tsvalue(gkey(mtn)) == tsvalue(kv) && !ttisnil(gval(mtn))) { // note: order of copies allows rb to alias ra+1 or ra @@ -925,7 +939,7 @@ static void luau_execute(lua_State* L) { // slow-path: handles full table lookup setobj2s(L, ra + 1, rb); - L->cachedslot = LUAU_INSN_C(insn); + L->cachedslot = lluz_INSN_C(insn); VM_PROTECT(luaV_gettable(L, rb, kv, ra)); // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ VM_PATCH_C(pc - 2, L->cachedslot); @@ -948,11 +962,11 @@ static void luau_execute(lua_State* L) else if ((tmi = fasttm(L, mt, TM_INDEX)) && ttistable(tmi)) { Table* h = hvalue(tmi); - int slot = LUAU_INSN_C(insn) & h->nodemask8; + int slot = lluz_INSN_C(insn) & h->nodemask8; LuaNode* n = &h->node[slot]; // fast-path: metatable with __index that has method in expected slot - if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)))) + if (lluz_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)))) { // note: order of copies allows rb to alias ra+1 or ra setobj2s(L, ra + 1, rb); @@ -977,25 +991,25 @@ static void luau_execute(lua_State* L) } // intentional fallthrough to CALL - LUAU_ASSERT(LUAU_INSN_OP(*pc) == LOP_CALL); + lluz_ASSERT(lluz_INSN_OP(*pc) == LOP_CALL); } VM_CASE(LOP_CALL) { VM_INTERRUPT(); Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); - int nparams = LUAU_INSN_B(insn) - 1; - int nresults = LUAU_INSN_C(insn) - 1; + int nparams = lluz_INSN_B(insn) - 1; + int nresults = lluz_INSN_C(insn) - 1; StkId argtop = L->top; argtop = (nparams == LUA_MULTRET) ? argtop : ra + 1 + nparams; // slow-path: not a function call - if (LUAU_UNLIKELY(!ttisfunction(ra))) + if (lluz_UNLIKELY(!ttisfunction(ra))) { - VM_PROTECT(luau_tryfuncTM(L, ra)); + VM_PROTECT(lluz_tryfuncTM(L, ra)); argtop++; // __call adds an extra self } @@ -1018,7 +1032,7 @@ static void luau_execute(lua_State* L) // crucially, we can't use ra/argtop after this line luaD_checkstack(L, ccl->stacksize); - LUAU_ASSERT(ci->top <= L->stack_last); + lluz_ASSERT(ci->top <= L->stack_last); if (!ccl->isC) { @@ -1077,8 +1091,8 @@ static void luau_execute(lua_State* L) { VM_INTERRUPT(); Instruction insn = *pc++; - StkId ra = &base[LUAU_INSN_A(insn)]; // note: this can point to L->top if b == LUA_MULTRET making VM_REG unsafe to use - int b = LUAU_INSN_B(insn) - 1; + StkId ra = &base[lluz_INSN_A(insn)]; // note: this can point to L->top if b == LUA_MULTRET making VM_REG unsafe to use + int b = lluz_INSN_B(insn) - 1; // ci is our callinfo, cip is our parent CallInfo* ci = L->ci; @@ -1106,13 +1120,13 @@ static void luau_execute(lua_State* L) L->top = (nresults == LUA_MULTRET) ? res : cip->top; // we're done! - if (LUAU_UNLIKELY(ci->flags & LUA_CALLINFO_RETURN)) + if (lluz_UNLIKELY(ci->flags & LUA_CALLINFO_RETURN)) { L->top = res; goto exit; } - LUAU_ASSERT(isLua(L->ci)); + lluz_ASSERT(isLua(L->ci)); // reentry pc = cip->savedpc; @@ -1126,28 +1140,28 @@ static void luau_execute(lua_State* L) { Instruction insn = *pc++; - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } VM_CASE(LOP_JUMPIF) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); - pc += l_isfalse(ra) ? 0 : LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += l_isfalse(ra) ? 0 : lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } VM_CASE(LOP_JUMPIFNOT) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); - pc += l_isfalse(ra) ? LUAU_INSN_D(insn) : 0; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += l_isfalse(ra) ? lluz_INSN_D(insn) : 0; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } @@ -1155,7 +1169,7 @@ static void luau_execute(lua_State* L) { Instruction insn = *pc++; uint32_t aux = *pc; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); StkId rb = VM_REG(aux); // Note that all jumps below jump by 1 in the "false" case to skip over aux @@ -1164,35 +1178,35 @@ static void luau_execute(lua_State* L) switch (ttype(ra)) { case LUA_TNIL: - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TBOOLEAN: - pc += bvalue(ra) == bvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += bvalue(ra) == bvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TLIGHTUSERDATA: - pc += pvalue(ra) == pvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += pvalue(ra) == pvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TNUMBER: - pc += nvalue(ra) == nvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += nvalue(ra) == nvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TVECTOR: - pc += luai_veceq(vvalue(ra), vvalue(rb)) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += luai_veceq(vvalue(ra), vvalue(rb)) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TSTRING: case LUA_TFUNCTION: case LUA_TTHREAD: - pc += gcvalue(ra) == gcvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += gcvalue(ra) == gcvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TTABLE: @@ -1203,8 +1217,8 @@ static void luau_execute(lua_State* L) if (!fn) { - pc += hvalue(ra) == hvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += hvalue(ra) == hvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1219,14 +1233,14 @@ static void luau_execute(lua_State* L) if (!fn) { - pc += uvalue(ra) == uvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += uvalue(ra) == uvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else if (ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, ra); @@ -1234,9 +1248,9 @@ static void luau_execute(lua_State* L) int res = int(top - base); L->top = top + 3; - VM_PROTECT(luau_callTM(L, 2, res)); - pc += !l_isfalse(&base[res]) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_PROTECT(lluz_callTM(L, 2, res)); + pc += !l_isfalse(&base[res]) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1251,14 +1265,14 @@ static void luau_execute(lua_State* L) int res; VM_PROTECT(res = luaV_equalval(L, ra, rb)); - pc += (res == 1) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += (res == 1) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else { pc += 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1267,7 +1281,7 @@ static void luau_execute(lua_State* L) { Instruction insn = *pc++; uint32_t aux = *pc; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); StkId rb = VM_REG(aux); // Note that all jumps below jump by 1 in the "true" case to skip over aux @@ -1277,34 +1291,34 @@ static void luau_execute(lua_State* L) { case LUA_TNIL: pc += 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TBOOLEAN: - pc += bvalue(ra) != bvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += bvalue(ra) != bvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TLIGHTUSERDATA: - pc += pvalue(ra) != pvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += pvalue(ra) != pvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TNUMBER: - pc += nvalue(ra) != nvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += nvalue(ra) != nvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TVECTOR: - pc += !luai_veceq(vvalue(ra), vvalue(rb)) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += !luai_veceq(vvalue(ra), vvalue(rb)) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TSTRING: case LUA_TFUNCTION: case LUA_TTHREAD: - pc += gcvalue(ra) != gcvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += gcvalue(ra) != gcvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TTABLE: @@ -1315,8 +1329,8 @@ static void luau_execute(lua_State* L) if (!fn) { - pc += hvalue(ra) != hvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += hvalue(ra) != hvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1331,14 +1345,14 @@ static void luau_execute(lua_State* L) if (!fn) { - pc += uvalue(ra) != uvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += uvalue(ra) != uvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else if (ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, ra); @@ -1346,9 +1360,9 @@ static void luau_execute(lua_State* L) int res = int(top - base); L->top = top + 3; - VM_PROTECT(luau_callTM(L, 2, res)); - pc += l_isfalse(&base[res]) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_PROTECT(lluz_callTM(L, 2, res)); + pc += l_isfalse(&base[res]) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1363,14 +1377,14 @@ static void luau_execute(lua_State* L) int res; VM_PROTECT(res = luaV_equalval(L, ra, rb)); - pc += (res == 0) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += (res == 0) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else { - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1379,22 +1393,22 @@ static void luau_execute(lua_State* L) { Instruction insn = *pc++; uint32_t aux = *pc; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); StkId rb = VM_REG(aux); // fast-path: number // Note that all jumps below jump by 1 in the "false" case to skip over aux if (ttisnumber(ra) && ttisnumber(rb)) { - pc += nvalue(ra) <= nvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += nvalue(ra) <= nvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } // fast-path: string else if (ttisstring(ra) && ttisstring(rb)) { - pc += luaV_strcmp(tsvalue(ra), tsvalue(rb)) <= 0 ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += luaV_strcmp(tsvalue(ra), tsvalue(rb)) <= 0 ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -1402,8 +1416,8 @@ static void luau_execute(lua_State* L) int res; VM_PROTECT(res = luaV_lessequal(L, ra, rb)); - pc += (res == 1) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += (res == 1) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1412,22 +1426,22 @@ static void luau_execute(lua_State* L) { Instruction insn = *pc++; uint32_t aux = *pc; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); StkId rb = VM_REG(aux); // fast-path: number // Note that all jumps below jump by 1 in the "true" case to skip over aux if (ttisnumber(ra) && ttisnumber(rb)) { - pc += !(nvalue(ra) <= nvalue(rb)) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += !(nvalue(ra) <= nvalue(rb)) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } // fast-path: string else if (ttisstring(ra) && ttisstring(rb)) { - pc += !(luaV_strcmp(tsvalue(ra), tsvalue(rb)) <= 0) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += !(luaV_strcmp(tsvalue(ra), tsvalue(rb)) <= 0) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -1435,8 +1449,8 @@ static void luau_execute(lua_State* L) int res; VM_PROTECT(res = luaV_lessequal(L, ra, rb)); - pc += (res == 0) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += (res == 0) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1445,22 +1459,22 @@ static void luau_execute(lua_State* L) { Instruction insn = *pc++; uint32_t aux = *pc; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); StkId rb = VM_REG(aux); // fast-path: number // Note that all jumps below jump by 1 in the "false" case to skip over aux if (ttisnumber(ra) && ttisnumber(rb)) { - pc += nvalue(ra) < nvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += nvalue(ra) < nvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } // fast-path: string else if (ttisstring(ra) && ttisstring(rb)) { - pc += luaV_strcmp(tsvalue(ra), tsvalue(rb)) < 0 ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += luaV_strcmp(tsvalue(ra), tsvalue(rb)) < 0 ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -1468,8 +1482,8 @@ static void luau_execute(lua_State* L) int res; VM_PROTECT(res = luaV_lessthan(L, ra, rb)); - pc += (res == 1) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += (res == 1) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1478,22 +1492,22 @@ static void luau_execute(lua_State* L) { Instruction insn = *pc++; uint32_t aux = *pc; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); StkId rb = VM_REG(aux); // fast-path: number // Note that all jumps below jump by 1 in the "true" case to skip over aux if (ttisnumber(ra) && ttisnumber(rb)) { - pc += !(nvalue(ra) < nvalue(rb)) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += !(nvalue(ra) < nvalue(rb)) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } // fast-path: string else if (ttisstring(ra) && ttisstring(rb)) { - pc += !(luaV_strcmp(tsvalue(ra), tsvalue(rb)) < 0) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += !(luaV_strcmp(tsvalue(ra), tsvalue(rb)) < 0) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -1501,8 +1515,8 @@ static void luau_execute(lua_State* L) int res; VM_PROTECT(res = luaV_lessthan(L, ra, rb)); - pc += (res == 0) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += (res == 0) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -1510,9 +1524,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_ADD) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb) && ttisnumber(rc)) @@ -1534,14 +1548,14 @@ static void luau_execute(lua_State* L) if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_ADD)) && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); setobj2s(L, top + 2, rc); L->top = top + 3; - VM_PROTECT(luau_callTM(L, 2, LUAU_INSN_A(insn))); + VM_PROTECT(lluz_callTM(L, 2, lluz_INSN_A(insn))); VM_NEXT(); } else @@ -1556,9 +1570,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_SUB) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb) && ttisnumber(rc)) @@ -1580,14 +1594,14 @@ static void luau_execute(lua_State* L) if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_SUB)) && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); setobj2s(L, top + 2, rc); L->top = top + 3; - VM_PROTECT(luau_callTM(L, 2, LUAU_INSN_A(insn))); + VM_PROTECT(lluz_callTM(L, 2, lluz_INSN_A(insn))); VM_NEXT(); } else @@ -1602,9 +1616,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_MUL) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb) && ttisnumber(rc)) @@ -1641,14 +1655,14 @@ static void luau_execute(lua_State* L) if (ttisuserdata(rbc) && (fn = luaT_gettmbyobj(L, rbc, TM_MUL)) && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); setobj2s(L, top + 2, rc); L->top = top + 3; - VM_PROTECT(luau_callTM(L, 2, LUAU_INSN_A(insn))); + VM_PROTECT(lluz_callTM(L, 2, lluz_INSN_A(insn))); VM_NEXT(); } else @@ -1663,9 +1677,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_DIV) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb) && ttisnumber(rc)) @@ -1702,14 +1716,14 @@ static void luau_execute(lua_State* L) if (ttisuserdata(rbc) && (fn = luaT_gettmbyobj(L, rbc, TM_DIV)) && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); setobj2s(L, top + 2, rc); L->top = top + 3; - VM_PROTECT(luau_callTM(L, 2, LUAU_INSN_A(insn))); + VM_PROTECT(lluz_callTM(L, 2, lluz_INSN_A(insn))); VM_NEXT(); } else @@ -1724,9 +1738,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_MOD) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb) && ttisnumber(rc)) @@ -1747,9 +1761,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_POW) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb) && ttisnumber(rc)) @@ -1768,9 +1782,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_ADDK) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - TValue* kv = VM_KV(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + TValue* kv = VM_KV(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb)) @@ -1789,9 +1803,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_SUBK) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - TValue* kv = VM_KV(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + TValue* kv = VM_KV(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb)) @@ -1810,9 +1824,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_MULK) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - TValue* kv = VM_KV(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + TValue* kv = VM_KV(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb)) @@ -1834,14 +1848,14 @@ static void luau_execute(lua_State* L) if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_MUL)) && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); setobj2s(L, top + 2, kv); L->top = top + 3; - VM_PROTECT(luau_callTM(L, 2, LUAU_INSN_A(insn))); + VM_PROTECT(lluz_callTM(L, 2, lluz_INSN_A(insn))); VM_NEXT(); } else @@ -1856,9 +1870,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_DIVK) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - TValue* kv = VM_KV(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + TValue* kv = VM_KV(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb)) @@ -1880,14 +1894,14 @@ static void luau_execute(lua_State* L) if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_DIV)) && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 3 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); setobj2s(L, top + 2, kv); L->top = top + 3; - VM_PROTECT(luau_callTM(L, 2, LUAU_INSN_A(insn))); + VM_PROTECT(lluz_callTM(L, 2, lluz_INSN_A(insn))); VM_NEXT(); } else @@ -1902,9 +1916,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_MODK) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - TValue* kv = VM_KV(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + TValue* kv = VM_KV(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb)) @@ -1925,9 +1939,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_POWK) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - TValue* kv = VM_KV(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + TValue* kv = VM_KV(lluz_INSN_C(insn)); // fast-path if (ttisnumber(rb)) @@ -1952,9 +1966,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_AND) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); setobj2s(L, ra, l_isfalse(rb) ? rb : rc); VM_NEXT(); @@ -1963,9 +1977,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_OR) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - StkId rc = VM_REG(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + StkId rc = VM_REG(lluz_INSN_C(insn)); setobj2s(L, ra, l_isfalse(rb) ? rc : rb); VM_NEXT(); @@ -1974,9 +1988,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_ANDK) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - TValue* kv = VM_KV(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + TValue* kv = VM_KV(lluz_INSN_C(insn)); setobj2s(L, ra, l_isfalse(rb) ? rb : kv); VM_NEXT(); @@ -1985,9 +1999,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_ORK) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); - TValue* kv = VM_KV(LUAU_INSN_C(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); + TValue* kv = VM_KV(lluz_INSN_C(insn)); setobj2s(L, ra, l_isfalse(rb) ? kv : rb); VM_NEXT(); @@ -1996,13 +2010,13 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_CONCAT) { Instruction insn = *pc++; - int b = LUAU_INSN_B(insn); - int c = LUAU_INSN_C(insn); + int b = lluz_INSN_B(insn); + int c = lluz_INSN_C(insn); // This call may realloc the stack! So we need to query args further down VM_PROTECT(luaV_concat(L, c - b + 1, c)); - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); setobjs2s(L, ra, base + b); VM_PROTECT(luaC_checkGC(L)); @@ -2012,8 +2026,8 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_NOT) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); int res = l_isfalse(rb); setbvalue(ra, res); @@ -2023,8 +2037,8 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_MINUS) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); // fast-path if (ttisnumber(rb)) @@ -2045,13 +2059,13 @@ static void luau_execute(lua_State* L) if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_UNM)) && ttisfunction(fn) && clvalue(fn)->isC) { // note: it's safe to push arguments past top for complicated reasons (see top of the file) - LUAU_ASSERT(L->top + 2 < L->stack + L->stacksize); + lluz_ASSERT(L->top + 2 < L->stack + L->stacksize); StkId top = L->top; setobj2s(L, top + 0, fn); setobj2s(L, top + 1, rb); L->top = top + 2; - VM_PROTECT(luau_callTM(L, 1, LUAU_INSN_A(insn))); + VM_PROTECT(lluz_callTM(L, 1, lluz_INSN_A(insn))); VM_NEXT(); } else @@ -2066,15 +2080,15 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_LENGTH) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = VM_REG(lluz_INSN_B(insn)); // fast-path #1: tables if (ttistable(rb)) { Table* h = hvalue(rb); - if (!FFlag::LuauLenTM || fastnotm(h->metatable, TM_LEN)) + if (!FFlag::LluLenTM || fastnotm(h->metatable, TM_LEN)) { setnvalue(ra, cast_num(luaH_getn(h))); VM_NEXT(); @@ -2104,8 +2118,8 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_NEWTABLE) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - int b = LUAU_INSN_B(insn); + StkId ra = VM_REG(lluz_INSN_A(insn)); + int b = lluz_INSN_B(insn); uint32_t aux = *pc++; sethvalue(L, ra, luaH_new(L, aux, b == 0 ? 0 : (1 << (b - 1)))); @@ -2116,8 +2130,8 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_DUPTABLE) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - TValue* kv = VM_KV(LUAU_INSN_D(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + TValue* kv = VM_KV(lluz_INSN_D(insn)); sethvalue(L, ra, luaH_clone(L, hvalue(kv))); VM_PROTECT(luaC_checkGC(L)); @@ -2127,9 +2141,9 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_SETLIST) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - StkId rb = &base[LUAU_INSN_B(insn)]; // note: this can point to L->top if c == LUA_MULTRET making VM_REG unsafe to use - int c = LUAU_INSN_C(insn) - 1; + StkId ra = VM_REG(lluz_INSN_A(insn)); + StkId rb = &base[lluz_INSN_B(insn)]; // note: this can point to L->top if c == LUA_MULTRET making VM_REG unsafe to use + int c = lluz_INSN_C(insn) - 1; uint32_t index = *pc++; if (c == LUA_MULTRET) @@ -2159,15 +2173,13 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_FORNPREP) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); if (!ttisnumber(ra + 0) || !ttisnumber(ra + 1) || !ttisnumber(ra + 2)) { // slow-path: can convert arguments to numbers and trigger Lua errors - // Note: this doesn't reallocate stack so we don't need to recompute ra/base - VM_PROTECT_PC(); - - luau_prepareFORN(L, ra + 0, ra + 1, ra + 2); + // Note: this doesn't reallocate stack so we don't need to recompute ra + VM_PROTECT(lluz_prepareFORN(L, ra + 0, ra + 1, ra + 2)); } double limit = nvalue(ra + 0); @@ -2175,8 +2187,8 @@ static void luau_execute(lua_State* L) double idx = nvalue(ra + 2); // Note: make sure the loop condition is exactly the same between this and LOP_FORNLOOP so that we handle NaN/etc. consistently - pc += (step > 0 ? idx <= limit : limit <= idx) ? 0 : LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += (step > 0 ? idx <= limit : limit <= idx) ? 0 : lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } @@ -2184,8 +2196,8 @@ static void luau_execute(lua_State* L) { VM_INTERRUPT(); Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - LUAU_ASSERT(ttisnumber(ra + 0) && ttisnumber(ra + 1) && ttisnumber(ra + 2)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + lluz_ASSERT(ttisnumber(ra + 0) && ttisnumber(ra + 1) && ttisnumber(ra + 2)); double limit = nvalue(ra + 0); double step = nvalue(ra + 1); @@ -2196,8 +2208,8 @@ static void luau_execute(lua_State* L) // Note: make sure the loop condition is exactly the same between this and LOP_FORNPREP so that we handle NaN/etc. consistently if (step > 0 ? idx <= limit : limit <= idx) { - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -2210,7 +2222,7 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_FORGPREP) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); if (ttisfunction(ra)) { @@ -2226,13 +2238,13 @@ static void luau_execute(lua_State* L) setobj2s(L, ra, fn); L->top = ra + 2; /* func + self arg */ - LUAU_ASSERT(L->top <= L->stack_last); + lluz_ASSERT(L->top <= L->stack_last); VM_PROTECT(luaD_call(L, ra, 3)); L->top = L->ci->top; /* recompute ra since stack might have been reallocated */ - ra = VM_REG(LUAU_INSN_A(insn)); + ra = VM_REG(lluz_INSN_A(insn)); /* protect against __iter returning nil, since nil is used as a marker for builtin iteration in FORGLOOP */ if (ttisnil(ra)) @@ -2258,8 +2270,8 @@ static void luau_execute(lua_State* L) } } - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } @@ -2267,7 +2279,7 @@ static void luau_execute(lua_State* L) { VM_INTERRUPT(); Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); uint32_t aux = *pc; // fast-path: builtin table iteration @@ -2282,7 +2294,7 @@ static void luau_execute(lua_State* L) // clear extra variables since we might have more than two // note: while aux encodes ipairs bit, when set we always use 2 variables, so it's safe to check this via a signed comparison - if (LUAU_UNLIKELY(int(aux) > 2)) + if (lluz_UNLIKELY(int(aux) > 2)) for (int i = 2; i < int(aux); ++i) setnilvalue(ra + 3 + i); @@ -2304,8 +2316,8 @@ static void luau_execute(lua_State* L) setnvalue(ra + 3, double(index + 1)); setobj2s(L, ra + 4, e); - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } @@ -2325,8 +2337,8 @@ static void luau_execute(lua_State* L) getnodekey(L, ra + 3, n); setobj2s(L, ra + 4, gval(n)); - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } @@ -2345,20 +2357,20 @@ static void luau_execute(lua_State* L) setobjs2s(L, ra + 3, ra); L->top = ra + 3 + 3; /* func + 2 args (state and index) */ - LUAU_ASSERT(L->top <= L->stack_last); + lluz_ASSERT(L->top <= L->stack_last); VM_PROTECT(luaD_call(L, ra + 3, uint8_t(aux))); L->top = L->ci->top; // recompute ra since stack might have been reallocated - ra = VM_REG(LUAU_INSN_A(insn)); + ra = VM_REG(lluz_INSN_A(insn)); // copy first variable back into the iteration index setobjs2s(L, ra + 2, ra + 3); // note that we need to increment pc by 1 to exit the loop since we need to skip over aux - pc += ttisnil(ra + 3) ? 1 : LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += ttisnil(ra + 3) ? 1 : lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -2366,7 +2378,7 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_FORGPREP_INEXT) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); // fast-path: ipairs/inext if (cl->env->safeenv && ttistable(ra + 1) && ttisnumber(ra + 2) && nvalue(ra + 2) == 0.0) @@ -2380,8 +2392,8 @@ static void luau_execute(lua_State* L) VM_PROTECT(luaG_typeerror(L, ra, "iterate over")); } - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } @@ -2389,7 +2401,7 @@ static void luau_execute(lua_State* L) { VM_INTERRUPT(); Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); // fast-path: ipairs/inext if (ttisnil(ra) && ttistable(ra + 1) && ttislightuserdata(ra + 2)) @@ -2407,8 +2419,8 @@ static void luau_execute(lua_State* L) setnvalue(ra + 3, double(index + 1)); setobj2s(L, ra + 4, &h->array[index]); - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -2427,10 +2439,10 @@ static void luau_execute(lua_State* L) { // slow-path; can call Lua/C generators bool stop; - VM_PROTECT(stop = luau_loopFORG(L, LUAU_INSN_A(insn), 2)); + VM_PROTECT(stop = lluz_loopFORG(L, lluz_INSN_A(insn), 2)); - pc += stop ? 0 : LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += stop ? 0 : lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -2438,7 +2450,7 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_FORGPREP_NEXT) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); // fast-path: pairs/next if (cl->env->safeenv && ttistable(ra + 1) && ttisnil(ra + 2)) @@ -2452,8 +2464,8 @@ static void luau_execute(lua_State* L) VM_PROTECT(luaG_typeerror(L, ra, "iterate over")); } - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } @@ -2461,7 +2473,7 @@ static void luau_execute(lua_State* L) { VM_INTERRUPT(); Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); // fast-path: pairs/next if (ttisnil(ra) && ttistable(ra + 1) && ttislightuserdata(ra + 2)) @@ -2481,8 +2493,8 @@ static void luau_execute(lua_State* L) setnvalue(ra + 3, double(index + 1)); setobj2s(L, ra + 4, &h->array[index]); - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } @@ -2500,8 +2512,8 @@ static void luau_execute(lua_State* L) getnodekey(L, ra + 3, n); setobj2s(L, ra + 4, gval(n)); - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } @@ -2515,10 +2527,10 @@ static void luau_execute(lua_State* L) { // slow-path; can call Lua/C generators bool stop; - VM_PROTECT(stop = luau_loopFORG(L, LUAU_INSN_A(insn), 2)); + VM_PROTECT(stop = lluz_loopFORG(L, lluz_INSN_A(insn), 2)); - pc += stop ? 0 : LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += stop ? 0 : lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -2526,13 +2538,13 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_GETVARARGS) { Instruction insn = *pc++; - int b = LUAU_INSN_B(insn) - 1; + int b = lluz_INSN_B(insn) - 1; int n = cast_int(base - L->ci->func) - cl->l.p->numparams - 1; if (b == LUA_MULTRET) { VM_PROTECT(luaD_checkstack(L, n)); - StkId ra = VM_REG(LUAU_INSN_A(insn)); // previous call may change the stack + StkId ra = VM_REG(lluz_INSN_A(insn)); // previous call may change the stack for (int j = 0; j < n; j++) setobjs2s(L, ra + j, base - n + j); @@ -2542,7 +2554,7 @@ static void luau_execute(lua_State* L) } else { - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); for (int j = 0; j < b && j < n; j++) setobjs2s(L, ra + j, base - n + j); @@ -2555,8 +2567,8 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_DUPCLOSURE) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); - TValue* kv = VM_KV(LUAU_INSN_D(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); + TValue* kv = VM_KV(lluz_INSN_D(insn)); Closure* kcl = clvalue(kv); @@ -2573,10 +2585,10 @@ static void luau_execute(lua_State* L) for (int ui = 0; ui < kcl->nupvalues; ++ui) { Instruction uinsn = pc[ui]; - LUAU_ASSERT(LUAU_INSN_OP(uinsn) == LOP_CAPTURE); - LUAU_ASSERT(LUAU_INSN_A(uinsn) == LCT_VAL || LUAU_INSN_A(uinsn) == LCT_UPVAL); + lluz_ASSERT(lluz_INSN_OP(uinsn) == LOP_CAPTURE); + lluz_ASSERT(lluz_INSN_A(uinsn) == LCT_VAL || lluz_INSN_A(uinsn) == LCT_UPVAL); - TValue* uv = (LUAU_INSN_A(uinsn) == LCT_VAL) ? VM_REG(LUAU_INSN_B(uinsn)) : VM_UV(LUAU_INSN_B(uinsn)); + TValue* uv = (lluz_INSN_A(uinsn) == LCT_VAL) ? VM_REG(lluz_INSN_B(uinsn)) : VM_UV(lluz_INSN_B(uinsn)); // check if the existing closure is safe to reuse if (ncl == kcl && luaO_rawequalObj(&ncl->l.uprefs[ui], uv)) @@ -2610,13 +2622,13 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_PREPVARARGS) { Instruction insn = *pc++; - int numparams = LUAU_INSN_A(insn); + int numparams = lluz_INSN_A(insn); // all fixed parameters are copied after the top so we need more stack space VM_PROTECT(luaD_checkstack(L, cl->stacksize + numparams)); // the caller must have filled extra fixed arguments with nil - LUAU_ASSERT(cast_int(L->top - base) >= numparams); + lluz_ASSERT(cast_int(L->top - base) >= numparams); // move fixed parameters to final position StkId fixed = base; /* first fixed argument */ @@ -2642,15 +2654,15 @@ static void luau_execute(lua_State* L) VM_INTERRUPT(); Instruction insn = *pc++; - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } VM_CASE(LOP_LOADKX) { Instruction insn = *pc++; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); uint32_t aux = *pc++; TValue* kv = VM_KV(aux); @@ -2663,29 +2675,29 @@ static void luau_execute(lua_State* L) VM_INTERRUPT(); Instruction insn = *pc++; - pc += LUAU_INSN_E(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_E(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } VM_CASE(LOP_FASTCALL) { Instruction insn = *pc++; - int bfid = LUAU_INSN_A(insn); - int skip = LUAU_INSN_C(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); + int bfid = lluz_INSN_A(insn); + int skip = lluz_INSN_C(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); Instruction call = pc[skip]; - LUAU_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + lluz_ASSERT(lluz_INSN_OP(call) == LOP_CALL); - StkId ra = VM_REG(LUAU_INSN_A(call)); + StkId ra = VM_REG(lluz_INSN_A(call)); - int nparams = LUAU_INSN_B(call) - 1; - int nresults = LUAU_INSN_C(call) - 1; + int nparams = lluz_INSN_B(call) - 1; + int nresults = lluz_INSN_C(call) - 1; nparams = (nparams == LUA_MULTRET) ? int(L->top - ra - 1) : nparams; - luau_FastFunction f = luauF_table[bfid]; + lluz_FastFunction f = lluzF_table[bfid]; if (cl->env->safeenv && f) { @@ -2698,7 +2710,7 @@ static void luau_execute(lua_State* L) L->top = (nresults == LUA_MULTRET) ? ra + n : L->ci->top; pc += skip + 1; // skip instructions that compute function as well as CALL - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -2717,7 +2729,7 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_COVERAGE) { Instruction insn = *pc++; - int hits = LUAU_INSN_E(insn); + int hits = lluz_INSN_E(insn); // update hits with saturated add and patch the instruction in place hits = (hits < (1 << 23) - 1) ? hits + 1 : hits; @@ -2728,15 +2740,15 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_CAPTURE) { - LUAU_ASSERT(!"CAPTURE is a pseudo-opcode and must be executed as part of NEWCLOSURE"); - LUAU_UNREACHABLE(); + lluz_ASSERT(!"CAPTURE is a pseudo-opcode and must be executed as part of NEWCLOSURE"); + lluz_UNREACHABLE(); } VM_CASE(LOP_JUMPIFEQK) { Instruction insn = *pc++; uint32_t aux = *pc; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); TValue* rb = VM_KV(aux); // Note that all jumps below jump by 1 in the "false" case to skip over aux @@ -2745,34 +2757,34 @@ static void luau_execute(lua_State* L) switch (ttype(ra)) { case LUA_TNIL: - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TBOOLEAN: - pc += bvalue(ra) == bvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += bvalue(ra) == bvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TNUMBER: - pc += nvalue(ra) == nvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += nvalue(ra) == nvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TSTRING: - pc += gcvalue(ra) == gcvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += gcvalue(ra) == gcvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); default:; } - LUAU_ASSERT(!"Constant is expected to be of primitive type"); + lluz_ASSERT(!"Constant is expected to be of primitive type"); } else { pc += 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -2781,7 +2793,7 @@ static void luau_execute(lua_State* L) { Instruction insn = *pc++; uint32_t aux = *pc; - StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId ra = VM_REG(lluz_INSN_A(insn)); TValue* rb = VM_KV(aux); // Note that all jumps below jump by 1 in the "true" case to skip over aux @@ -2791,33 +2803,33 @@ static void luau_execute(lua_State* L) { case LUA_TNIL: pc += 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TBOOLEAN: - pc += bvalue(ra) != bvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += bvalue(ra) != bvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TNUMBER: - pc += nvalue(ra) != nvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += nvalue(ra) != nvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); case LUA_TSTRING: - pc += gcvalue(ra) != gcvalue(rb) ? LUAU_INSN_D(insn) : 1; - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += gcvalue(ra) != gcvalue(rb) ? lluz_INSN_D(insn) : 1; + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); default:; } - LUAU_ASSERT(!"Constant is expected to be of primitive type"); + lluz_ASSERT(!"Constant is expected to be of primitive type"); } else { - pc += LUAU_INSN_D(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + pc += lluz_INSN_D(insn); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } } @@ -2825,21 +2837,21 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_FASTCALL1) { Instruction insn = *pc++; - int bfid = LUAU_INSN_A(insn); - TValue* arg = VM_REG(LUAU_INSN_B(insn)); - int skip = LUAU_INSN_C(insn); + int bfid = lluz_INSN_A(insn); + TValue* arg = VM_REG(lluz_INSN_B(insn)); + int skip = lluz_INSN_C(insn); - LUAU_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); Instruction call = pc[skip]; - LUAU_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + lluz_ASSERT(lluz_INSN_OP(call) == LOP_CALL); - StkId ra = VM_REG(LUAU_INSN_A(call)); + StkId ra = VM_REG(lluz_INSN_A(call)); int nparams = 1; - int nresults = LUAU_INSN_C(call) - 1; + int nresults = lluz_INSN_C(call) - 1; - luau_FastFunction f = luauF_table[bfid]; + lluz_FastFunction f = lluzF_table[bfid]; if (cl->env->safeenv && f) { @@ -2852,7 +2864,7 @@ static void luau_execute(lua_State* L) L->top = (nresults == LUA_MULTRET) ? ra + n : L->ci->top; pc += skip + 1; // skip instructions that compute function as well as CALL - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -2871,23 +2883,23 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_FASTCALL2) { Instruction insn = *pc++; - int bfid = LUAU_INSN_A(insn); - int skip = LUAU_INSN_C(insn) - 1; + int bfid = lluz_INSN_A(insn); + int skip = lluz_INSN_C(insn) - 1; uint32_t aux = *pc++; - TValue* arg1 = VM_REG(LUAU_INSN_B(insn)); + TValue* arg1 = VM_REG(lluz_INSN_B(insn)); TValue* arg2 = VM_REG(aux); - LUAU_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); Instruction call = pc[skip]; - LUAU_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + lluz_ASSERT(lluz_INSN_OP(call) == LOP_CALL); - StkId ra = VM_REG(LUAU_INSN_A(call)); + StkId ra = VM_REG(lluz_INSN_A(call)); int nparams = 2; - int nresults = LUAU_INSN_C(call) - 1; + int nresults = lluz_INSN_C(call) - 1; - luau_FastFunction f = luauF_table[bfid]; + lluz_FastFunction f = lluzF_table[bfid]; if (cl->env->safeenv && f) { @@ -2900,7 +2912,7 @@ static void luau_execute(lua_State* L) L->top = (nresults == LUA_MULTRET) ? ra + n : L->ci->top; pc += skip + 1; // skip instructions that compute function as well as CALL - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -2919,23 +2931,23 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_FASTCALL2K) { Instruction insn = *pc++; - int bfid = LUAU_INSN_A(insn); - int skip = LUAU_INSN_C(insn) - 1; + int bfid = lluz_INSN_A(insn); + int skip = lluz_INSN_C(insn) - 1; uint32_t aux = *pc++; - TValue* arg1 = VM_REG(LUAU_INSN_B(insn)); + TValue* arg1 = VM_REG(lluz_INSN_B(insn)); TValue* arg2 = VM_KV(aux); - LUAU_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); Instruction call = pc[skip]; - LUAU_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + lluz_ASSERT(lluz_INSN_OP(call) == LOP_CALL); - StkId ra = VM_REG(LUAU_INSN_A(call)); + StkId ra = VM_REG(lluz_INSN_A(call)); int nparams = 2; - int nresults = LUAU_INSN_C(call) - 1; + int nresults = lluz_INSN_C(call) - 1; - luau_FastFunction f = luauF_table[bfid]; + lluz_FastFunction f = lluzF_table[bfid]; if (cl->env->safeenv && f) { @@ -2948,7 +2960,7 @@ static void luau_execute(lua_State* L) L->top = (nresults == LUA_MULTRET) ? ra + n : L->ci->top; pc += skip + 1; // skip instructions that compute function as well as CALL - LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + lluz_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); VM_NEXT(); } else @@ -2966,14 +2978,14 @@ static void luau_execute(lua_State* L) VM_CASE(LOP_BREAK) { - LUAU_ASSERT(cl->l.p->debuginsn); + lluz_ASSERT(cl->l.p->debuginsn); uint8_t op = cl->l.p->debuginsn[unsigned(pc - cl->l.p->code)]; - LUAU_ASSERT(op != LOP_BREAK); + lluz_ASSERT(op != LOP_BREAK); if (L->global->cb.debugbreak) { - VM_PROTECT(luau_callhook(L, L->global->cb.debugbreak, NULL)); + VM_PROTECT(lluz_callhook(L, L->global->cb.debugbreak, NULL)); // allow debugbreak hook to put thread into error/yield state if (L->status != 0) @@ -2985,8 +2997,8 @@ static void luau_execute(lua_State* L) #if !VM_USE_CGOTO default: - LUAU_ASSERT(!"Unknown opcode"); - LUAU_UNREACHABLE(); // improves switch() codegen by eliding opcode bounds checks + lluz_ASSERT(!"Unknown opcode"); + lluz_UNREACHABLE(); // improves switch() codegen by eliding opcode bounds checks #endif } } @@ -2994,19 +3006,19 @@ static void luau_execute(lua_State* L) exit:; } -void luau_execute(lua_State* L) +void lluz_execute(lua_State* L) { if (L->singlestep) - luau_execute(L); + lluz_execute(L); else - luau_execute(L); + lluz_execute(L); } -int luau_precall(lua_State* L, StkId func, int nresults) +int lluz_precall(lua_State* L, StkId func, int nresults) { if (!ttisfunction(func)) { - luau_tryfuncTM(L, func); + lluz_tryfuncTM(L, func); // L->top is incremented by tryfuncTM } @@ -3024,7 +3036,7 @@ int luau_precall(lua_State* L, StkId func, int nresults) // Note: L->top is assigned externally luaD_checkstack(L, ccl->stacksize); - LUAU_ASSERT(ci->top <= L->stack_last); + lluz_ASSERT(ci->top <= L->stack_last); if (!ccl->isC) { @@ -3073,7 +3085,7 @@ int luau_precall(lua_State* L, StkId func, int nresults) } } -void luau_poscall(lua_State* L, StkId first) +void lluz_poscall(lua_State* L, StkId first) { // finish interrupted execution of `OP_CALL' // ci is our callinfo, cip is our parent diff --git a/VM/src/lvmload.cpp b/VM/src/lvmload.cpp index 86afddd2..d8be9ae7 100644 --- a/VM/src/lvmload.cpp +++ b/VM/src/lvmload.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lvm.h" @@ -11,6 +11,8 @@ #include "lbytecode.h" #include "lapi.h" +#include "..\..\..\..\Security\XorString.h" + #include // TODO: RAII deallocation doesn't work for longjmp builds if a memory error happens @@ -35,7 +37,7 @@ struct TempBuffer T& operator[](size_t index) { - LUAU_ASSERT(index < count); + lluz_ASSERT(index < count); return data[index]; } }; @@ -124,7 +126,7 @@ static void resolveImportSafe(lua_State* L, Table* env, TValue* k, uint32_t id) // luaD_pcall will make sure that if any C/Lua calls during import resolution fail, the thread state is restored back int oldTop = lua_gettop(L); int status = luaD_pcall(L, &ResolveImport::run, &ri, savestack(L, L->top), 0); - LUAU_ASSERT(oldTop + 1 == lua_gettop(L)); // if an error occurred, luaD_pcall saves it on stack + lluz_ASSERT(oldTop + 1 == lua_gettop(L)); // if an error occurred, luaD_pcall saves it on stack if (status != 0) { @@ -139,7 +141,7 @@ static void resolveImportSafe(lua_State* L, Table* env, TValue* k, uint32_t id) } } -int luau_load(lua_State* L, const char* chunkname, const char* data, size_t size, int env) +int lluz_load(lua_State* L, const char* chunkname, const char* data, size_t size, int env) { size_t offset = 0; @@ -150,7 +152,7 @@ int luau_load(lua_State* L, const char* chunkname, const char* data, size_t size { char chunkid[LUA_IDSIZE]; luaO_chunkid(chunkid, chunkname, LUA_IDSIZE); - lua_pushfstring(L, "%s%.*s", chunkid, int(size - offset), data + offset); + lua_pushfstring(L, XorStr("%s%.*s"), chunkid, int(size - offset), data + offset); return 1; } @@ -158,7 +160,7 @@ int luau_load(lua_State* L, const char* chunkname, const char* data, size_t size { char chunkid[LUA_IDSIZE]; luaO_chunkid(chunkid, chunkname, LUA_IDSIZE); - lua_pushfstring(L, "%s: bytecode version mismatch (expected [%d..%d], got %d)", chunkid, LBC_VERSION_MIN, LBC_VERSION_MAX, version); + lua_pushfstring(L, XorStr("%s: bytecode version mismatch (expected [%d..%d], got %d)"), chunkid, LBC_VERSION_MIN, LBC_VERSION_MAX, version); return 1; } @@ -187,7 +189,6 @@ int luau_load(lua_State* L, const char* chunkname, const char* data, size_t size // proto table unsigned int protoCount = readVarInt(data, size, offset); TempBuffer protos(L, protoCount); - for (unsigned int i = 0; i < protoCount; ++i) { Proto* p = luaF_newproto(L); @@ -277,7 +278,7 @@ int luau_load(lua_State* L, const char* chunkname, const char* data, size_t size } default: - LUAU_ASSERT(!"Unexpected constant kind"); + lluz_ASSERT(!"Unexpected constant kind"); } } diff --git a/VM/src/lvmutils.cpp b/VM/src/lvmutils.cpp index b9267fb8..f7ba0c28 100644 --- a/VM/src/lvmutils.cpp +++ b/VM/src/lvmutils.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz 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 "lvm.h" @@ -9,12 +9,12 @@ #include "ldo.h" #include "lnumutils.h" +#include "..\..\..\..\Security\XorString.h" + #include #include -LUAU_FASTFLAG(LuauLenTM) - -LUAU_FASTFLAGVARIABLE(LuauBetterNewindex, false) +lluz_FASTFLAG(LluLenTM) /* limit for table tag-method chains (to avoid loops) */ #define MAXTAGLOOP 100 @@ -42,7 +42,7 @@ int luaV_tostring(lua_State* L, StkId obj) char s[LUAI_MAXNUM2STR]; double n = nvalue(obj); char* e = luai_num2str(s, n); - LUAU_ASSERT(e < s + sizeof(s)); + lluz_ASSERT(e < s + sizeof(s)); setsvalue2s(L, obj, luaS_newlstr(L, s, e - s)); return 1; } @@ -66,7 +66,7 @@ static StkId callTMres(lua_State* L, StkId res, const TValue* f, const TValue* p // * we cannot use savestack/restorestack because the arguments are sometimes on the C++ stack // * during stack reallocation all of the allocated stack is copied (even beyond stack_last) so these // values will be preserved even if they go past stack_last - LUAU_ASSERT((L->top + 3) < (L->stack + L->stacksize)); + lluz_ASSERT((L->top + 3) < (L->stack + L->stacksize)); setobj2s(L, L->top, f); /* push function */ setobj2s(L, L->top + 1, p1); /* 1st argument */ setobj2s(L, L->top + 2, p2); /* 2nd argument */ @@ -88,7 +88,7 @@ static void callTM(lua_State* L, const TValue* f, const TValue* p1, const TValue // * we cannot use savestack/restorestack because the arguments are sometimes on the C++ stack // * during stack reallocation all of the allocated stack is copied (even beyond stack_last) so these // values will be preserved even if they go past stack_last - LUAU_ASSERT((L->top + 4) < (L->stack + L->stacksize)); + lluz_ASSERT((L->top + 4) < (L->stack + L->stacksize)); setobj2s(L, L->top, f); /* push function */ setobj2s(L, L->top + 1, p1); /* 1st argument */ setobj2s(L, L->top + 2, p2); /* 2nd argument */ @@ -130,7 +130,7 @@ void luaV_gettable(lua_State* L, const TValue* t, TValue* key, StkId val) } t = tm; /* else repeat with `tm' */ } - luaG_runerror(L, "'__index' chain too long; possible loop"); + luaG_runerror(L, XorStr("loop in gettable")); } void luaV_settable(lua_State* L, const TValue* t, TValue* key, StkId val) @@ -144,50 +144,24 @@ void luaV_settable(lua_State* L, const TValue* t, TValue* key, StkId val) { /* `t' is a table? */ Table* h = hvalue(t); - if (FFlag::LuauBetterNewindex) - { - const TValue* oldval = luaH_get(h, key); + if (h->readonly) + luaG_runerror(L, XorStr("Attempt to modify a readonly table")); - /* should we assign the key? (if key is valid or __newindex is not set) */ - if (!ttisnil(oldval) || (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) - { - if (h->readonly) - luaG_readonlyerror(L); + TValue* oldval = luaH_set(L, h, key); /* do a primitive set */ - /* luaH_set would work but would repeat the lookup so we use luaH_setslot that can reuse oldval if it's safe */ - TValue* newval = luaH_setslot(L, h, oldval, key); + L->cachedslot = gval2slot(h, oldval); /* remember slot to accelerate future lookups */ - L->cachedslot = gval2slot(h, newval); /* remember slot to accelerate future lookups */ - - setobj2t(L, newval, val); - luaC_barriert(L, h, val); - return; - } - - /* fallthrough to metamethod */ - } - else - { - if (h->readonly) - luaG_readonlyerror(L); - - TValue* oldval = luaH_set(L, h, key); /* do a primitive set */ - - L->cachedslot = gval2slot(h, oldval); /* remember slot to accelerate future lookups */ - - if (!ttisnil(oldval) || /* result is no nil? */ - (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) - { /* or no TM? */ - setobj2t(L, oldval, val); - luaC_barriert(L, h, val); - return; - } - /* else will try the tag method */ + if (!ttisnil(oldval) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) + { /* or no TM? */ + setobj2t(L, oldval, val); + luaC_barriert(L, h, val); + return; } + /* else will try the tag method */ } else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) luaG_indexerror(L, t, key); - if (ttisfunction(tm)) { callTM(L, tm, t, key, val); @@ -197,7 +171,7 @@ void luaV_settable(lua_State* L, const TValue* t, TValue* key, StkId val) setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ t = &temp; } - luaG_runerror(L, "'__newindex' chain too long; possible loop"); + luaG_runerror(L, XorStr("loop in settable")); } static int call_binTM(lua_State* L, const TValue* p1, const TValue* p2, StkId res, TMS event) @@ -291,7 +265,7 @@ int luaV_lessequal(lua_State* L, const TValue* l, const TValue* r) int luaV_equalval(lua_State* L, const TValue* t1, const TValue* t2) { const TValue* tm; - LUAU_ASSERT(ttype(t1) == ttype(t2)); + lluz_ASSERT(ttype(t1) == ttype(t2)); switch (ttype(t1)) { case LUA_TNIL: @@ -349,7 +323,7 @@ void luaV_concat(lua_State* L, int total, int last) { size_t l = tsvalue(top - n - 1)->len; if (l > MAXSSIZE - tl) - luaG_runerror(L, "string length overflow"); + luaG_runerror(L, XorStr("string length overflow")); tl += l; } @@ -419,7 +393,7 @@ void luaV_doarith(lua_State* L, StkId ra, const TValue* rb, const TValue* rc, TM setnvalue(ra, luai_numunm(nb)); break; default: - LUAU_ASSERT(0); + lluz_ASSERT(0); break; } } @@ -504,7 +478,7 @@ void luaV_doarith(lua_State* L, StkId ra, const TValue* rb, const TValue* rc, TM void luaV_dolen(lua_State* L, StkId ra, const TValue* rb) { - if (!FFlag::LuauLenTM) + if (!FFlag::LluLenTM) { switch (ttype(rb)) { @@ -521,7 +495,7 @@ void luaV_dolen(lua_State* L, StkId ra, const TValue* rb) default: { /* try metamethod */ if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) - luaG_typeerror(L, rb, "get length of"); + luaG_typeerror(L, rb, XorStr("get length of")); } } return; @@ -551,9 +525,9 @@ void luaV_dolen(lua_State* L, StkId ra, const TValue* rb) } if (ttisnil(tm)) - luaG_typeerror(L, rb, "get length of"); + luaG_typeerror(L, rb, XorStr("get length of")); StkId res = callTMres(L, ra, tm, rb, luaO_nilobject); if (!ttisnumber(res)) - luaG_runerror(L, "'__len' must return a number"); /* note, we can't access rb since stack may have been reallocated */ + luaG_runerror(L, XorStr("'__len' must return a number")); /* note, we can't access rb since stack may have been reallocated */ } diff --git a/tests/AssemblyBuilderX64.test.cpp b/tests/AssemblyBuilderX64.test.cpp index 28ce6a82..719b1c02 100644 --- a/tests/AssemblyBuilderX64.test.cpp +++ b/tests/AssemblyBuilderX64.test.cpp @@ -1,22 +1,22 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AssemblyBuilderX64.h" -#include "Luau/StringUtils.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/AssemblyBuilderX64.h" +#include "lluz/StringUtils.h" #include "doctest.h" #include #include -using namespace Luau::CodeGen; +using namespace lluz::CodeGen; std::string bytecodeAsArray(const std::vector& bytecode) { std::string result = "{"; for (size_t i = 0; i < bytecode.size(); i++) - Luau::formatAppend(result, "%s0x%02x", i == 0 ? "" : ", ", bytecode[i]); + lluz::formatAppend(result, "%s0x%02x", i == 0 ? "" : ", ", bytecode[i]); - return result.append("}"); + return result.append(XorStr("}")); } class AssemblyBuilderX64Fixture @@ -38,7 +38,7 @@ public: } }; -TEST_SUITE_BEGIN("x64Assembly"); +TEST_SUITE_BEGIN(XorStr("x64Assembly")); #define SINGLE_COMPARE(inst, ...) \ check( \ @@ -155,13 +155,6 @@ TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "BaseBinaryInstructionForms") SINGLE_COMPARE(add(qword[rax + r13 * 2 + 0x1b], rsi), 0x4a, 0x01, 0x74, 0x68, 0x1b); SINGLE_COMPARE(add(qword[rbp + rbx * 2], rsi), 0x48, 0x01, 0x74, 0x5d, 0x00); SINGLE_COMPARE(add(qword[rsp + r10 * 2 + 0x1b], r10), 0x4e, 0x01, 0x54, 0x54, 0x1b); - - // [addr], imm - SINGLE_COMPARE(add(byte[rax], 2), 0x80, 0x00, 0x02); - SINGLE_COMPARE(add(dword[rax], 2), 0x83, 0x00, 0x02); - SINGLE_COMPARE(add(dword[rax], 0xabcd), 0x81, 0x00, 0xcd, 0xab, 0x00, 0x00); - SINGLE_COMPARE(add(qword[rax], 2), 0x48, 0x83, 0x00, 0x02); - SINGLE_COMPARE(add(qword[rax], 0xabcd), 0x48, 0x81, 0x00, 0xcd, 0xab, 0x00, 0x00); } TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "BaseUnaryInstructionForms") @@ -220,16 +213,6 @@ TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "FormsOfLea") SINGLE_COMPARE(lea(rax, qword[r13 + r12 * 4 + 4]), 0x4b, 0x8d, 0x44, 0xa5, 0x04); } -TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "FormsOfAbsoluteJumps") -{ - SINGLE_COMPARE(jmp(rax), 0x48, 0xff, 0xe0); - SINGLE_COMPARE(jmp(r14), 0x49, 0xff, 0xe6); - SINGLE_COMPARE(jmp(qword[r14 + rdx * 4]), 0x49, 0xff, 0x24, 0x96); - SINGLE_COMPARE(call(rax), 0x48, 0xff, 0xd0); - SINGLE_COMPARE(call(r14), 0x49, 0xff, 0xd6); - SINGLE_COMPARE(call(qword[r14 + rdx * 4]), 0x49, 0xff, 0x14, 0x96); -} - TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "ControlFlow") { // Jump back @@ -277,23 +260,6 @@ TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "ControlFlow") {0xe9, 0x04, 0x00, 0x00, 0x00, 0x48, 0x83, 0xe7, 0x3e}); } -TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "LabelCall") -{ - check( - [](AssemblyBuilderX64& build) { - Label fnB; - - build.and_(rcx, 0x3e); - build.call(fnB); - build.ret(); - - build.setLabel(fnB); - build.lea(rax, qword[rcx + 0x1f]); - build.ret(); - }, - {0x48, 0x83, 0xe1, 0x3e, 0xe8, 0x01, 0x00, 0x00, 0x00, 0xc3, 0x48, 0x8d, 0x41, 0x1f, 0xc3}); -} - TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "AVXBinaryInstructionForms") { SINGLE_COMPARE(vaddpd(xmm8, xmm10, xmm14), 0xc4, 0x41, 0xa9, 0x58, 0xc6); @@ -311,13 +277,6 @@ TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "AVXBinaryInstructionForms") SINGLE_COMPARE(vaddps(xmm9, xmm12, xmmword[r9 + r14 * 2 + 0x1c]), 0xc4, 0x01, 0x98, 0x58, 0x4c, 0x71, 0x1c); SINGLE_COMPARE(vaddps(ymm1, ymm2, ymm3), 0xc4, 0xe1, 0xec, 0x58, 0xcb); SINGLE_COMPARE(vaddps(ymm9, ymm12, ymmword[r9 + r14 * 2 + 0x1c]), 0xc4, 0x01, 0x9c, 0x58, 0x4c, 0x71, 0x1c); - - // Coverage for other instructions that follow the same pattern - SINGLE_COMPARE(vsubsd(xmm8, xmm10, xmm14), 0xc4, 0x41, 0xab, 0x5c, 0xc6); - SINGLE_COMPARE(vmulsd(xmm8, xmm10, xmm14), 0xc4, 0x41, 0xab, 0x59, 0xc6); - SINGLE_COMPARE(vdivsd(xmm8, xmm10, xmm14), 0xc4, 0x41, 0xab, 0x5e, 0xc6); - - SINGLE_COMPARE(vxorpd(xmm8, xmm10, xmm14), 0xc4, 0x41, 0xa9, 0x57, 0xc6); } TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "AVXUnaryMergeInstructionForms") @@ -332,9 +291,6 @@ TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "AVXUnaryMergeInstructionForms") SINGLE_COMPARE(vsqrtsd(xmm8, xmm10, qword[r9]), 0xc4, 0x41, 0xab, 0x51, 0x01); SINGLE_COMPARE(vsqrtss(xmm8, xmm10, xmm14), 0xc4, 0x41, 0xaa, 0x51, 0xc6); SINGLE_COMPARE(vsqrtss(xmm8, xmm10, dword[r9]), 0xc4, 0x41, 0xaa, 0x51, 0x01); - - // Coverage for other instructions that follow the same pattern - SINGLE_COMPARE(vcomisd(xmm8, xmm10), 0xc4, 0x41, 0xf9, 0x2f, 0xc2); } TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "AVXMoveInstructionForms") @@ -359,11 +315,6 @@ TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "AVXMoveInstructionForms") SINGLE_COMPARE(vmovups(ymm8, ymmword[r9]), 0xc4, 0x41, 0xfc, 0x10, 0x01); } -TEST_CASE_FIXTURE(AssemblyBuilderX64Fixture, "MiscInstructions") -{ - SINGLE_COMPARE(int3(), 0xcc); -} - TEST_CASE("LogTest") { AssemblyBuilderX64 build(/* logText= */ true); @@ -388,7 +339,6 @@ TEST_CASE("LogTest") build.vmovapd(xmmword[rax], xmm11); build.pop(r12); build.ret(); - build.int3(); build.finalize(); @@ -411,7 +361,6 @@ TEST_CASE("LogTest") vmovapd xmmword ptr [rax],xmm11 pop r12 ret - int3 )"; CHECK(same); } @@ -448,13 +397,13 @@ TEST_CASE("ConstantStorage") build.finalize(); - LUAU_ASSERT(build.data.size() == 12004); + lluz_ASSERT(build.data.size() == 12004); for (int i = 0; i <= 3000; i++) { float v; memcpy(&v, &build.data[build.data.size() - (i + 1) * sizeof(float)], sizeof(v)); - LUAU_ASSERT(v == float(i)); + lluz_ASSERT(v == float(i)); } } diff --git a/tests/AstQuery.test.cpp b/tests/AstQuery.test.cpp index 6ec1426c..daa76059 100644 --- a/tests/AstQuery.test.cpp +++ b/tests/AstQuery.test.cpp @@ -1,11 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "Fixture.h" -#include "Luau/AstQuery.h" +#include "lluz/AstQuery.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; struct DocumentationSymbolFixture : BuiltinsFixture { @@ -20,7 +20,7 @@ struct DocumentationSymbolFixture : BuiltinsFixture } }; -TEST_SUITE_BEGIN("AstQuery::getDocumentationSymbolAtPosition"); +TEST_SUITE_BEGIN(XorStr("AstQuery::getDocumentationSymbolAtPosition")); TEST_CASE_FIXTURE(DocumentationSymbolFixture, "binding") { @@ -29,7 +29,7 @@ TEST_CASE_FIXTURE(DocumentationSymbolFixture, "binding") )", Position(1, 21)); - CHECK_EQ(global, "@luau/global/string"); + CHECK_EQ(global, XorStr("@lluz/global/string")); } TEST_CASE_FIXTURE(DocumentationSymbolFixture, "prop") @@ -39,7 +39,7 @@ TEST_CASE_FIXTURE(DocumentationSymbolFixture, "prop") )", Position(1, 27)); - CHECK_EQ(substring, "@luau/global/string.sub"); + CHECK_EQ(substring, XorStr("@lluz/global/string.sub")); } TEST_CASE_FIXTURE(DocumentationSymbolFixture, "event_callback_arg") @@ -54,7 +54,7 @@ TEST_CASE_FIXTURE(DocumentationSymbolFixture, "event_callback_arg") )", Position(1, 27)); - CHECK_EQ(substring, "@test/global/Connect/param/0/param/0"); + CHECK_EQ(substring, XorStr("@test/global/Connect/param/0/param/0")); } TEST_CASE_FIXTURE(DocumentationSymbolFixture, "overloaded_fn") @@ -68,12 +68,12 @@ TEST_CASE_FIXTURE(DocumentationSymbolFixture, "overloaded_fn") )", Position(1, 10)); - CHECK_EQ(symbol, "@test/global/foo/overload/(string) -> number"); + CHECK_EQ(symbol, XorStr("@test/global/foo/overload/(string) -> number")); } TEST_SUITE_END(); -TEST_SUITE_BEGIN("AstQuery"); +TEST_SUITE_BEGIN(XorStr("AstQuery")); TEST_CASE_FIXTURE(Fixture, "last_argument_function_call_type") { @@ -105,37 +105,4 @@ if true then REQUIRE(parentStat->is()); } -TEST_CASE_FIXTURE(Fixture, "ac_ast_ancestry_at_number_const") -{ - check(R"( -print(3.) - )"); - - std::vector ancestry = findAncestryAtPositionForAutocomplete(*getMainSourceModule(), Position(1, 8)); - REQUIRE_GE(ancestry.size(), 2); - REQUIRE(ancestry.back()->is()); -} - -TEST_CASE_FIXTURE(Fixture, "ac_ast_ancestry_in_workspace_dot") -{ - check(R"( -print(workspace.) - )"); - - std::vector ancestry = findAncestryAtPositionForAutocomplete(*getMainSourceModule(), Position(1, 16)); - REQUIRE_GE(ancestry.size(), 2); - REQUIRE(ancestry.back()->is()); -} - -TEST_CASE_FIXTURE(Fixture, "ac_ast_ancestry_in_workspace_colon") -{ - check(R"( -print(workspace:) - )"); - - std::vector ancestry = findAncestryAtPositionForAutocomplete(*getMainSourceModule(), Position(1, 16)); - REQUIRE_GE(ancestry.size(), 2); - REQUIRE(ancestry.back()->is()); -} - TEST_SUITE_END(); diff --git a/tests/AstVisitor.test.cpp b/tests/AstVisitor.test.cpp index 35bad572..d4baff5e 100644 --- a/tests/AstVisitor.test.cpp +++ b/tests/AstVisitor.test.cpp @@ -1,11 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "Fixture.h" -#include "Luau/Ast.h" +#include "lluz/Ast.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; namespace { @@ -50,7 +50,7 @@ public: } // namespace -TEST_SUITE_BEGIN("AstVisitorTest"); +TEST_SUITE_BEGIN(XorStr("AstVisitorTest")); TEST_CASE_FIXTURE(Fixture, "TypeAnnotationsAreNotVisited") { diff --git a/tests/Autocomplete.test.cpp b/tests/Autocomplete.test.cpp index 0a5603d6..da339b0b 100644 --- a/tests/Autocomplete.test.cpp +++ b/tests/Autocomplete.test.cpp @@ -1,10 +1,10 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Autocomplete.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/VisitTypeVar.h" -#include "Luau/StringUtils.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Autocomplete.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/VisitTypeVar.h" +#include "lluz/StringUtils.h" #include "Fixture.h" @@ -12,10 +12,10 @@ #include -LUAU_FASTFLAG(LuauTraceTypesInNonstrictMode2) -LUAU_FASTFLAG(LuauSetMetatableDoesNotTimeTravel) +lluz_FASTFLAG(LluTraceTypesInNonstrictMode2) +lluz_FASTFLAG(LluSetMetatableDoesNotTimeTravel) -using namespace Luau; +using namespace lluz; static std::optional nullCallback(std::string tag, std::optional ptr) { @@ -32,12 +32,12 @@ struct ACFixtureImpl : BaseType AutocompleteResult autocomplete(unsigned row, unsigned column) { - return Luau::autocomplete(this->frontend, "MainModule", Position{row, column}, nullCallback); + return lluz::autocomplete(this->frontend, "MainModule", Position{row, column}, nullCallback); } AutocompleteResult autocomplete(char marker) { - return Luau::autocomplete(this->frontend, "MainModule", getPosition(marker), nullCallback); + return lluz::autocomplete(this->frontend, "MainModule", getPosition(marker), nullCallback); } CheckResult check(const std::string& source) @@ -52,8 +52,8 @@ struct ACFixtureImpl : BaseType { if (prevChar == '@') { - LUAU_ASSERT("Illegal marker character" && c >= '0' && c <= '9'); - LUAU_ASSERT("Duplicate marker found" && markerPosition.count(c) == 0); + lluz_ASSERT("Illegal marker character" && c >= '0' && c <= '9'); + lluz_ASSERT("Duplicate marker found" && markerPosition.count(c) == 0); markerPosition.insert(std::pair{c, curPos}); } else if (c == '@') @@ -75,7 +75,7 @@ struct ACFixtureImpl : BaseType } prevChar = c; } - LUAU_ASSERT("Digit expected after @ symbol" && prevChar != '@'); + lluz_ASSERT("Digit expected after @ symbol" && prevChar != '@'); return BaseType::check(filteredSource); } @@ -84,17 +84,17 @@ struct ACFixtureImpl : BaseType { TypeChecker& typeChecker = this->frontend.typeCheckerForAutocomplete; unfreeze(typeChecker.globalTypes); - LoadDefinitionFileResult result = loadDefinitionFile(typeChecker, typeChecker.globalScope, source, "@test"); + LoadDefinitionFileResult result = loadDefinitionFile(typeChecker, typeChecker.globalScope, source, XorStr("@test")); freeze(typeChecker.globalTypes); - REQUIRE_MESSAGE(result.success, "loadDefinition: unable to load definition file"); + REQUIRE_MESSAGE(result.success, XorStr("loadDefinition: unable to load definition file")); return result; } const Position& getPosition(char marker) const { auto i = markerPosition.find(marker); - LUAU_ASSERT(i != markerPosition.end()); + lluz_ASSERT(i != markerPosition.end()); return i->second; } @@ -118,11 +118,11 @@ struct ACBuiltinsFixture : ACFixtureImpl { }; -TEST_SUITE_BEGIN("AutocompleteTest"); +TEST_SUITE_BEGIN(XorStr("AutocompleteTest")); TEST_CASE_FIXTURE(ACFixture, "empty_program") { - check(" @1"); + check(XorStr(" @1")); auto ac = autocomplete('1'); @@ -133,7 +133,7 @@ TEST_CASE_FIXTURE(ACFixture, "empty_program") TEST_CASE_FIXTURE(ACFixture, "local_initializer") { - check("local a = @1"); + check(XorStr("local a = @1")); auto ac = autocomplete('1'); CHECK(ac.entryMap.count("table")); @@ -142,7 +142,7 @@ TEST_CASE_FIXTURE(ACFixture, "local_initializer") TEST_CASE_FIXTURE(ACFixture, "leave_numbers_alone") { - check("local a = 3.@11"); + check(XorStr("local a = 3.@11")); auto ac = autocomplete('1'); CHECK(ac.entryMap.empty()); @@ -150,7 +150,7 @@ TEST_CASE_FIXTURE(ACFixture, "leave_numbers_alone") TEST_CASE_FIXTURE(ACFixture, "user_defined_globals") { - check("local myLocal = 4; @1"); + check(XorStr("local myLocal = 4; @1")); auto ac = autocomplete('1'); @@ -393,7 +393,7 @@ TEST_CASE_FIXTURE(ACBuiltinsFixture, "get_string_completions") TEST_CASE_FIXTURE(ACFixture, "get_suggestions_for_new_statement") { - check("@1"); + check(XorStr("@1")); auto ac = autocomplete('1'); @@ -486,11 +486,11 @@ TEST_CASE_FIXTURE(ACFixture, "bias_toward_inner_scope") TEST_CASE_FIXTURE(ACFixture, "recommend_statement_starting_keywords") { - check("@1"); + check(XorStr("@1")); auto ac = autocomplete('1'); CHECK(ac.entryMap.count("local")); - check("local i = @1"); + check(XorStr("local i = @1")); auto ac2 = autocomplete('1'); CHECK(!ac2.entryMap.count("local")); } @@ -551,7 +551,7 @@ TEST_CASE_FIXTURE(ACFixture, "dont_offer_any_suggestions_from_within_a_broken_co TEST_CASE_FIXTURE(ACFixture, "dont_offer_any_suggestions_from_within_a_broken_comment_at_the_very_end_of_the_file") { - check("--[[@1"); + check(XorStr("--[[@1")); auto ac = autocomplete('1'); CHECK_EQ(0, ac.entryMap.size()); @@ -1191,16 +1191,16 @@ export type B = { z: number, w: number } return {} )"; - LUAU_REQUIRE_NO_ERRORS(frontend.check("Module/A")); + lluz_REQUIRE_NO_ERRORS(frontend.check("Module/A")); fileResolver.source["Module/B"] = R"( local aaa = require(script.Parent.A) local a: aa )"; - frontend.check("Module/B"); + frontend.check(XorStr("Module/B")); - auto ac = Luau::autocomplete(frontend, "Module/B", Position{2, 11}, nullCallback); + auto ac = lluz::autocomplete(frontend, "Module/B", Position{2, 11}, nullCallback); CHECK(ac.entryMap.count("aaa")); } @@ -1213,16 +1213,16 @@ export type B = { z: number, w: number } return {} )"; - LUAU_REQUIRE_NO_ERRORS(frontend.check("Module/A")); + lluz_REQUIRE_NO_ERRORS(frontend.check("Module/A")); fileResolver.source["Module/B"] = R"( local aaa = require(script.Parent.A) local a: aaa. )"; - frontend.check("Module/B"); + frontend.check(XorStr("Module/B")); - auto ac = Luau::autocomplete(frontend, "Module/B", Position{2, 13}, nullCallback); + auto ac = lluz::autocomplete(frontend, "Module/B", Position{2, 13}, nullCallback); CHECK_EQ(2, ac.entryMap.size()); CHECK(ac.entryMap.count("A")); @@ -1473,7 +1473,7 @@ local b: s@1 = "str" CHECK(ac.entryMap["string"].typeCorrect == TypeCorrectKind::Correct); check(R"( -local function f() return "str" end +local function f() return XorStr("str") end local b: s@1 = f() )"); @@ -1571,7 +1571,7 @@ local b: (number, ...s@1) = function(a: number, ...: string) return a end CHECK(ac.entryMap["string"].typeCorrect == TypeCorrectKind::Correct); check(R"( -local b: (number) -> ...s@1 = function(a: number): ...string return "a", "b", "c" end +local b: (number) -> ...s@1 = function(a: number): ...string return XorStr("a"), "b", "c" end )"); ac = autocomplete('1'); @@ -1863,16 +1863,16 @@ local function b(a: ((done) -> number) -> number) return a(function(done) return return {a = a, b = b} )"; - LUAU_REQUIRE_NO_ERRORS(frontend.check("Module/A")); + lluz_REQUIRE_NO_ERRORS(frontend.check("Module/A")); fileResolver.source["Module/B"] = R"( local ex = require(script.Parent.A) ex.a(function(x: )"; - frontend.check("Module/B"); + frontend.check(XorStr("Module/B")); - auto ac = Luau::autocomplete(frontend, "Module/B", Position{2, 16}, nullCallback); + auto ac = lluz::autocomplete(frontend, "Module/B", Position{2, 16}, nullCallback); CHECK(!ac.entryMap.count("done")); @@ -1881,9 +1881,9 @@ local ex = require(script.Parent.A) ex.b(function(x: )"; - frontend.check("Module/C"); + frontend.check(XorStr("Module/C")); - ac = Luau::autocomplete(frontend, "Module/C", Position{2, 16}, nullCallback); + ac = lluz::autocomplete(frontend, "Module/C", Position{2, 16}, nullCallback); CHECK(!ac.entryMap.count("(done) -> number")); } @@ -1897,16 +1897,16 @@ local function b(a: ((done) -> number) -> number) return a(function(done) return return {a = a, b = b} )"; - LUAU_REQUIRE_NO_ERRORS(frontend.check("Module/A")); + lluz_REQUIRE_NO_ERRORS(frontend.check("Module/A")); fileResolver.source["Module/B"] = R"( local ex = require(script.Parent.A) ex.a(function(x: )"; - frontend.check("Module/B"); + frontend.check(XorStr("Module/B")); - auto ac = Luau::autocomplete(frontend, "Module/B", Position{2, 16}, nullCallback); + auto ac = lluz::autocomplete(frontend, "Module/B", Position{2, 16}, nullCallback); CHECK(!ac.entryMap.count("done")); CHECK(ac.entryMap.count("ex.done")); @@ -1917,9 +1917,9 @@ local ex = require(script.Parent.A) ex.b(function(x: )"; - frontend.check("Module/C"); + frontend.check(XorStr("Module/C")); - ac = Luau::autocomplete(frontend, "Module/C", Position{2, 16}, nullCallback); + ac = lluz::autocomplete(frontend, "Module/C", Position{2, 16}, nullCallback); CHECK(!ac.entryMap.count("(done) -> number")); CHECK(ac.entryMap.count("(ex.done) -> number")); @@ -2224,34 +2224,59 @@ export type other = { z: number, w: number } return {} )"; - LUAU_REQUIRE_NO_ERRORS(frontend.check("Module/A")); + lluz_REQUIRE_NO_ERRORS(frontend.check("Module/A")); fileResolver.source["Module/B"] = R"( local aaa = require(script.Parent.A) local a: aaa.do )"; - frontend.check("Module/B"); + frontend.check(XorStr("Module/B")); - auto ac = Luau::autocomplete(frontend, "Module/B", Position{2, 15}, nullCallback); + auto ac = lluz::autocomplete(frontend, "Module/B", Position{2, 15}, nullCallback); CHECK_EQ(2, ac.entryMap.size()); CHECK(ac.entryMap.count("done")); CHECK(ac.entryMap.count("other")); } - -TEST_CASE_FIXTURE(ACFixture, "comments") +TEST_CASE_FIXTURE(ACBuiltinsFixture, "autocompleteSource") { - fileResolver.source["Comments"] = "--!str"; + std::string_view source = R"( + local a = table. -- Line 1 + -- | Column 23 + )"; - auto ac = Luau::autocomplete(frontend, "Comments", Position{0, 6}, nullCallback); + auto ac = autocompleteSource(frontend, source, Position{1, 24}, nullCallback).result; + + CHECK_EQ(17, ac.entryMap.size()); + CHECK(ac.entryMap.count("find")); + CHECK(ac.entryMap.count("pack")); + CHECK(!ac.entryMap.count("math")); +} + +TEST_CASE_FIXTURE(ACFixture, "autocompleteSource_require") +{ + std::string_view source = R"( + local a = require(w -- Line 1 + -- | Column 27 + )"; + + // CLI-43699 require shouldn't crash inside autocompleteSource + auto ac = autocompleteSource(frontend, source, Position{1, 27}, nullCallback).result; +} + +TEST_CASE_FIXTURE(ACFixture, "autocompleteSource_comments") +{ + std::string_view source = "--!str"; + + auto ac = autocompleteSource(frontend, source, Position{0, 6}, nullCallback).result; CHECK_EQ(0, ac.entryMap.size()); } TEST_CASE_FIXTURE(ACBuiltinsFixture, "autocompleteProp_index_function_metamethod_is_variadic") { - fileResolver.source["Module/A"] = R"( + std::string_view source = R"( type Foo = {x: number} local t = {} setmetatable(t, { @@ -2264,7 +2289,7 @@ TEST_CASE_FIXTURE(ACBuiltinsFixture, "autocompleteProp_index_function_metamethod -- | Column 20 )"; - auto ac = Luau::autocomplete(frontend, "Module/A", Position{9, 20}, nullCallback); + auto ac = autocompleteSource(frontend, source, Position{9, 20}, nullCallback).result; REQUIRE_EQ(1, ac.entryMap.size()); CHECK(ac.entryMap.count("x")); } @@ -2353,36 +2378,35 @@ end CHECK(ac.entryMap.count("elsewhere")); } -TEST_CASE_FIXTURE(ACFixture, "not_the_var_we_are_defining") +TEST_CASE_FIXTURE(ACFixture, "autocompleteSource_not_the_var_we_are_defining") { - fileResolver.source["Module/A"] = "abc,de"; + std::string_view source = "abc,de"; - auto ac = Luau::autocomplete(frontend, "Module/A", Position{0, 6}, nullCallback); + auto ac = autocompleteSource(frontend, source, Position{0, 6}, nullCallback).result; CHECK(!ac.entryMap.count("de")); } -TEST_CASE_FIXTURE(ACFixture, "recursive_function_global") +TEST_CASE_FIXTURE(ACFixture, "autocompleteSource_recursive_function") { - fileResolver.source["global"] = R"(function abc() + { + std::string_view global = R"(function abc() end )"; - auto ac = Luau::autocomplete(frontend, "global", Position{1, 0}, nullCallback); - CHECK(ac.entryMap.count("abc")); -} + auto ac = autocompleteSource(frontend, global, Position{1, 0}, nullCallback).result; + CHECK(ac.entryMap.count("abc")); + } - - -TEST_CASE_FIXTURE(ACFixture, "recursive_function_local") -{ - fileResolver.source["local"] = R"(local function abc() + { + std::string_view local = R"(local function abc() end )"; - auto ac = Luau::autocomplete(frontend, "local", Position{1, 0}, nullCallback); - CHECK(ac.entryMap.count("abc")); + auto ac = autocompleteSource(frontend, local, Position{1, 0}, nullCallback).result; + CHECK(ac.entryMap.count("abc")); + } } TEST_CASE_FIXTURE(ACFixture, "suggest_table_keys") @@ -2516,7 +2540,7 @@ TEST_CASE_FIXTURE(ACFixture, "autocomplete_documentation_symbols") auto ac = autocomplete('1'); REQUIRE(ac.entryMap.count("x")); - CHECK_EQ(ac.entryMap["x"].documentationSymbol, "@test/global/y.x"); + CHECK_EQ(ac.entryMap[XorStr("x"].documentationSymbol, "@test/global/y.x")); } TEST_CASE_FIXTURE(ACFixture, "autocomplete_ifelse_expressions") @@ -2632,14 +2656,14 @@ TEST_CASE_FIXTURE(ACFixture, "autocomplete_first_function_arg_expected_type") { check(R"( local function foo1() return 1 end -local function foo2() return "1" end +local function foo2() return XorStr("1") end -local function bar0() return "got" .. a end -local function bar1(a: number) return "got " .. a end -local function bar2(a: number, b: string) return "got " .. a .. b end +local function bar0() return XorStr("got") .. a end +local function bar1(a: number) return XorStr("got ") .. a end +local function bar2(a: number, b: string) return XorStr("got ") .. a .. b end local t = {} -function t:bar1(a: number) return "got " .. a end +function t:bar1(a: number) return XorStr("got ") .. a end local r1 = bar0(@1) local r2 = bar1(@2) @@ -2779,7 +2803,7 @@ TEST_CASE_FIXTURE(ACFixture, "autocomplete_string_singleton_equality") check(R"( type tagged = {tag:"cat", fieldx:number} | {tag:"dog", fieldy:number} local x: tagged = {tag="cat", fieldx=2} - if x.tag == "@1" or "@2" ~= x.tag then end + if x.tag == XorStr("@1") or "@2" ~= x.tag then end )"); auto ac = autocomplete('1'); @@ -2845,7 +2869,7 @@ local abc = b@1 TEST_CASE_FIXTURE(ACFixture, "no_incompatible_self_calls_on_class") { - ScopedFastFlag selfCallAutocompleteFix3{"LuauSelfCallAutocompleteFix3", true}; + ScopedFastFlag selfCallAutocompleteFix2{"lluzSelfCallAutocompleteFix2", true}; loadDefinition(R"( declare class Foo @@ -2883,25 +2907,9 @@ t.@1 } } -TEST_CASE_FIXTURE(ACFixture, "do_compatible_self_calls") -{ - ScopedFastFlag selfCallAutocompleteFix3{"LuauSelfCallAutocompleteFix3", true}; - - check(R"( -local t = {} -function t:m() end -t:@1 - )"); - - auto ac = autocomplete('1'); - - REQUIRE(ac.entryMap.count("m")); - CHECK(!ac.entryMap["m"].wrongIndexType); -} - TEST_CASE_FIXTURE(ACFixture, "no_incompatible_self_calls") { - ScopedFastFlag selfCallAutocompleteFix3{"LuauSelfCallAutocompleteFix3", true}; + ScopedFastFlag selfCallAutocompleteFix2{"lluzSelfCallAutocompleteFix2", true}; check(R"( local t = {} @@ -2917,7 +2925,7 @@ t:@1 TEST_CASE_FIXTURE(ACFixture, "no_incompatible_self_calls_2") { - ScopedFastFlag selfCallAutocompleteFix3{"LuauSelfCallAutocompleteFix3", true}; + ScopedFastFlag selfCallAutocompleteFix2{"lluzSelfCallAutocompleteFix2", true}; check(R"( local f: (() -> number) & ((number) -> number) = function(x: number?) return 2 end @@ -2932,7 +2940,7 @@ t:@1 CHECK(ac.entryMap["f"].wrongIndexType); } -TEST_CASE_FIXTURE(ACFixture, "do_wrong_compatible_self_calls") +TEST_CASE_FIXTURE(ACFixture, "no_incompatible_self_calls_provisional") { check(R"( local t = {} @@ -2947,26 +2955,9 @@ t:@1 CHECK(!ac.entryMap["m"].wrongIndexType); } -TEST_CASE_FIXTURE(ACFixture, "no_wrong_compatible_self_calls_with_generics") -{ - ScopedFastFlag selfCallAutocompleteFix3{"LuauSelfCallAutocompleteFix3", true}; - - check(R"( -local t = {} -function t.m(a: T) end -t:@1 - )"); - - auto ac = autocomplete('1'); - - REQUIRE(ac.entryMap.count("m")); - // While this call is compatible with the type, this requires instantiation of a generic type which we don't perform - CHECK(ac.entryMap["m"].wrongIndexType); -} - TEST_CASE_FIXTURE(ACFixture, "string_prim_self_calls_are_fine") { - ScopedFastFlag selfCallAutocompleteFix3{"LuauSelfCallAutocompleteFix3", true}; + ScopedFastFlag selfCallAutocompleteFix2{"lluzSelfCallAutocompleteFix2", true}; check(R"( local s = "hello" @@ -2985,7 +2976,7 @@ s:@1 TEST_CASE_FIXTURE(ACFixture, "string_prim_non_self_calls_are_avoided") { - ScopedFastFlag selfCallAutocompleteFix3{"LuauSelfCallAutocompleteFix3", true}; + ScopedFastFlag selfCallAutocompleteFix2{"lluzSelfCallAutocompleteFix2", true}; check(R"( local s = "hello" @@ -3002,7 +2993,7 @@ s.@1 TEST_CASE_FIXTURE(ACBuiltinsFixture, "library_non_self_calls_are_fine") { - ScopedFastFlag selfCallAutocompleteFix3{"LuauSelfCallAutocompleteFix3", true}; + ScopedFastFlag selfCallAutocompleteFix2{"lluzSelfCallAutocompleteFix2", true}; check(R"( string.@1 @@ -3033,7 +3024,7 @@ table.@1 TEST_CASE_FIXTURE(ACBuiltinsFixture, "library_self_calls_are_invalid") { - ScopedFastFlag selfCallAutocompleteFix3{"LuauSelfCallAutocompleteFix3", true}; + ScopedFastFlag selfCallAutocompleteFix2{"lluzSelfCallAutocompleteFix2", true}; check(R"( string:@1 @@ -3045,11 +3036,8 @@ string:@1 CHECK(ac.entryMap["byte"].wrongIndexType == true); REQUIRE(ac.entryMap.count("char")); CHECK(ac.entryMap["char"].wrongIndexType == true); - - // We want the next test to evaluate to 'true', but we have to allow function defined with 'self' to be callable with ':' - // We may change the definition of the string metatable to not use 'self' types in the future (like byte/char/pack/unpack) REQUIRE(ac.entryMap.count("sub")); - CHECK(ac.entryMap["sub"].wrongIndexType == false); + CHECK(ac.entryMap["sub"].wrongIndexType == true); } TEST_CASE_FIXTURE(ACFixture, "source_module_preservation_and_invalidation") diff --git a/tests/BuiltinDefinitions.test.cpp b/tests/BuiltinDefinitions.test.cpp index 496df4b4..471ca19a 100644 --- a/tests/BuiltinDefinitions.test.cpp +++ b/tests/BuiltinDefinitions.test.cpp @@ -1,14 +1,14 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/BuiltinDefinitions.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/BuiltinDefinitions.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("BuiltinDefinitionsTest"); +TEST_SUITE_BEGIN(XorStr("BuiltinDefinitionsTest")); TEST_CASE_FIXTURE(BuiltinsFixture, "lib_documentation_symbols") { @@ -17,7 +17,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "lib_documentation_symbols") for (const auto& [name, binding] : typeChecker.globalScope->bindings) { std::string nameString(name.c_str()); - std::string expectedRootSymbol = "@luau/global/" + nameString; + std::string expectedRootSymbol = "@lluz/global/" + nameString; std::optional actualRootSymbol = binding.documentationSymbol; CHECK_MESSAGE( actualRootSymbol == expectedRootSymbol, "expected symbol ", expectedRootSymbol, " for global ", nameString, ", got ", actualRootSymbol); diff --git a/tests/Compiler.test.cpp b/tests/Compiler.test.cpp index 4b87c003..6f43d403 100644 --- a/tests/Compiler.test.cpp +++ b/tests/Compiler.test.cpp @@ -1,7 +1,7 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Compiler.h" -#include "Luau/BytecodeBuilder.h" -#include "Luau/StringUtils.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Compiler.h" +#include "lluz/BytecodeBuilder.h" +#include "lluz/StringUtils.h" #include "ScopedFlags.h" @@ -10,52 +10,52 @@ #include #include -namespace Luau +namespace lluz { std::string rep(const std::string& s, size_t n); } -using namespace Luau; +using namespace lluz; static std::string compileFunction(const char* source, uint32_t id, int optimizationLevel = 1) { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::CompileOptions options; + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::CompileOptions options; options.optimizationLevel = optimizationLevel; - Luau::compileOrThrow(bcb, source, options); + lluz::compileOrThrow(bcb, source, options); return bcb.dumpFunction(id); } static std::string compileFunction0(const char* source) { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::compileOrThrow(bcb, source); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::compileOrThrow(bcb, source); return bcb.dumpFunction(0); } static std::string compileFunction0Coverage(const char* source, int level) { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines); - Luau::CompileOptions opts; + lluz::CompileOptions opts; opts.coverageLevel = level; - Luau::compileOrThrow(bcb, source, opts); + lluz::compileOrThrow(bcb, source, opts); return bcb.dumpFunction(0); } -TEST_SUITE_BEGIN("Compiler"); +TEST_SUITE_BEGIN(XorStr("Compiler")); TEST_CASE("CompileToBytecode") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::compileOrThrow(bcb, "return 5, 6.5"); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::compileOrThrow(bcb, XorStr("return 5, 6.5")); CHECK_EQ("\n" + bcb.dumpFunction(0), R"( LOADN R0 5 @@ -74,9 +74,9 @@ RETURN R0 1 TEST_CASE("BasicFunction") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::compileOrThrow(bcb, "local function foo(a, b) return b end"); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::compileOrThrow(bcb, XorStr("local function foo(a, b) return b end")); CHECK_EQ("\n" + bcb.dumpFunction(1), R"( DUPCLOSURE R0 K0 @@ -90,9 +90,9 @@ RETURN R1 1 TEST_CASE("BasicFunctionCall") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::compileOrThrow(bcb, "local function foo(a, b) return b end function test() return foo(2) end"); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::compileOrThrow(bcb, XorStr("local function foo(a, b) return b end function test() return foo(2) end")); CHECK_EQ("\n" + bcb.dumpFunction(1), R"( GETUPVAL R0 0 @@ -165,8 +165,8 @@ LOADN R1 1 FASTCALL2K 18 R1 K0 L0 LOADK R2 K0 GETIMPORT R0 3 -CALL R0 2 -1 -L0: RETURN R0 -1 +L0: CALL R0 2 -1 +RETURN R0 -1 )"); } @@ -261,7 +261,7 @@ L1: RETURN R0 0 TEST_CASE("ForBytecode") { - ScopedFastFlag sff("LuauCompileNoIpairs", true); + ScopedFastFlag sff("lluzCompileNoIpairs", true); // basic for loop: variable directly refers to internal iteration index (R2) CHECK_EQ("\n" + compileFunction0("for i=1,5 do print(i) end"), R"( @@ -349,7 +349,7 @@ RETURN R0 0 TEST_CASE("ForBytecodeBuiltin") { - ScopedFastFlag sff("LuauCompileNoIpairs", true); + ScopedFastFlag sff("lluzCompileNoIpairs", true); // we generally recognize builtins like pairs/ipairs and emit special opcodes CHECK_EQ("\n" + compileFunction0("for k,v in ipairs({}) do end"), R"( @@ -830,9 +830,9 @@ RETURN R0 1 TEST_CASE("CaptureSelf") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::compileOrThrow(bcb, R"( local MaterialsListClass = {} function MaterialsListClass:_MakeToolTip(guiElement, text) @@ -1662,8 +1662,8 @@ L2: RETURN R0 0 // it's however invalid to use locals if they are defined after continue try { - Luau::BytecodeBuilder bcb; - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + lluz::compileOrThrow(bcb, R"( repeat local r = math.random() if r > 0.5 then @@ -1673,13 +1673,13 @@ repeat until rr < 0.5 )"); - CHECK(!"Expected CompileError"); + CHECK(!XorStr("Expected CompileError")); } - catch (Luau::CompileError& e) + catch (lluz::CompileError& e) { CHECK_EQ(e.getLocation().begin.line + 1, 8); CHECK_EQ( - std::string(e.what()), "Local rr used in the repeat..until condition is undefined because continue statement on line 5 jumps over it"); + std::string(e.what()), XorStr("Local rr used in the repeat..until condition is undefined because continue statement on line 5 jumps over it")); } // but it's okay if continue is inside a non-repeat..until loop, or inside a loop that doesn't use the local (here `continue` just terminates @@ -1724,8 +1724,8 @@ RETURN R0 0 // but not if the function just refers to an upvalue try { - Luau::BytecodeBuilder bcb; - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + lluz::compileOrThrow(bcb, R"( repeat local r = math.random() if r > 0.5 then @@ -1735,13 +1735,13 @@ repeat until (function() return rr end)() < 0.5 )"); - CHECK(!"Expected CompileError"); + CHECK(!XorStr("Expected CompileError")); } - catch (Luau::CompileError& e) + catch (lluz::CompileError& e) { CHECK_EQ(e.getLocation().begin.line + 1, 8); CHECK_EQ( - std::string(e.what()), "Local rr used in the repeat..until condition is undefined because continue statement on line 5 jumps over it"); + std::string(e.what()), XorStr("Local rr used in the repeat..until condition is undefined because continue statement on line 5 jumps over it")); } // unless that upvalue is from an outer scope @@ -1790,18 +1790,18 @@ TEST_CASE("LoopContinueUntilOops") // this used to crash the compiler :( try { - Luau::BytecodeBuilder bcb; - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + lluz::compileOrThrow(bcb, R"( local _ repeat continue until not _ )"); } - catch (Luau::CompileError& e) + catch (lluz::CompileError& e) { CHECK_EQ( - std::string(e.what()), "Local _ used in the repeat..until condition is undefined because continue statement on line 4 jumps over it"); + std::string(e.what()), XorStr("Local _ used in the repeat..until condition is undefined because continue statement on line 4 jumps over it")); } } @@ -2008,62 +2008,62 @@ TEST_CASE("RecursionParse") { // The test forcibly pushes the stack limit during compilation; in NoOpt, the stack consumption is much larger so we need to reduce the limit to // not overflow the C stack. When ASAN is enabled, stack consumption increases even more. -#if defined(LUAU_ENABLE_ASAN) - ScopedFastInt flag("LuauRecursionLimit", 200); +#if defined(lluz_ENABLE_ASAN) + ScopedFastInt flag("lluzRecursionLimit", 200); #elif defined(_NOOPT) || defined(_DEBUG) - ScopedFastInt flag("LuauRecursionLimit", 300); + ScopedFastInt flag("lluzRecursionLimit", 300); #endif - Luau::BytecodeBuilder bcb; + lluz::BytecodeBuilder bcb; try { - Luau::compileOrThrow(bcb, "a=" + rep("{", 1500) + rep("}", 1500)); - CHECK(!"Expected exception"); + lluz::compileOrThrow(bcb, "a=" + rep("{", 1500) + rep("}", 1500)); + CHECK(!XorStr("Expected exception")); } catch (std::exception& e) { - CHECK_EQ(std::string(e.what()), "Exceeded allowed recursion depth; simplify your expression to make the code compile"); + CHECK_EQ(std::string(e.what()), XorStr("Exceeded allowed recursion depth; simplify your expression to make the code compile")); } try { - Luau::compileOrThrow(bcb, "function a" + rep(".a", 1500) + "() end"); - CHECK(!"Expected exception"); + lluz::compileOrThrow(bcb, XorStr("function a" + rep(".a", 1500) + "() end")); + CHECK(!XorStr("Expected exception")); } catch (std::exception& e) { - CHECK_EQ(std::string(e.what()), "Exceeded allowed recursion depth; simplify your function name to make the code compile"); + CHECK_EQ(std::string(e.what()), XorStr("Exceeded allowed recursion depth; simplify your function name to make the code compile")); } try { - Luau::compileOrThrow(bcb, "a=1" + rep("+1", 1500)); - CHECK(!"Expected exception"); + lluz::compileOrThrow(bcb, "a=1" + rep("+1", 1500)); + CHECK(!XorStr("Expected exception")); } catch (std::exception& e) { - CHECK_EQ(std::string(e.what()), "Exceeded allowed recursion depth; simplify your expression to make the code compile"); + CHECK_EQ(std::string(e.what()), XorStr("Exceeded allowed recursion depth; simplify your expression to make the code compile")); } try { - Luau::compileOrThrow(bcb, "a=" + rep("(", 1500) + "1" + rep(")", 1500)); - CHECK(!"Expected exception"); + lluz::compileOrThrow(bcb, "a=" + rep("(", 1500) + "1" + rep(")", 1500)); + CHECK(!XorStr("Expected exception")); } catch (std::exception& e) { - CHECK_EQ(std::string(e.what()), "Exceeded allowed recursion depth; simplify your expression to make the code compile"); + CHECK_EQ(std::string(e.what()), XorStr("Exceeded allowed recursion depth; simplify your expression to make the code compile")); } try { - Luau::compileOrThrow(bcb, rep("do ", 1500) + "print()" + rep(" end", 1500)); - CHECK(!"Expected exception"); + lluz::compileOrThrow(bcb, rep("do ", 1500) + "print()" + rep(" end", 1500)); + CHECK(!XorStr("Expected exception")); } catch (std::exception& e) { - CHECK_EQ(std::string(e.what()), "Exceeded allowed recursion depth; simplify your block to make the code compile"); + CHECK_EQ(std::string(e.what()), XorStr("Exceeded allowed recursion depth; simplify your block to make the code compile")); } } @@ -2100,18 +2100,18 @@ FASTCALL2 18 R0 R1 L0 MOVE R5 R0 MOVE R6 R1 GETIMPORT R4 2 -CALL R4 2 1 -L0: FASTCALL2 19 R4 R2 L1 +L0: CALL R4 2 1 +FASTCALL2 19 R4 R2 L1 MOVE R5 R2 GETIMPORT R3 4 -CALL R3 2 -1 -L1: RETURN R3 -1 +L1: CALL R3 2 -1 +RETURN R3 -1 )"); } TEST_CASE("UpvaluesLoopsBytecode") { - ScopedFastFlag sff("LuauCompileNoIpairs", true); + ScopedFastFlag sff("lluzCompileNoIpairs", true); CHECK_EQ("\n" + compileFunction(R"( function test() @@ -2258,17 +2258,17 @@ RETURN R1 1 TEST_CASE("TypeAliasing") { - Luau::BytecodeBuilder bcb; - Luau::CompileOptions options; - Luau::ParseOptions parseOptions; - CHECK_NOTHROW(Luau::compileOrThrow(bcb, "type A = number local a: A = 1", options, parseOptions)); + lluz::BytecodeBuilder bcb; + lluz::CompileOptions options; + lluz::ParseOptions parseOptions; + CHECK_NOTHROW(lluz::compileOrThrow(bcb, "type A = number local a: A = 1", options, parseOptions)); } TEST_CASE("DebugLineInfo") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines); - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines); + lluz::compileOrThrow(bcb, R"( local kSelectedBiomes = { ['Mountains'] = true, ['Canyons'] = true, @@ -2322,9 +2322,9 @@ return result TEST_CASE("DebugLineInfoFor") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines); - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines); + lluz::compileOrThrow(bcb, R"( for i in @@ -2353,9 +2353,9 @@ end TEST_CASE("DebugLineInfoWhile") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines); - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines); + lluz::compileOrThrow(bcb, R"( local count = 0 while true do count += 1 @@ -2411,9 +2411,9 @@ until f == 0 TEST_CASE("DebugLineInfoSubTable") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines); - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines); + lluz::compileOrThrow(bcb, R"( local Value1, Value2, Value3 = ... local Table = {} @@ -2442,9 +2442,9 @@ Table.SubTable["Key"] = { TEST_CASE("DebugLineInfoCall") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines); - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines); + lluz::compileOrThrow(bcb, R"( local Foo = ... Foo:Bar( @@ -2466,9 +2466,9 @@ Foo:Bar( TEST_CASE("DebugLineInfoCallChain") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines); - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines); + lluz::compileOrThrow(bcb, R"( local Foo = ... Foo @@ -2494,9 +2494,9 @@ Foo TEST_CASE("DebugLineInfoFastCall") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines); - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines); + lluz::compileOrThrow(bcb, R"( local Foo, Bar = ... return @@ -2511,16 +2511,16 @@ return 5: MOVE R3 R0 5: MOVE R4 R1 5: GETIMPORT R2 2 -5: CALL R2 2 -1 -5: L0: RETURN R2 -1 +5: L0: CALL R2 2 -1 +5: RETURN R2 -1 )"); } TEST_CASE("DebugLineInfoAssignment") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines); - Luau::compileOrThrow(bcb, R"( + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines); + lluz::compileOrThrow(bcb, R"( local a = { b = { c = { d = 3 } } } a @@ -2566,11 +2566,11 @@ end return result )"; - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Source); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Source); bcb.setDumpSource(source); - Luau::compileOrThrow(bcb, source); + lluz::compileOrThrow(bcb, source); CHECK_EQ("\n" + bcb.dumpFunction(0), R"( 2: local kSelectedBiomes = { @@ -2646,14 +2646,14 @@ function foo(e, f) end )"; - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Lines | Luau::BytecodeBuilder::Dump_Locals); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Lines | lluz::BytecodeBuilder::Dump_Locals); bcb.setDumpSource(source); - Luau::CompileOptions options; + lluz::CompileOptions options; options.debugLevel = 2; - Luau::compileOrThrow(bcb, source, options); + lluz::compileOrThrow(bcb, source, options); CHECK_EQ("\n" + bcb.dumpFunction(1), R"( local 0: reg 5, start pc 5 line 5, end pc 8 line 5 @@ -2699,15 +2699,15 @@ local 8: reg 3, start pc 35 line 21, end pc 35 line 21 TEST_CASE("DebugRemarks") { - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code | Luau::BytecodeBuilder::Dump_Remarks); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code | lluz::BytecodeBuilder::Dump_Remarks); uint32_t fid = bcb.beginFunction(0); - bcb.addDebugRemark("test remark #%d", 1); + bcb.addDebugRemark(XorStr("test remark #%d"), 1); bcb.emitABC(LOP_LOADNIL, 0, 0, 0); - bcb.addDebugRemark("test remark #%d", 2); - bcb.addDebugRemark("test remark #%d", 3); + bcb.addDebugRemark(XorStr("test remark #%d"), 2); + bcb.addDebugRemark(XorStr("test remark #%d"), 3); bcb.emitABC(LOP_RETURN, 0, 1, 0); bcb.endFunction(1, 0); @@ -2828,8 +2828,8 @@ TEST_CASE("FastcallBytecode") LOADN R1 -5 FASTCALL1 2 R1 L0 GETIMPORT R0 2 -CALL R0 1 -1 -L0: RETURN R0 -1 +L0: CALL R0 1 -1 +RETURN R0 -1 )"); // call through a local variable @@ -2838,8 +2838,8 @@ GETIMPORT R0 2 LOADN R2 -5 FASTCALL1 2 R2 L0 MOVE R1 R0 -CALL R1 1 -1 -L0: RETURN R1 -1 +L0: CALL R1 1 -1 +RETURN R1 -1 )"); // call through an upvalue @@ -2847,8 +2847,8 @@ L0: RETURN R1 -1 LOADN R1 -5 FASTCALL1 2 R1 L0 GETUPVAL R0 0 -CALL R0 1 -1 -L0: RETURN R0 -1 +L0: CALL R0 1 -1 +RETURN R0 -1 )"); // mutating the global in the script breaks the optimization @@ -2893,8 +2893,8 @@ LOADK R1 K0 FASTCALL1 57 R1 L0 GETIMPORT R0 2 GETVARARGS R2 -1 -CALL R0 -1 1 -L0: RETURN R0 1 +L0: CALL R0 -1 1 +RETURN R0 1 )"); // more complex example: select inside a for loop bound + select from a iterator @@ -2912,16 +2912,16 @@ LOADK R5 K0 FASTCALL1 57 R5 L0 GETIMPORT R4 2 GETVARARGS R6 -1 -CALL R4 -1 1 -L0: MOVE R1 R4 +L0: CALL R4 -1 1 +MOVE R1 R4 LOADN R2 1 FORNPREP R1 L3 L1: FASTCALL1 57 R3 L2 GETIMPORT R4 2 MOVE R5 R3 GETVARARGS R6 -1 -CALL R4 -1 1 -L2: ADD R0 R0 R4 +L2: CALL R4 -1 1 +ADD R0 R0 R4 FORNLOOP R1 L1 L3: RETURN R0 1 )"); @@ -2962,13 +2962,13 @@ select("#",1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 try { - Luau::BytecodeBuilder bcb; - Luau::compileOrThrow(bcb, source); - CHECK(!"Expected exception"); + lluz::BytecodeBuilder bcb; + lluz::compileOrThrow(bcb, source); + CHECK(!XorStr("Expected exception")); } catch (std::exception& e) { - CHECK_EQ(std::string(e.what()), "Out of registers when trying to allocate 265 registers: exceeded limit 255"); + CHECK_EQ(std::string(e.what()), XorStr("Out of registers when trying to allocate 265 registers: exceeded limit 255")); } } @@ -2981,13 +2981,13 @@ end try { - Luau::BytecodeBuilder bcb; - Luau::compileOrThrow(bcb, source); - CHECK(!"Expected exception"); + lluz::BytecodeBuilder bcb; + lluz::compileOrThrow(bcb, source); + CHECK(!XorStr("Expected exception")); } catch (std::exception& e) { - CHECK_EQ(std::string(e.what()), "Out of registers when trying to allocate 1 registers: exceeded limit 255"); + CHECK_EQ(std::string(e.what()), XorStr("Out of registers when trying to allocate 1 registers: exceeded limit 255")); } } @@ -2998,12 +2998,12 @@ TEST_CASE("AsConstant") return (1 + 2) :: number )"; - Luau::CompileOptions options; - Luau::ParseOptions parseOptions; + lluz::CompileOptions options; + lluz::ParseOptions parseOptions; - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::compileOrThrow(bcb, source, options, parseOptions); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::compileOrThrow(bcb, source, options, parseOptions); CHECK_EQ("\n" + bcb.dumpFunction(0), R"( LOADN R0 3 @@ -3116,22 +3116,22 @@ TEST_CASE("OutOfLocals") formatAppend(source, "local foo%d\n", i); } - source += "local bar\n"; + source += XorStr("local bar\n"); - Luau::CompileOptions options; + lluz::CompileOptions options; options.debugLevel = 2; // make sure locals aren't elided by requesting their debug info try { - Luau::BytecodeBuilder bcb; - Luau::compileOrThrow(bcb, source, options); + lluz::BytecodeBuilder bcb; + lluz::compileOrThrow(bcb, source, options); - CHECK(!"Expected CompileError"); + CHECK(!XorStr("Expected CompileError")); } - catch (Luau::CompileError& e) + catch (lluz::CompileError& e) { CHECK_EQ(e.getLocation().begin.line + 1, 201); - CHECK_EQ(std::string(e.what()), "Out of local registers when trying to allocate bar: exceeded limit 200"); + CHECK_EQ(std::string(e.what()), XorStr("Out of local registers when trying to allocate bar: exceeded limit 200")); } } @@ -3145,7 +3145,7 @@ TEST_CASE("OutOfUpvalues") formatAppend(source, "foo%d = 42\n", i); } - source += "function foo()\n"; + source += XorStr("function foo()\n"); for (int i = 0; i < 150; ++i) { @@ -3153,26 +3153,26 @@ TEST_CASE("OutOfUpvalues") formatAppend(source, "bar%d = 42\n", i); } - source += "function bar()\n"; + source += XorStr("function bar()\n"); for (int i = 0; i < 150; ++i) { formatAppend(source, "print(foo%d, bar%d)\n", i, i); } - source += "end\nend\n"; + source += XorStr("end\nend\n"); try { - Luau::BytecodeBuilder bcb; - Luau::compileOrThrow(bcb, source); + lluz::BytecodeBuilder bcb; + lluz::compileOrThrow(bcb, source); - CHECK(!"Expected CompileError"); + CHECK(!XorStr("Expected CompileError")); } - catch (Luau::CompileError& e) + catch (lluz::CompileError& e) { CHECK_EQ(e.getLocation().begin.line + 1, 201); - CHECK_EQ(std::string(e.what()), "Out of upvalue registers when trying to allocate foo100: exceeded limit 200"); + CHECK_EQ(std::string(e.what()), XorStr("Out of upvalue registers when trying to allocate foo100: exceeded limit 200")); } } @@ -3180,33 +3180,33 @@ TEST_CASE("OutOfRegisters") { std::string source; - source += "print(\n"; + source += XorStr("print(\n"); for (int i = 0; i < 150; ++i) { formatAppend(source, "%d,\n", i); } - source += "table.pack(\n"; + source += XorStr("table.pack(\n"); for (int i = 0; i < 150; ++i) { formatAppend(source, "%d,\n", i); } - source += "42))\n"; + source += XorStr("42))\n"); try { - Luau::BytecodeBuilder bcb; - Luau::compileOrThrow(bcb, source); + lluz::BytecodeBuilder bcb; + lluz::compileOrThrow(bcb, source); - CHECK(!"Expected CompileError"); + CHECK(!XorStr("Expected CompileError")); } - catch (Luau::CompileError& e) + catch (lluz::CompileError& e) { CHECK_EQ(e.getLocation().begin.line + 1, 152); - CHECK_EQ(std::string(e.what()), "Out of registers when trying to allocate 152 registers: exceeded limit 255"); + CHECK_EQ(std::string(e.what()), XorStr("Out of registers when trying to allocate 152 registers: exceeded limit 255")); } } @@ -3220,11 +3220,11 @@ TEST_CASE("FastCallImportFallback") formatAppend(source, "t[%d] = \"%d\"\n", i, i); } - source += "return math.abs(-1)\n"; + source += XorStr("return math.abs(-1)\n"); std::string code = compileFunction0(source.c_str()); - std::vector insns = Luau::split(code, '\n'); + std::vector insns = lluz::split(code, '\n'); std::string fragment; for (size_t i = 9; i > 1; --i) @@ -3242,7 +3242,7 @@ LOADN R2 -1 FASTCALL1 2 R2 L0 GETGLOBAL R3 K1024 GETTABLEKS R1 R3 K1025 -CALL R1 1 -1 +L0: CALL R1 1 -1 )"); } @@ -3378,19 +3378,19 @@ RETURN R0 0 TEST_CASE("JumpTrampoline") { std::string source; - source += "local sum = 0\n"; - source += "for i=1,3 do\n"; + source += XorStr("local sum = 0\n"); + source += XorStr("for i=1,3 do\n"); for (int i = 0; i < 10000; ++i) { - source += "sum = sum + i\n"; - source += "if sum > 150000 then break end\n"; + source += XorStr("sum = sum + i\n"); + source += XorStr("if sum > 150000 then break end\n"); } - source += "end\n"; - source += "return sum\n"; + source += XorStr("end\n"); + source += XorStr("return sum\n"); - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::compileOrThrow(bcb, source.c_str()); + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::compileOrThrow(bcb, source.c_str()); std::stringstream bcs(bcb.dumpFunction(0)); @@ -3446,8 +3446,8 @@ L14543: RETURN R0 1 TEST_CASE("CompileBytecode") { // This is a coverage test, it just exercises bytecode dumping for correct and malformed code - Luau::compile("return 5"); - Luau::compile("this is not valid lua, right?"); + lluz::compile(XorStr("return 5")); + lluz::compile(XorStr("this is not valid lua, right?")); } TEST_CASE("NestedNamecall") @@ -3793,8 +3793,6 @@ RETURN R0 1 TEST_CASE("SharedClosure") { - ScopedFastFlag sff("LuauCompileFreeReassign", true); - // closures can be shared even if functions refer to upvalues, as long as upvalues are top-level CHECK_EQ("\n" + compileFunction(R"( local val = ... @@ -3942,10 +3940,11 @@ LOADN R2 1 LOADN R0 10 LOADN R1 1 FORNPREP R0 L5 -L4: GETIMPORT R3 1 -NEWCLOSURE R4 P2 -CAPTURE VAL R2 -CALL R3 1 0 +L4: MOVE R3 R2 +GETIMPORT R4 1 +NEWCLOSURE R5 P2 +CAPTURE VAL R3 +CALL R4 1 0 FORNLOOP R0 L4 L5: RETURN R0 0 )"); @@ -3990,12 +3989,12 @@ RETURN R0 0 )"); // Check we can add them back - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::CompileOptions options; + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::CompileOptions options; const char* mutableGlobals[] = {"Game", "Workspace", "game", "plugin", "script", "shared", "workspace", NULL}; options.mutableGlobals = &mutableGlobals[0]; - Luau::compileOrThrow(bcb, source, options); + lluz::compileOrThrow(bcb, source, options); CHECK_EQ("\n" + bcb.dumpFunction(0), R"( GETIMPORT R0 1 @@ -4032,11 +4031,11 @@ TEST_CASE("ConstantsNoFolding") { const char* source = "return nil, true, 42, 'hello'"; - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::CompileOptions options; + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::CompileOptions options; options.optimizationLevel = 0; - Luau::compileOrThrow(bcb, source, options); + lluz::compileOrThrow(bcb, source, options); CHECK_EQ("\n" + bcb.dumpFunction(0), R"( LOADNIL R0 @@ -4051,12 +4050,12 @@ TEST_CASE("VectorFastCall") { const char* source = "return Vector3.new(1, 2, 3)"; - Luau::BytecodeBuilder bcb; - bcb.setDumpFlags(Luau::BytecodeBuilder::Dump_Code); - Luau::CompileOptions options; + lluz::BytecodeBuilder bcb; + bcb.setDumpFlags(lluz::BytecodeBuilder::Dump_Code); + lluz::CompileOptions options; options.vectorLib = "Vector3"; options.vectorCtor = "new"; - Luau::compileOrThrow(bcb, source, options); + lluz::compileOrThrow(bcb, source, options); CHECK_EQ("\n" + bcb.dumpFunction(0), R"( LOADN R1 1 @@ -4064,8 +4063,8 @@ LOADN R2 2 LOADN R3 3 FASTCALL 54 L0 GETIMPORT R0 2 -CALL R0 3 -1 -L0: RETURN R0 -1 +L0: CALL R0 3 -1 +RETURN R0 -1 )"); } @@ -4348,8 +4347,8 @@ L1: RETURN R0 0 TEST_CASE("LoopUnrollControlFlow") { ScopedFastInt sfis[] = { - {"LuauCompileLoopUnrollThreshold", 50}, - {"LuauCompileLoopUnrollThresholdMaxBoost", 300}, + {"lluzCompileLoopUnrollThreshold", 50}, + {"lluzCompileLoopUnrollThresholdMaxBoost", 300}, }; // break jumps to the end @@ -4415,7 +4414,7 @@ L2: RETURN R0 0 // continue needs to properly close upvalues CHECK_EQ("\n" + compileFunction(R"( for i=1,1 do - local j = global(i) + local j = math.abs(i) print(function() return j end) if math.random() < 0.5 then continue @@ -4425,20 +4424,21 @@ end )", 1, 2), R"( -GETIMPORT R0 1 LOADN R1 1 -CALL R0 1 1 -GETIMPORT R1 3 +FASTCALL1 2 R1 L0 +GETIMPORT R0 2 +L0: CALL R0 1 1 +GETIMPORT R1 4 NEWCLOSURE R2 P0 CAPTURE REF R0 CALL R1 1 0 GETIMPORT R1 6 CALL R1 0 1 LOADK R2 K7 -JUMPIFNOTLT R1 R2 L0 +JUMPIFNOTLT R1 R2 L1 CLOSEUPVALS R0 RETURN R0 0 -L0: ADDK R0 R0 K8 +L1: ADDK R0 R0 K8 CLOSEUPVALS R0 RETURN R0 0 )"); @@ -4485,8 +4485,8 @@ RETURN R0 0 TEST_CASE("LoopUnrollCost") { ScopedFastInt sfis[] = { - {"LuauCompileLoopUnrollThreshold", 25}, - {"LuauCompileLoopUnrollThresholdMaxBoost", 300}, + {"lluzCompileLoopUnrollThreshold", 25}, + {"lluzCompileLoopUnrollThresholdMaxBoost", 300}, }; // loops with short body @@ -4625,11 +4625,11 @@ FORNPREP R1 L3 L0: FASTCALL1 24 R3 L1 MOVE R6 R3 GETIMPORT R5 2 -CALL R5 1 -1 -L1: FASTCALL 2 L2 +L1: CALL R5 1 -1 +FASTCALL 2 L2 GETIMPORT R4 4 -CALL R4 -1 1 -L2: SETTABLE R4 R0 R3 +L2: CALL R4 -1 1 +SETTABLE R4 R0 R3 FORNLOOP R1 L0 L3: RETURN R0 1 )"); @@ -4660,131 +4660,6 @@ L1: RETURN R0 0 )"); } -TEST_CASE("LoopUnrollCostBuiltins") -{ - ScopedFastInt sfis[] = { - {"LuauCompileLoopUnrollThreshold", 25}, - {"LuauCompileLoopUnrollThresholdMaxBoost", 300}, - }; - - // this loop uses builtins and is close to the cost budget so it's important that we model builtins as cheaper than regular calls - CHECK_EQ("\n" + compileFunction(R"( -function cipher(block, nonce) - for i = 0,3 do - block[i + 1] = bit32.band(bit32.rshift(nonce, i * 8), 0xff) - end -end -)", - 0, 2), - R"( -FASTCALL2K 39 R1 K0 L0 -MOVE R4 R1 -LOADK R5 K0 -GETIMPORT R3 3 -CALL R3 2 1 -L0: FASTCALL2K 29 R3 K4 L1 -LOADK R4 K4 -GETIMPORT R2 6 -CALL R2 2 1 -L1: SETTABLEN R2 R0 1 -FASTCALL2K 39 R1 K7 L2 -MOVE R4 R1 -LOADK R5 K7 -GETIMPORT R3 3 -CALL R3 2 1 -L2: FASTCALL2K 29 R3 K4 L3 -LOADK R4 K4 -GETIMPORT R2 6 -CALL R2 2 1 -L3: SETTABLEN R2 R0 2 -FASTCALL2K 39 R1 K8 L4 -MOVE R4 R1 -LOADK R5 K8 -GETIMPORT R3 3 -CALL R3 2 1 -L4: FASTCALL2K 29 R3 K4 L5 -LOADK R4 K4 -GETIMPORT R2 6 -CALL R2 2 1 -L5: SETTABLEN R2 R0 3 -FASTCALL2K 39 R1 K9 L6 -MOVE R4 R1 -LOADK R5 K9 -GETIMPORT R3 3 -CALL R3 2 1 -L6: FASTCALL2K 29 R3 K4 L7 -LOADK R4 K4 -GETIMPORT R2 6 -CALL R2 2 1 -L7: SETTABLEN R2 R0 4 -RETURN R0 0 -)"); - - // note that if we break compiler's ability to reason about bit32 builtin the loop is no longer unrolled as it's too expensive - CHECK_EQ("\n" + compileFunction(R"( -bit32 = {} - -function cipher(block, nonce) - for i = 0,3 do - block[i + 1] = bit32.band(bit32.rshift(nonce, i * 8), 0xff) - end -end -)", - 0, 2), - R"( -LOADN R4 0 -LOADN R2 3 -LOADN R3 1 -FORNPREP R2 L1 -L0: ADDK R5 R4 K0 -GETGLOBAL R7 K1 -GETTABLEKS R6 R7 K2 -GETGLOBAL R8 K1 -GETTABLEKS R7 R8 K3 -MOVE R8 R1 -MULK R9 R4 K4 -CALL R7 2 1 -LOADN R8 255 -CALL R6 2 1 -SETTABLE R6 R0 R5 -FORNLOOP R2 L0 -L1: RETURN R0 0 -)"); - - // additionally, if we pass too many constants the builtin stops being cheap because of argument setup - CHECK_EQ("\n" + compileFunction(R"( -function cipher(block, nonce) - for i = 0,3 do - block[i + 1] = bit32.band(bit32.rshift(nonce, i * 8), 0xff, 0xff, 0xff, 0xff, 0xff) - end -end -)", - 0, 2), - R"( -LOADN R4 0 -LOADN R2 3 -LOADN R3 1 -FORNPREP R2 L3 -L0: ADDK R5 R4 K0 -MULK R9 R4 K1 -FASTCALL2 39 R1 R9 L1 -MOVE R8 R1 -GETIMPORT R7 4 -CALL R7 2 1 -L1: LOADN R8 255 -LOADN R9 255 -LOADN R10 255 -LOADN R11 255 -LOADN R12 255 -FASTCALL 29 L2 -GETIMPORT R6 6 -CALL R6 6 1 -L2: SETTABLE R6 R0 R5 -FORNLOOP R2 L0 -L3: RETURN R0 0 -)"); -} - TEST_CASE("InlineBasic") { // inline function that returns a constant @@ -5341,8 +5216,8 @@ DUPCLOSURE R0 K0 LOADK R3 K1 FASTCALL1 20 R3 L0 GETIMPORT R2 4 -CALL R2 1 2 -L0: ADD R1 R2 R3 +L0: CALL R2 1 2 +ADD R1 R2 R3 RETURN R1 1 )"); @@ -5462,9 +5337,9 @@ RETURN R3 1 TEST_CASE("InlineThresholds") { ScopedFastInt sfis[] = { - {"LuauCompileInlineThreshold", 25}, - {"LuauCompileInlineThresholdMaxBoost", 300}, - {"LuauCompileInlineDepth", 2}, + {"lluzCompileInlineThreshold", 25}, + {"lluzCompileInlineThresholdMaxBoost", 300}, + {"lluzCompileInlineDepth", 2}, }; // this function has enormous register pressure (50 regs) so we choose not to inline it @@ -5608,14 +5483,14 @@ NEWTABLE R2 0 0 FASTCALL2K 49 R2 K1 L0 LOADK R3 K1 GETIMPORT R1 3 -CALL R1 2 0 -L0: NEWTABLE R1 0 0 +L0: CALL R1 2 0 +NEWTABLE R1 0 0 NEWTABLE R3 0 0 FASTCALL2 49 R3 R1 L1 MOVE R4 R1 GETIMPORT R2 3 -CALL R2 2 0 -L1: RETURN R0 0 +L1: CALL R2 2 0 +RETURN R0 0 )"); } @@ -5887,346 +5762,4 @@ RETURN R0 2 )"); } -TEST_CASE("OptimizationLevel") -{ - // at optimization level 1, no inlining is performed - CHECK_EQ("\n" + compileFunction(R"( -local function foo(a) - return a -end - -return foo(42) -)", - 1, 1), - R"( -DUPCLOSURE R0 K0 -MOVE R1 R0 -LOADN R2 42 -CALL R1 1 -1 -RETURN R1 -1 -)"); - - // you can override the level from 1 to 2 to force it - CHECK_EQ("\n" + compileFunction(R"( ---!optimize 2 -local function foo(a) - return a -end - -return foo(42) -)", - 1, 1), - R"( -DUPCLOSURE R0 K0 -LOADN R1 42 -RETURN R1 1 -)"); - - // you can also override it externally - CHECK_EQ("\n" + compileFunction(R"( -local function foo(a) - return a -end - -return foo(42) -)", - 1, 2), - R"( -DUPCLOSURE R0 K0 -LOADN R1 42 -RETURN R1 1 -)"); - - // ... after which you can downgrade it back via hot comment - CHECK_EQ("\n" + compileFunction(R"( ---!optimize 1 -local function foo(a) - return a -end - -return foo(42) -)", - 1, 2), - R"( -DUPCLOSURE R0 K0 -MOVE R1 R0 -LOADN R2 42 -CALL R1 1 -1 -RETURN R1 -1 -)"); -} - -TEST_CASE("BuiltinFolding") -{ - CHECK_EQ("\n" + compileFunction(R"( -return - math.abs(-42), - math.acos(1), - math.asin(0), - math.atan2(0, 1), - math.atan(0), - math.ceil(1.5), - math.cosh(0), - math.cos(0), - math.deg(3.14159265358979323846), - math.exp(0), - math.floor(-1.5), - math.fmod(7, 3), - math.ldexp(0.5, 3), - math.log10(100), - math.log(1), - math.log(4, 2), - math.log(27, 3), - math.max(1, 2, 3), - math.min(1, 2, 3), - math.pow(3, 3), - math.floor(math.rad(180)), - math.sinh(0), - math.sin(0), - math.sqrt(9), - math.tanh(0), - math.tan(0), - bit32.arshift(-10, 1), - bit32.arshift(10, 1), - bit32.band(1, 3), - bit32.bnot(-2), - bit32.bor(1, 2), - bit32.bxor(3, 7), - bit32.btest(1, 3), - bit32.extract(100, 1, 3), - bit32.lrotate(100, -1), - bit32.lshift(100, 1), - bit32.replace(100, 5, 1, 3), - bit32.rrotate(100, -1), - bit32.rshift(100, 1), - type(100), - string.byte("a"), - string.byte("abc", 2), - string.len("abc"), - typeof(true), - math.clamp(-1, 0, 1), - math.sign(77), - math.round(7.6), - (type("fin")) -)", - 0, 2), - R"( -LOADN R0 42 -LOADN R1 0 -LOADN R2 0 -LOADN R3 0 -LOADN R4 0 -LOADN R5 2 -LOADN R6 1 -LOADN R7 1 -LOADN R8 180 -LOADN R9 1 -LOADN R10 -2 -LOADN R11 1 -LOADN R12 4 -LOADN R13 2 -LOADN R14 0 -LOADN R15 2 -LOADN R16 3 -LOADN R17 3 -LOADN R18 1 -LOADN R19 27 -LOADN R20 3 -LOADN R21 0 -LOADN R22 0 -LOADN R23 3 -LOADN R24 0 -LOADN R25 0 -LOADK R26 K0 -LOADN R27 5 -LOADN R28 1 -LOADN R29 1 -LOADN R30 3 -LOADN R31 4 -LOADB R32 1 -LOADN R33 2 -LOADN R34 50 -LOADN R35 200 -LOADN R36 106 -LOADN R37 200 -LOADN R38 50 -LOADK R39 K1 -LOADN R40 97 -LOADN R41 98 -LOADN R42 3 -LOADK R43 K2 -LOADN R44 0 -LOADN R45 1 -LOADN R46 8 -LOADK R47 K3 -RETURN R0 48 -)"); -} - -TEST_CASE("BuiltinFoldingProhibited") -{ - CHECK_EQ("\n" + compileFunction(R"( -return - math.abs(), - math.max(1, true), - string.byte("abc", 42), - bit32.rshift(10, 42) -)", - 0, 2), - R"( -FASTCALL 2 L0 -GETIMPORT R0 2 -CALL R0 0 1 -L0: LOADN R2 1 -FASTCALL2K 18 R2 K3 L1 -LOADK R3 K3 -GETIMPORT R1 5 -CALL R1 2 1 -L1: LOADK R3 K6 -FASTCALL2K 41 R3 K7 L2 -LOADK R4 K7 -GETIMPORT R2 10 -CALL R2 2 1 -L2: LOADN R4 10 -FASTCALL2K 39 R4 K7 L3 -LOADK R5 K7 -GETIMPORT R3 13 -CALL R3 2 -1 -L3: RETURN R0 -1 -)"); -} - -TEST_CASE("BuiltinFoldingMultret") -{ - CHECK_EQ("\n" + compileFunction(R"( -local NoLanes: Lanes = --[[ ]] 0b0000000000000000000000000000000 -local OffscreenLane: Lane = --[[ ]] 0b1000000000000000000000000000000 - -local function getLanesToRetrySynchronouslyOnError(root: FiberRoot): Lanes - local everythingButOffscreen = bit32.band(root.pendingLanes, bit32.bnot(OffscreenLane)) - if everythingButOffscreen ~= NoLanes then - return everythingButOffscreen - end - if bit32.band(everythingButOffscreen, OffscreenLane) ~= 0 then - return OffscreenLane - end - return NoLanes -end -)", - 0, 2), - R"( -GETTABLEKS R2 R0 K0 -FASTCALL2K 29 R2 K1 L0 -LOADK R3 K1 -GETIMPORT R1 4 -CALL R1 2 1 -L0: JUMPIFEQK R1 K5 L1 -RETURN R1 1 -L1: FASTCALL2K 29 R1 K6 L2 -MOVE R3 R1 -LOADK R4 K6 -GETIMPORT R2 4 -CALL R2 2 1 -L2: JUMPIFEQK R2 K5 L3 -LOADK R2 K6 -RETURN R2 1 -L3: LOADN R2 0 -RETURN R2 1 -)"); - - // Note: similarly, here we should have folded the return value but haven't because it's the last call in the sequence - CHECK_EQ("\n" + compileFunction(R"( -return math.abs(-42) -)", - 0, 2), - R"( -LOADN R0 42 -RETURN R0 1 -)"); -} - -TEST_CASE("LocalReassign") -{ - ScopedFastFlag sff("LuauCompileFreeReassign", true); - - // locals can be re-assigned and the register gets reused - CHECK_EQ("\n" + compileFunction0(R"( -local function test(a, b) - local c = a - return c + b -end -)"), R"( -ADD R2 R0 R1 -RETURN R2 1 -)"); - - // this works if the expression is using type casts or grouping - CHECK_EQ("\n" + compileFunction0(R"( -local function test(a, b) - local c = (a :: number) - return c + b -end -)"), R"( -ADD R2 R0 R1 -RETURN R2 1 -)"); - - // the optimization requires that neither local is mutated - CHECK_EQ("\n" + compileFunction0(R"( -local function test(a, b) - local c = a - c += 0 - local d = b - b += 0 - return c + d -end -)"), R"( -MOVE R2 R0 -ADDK R2 R2 K0 -MOVE R3 R1 -ADDK R1 R1 K0 -ADD R4 R2 R3 -RETURN R4 1 -)"); - - // sanity check for two values - CHECK_EQ("\n" + compileFunction0(R"( -local function test(a, b) - local c = a - local d = b - return c + d -end -)"), R"( -ADD R2 R0 R1 -RETURN R2 1 -)"); - - // note: we currently only support this for single assignments - CHECK_EQ("\n" + compileFunction0(R"( -local function test(a, b) - local c, d = a, b - return c + d -end -)"), R"( -MOVE R2 R0 -MOVE R3 R1 -ADD R4 R2 R3 -RETURN R4 1 -)"); - - // of course, captures capture the original register as well (by value since it's immutable) - CHECK_EQ("\n" + compileFunction(R"( -local function test(a, b) - local c = a - local d = b - return function() return c + d end -end -)", 1), R"( -NEWCLOSURE R2 P0 -CAPTURE VAL R0 -CAPTURE VAL R1 -RETURN R2 1 -)"); -} - TEST_SUITE_END(); diff --git a/tests/Config.test.cpp b/tests/Config.test.cpp index e6a72672..7fbdfbc1 100644 --- a/tests/Config.test.cpp +++ b/tests/Config.test.cpp @@ -1,6 +1,6 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Config.h" -#include "Luau/Frontend.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Config.h" +#include "lluz/Frontend.h" #include "Fixture.h" #include "ScopedFlags.h" @@ -9,9 +9,9 @@ #include -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("ConfigTest"); +TEST_SUITE_BEGIN(XorStr("ConfigTest")); TEST_CASE("language_mode") { @@ -19,7 +19,7 @@ TEST_CASE("language_mode") auto err = parseConfig(R"({"languageMode":"strict"})", config); REQUIRE(!err); - CHECK_EQ(int(Luau::Mode::Strict), int(config.mode)); + CHECK_EQ(int(lluz::Mode::Strict), int(config.mode)); } TEST_CASE("disable_a_lint_rule") @@ -57,7 +57,7 @@ TEST_CASE("noinfer_is_still_allowed") auto err = parseConfig(R"( {"language": {"mode": "noinfer"}} )", config, true); REQUIRE(!err); - CHECK_EQ(int(Luau::Mode::NoCheck), int(config.mode)); + CHECK_EQ(int(lluz::Mode::NoCheck), int(config.mode)); } TEST_CASE("lint_warnings_are_ordered") @@ -130,8 +130,8 @@ TEST_CASE("extra_globals") REQUIRE(!err); REQUIRE(config.globals.size() == 2); - CHECK(config.globals[0] == "it"); - CHECK(config.globals[1] == "__DEV__"); + CHECK(config.globals[0] == XorStr("it")); + CHECK(config.globals[1] == XorStr("__DEV__")); } TEST_CASE("lint_rules_compat") diff --git a/tests/conformance/basic.lua b/tests/conformance/basic.lua index b2dcaf94..385a0450 100644 --- a/tests/conformance/basic.lua +++ b/tests/conformance/basic.lua @@ -727,20 +727,16 @@ assert((function() local abs = math.abs function foo(...) return abs(...) end re -- NOTE: getfenv breaks fastcalls for the remainder of the source! hence why this is delayed until the end function testgetfenv() getfenv() - - -- declare constant so that at O2 this test doesn't interfere with constant folding which we can't deoptimize - local negfive negfive = -5 - -- getfenv breaks fastcalls (we assume we can't rely on knowing the semantics), but behavior shouldn't change - assert((function() return math.abs(negfive) end)() == 5) - assert((function() local abs = math.abs return abs(negfive) end)() == 5) - assert((function() local abs = math.abs function foo() return abs(negfive) end return foo() end)() == 5) + assert((function() return math.abs(-5) end)() == 5) + assert((function() local abs = math.abs return abs(-5) end)() == 5) + assert((function() local abs = math.abs function foo() return abs(-5) end return foo() end)() == 5) -- ... unless you actually reassign the function :D getfenv().math = { abs = function(n) return n*n end } - assert((function() return math.abs(negfive) end)() == 25) - assert((function() local abs = math.abs return abs(negfive) end)() == 25) - assert((function() local abs = math.abs function foo() return abs(negfive) end return foo() end)() == 25) + assert((function() return math.abs(-5) end)() == 25) + assert((function() local abs = math.abs return abs(-5) end)() == 25) + assert((function() local abs = math.abs function foo() return abs(-5) end return foo() end)() == 25) end -- you need to have enough arguments and arguments of the right type; if you don't, we'll fallback to the regular code. This checks coercions diff --git a/tests/conformance/errors.lua b/tests/conformance/errors.lua index 6c0ac5e6..0b5aafed 100644 --- a/tests/conformance/errors.lua +++ b/tests/conformance/errors.lua @@ -380,8 +380,7 @@ assert(ecall(function() return "a" + "b" end) == "attempt to perform arithmetic assert(ecall(function() return 1 > nil end) == "attempt to compare nil < number") -- note reversed order (by design) assert(ecall(function() return "a" <= 5 end) == "attempt to compare string <= number") -assert(ecall(function() local t = {} t[nil] = 2 end) == "table index is nil") -assert(ecall(function() local t = {} t[0/0] = 2 end) == "table index is NaN") +assert(ecall(function() local t = {} setmetatable(t, { __newindex = function(t,i,v) end }) t[nil] = 2 end) == "table index is nil") -- for loop type errors assert(ecall(function() for i='a',2 do end end) == "invalid 'for' initial value (number expected, got string)") diff --git a/tests/conformance/events.lua b/tests/conformance/events.lua index 6dcdbf0e..42f1beda 100644 --- a/tests/conformance/events.lua +++ b/tests/conformance/events.lua @@ -424,57 +424,4 @@ do assert(not ok and err:match("table or string expected")) end --- verify that NaN/nil keys are passed to __newindex even though table assignment with them anywhere in the chain fails -do - assert(pcall(function() local t = {} t[nil] = 5 end) == false) - assert(pcall(function() local t = {} setmetatable(t, { __newindex = {} }) t[nil] = 5 end) == false) - assert(pcall(function() local t = {} setmetatable(t, { __newindex = function() end }) t[nil] = 5 end) == true) - - assert(pcall(function() local t = {} t[0/0] = 5 end) == false) - assert(pcall(function() local t = {} setmetatable(t, { __newindex = {} }) t[0/0] = 5 end) == false) - assert(pcall(function() local t = {} setmetatable(t, { __newindex = function() end }) t[0/0] = 5 end) == true) -end - --- verify that __newindex gets called for frozen tables but only if the assignment is to a key absent from the table -do - local ni = {} - local t = table.create(2) - - t[1] = 42 - -- t[2] is semantically absent with storage allocated for it - - t.a = 1 - t.b = 2 - t.b = nil -- this sets 'b' value to nil but leaves key as is to exercise more internal paths -- no observable behavior change expected between b and other absent keys - - setmetatable(t, { __newindex = function(_, k, v) - assert(v == 42) - table.insert(ni, k) - end }) - table.freeze(t) - - -- "redundant" combinations are there to test all three of SETTABLEN/SETTABLEKS/SETTABLE - assert(pcall(function() t.a = 42 end) == false) - assert(pcall(function() t[1] = 42 end) == false) - assert(pcall(function() local key key = "a" t[key] = 42 end) == false) - assert(pcall(function() local key key = 1 t[key] = 42 end) == false) - - -- now repeat the same for keys absent from the table: b (semantically absent), c (physically absent), 2 (semantically absent), 3 (physically absent) - assert(pcall(function() t.b = 42 end) == true) - assert(pcall(function() t.c = 42 end) == true) - assert(pcall(function() local key key = "b" t[key] = 42 end) == true) - assert(pcall(function() local key key = "c" t[key] = 42 end) == true) - assert(pcall(function() t[2] = 42 end) == true) - assert(pcall(function() t[3] = 42 end) == true) - assert(pcall(function() local key key = 2 t[key] = 42 end) == true) - assert(pcall(function() local key key = 3 t[key] = 42 end) == true) - - -- validate the assignment sequence - local ei = { "b", "c", "b", "c", 2, 3, 2, 3 } - assert(#ni == #ei) - for k,v in ni do - assert(ei[k] == v) - end -end - return 'OK' diff --git a/tools/natvis/Analysis.natvis b/tools/natvis/Analysis.natvis index 7d03dd3f..b9ea3141 100644 --- a/tools/natvis/Analysis.natvis +++ b/tools/natvis/Analysis.natvis @@ -38,38 +38,6 @@ {{ typeId=29, value={*($T30*)storage} }} {{ typeId=30, value={*($T31*)storage} }} {{ typeId=31, value={*($T32*)storage} }} - {{ typeId=32, value={*($T33*)storage} }} - {{ typeId=33, value={*($T34*)storage} }} - {{ typeId=34, value={*($T35*)storage} }} - {{ typeId=35, value={*($T36*)storage} }} - {{ typeId=36, value={*($T37*)storage} }} - {{ typeId=37, value={*($T38*)storage} }} - {{ typeId=38, value={*($T39*)storage} }} - {{ typeId=39, value={*($T40*)storage} }} - {{ typeId=40, value={*($T41*)storage} }} - {{ typeId=41, value={*($T42*)storage} }} - {{ typeId=42, value={*($T43*)storage} }} - {{ typeId=43, value={*($T44*)storage} }} - {{ typeId=44, value={*($T45*)storage} }} - {{ typeId=45, value={*($T46*)storage} }} - {{ typeId=46, value={*($T47*)storage} }} - {{ typeId=47, value={*($T48*)storage} }} - {{ typeId=48, value={*($T49*)storage} }} - {{ typeId=49, value={*($T50*)storage} }} - {{ typeId=50, value={*($T51*)storage} }} - {{ typeId=51, value={*($T52*)storage} }} - {{ typeId=52, value={*($T53*)storage} }} - {{ typeId=53, value={*($T54*)storage} }} - {{ typeId=54, value={*($T55*)storage} }} - {{ typeId=55, value={*($T56*)storage} }} - {{ typeId=56, value={*($T57*)storage} }} - {{ typeId=57, value={*($T58*)storage} }} - {{ typeId=58, value={*($T59*)storage} }} - {{ typeId=59, value={*($T60*)storage} }} - {{ typeId=60, value={*($T61*)storage} }} - {{ typeId=61, value={*($T62*)storage} }} - {{ typeId=62, value={*($T63*)storage} }} - {{ typeId=63, value={*($T64*)storage} }} typeId *($T1*)storage @@ -104,38 +72,6 @@ *($T30*)storage *($T31*)storage *($T32*)storage - *($T33*)storage - *($T34*)storage - *($T35*)storage - *($T36*)storage - *($T37*)storage - *($T38*)storage - *($T39*)storage - *($T40*)storage - *($T41*)storage - *($T42*)storage - *($T43*)storage - *($T44*)storage - *($T45*)storage - *($T46*)storage - *($T47*)storage - *($T48*)storage - *($T49*)storage - *($T50*)storage - *($T51*)storage - *($T52*)storage - *($T53*)storage - *($T54*)storage - *($T55*)storage - *($T56*)storage - *($T57*)storage - *($T58*)storage - *($T59*)storage - *($T60*)storage - *($T61*)storage - *($T62*)storage - *($T63*)storage - *($T64*)storage diff --git a/tools/natvis/VM.natvis b/tools/natvis/VM.natvis index cb2f355f..ccc7e390 100644 --- a/tools/natvis/VM.natvis +++ b/tools/natvis/VM.natvis @@ -137,28 +137,16 @@ {data,s} - - - - - - - - - empty - none - - - {proto()->source->data,sb}:{line()} function {proto()->debugname->data,sb}() - {proto()->source->data,sb}:{line()} function() - - - =[C] function {cl().c.debugname,sb}() {cl().c.f,na} - =[C] {cl().c.f,na} - - - {ci,na} + + {ci->func->value.gc->cl.c.f,na} + + + {ci->func->value.gc->cl.l.p->source->data,sb}:{ci->func->value.gc->cl.l.p->linedefined,d} {ci->func->value.gc->cl.l.p->debugname->data,sb} + + + {ci->func->value.gc->cl.l.p->source->data,sb}:{ci->func->value.gc->cl.l.p->linedefined,d} + thread @@ -168,7 +156,7 @@ ci-base_ci - base_ci[ci-base_ci - $i] + base_ci[ci-base_ci - $i].func->value.gc->cl,view(short) diff --git a/tools/patchtests.py b/tools/patchtests.py index 56970c9f..dcaf6083 100644 --- a/tools/patchtests.py +++ b/tools/patchtests.py @@ -16,11 +16,7 @@ state = 0 # parse input into errors[] with the state machine; this is using doctest output and expects multi-line match failures for line in input: if state == 0: - if sys.platform == "win32": - match = re.match("[^(]+\((\d+)\): ERROR: CHECK_EQ", line) - else: - match = re.match("tests/[^:]+:(\d+): ERROR: CHECK_EQ", line) - + match = re.match("tests/[^:]+:(\d+): ERROR: CHECK_EQ", line) if match: error_line = int(match[1]) state = 1 @@ -56,16 +52,12 @@ result = [] current = 0 index = 0 -target = 0 while index < len(source): line = source[index] error = errors[current] if current < len(errors) else None - if error: - target = error[0] if sys.platform != "win32" else error[0] - len(error[1]) - 1 - - if not error or index < target or line != error[1][0]: + if not error or index < error[0] or line != error[1][0]: result.append(line) index += 1 else: