Add files via upload

This commit is contained in:
Babyhamsta 2022-07-30 22:25:25 -05:00 committed by GitHub
parent d3b566c258
commit 08d5a16a5e
Signed by: DevComp
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 1809 additions and 2729 deletions

View file

@ -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)

View file

@ -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

View file

@ -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).

View file

@ -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

View file

@ -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) */

View file

@ -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

View file

@ -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 */

View file

@ -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 <string.h>
/*
@ -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);

View file

@ -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

View file

@ -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 <string.h>
/* 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;
}
}

View file

@ -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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
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;
}

View file

@ -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},
};

View file

@ -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 <intrin.h>
#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,
};

View file

@ -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];

View file

@ -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"

View file

@ -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))

View file

@ -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;
}

View file

@ -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 <string.h>
#include <stdio.h>
#include <stdlib.h>
@ -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},
};

View file

@ -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 <string.h>
#include <stdio.h>
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;

View file

@ -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);

View file

@ -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 <setjmp.h>
#include <stdlib.h>
@ -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);

View file

@ -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); \
}

View file

@ -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);

View file

@ -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

View file

@ -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 <string.h>
#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;

View file

@ -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

View file

@ -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 <string.h>
#include <stdio.h>
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*>(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"));
}

View file

@ -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 <stdlib.h>
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);

View file

@ -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 <math.h>
#include <time.h>
@ -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;
}

View file

@ -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 <Windows.h>
#include <string.h>
/*
* 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<uintptr_t>(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 <sanitizer/asan_interface.h>
#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)

View file

@ -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)

View file

@ -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;

View file

@ -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))

View file

@ -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 <ctype.h>
#include <string.h>
#include <stdio.h>
@ -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("\"]"));
}
}

View file

@ -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;

View file

@ -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 <string.h>
#include <time.h>
@ -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},
};

View file

@ -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 <time.h>
#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());

View file

@ -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);

View file

@ -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;
};

View file

@ -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;

View file

@ -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)))

View file

@ -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 <ctype.h>
#include <string.h>
#include <stdio.h>
@ -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 */
}

View file

@ -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 <string.h>
// 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;
}
}

View file

@ -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<const TValue*>(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;

View file

@ -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;
}

View file

@ -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 <string.h>
// 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 */

View file

@ -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

View file

@ -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 <string.h>
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)
{

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

File diff suppressed because it is too large Load diff

View file

@ -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 <string.h>
// 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<Proto*> 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");
}
}

View file

@ -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 <string.h>
#include <stdio.h>
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 */
}

View file

@ -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 <functional>
#include <string.h>
using namespace Luau::CodeGen;
using namespace lluz::CodeGen;
std::string bytecodeAsArray(const std::vector<uint8_t>& 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));
}
}

View file

@ -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<AstStatIf>());
}
TEST_CASE_FIXTURE(Fixture, "ac_ast_ancestry_at_number_const")
{
check(R"(
print(3.)
)");
std::vector<AstNode*> ancestry = findAncestryAtPositionForAutocomplete(*getMainSourceModule(), Position(1, 8));
REQUIRE_GE(ancestry.size(), 2);
REQUIRE(ancestry.back()->is<AstExprConstantNumber>());
}
TEST_CASE_FIXTURE(Fixture, "ac_ast_ancestry_in_workspace_dot")
{
check(R"(
print(workspace.)
)");
std::vector<AstNode*> ancestry = findAncestryAtPositionForAutocomplete(*getMainSourceModule(), Position(1, 16));
REQUIRE_GE(ancestry.size(), 2);
REQUIRE(ancestry.back()->is<AstExprIndexName>());
}
TEST_CASE_FIXTURE(Fixture, "ac_ast_ancestry_in_workspace_colon")
{
check(R"(
print(workspace:)
)");
std::vector<AstNode*> ancestry = findAncestryAtPositionForAutocomplete(*getMainSourceModule(), Position(1, 16));
REQUIRE_GE(ancestry.size(), 2);
REQUIRE(ancestry.back()->is<AstExprIndexName>());
}
TEST_SUITE_END();

View file

