From a4d6b59251e83272ca431ddc710f3f8304b37ac7 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Mon, 24 Apr 2023 10:48:55 +0100 Subject: [PATCH] v0.5.6+luau573 --- Cargo.toml | 2 +- luau/Ast/include/Luau/Ast.h | 6 ++++-- luau/Ast/src/Ast.cpp | 6 ++++-- luau/Ast/src/Parser.cpp | 13 ++++++++----- luau/Ast/src/StringUtils.cpp | 8 ++++++-- luau/VM/include/lua.h | 6 +++++- luau/VM/src/lapi.cpp | 10 +++++++++- luau/VM/src/ltable.cpp | 36 +++++++++++++----------------------- luau/VM/src/ludata.cpp | 3 +-- 9 files changed, 51 insertions(+), 39 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a9ed4e4..060c862 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "luau0-src" -version = "0.5.5+luau571" +version = "0.5.6+luau573" authors = ["Aleksandr Orlenko "] edition = "2021" repository = "https://github.com/khvzak/luau-src-rs" diff --git a/luau/Ast/include/Luau/Ast.h b/luau/Ast/include/Luau/Ast.h index 9c352f9..20158e8 100644 --- a/luau/Ast/include/Luau/Ast.h +++ b/luau/Ast/include/Luau/Ast.h @@ -841,14 +841,16 @@ class AstTypeReference : public AstType public: LUAU_RTTI(AstTypeReference) - AstTypeReference(const Location& location, std::optional prefix, AstName name, bool hasParameterList = false, - const AstArray& parameters = {}); + AstTypeReference(const Location& location, std::optional prefix, AstName name, std::optional prefixLocation, + const Location& nameLocation, bool hasParameterList = false, const AstArray& parameters = {}); void visit(AstVisitor* visitor) override; bool hasParameterList; std::optional prefix; + std::optional prefixLocation; AstName name; + Location nameLocation; AstArray parameters; }; diff --git a/luau/Ast/src/Ast.cpp b/luau/Ast/src/Ast.cpp index e01ced0..d2c552a 100644 --- a/luau/Ast/src/Ast.cpp +++ b/luau/Ast/src/Ast.cpp @@ -753,12 +753,14 @@ void AstStatError::visit(AstVisitor* visitor) } } -AstTypeReference::AstTypeReference( - const Location& location, std::optional prefix, AstName name, bool hasParameterList, const AstArray& parameters) +AstTypeReference::AstTypeReference(const Location& location, std::optional prefix, AstName name, std::optional prefixLocation, + const Location& nameLocation, bool hasParameterList, const AstArray& parameters) : AstType(ClassIndex(), location) , hasParameterList(hasParameterList) , prefix(prefix) + , prefixLocation(prefixLocation) , name(name) + , nameLocation(nameLocation) , parameters(parameters) { } diff --git a/luau/Ast/src/Parser.cpp b/luau/Ast/src/Parser.cpp index 40fa754..6a76eda 100644 --- a/luau/Ast/src/Parser.cpp +++ b/luau/Ast/src/Parser.cpp @@ -1343,7 +1343,7 @@ AstType* Parser::parseTableType() AstType* type = parseType(); // array-like table type: {T} desugars into {[number]: T} - AstType* index = allocator.alloc(type->location, std::nullopt, nameNumber); + AstType* index = allocator.alloc(type->location, std::nullopt, nameNumber, std::nullopt, type->location); indexer = allocator.alloc(AstTableIndexer{index, type, type->location}); break; @@ -1449,7 +1449,7 @@ AstType* Parser::parseFunctionTypeTail(const Lexeme& begin, AstArray' after '()' when parsing function type; did you mean 'nil'?"); - return allocator.alloc(begin.location, std::nullopt, nameNil); + return allocator.alloc(begin.location, std::nullopt, nameNil, std::nullopt, begin.location); } else { @@ -1493,7 +1493,7 @@ AstType* Parser::parseTypeSuffix(AstType* type, const Location& begin) { Location loc = lexer.current().location; nextLexeme(); - parts.push_back(allocator.alloc(loc, std::nullopt, nameNil)); + parts.push_back(allocator.alloc(loc, std::nullopt, nameNil, std::nullopt, loc)); isUnion = true; } else if (c == '&') @@ -1577,7 +1577,7 @@ AstTypeOrPack Parser::parseSimpleType(bool allowPack) if (lexer.current().type == Lexeme::ReservedNil) { nextLexeme(); - return {allocator.alloc(start, std::nullopt, nameNil), {}}; + return {allocator.alloc(start, std::nullopt, nameNil, std::nullopt, start), {}}; } else if (lexer.current().type == Lexeme::ReservedTrue) { @@ -1613,6 +1613,7 @@ AstTypeOrPack Parser::parseSimpleType(bool allowPack) else if (lexer.current().type == Lexeme::Name) { std::optional prefix; + std::optional prefixLocation; Name name = parseName("type name"); if (lexer.current().type == '.') @@ -1621,6 +1622,7 @@ AstTypeOrPack Parser::parseSimpleType(bool allowPack) nextLexeme(); prefix = name.name; + prefixLocation = name.location; name = parseIndexName("field name", pointPosition); } else if (lexer.current().type == Lexeme::Dot3) @@ -1653,7 +1655,8 @@ AstTypeOrPack Parser::parseSimpleType(bool allowPack) Location end = lexer.previousLocation(); - return {allocator.alloc(Location(start, end), prefix, name.name, hasParameters, parameters), {}}; + return { + allocator.alloc(Location(start, end), prefix, name.name, prefixLocation, name.location, hasParameters, parameters), {}}; } else if (lexer.current().type == '{') { diff --git a/luau/Ast/src/StringUtils.cpp b/luau/Ast/src/StringUtils.cpp index 11e0076..343c553 100644 --- a/luau/Ast/src/StringUtils.cpp +++ b/luau/Ast/src/StringUtils.cpp @@ -167,7 +167,9 @@ size_t editDistance(std::string_view a, std::string_view b) for (size_t y = 1; y <= b.size(); ++y) { - size_t x1 = seenCharToRow[b[y - 1]]; + // The value of b[N] can be negative with unicode characters + unsigned char bSeenCharIndex = static_cast(b[y - 1]); + size_t x1 = seenCharToRow[bSeenCharIndex]; size_t y1 = lastMatchedY; size_t cost = 1; @@ -187,7 +189,9 @@ size_t editDistance(std::string_view a, std::string_view b) distances[getPos(x + 1, y + 1)] = std::min(std::min(insertion, deletion), std::min(substitution, transposition)); } - seenCharToRow[a[x - 1]] = x; + // The value of a[N] can be negative with unicode characters + unsigned char aSeenCharIndex = static_cast(a[x - 1]); + seenCharToRow[aSeenCharIndex] = x; } return distances[getPos(a.size() + 1, b.size() + 1)]; diff --git a/luau/VM/include/lua.h b/luau/VM/include/lua.h index 3f5e99f..e49e6ad 100644 --- a/luau/VM/include/lua.h +++ b/luau/VM/include/lua.h @@ -313,7 +313,11 @@ 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*)); + +typedef void (*lua_Destructor)(lua_State* L, void* userdata); + +LUA_API void lua_setuserdatadtor(lua_State* L, int tag, lua_Destructor dtor); +LUA_API lua_Destructor lua_getuserdatadtor(lua_State* L, int tag); LUA_API void lua_clonefunction(lua_State* L, int idx); diff --git a/luau/VM/src/lapi.cpp b/luau/VM/src/lapi.cpp index 1528aa3..054faa7 100644 --- a/luau/VM/src/lapi.cpp +++ b/luau/VM/src/lapi.cpp @@ -538,6 +538,8 @@ const void* lua_topointer(lua_State* L, int idx) StkId o = index2addr(L, idx); switch (ttype(o)) { + case LUA_TSTRING: + return tsvalue(o); case LUA_TTABLE: return hvalue(o); case LUA_TFUNCTION: @@ -1378,12 +1380,18 @@ void lua_setuserdatatag(lua_State* L, int idx, int tag) uvalue(o)->tag = uint8_t(tag); } -void lua_setuserdatadtor(lua_State* L, int tag, void (*dtor)(lua_State*, void*)) +void lua_setuserdatadtor(lua_State* L, int tag, lua_Destructor dtor) { api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); L->global->udatagc[tag] = dtor; } +lua_Destructor lua_getuserdatadtor(lua_State* L, int tag) +{ + api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); + return L->global->udatagc[tag]; +} + void lua_clonefunction(lua_State* L, int idx) { luaC_checkGC(L); diff --git a/luau/VM/src/ltable.cpp b/luau/VM/src/ltable.cpp index 5eceea7..c963ac8 100644 --- a/luau/VM/src/ltable.cpp +++ b/luau/VM/src/ltable.cpp @@ -33,8 +33,6 @@ #include -LUAU_FASTFLAGVARIABLE(LuauArrBoundResizeFix, false) - // max size of both array and hash part is 2^MAXBITS #define MAXBITS 26 #define MAXSIZE (1 << MAXBITS) @@ -466,30 +464,22 @@ static void rehash(lua_State* L, Table* t, const TValue* ek) int na = computesizes(nums, &nasize); int nh = totaluse - na; - if (FFlag::LuauArrBoundResizeFix) + // enforce the boundary invariant; for performance, only do hash lookups if we must + int nadjusted = adjustasize(t, nasize, ek); + + // count how many extra elements belong to array part instead of hash part + int aextra = nadjusted - nasize; + + if (aextra != 0) { - // enforce the boundary invariant; for performance, only do hash lookups if we must - int nadjusted = adjustasize(t, nasize, ek); + // we no longer need to store those extra array elements in hash part + nh -= aextra; - // count how many extra elements belong to array part instead of hash part - int aextra = nadjusted - nasize; + // because hash nodes are twice as large as array nodes, the memory we saved for hash parts can be used by array part + // this follows the general sparse array part optimization where array is allocated when 50% occupation is reached + nasize = nadjusted + aextra; - if (aextra != 0) - { - // we no longer need to store those extra array elements in hash part - nh -= aextra; - - // because hash nodes are twice as large as array nodes, the memory we saved for hash parts can be used by array part - // this follows the general sparse array part optimization where array is allocated when 50% occupation is reached - nasize = nadjusted + aextra; - - // since the size was changed, it's again important to enforce the boundary invariant at the new size - nasize = adjustasize(t, nasize, ek); - } - } - else - { - // enforce the boundary invariant; for performance, only do hash lookups if we must + // since the size was changed, it's again important to enforce the boundary invariant at the new size nasize = adjustasize(t, nasize, ek); } diff --git a/luau/VM/src/ludata.cpp b/luau/VM/src/ludata.cpp index c2110cb..13e8702 100644 --- a/luau/VM/src/ludata.cpp +++ b/luau/VM/src/ludata.cpp @@ -24,8 +24,7 @@ void luaU_freeudata(lua_State* L, Udata* u, lua_Page* page) { if (u->tag < LUA_UTAG_LIMIT) { - void (*dtor)(lua_State*, void*) = nullptr; - dtor = L->global->udatagc[u->tag]; + lua_Destructor dtor = L->global->udatagc[u->tag]; // TODO: access to L here is highly unsafe since this is called during internal GC traversal // certain operations such as lua_getthreaddata are okay, but by and large this risks crashes on improper use if (dtor)