@ -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")
{

View file

@ -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 <map>
LUAU_FASTFLAG(LuauTraceTypesInNonstrictMode2)
LUAU_FASTFLAG(LuauSetMetatableDoesNotTimeTravel)
lluz_FASTFLAG(LluTraceTypesInNonstrictMode2)
lluz_FASTFLAG(LluSetMetatableDoesNotTimeTravel)
using namespace Luau;
using namespace lluz;
static std::optional<AutocompleteEntryMap> nullCallback(std::string tag, std::optional<const ClassTypeVar*> 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<BuiltinsFixture>
{
};
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<T>(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")

View file

@ -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<std::string> actualRootSymbol = binding.documentationSymbol;
CHECK_MESSAGE(
actualRootSymbol == expectedRootSymbol, "expected symbol ", expectedRootSymbol, " for global ", nameString, ", got ", actualRootSymbol);

File diff suppressed because it is too large Load diff

View file

@ -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 <iostream>
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")

View file

@ -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

View file

@ -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)")

View file

@ -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'

View file

@ -38,38 +38,6 @@
<DisplayString Condition="typeId == 29" Optional="true">{{ typeId=29, value={*($T30*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 30" Optional="true">{{ typeId=30, value={*($T31*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 31" Optional="true">{{ typeId=31, value={*($T32*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 32" Optional="true">{{ typeId=32, value={*($T33*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 33" Optional="true">{{ typeId=33, value={*($T34*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 34" Optional="true">{{ typeId=34, value={*($T35*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 35" Optional="true">{{ typeId=35, value={*($T36*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 36" Optional="true">{{ typeId=36, value={*($T37*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 37" Optional="true">{{ typeId=37, value={*($T38*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 38" Optional="true">{{ typeId=38, value={*($T39*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 39" Optional="true">{{ typeId=39, value={*($T40*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 40" Optional="true">{{ typeId=40, value={*($T41*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 41" Optional="true">{{ typeId=41, value={*($T42*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 42" Optional="true">{{ typeId=42, value={*($T43*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 43" Optional="true">{{ typeId=43, value={*($T44*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 44" Optional="true">{{ typeId=44, value={*($T45*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 45" Optional="true">{{ typeId=45, value={*($T46*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 46" Optional="true">{{ typeId=46, value={*($T47*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 47" Optional="true">{{ typeId=47, value={*($T48*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 48" Optional="true">{{ typeId=48, value={*($T49*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 49" Optional="true">{{ typeId=49, value={*($T50*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 50" Optional="true">{{ typeId=50, value={*($T51*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 51" Optional="true">{{ typeId=51, value={*($T52*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 52" Optional="true">{{ typeId=52, value={*($T53*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 53" Optional="true">{{ typeId=53, value={*($T54*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 54" Optional="true">{{ typeId=54, value={*($T55*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 55" Optional="true">{{ typeId=55, value={*($T56*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 56" Optional="true">{{ typeId=56, value={*($T57*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 57" Optional="true">{{ typeId=57, value={*($T58*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 58" Optional="true">{{ typeId=58, value={*($T59*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 59" Optional="true">{{ typeId=59, value={*($T60*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 60" Optional="true">{{ typeId=60, value={*($T61*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 61" Optional="true">{{ typeId=61, value={*($T62*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 62" Optional="true">{{ typeId=62, value={*($T63*)storage} }}</DisplayString>
<DisplayString Condition="typeId == 63" Optional="true">{{ typeId=63, value={*($T64*)storage} }}</DisplayString>
<Expand>
<Item Name="typeId">typeId</Item>
<Item Name="[value]" Condition="typeId == 0" Optional="true">*($T1*)storage</Item>
@ -104,38 +72,6 @@
<Item Name="[value]" Condition="typeId == 29" Optional="true">*($T30*)storage</Item>
<Item Name="[value]" Condition="typeId == 30" Optional="true">*($T31*)storage</Item>
<Item Name="[value]" Condition="typeId == 31" Optional="true">*($T32*)storage</Item>
<Item Name="[value]" Condition="typeId == 32" Optional="true">*($T33*)storage</Item>
<Item Name="[value]" Condition="typeId == 33" Optional="true">*($T34*)storage</Item>
<Item Name="[value]" Condition="typeId == 34" Optional="true">*($T35*)storage</Item>
<Item Name="[value]" Condition="typeId == 35" Optional="true">*($T36*)storage</Item>
<Item Name="[value]" Condition="typeId == 36" Optional="true">*($T37*)storage</Item>
<Item Name="[value]" Condition="typeId == 37" Optional="true">*($T38*)storage</Item>
<Item Name="[value]" Condition="typeId == 38" Optional="true">*($T39*)storage</Item>
<Item Name="[value]" Condition="typeId == 39" Optional="true">*($T40*)storage</Item>
<Item Name="[value]" Condition="typeId == 40" Optional="true">*($T41*)storage</Item>
<Item Name="[value]" Condition="typeId == 41" Optional="true">*($T42*)storage</Item>
<Item Name="[value]" Condition="typeId == 42" Optional="true">*($T43*)storage</Item>
<Item Name="[value]" Condition="typeId == 43" Optional="true">*($T44*)storage</Item>
<Item Name="[value]" Condition="typeId == 44" Optional="true">*($T45*)storage</Item>
<Item Name="[value]" Condition="typeId == 45" Optional="true">*($T46*)storage</Item>
<Item Name="[value]" Condition="typeId == 46" Optional="true">*($T47*)storage</Item>
<Item Name="[value]" Condition="typeId == 47" Optional="true">*($T48*)storage</Item>
<Item Name="[value]" Condition="typeId == 48" Optional="true">*($T49*)storage</Item>
<Item Name="[value]" Condition="typeId == 49" Optional="true">*($T50*)storage</Item>
<Item Name="[value]" Condition="typeId == 50" Optional="true">*($T51*)storage</Item>
<Item Name="[value]" Condition="typeId == 51" Optional="true">*($T52*)storage</Item>
<Item Name="[value]" Condition="typeId == 52" Optional="true">*($T53*)storage</Item>
<Item Name="[value]" Condition="typeId == 53" Optional="true">*($T54*)storage</Item>
<Item Name="[value]" Condition="typeId == 54" Optional="true">*($T55*)storage</Item>
<Item Name="[value]" Condition="typeId == 55" Optional="true">*($T56*)storage</Item>
<Item Name="[value]" Condition="typeId == 56" Optional="true">*($T57*)storage</Item>
<Item Name="[value]" Condition="typeId == 57" Optional="true">*($T58*)storage</Item>
<Item Name="[value]" Condition="typeId == 58" Optional="true">*($T59*)storage</Item>
<Item Name="[value]" Condition="typeId == 59" Optional="true">*($T60*)storage</Item>
<Item Name="[value]" Condition="typeId == 60" Optional="true">*($T61*)storage</Item>
<Item Name="[value]" Condition="typeId == 61" Optional="true">*($T62*)storage</Item>
<Item Name="[value]" Condition="typeId == 62" Optional="true">*($T63*)storage</Item>
<Item Name="[value]" Condition="typeId == 63" Optional="true">*($T64*)storage</Item>
</Expand>
</Type>

View file

@ -137,28 +137,16 @@
<DisplayString>{data,s}</DisplayString>
</Type>
<Type Name="::CallInfo">
<Intrinsic Name="cl" Category="Property" Expression="func->value.gc->cl"/>
<Intrinsic Name="isC" Category="Property" Expression="cl().isC"/>
<Intrinsic Name="proto" Category="Property" Expression="cl().l.p"/>
<Intrinsic Name="pcRel" Category="Property" Expression="savedpc ? savedpc - proto()->code - 1 : 0"/>
<Intrinsic Name="line" Category="Property" Expression="proto()->abslineinfo[pcRel() >> proto()->linegaplog2] + proto()->lineinfo[pcRel()]"/>
<!-- Special frames -->
<DisplayString Condition="!func">empty</DisplayString>
<DisplayString Condition="func->tt != lua_Type::LUA_TFUNCTION">none</DisplayString>
<!-- Lua functions-->
<DisplayString Condition="!isC() &amp;&amp; proto()->debugname">{proto()->source->data,sb}:{line()} function {proto()->debugname->data,sb}()</DisplayString>
<DisplayString Condition="!isC()">{proto()->source->data,sb}:{line()} function()</DisplayString>
<!-- C functions-->
<DisplayString Condition="isC() &amp;&amp; cl().c.debugname">=[C] function {cl().c.debugname,sb}() {cl().c.f,na}</DisplayString>
<DisplayString Condition="isC()">=[C] {cl().c.f,na}</DisplayString>
</Type>
<Type Name ="::lua_State">
<DisplayString Condition="ci">{ci,na}</DisplayString>
<DisplayString Condition="ci-&gt;func-&gt;value.gc-&gt;cl.isC">
{ci-&gt;func-&gt;value.gc-&gt;cl.c.f,na}
</DisplayString>
<DisplayString Condition="!ci-&gt;func-&gt;value.gc-&gt;cl.isC &amp;&amp; ci-&gt;func-&gt;value.gc-&gt;cl.l.p-&gt;debugname" Optional="true">
{ci-&gt;func-&gt;value.gc-&gt;cl.l.p-&gt;source-&gt;data,sb}:{ci-&gt;func-&gt;value.gc-&gt;cl.l.p-&gt;linedefined,d} {ci-&gt;func-&gt;value.gc-&gt;cl.l.p-&gt;debugname->data,sb}
</DisplayString>
<DisplayString Condition="!ci-&gt;func-&gt;value.gc-&gt;cl.isC" Optional="true">
{ci-&gt;func-&gt;value.gc-&gt;cl.l.p-&gt;source-&gt;data,sb}:{ci-&gt;func-&gt;value.gc-&gt;cl.l.p-&gt;linedefined,d}
</DisplayString>
<DisplayString>thread</DisplayString>
<Expand>
<Synthetic Name="[call stack]">
@ -168,7 +156,7 @@
<Size>ci-base_ci</Size>
<!-- the +1 is omitted here to avoid some issues with a blank call -->
<ValueNode>
base_ci[ci-base_ci - $i]
base_ci[ci-base_ci - $i].func-&gt;value.gc-&gt;cl,view(short)
</ValueNode>
</IndexListItems>
</Expand>

View file

@ -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: