From 0e1249cb86766a2223e09cfe71015a0a97118224 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Fri, 2 Dec 2022 22:29:58 +0000 Subject: [PATCH] Update Luau to 0.555 (with patch to change LUAI_MAXCSTACK) --- luau/Ast/include/Luau/Location.h | 30 +++++++++ luau/Ast/src/Parser.cpp | 65 +++++++++++++------- luau/Common/include/Luau/ExperimentalFlags.h | 1 - luau/Compiler/src/BytecodeBuilder.cpp | 5 +- luau/Compiler/src/Compiler.cpp | 45 +++++++++++--- luau/VM/include/lua.h | 6 +- luau/VM/src/lapi.cpp | 32 ---------- luau/VM/src/loslib.cpp | 15 +++++ 8 files changed, 130 insertions(+), 69 deletions(-) diff --git a/luau/Ast/include/Luau/Location.h b/luau/Ast/include/Luau/Location.h index d3c0a46..e39bbf8 100644 --- a/luau/Ast/include/Luau/Location.h +++ b/luau/Ast/include/Luau/Location.h @@ -50,6 +50,20 @@ struct Position { return *this == rhs || *this > rhs; } + + void shift(const Position& start, const Position& oldEnd, const Position& newEnd) + { + if (*this >= start) + { + if (this->line > oldEnd.line) + this->line += (newEnd.line - oldEnd.line); + else + { + this->line = newEnd.line; + this->column += (newEnd.column - oldEnd.column); + } + } + } }; struct Location @@ -93,6 +107,10 @@ struct Location { return begin <= l.begin && end >= l.end; } + bool overlaps(const Location& l) const + { + return (begin <= l.begin && end >= l.begin) || (begin <= l.end && end >= l.end) || (begin >= l.begin && end <= l.end); + } bool contains(const Position& p) const { return begin <= p && p < end; @@ -101,6 +119,18 @@ struct Location { return begin <= p && p <= end; } + void extend(const Location& other) + { + if (other.begin < begin) + begin = other.begin; + if (other.end > end) + end = other.end; + } + void shift(const Position& start, const Position& oldEnd, const Position& newEnd) + { + begin.shift(start, oldEnd, newEnd); + end.shift(start, oldEnd, newEnd); + } }; std::string toString(const Position& position); diff --git a/luau/Ast/src/Parser.cpp b/luau/Ast/src/Parser.cpp index 8338a04..5cd5f74 100644 --- a/luau/Ast/src/Parser.cpp +++ b/luau/Ast/src/Parser.cpp @@ -24,9 +24,6 @@ LUAU_DYNAMIC_FASTFLAGVARIABLE(LuaReportParseIntegerIssues, false) LUAU_FASTFLAGVARIABLE(LuauInterpolatedStringBaseSupport, false) -LUAU_FASTFLAGVARIABLE(LuauCommaParenWarnings, false) -LUAU_FASTFLAGVARIABLE(LuauTableConstructorRecovery, false) - LUAU_FASTFLAGVARIABLE(LuauParserErrorsOnMissingDefaultTypePackArgument, false) bool lua_telemetry_parsed_out_of_range_bin_integer = false; @@ -1084,7 +1081,7 @@ void Parser::parseExprList(TempVector& result) { nextLexeme(); - if (FFlag::LuauCommaParenWarnings && lexer.current().type == ')') + if (lexer.current().type == ')') { report(lexer.current().location, "Expected expression after ',' but got ')' instead"); break; @@ -1179,7 +1176,7 @@ AstTypePack* Parser::parseTypeList(TempVector& result, TempVector, AstArray> Parser::parseG { nextLexeme(); - if (FFlag::LuauCommaParenWarnings && lexer.current().type == '>') + if (lexer.current().type == '>') { report(lexer.current().location, "Expected type after ',' but got '>' instead"); break; @@ -2661,6 +2656,7 @@ AstExpr* Parser::parseInterpString() TempVector expressions(scratchExpr); Location startLocation = lexer.current().location; + Location endLocation; do { @@ -2668,16 +2664,16 @@ AstExpr* Parser::parseInterpString() LUAU_ASSERT(currentLexeme.type == Lexeme::InterpStringBegin || currentLexeme.type == Lexeme::InterpStringMid || currentLexeme.type == Lexeme::InterpStringEnd || currentLexeme.type == Lexeme::InterpStringSimple); - Location location = currentLexeme.location; + endLocation = currentLexeme.location; - Location startOfBrace = Location(location.end, 1); + Location startOfBrace = Location(endLocation.end, 1); scratchData.assign(currentLexeme.data, currentLexeme.length); if (!Lexer::fixupQuotedString(scratchData)) { nextLexeme(); - return reportExprError(startLocation, {}, "Interpolated string literal contains malformed escape sequence"); + return reportExprError(Location{startLocation, endLocation}, {}, "Interpolated string literal contains malformed escape sequence"); } AstArray chars = copy(scratchData); @@ -2688,15 +2684,36 @@ AstExpr* Parser::parseInterpString() if (currentLexeme.type == Lexeme::InterpStringEnd || currentLexeme.type == Lexeme::InterpStringSimple) { - AstArray> stringsArray = copy(strings); - AstArray expressionsArray = copy(expressions); - - return allocator.alloc(startLocation, stringsArray, expressionsArray); + break; } - AstExpr* expression = parseExpr(); + bool errorWhileChecking = false; - expressions.push_back(expression); + switch (lexer.current().type) + { + case Lexeme::InterpStringMid: + case Lexeme::InterpStringEnd: + { + errorWhileChecking = true; + nextLexeme(); + expressions.push_back(reportExprError(endLocation, {}, "Malformed interpolated string, expected expression inside '{}'")); + break; + } + case Lexeme::BrokenString: + { + errorWhileChecking = true; + nextLexeme(); + expressions.push_back(reportExprError(endLocation, {}, "Malformed interpolated string, did you forget to add a '`'?")); + break; + } + default: + expressions.push_back(parseExpr()); + } + + if (errorWhileChecking) + { + break; + } switch (lexer.current().type) { @@ -2706,14 +2723,18 @@ AstExpr* Parser::parseInterpString() break; case Lexeme::BrokenInterpDoubleBrace: nextLexeme(); - return reportExprError(location, {}, ERROR_INVALID_INTERP_DOUBLE_BRACE); + return reportExprError(endLocation, {}, ERROR_INVALID_INTERP_DOUBLE_BRACE); case Lexeme::BrokenString: nextLexeme(); - return reportExprError(location, {}, "Malformed interpolated string, did you forget to add a '}'?"); + return reportExprError(endLocation, {}, "Malformed interpolated string, did you forget to add a '}'?"); default: - return reportExprError(location, {}, "Malformed interpolated string, got %s", lexer.current().toString().c_str()); + return reportExprError(endLocation, {}, "Malformed interpolated string, got %s", lexer.current().toString().c_str()); } } while (true); + + AstArray> stringsArray = copy(strings); + AstArray expressionsArray = copy(expressions); + return allocator.alloc(Location{startLocation, endLocation}, stringsArray, expressionsArray); } AstExpr* Parser::parseNumber() diff --git a/luau/Common/include/Luau/ExperimentalFlags.h b/luau/Common/include/Luau/ExperimentalFlags.h index 15db9ea..41c1af5 100644 --- a/luau/Common/include/Luau/ExperimentalFlags.h +++ b/luau/Common/include/Luau/ExperimentalFlags.h @@ -13,7 +13,6 @@ inline bool isFlagExperimental(const char* flag) static const char* kList[] = { "LuauInterpolatedStringBaseSupport", "LuauInstantiateInSubtyping", // requires some fixes to lua-apps code - "LuauOptionalNextKey", // waiting for a fix to land in lua-apps "LuauTryhardAnd", // waiting for a fix in graphql-lua -> apollo-client-lia -> lua-apps // makes sure we always have at least one entry nullptr, diff --git a/luau/Compiler/src/BytecodeBuilder.cpp b/luau/Compiler/src/BytecodeBuilder.cpp index 8376424..7d23073 100644 --- a/luau/Compiler/src/BytecodeBuilder.cpp +++ b/luau/Compiler/src/BytecodeBuilder.cpp @@ -1895,10 +1895,7 @@ void BytecodeBuilder::dumpInstruction(const uint32_t* code, std::string& result, case LOP_CAPTURE: formatAppend(result, "CAPTURE %s %c%d\n", - LUAU_INSN_A(insn) == LCT_UPVAL ? "UPVAL" - : LUAU_INSN_A(insn) == LCT_REF ? "REF" - : LUAU_INSN_A(insn) == LCT_VAL ? "VAL" - : "", + LUAU_INSN_A(insn) == LCT_UPVAL ? "UPVAL" : LUAU_INSN_A(insn) == LCT_REF ? "REF" : LUAU_INSN_A(insn) == LCT_VAL ? "VAL" : "", LUAU_INSN_A(insn) == LCT_UPVAL ? 'U' : 'R', LUAU_INSN_B(insn)); break; diff --git a/luau/Compiler/src/Compiler.cpp b/luau/Compiler/src/Compiler.cpp index 7ccd116..5d67236 100644 --- a/luau/Compiler/src/Compiler.cpp +++ b/luau/Compiler/src/Compiler.cpp @@ -26,6 +26,7 @@ LUAU_FASTINTVARIABLE(LuauCompileInlineThresholdMaxBoost, 300) LUAU_FASTINTVARIABLE(LuauCompileInlineDepth, 5) LUAU_FASTFLAG(LuauInterpolatedStringBaseSupport) +LUAU_FASTFLAGVARIABLE(LuauMultiAssignmentConflictFix, false) namespace Luau { @@ -2977,16 +2978,46 @@ struct Compiler Visitor visitor(this); - // mark any registers that are used *after* assignment as conflicting - for (size_t i = 0; i < vars.size(); ++i) + if (FFlag::LuauMultiAssignmentConflictFix) { - const LValue& li = vars[i].lvalue; + // mark any registers that are used *after* assignment as conflicting - if (i < values.size) - values.data[i]->visit(&visitor); + // first we go through assignments to locals, since they are performed before assignments to other l-values + for (size_t i = 0; i < vars.size(); ++i) + { + const LValue& li = vars[i].lvalue; - if (li.kind == LValue::Kind_Local) - visitor.assigned[li.reg] = true; + if (li.kind == LValue::Kind_Local) + { + if (i < values.size) + values.data[i]->visit(&visitor); + + visitor.assigned[li.reg] = true; + } + } + + // and now we handle all other l-values + for (size_t i = 0; i < vars.size(); ++i) + { + const LValue& li = vars[i].lvalue; + + if (li.kind != LValue::Kind_Local && i < values.size) + values.data[i]->visit(&visitor); + } + } + else + { + // mark any registers that are used *after* assignment as conflicting + for (size_t i = 0; i < vars.size(); ++i) + { + const LValue& li = vars[i].lvalue; + + if (i < values.size) + values.data[i]->visit(&visitor); + + if (li.kind == LValue::Kind_Local) + visitor.assigned[li.reg] = true; + } } // mark any registers used in trailing expressions as conflicting as well diff --git a/luau/VM/include/lua.h b/luau/VM/include/lua.h index 73ebbb0..783e60a 100644 --- a/luau/VM/include/lua.h +++ b/luau/VM/include/lua.h @@ -17,9 +17,9 @@ /* ** pseudo-indices */ -#define LUA_REGISTRYINDEX (-10000) -#define LUA_ENVIRONINDEX (-10001) -#define LUA_GLOBALSINDEX (-10002) +#define LUA_REGISTRYINDEX (-LUAI_MAXCSTACK - 2000) +#define LUA_ENVIRONINDEX (-LUAI_MAXCSTACK - 2001) +#define LUA_GLOBALSINDEX (-LUAI_MAXCSTACK - 2002) #define lua_upvalueindex(i) (LUA_GLOBALSINDEX - (i)) #define lua_ispseudo(i) ((i) <= LUA_REGISTRYINDEX) diff --git a/luau/VM/src/lapi.cpp b/luau/VM/src/lapi.cpp index 28307eb..d2091c6 100644 --- a/luau/VM/src/lapi.cpp +++ b/luau/VM/src/lapi.cpp @@ -148,7 +148,6 @@ void lua_rawcheckstack(lua_State* L, int size) { luaD_checkstack(L, size); expandstacklimit(L, L->top + size); - return; } void lua_xmove(lua_State* from, lua_State* to, int n) @@ -167,8 +166,6 @@ void lua_xmove(lua_State* from, lua_State* to, int n) from->top = ftop; to->top = ttop + n; - - return; } void lua_xpush(lua_State* from, lua_State* to, int idx) @@ -177,7 +174,6 @@ void lua_xpush(lua_State* from, lua_State* to, int idx) luaC_threadbarrier(to); setobj2s(to, to->top, index2addr(from, idx)); api_incr_top(to); - return; } lua_State* lua_newthread(lua_State* L) @@ -227,7 +223,6 @@ void lua_settop(lua_State* L, int idx) api_check(L, -(idx + 1) <= (L->top - L->base)); L->top += idx + 1; // `subtract' index (index is negative) } - return; } void lua_remove(lua_State* L, int idx) @@ -237,7 +232,6 @@ void lua_remove(lua_State* L, int idx) while (++p < L->top) setobj2s(L, p - 1, p); L->top--; - return; } void lua_insert(lua_State* L, int idx) @@ -248,7 +242,6 @@ void lua_insert(lua_State* L, int idx) for (StkId q = L->top; q > p; q--) setobj2s(L, q, q - 1); setobj2s(L, p, L->top); - return; } void lua_replace(lua_State* L, int idx) @@ -277,7 +270,6 @@ void lua_replace(lua_State* L, int idx) luaC_barrier(L, curr_func(L), L->top - 1); } L->top--; - return; } void lua_pushvalue(lua_State* L, int idx) @@ -286,7 +278,6 @@ void lua_pushvalue(lua_State* L, int idx) StkId o = index2addr(L, idx); setobj2s(L, L->top, o); api_incr_top(L); - return; } /* @@ -570,28 +561,24 @@ void lua_pushnil(lua_State* L) { setnilvalue(L->top); api_incr_top(L); - return; } void lua_pushnumber(lua_State* L, double n) { setnvalue(L->top, n); api_incr_top(L); - return; } void lua_pushinteger(lua_State* L, int n) { setnvalue(L->top, cast_num(n)); api_incr_top(L); - return; } void lua_pushunsigned(lua_State* L, unsigned u) { setnvalue(L->top, cast_num(u)); api_incr_top(L); - return; } #if LUA_VECTOR_SIZE == 4 @@ -599,14 +586,12 @@ void lua_pushvector(lua_State* L, float x, float y, float z, float w) { setvvalue(L->top, x, y, z, w); api_incr_top(L); - return; } #else void lua_pushvector(lua_State* L, float x, float y, float z) { setvvalue(L->top, x, y, z, 0.0f); api_incr_top(L); - return; } #endif @@ -616,7 +601,6 @@ void lua_pushlstring(lua_State* L, const char* s, size_t len) luaC_threadbarrier(L); setsvalue(L, L->top, luaS_newlstr(L, s, len)); api_incr_top(L); - return; } void lua_pushstring(lua_State* L, const char* s) @@ -661,21 +645,18 @@ void lua_pushcclosurek(lua_State* L, lua_CFunction fn, const char* debugname, in setclvalue(L, L->top, cl); LUAU_ASSERT(iswhite(obj2gco(cl))); api_incr_top(L); - return; } void lua_pushboolean(lua_State* L, int b) { setbvalue(L->top, (b != 0)); // ensure that true is 1 api_incr_top(L); - return; } void lua_pushlightuserdata(lua_State* L, void* p) { setpvalue(L->top, p); api_incr_top(L); - return; } int lua_pushthread(lua_State* L) @@ -748,7 +729,6 @@ void lua_createtable(lua_State* L, int narray, int nrec) luaC_threadbarrier(L); sethvalue(L, L->top, luaH_new(L, narray, nrec)); api_incr_top(L); - return; } void lua_setreadonly(lua_State* L, int objindex, int enabled) @@ -758,7 +738,6 @@ void lua_setreadonly(lua_State* L, int objindex, int enabled) Table* t = hvalue(o); api_check(L, t != hvalue(registry(L))); t->readonly = bool(enabled); - return; } int lua_getreadonly(lua_State* L, int objindex) @@ -776,7 +755,6 @@ void lua_setsafeenv(lua_State* L, int objindex, int enabled) api_check(L, ttistable(o)); Table* t = hvalue(o); t->safeenv = bool(enabled); - return; } int lua_getmetatable(lua_State* L, int objindex) @@ -822,7 +800,6 @@ void lua_getfenv(lua_State* L, int idx) break; } api_incr_top(L); - return; } /* @@ -836,7 +813,6 @@ void lua_settable(lua_State* L, int idx) api_checkvalidindex(L, t); luaV_settable(L, t, L->top - 2, L->top - 1); L->top -= 2; // pop index and value - return; } void lua_setfield(lua_State* L, int idx, const char* k) @@ -848,7 +824,6 @@ void lua_setfield(lua_State* L, int idx, const char* k) setsvalue(L, &key, luaS_new(L, k)); luaV_settable(L, t, &key, L->top - 1); L->top--; - return; } void lua_rawsetfield(lua_State* L, int idx, const char* k) @@ -861,7 +836,6 @@ void lua_rawsetfield(lua_State* L, int idx, const char* k) setobj2t(L, luaH_setstr(L, hvalue(t), luaS_new(L, k)), L->top - 1); luaC_barriert(L, hvalue(t), L->top - 1); L->top--; - return; } void lua_rawset(lua_State* L, int idx) @@ -874,7 +848,6 @@ void lua_rawset(lua_State* L, int idx) setobj2t(L, luaH_set(L, hvalue(t), L->top - 2), L->top - 1); luaC_barriert(L, hvalue(t), L->top - 1); L->top -= 2; - return; } void lua_rawseti(lua_State* L, int idx, int n) @@ -887,7 +860,6 @@ void lua_rawseti(lua_State* L, int idx, int n) setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top - 1); luaC_barriert(L, hvalue(o), L->top - 1); L->top--; - return; } int lua_setmetatable(lua_State* L, int objindex) @@ -979,7 +951,6 @@ void lua_call(lua_State* L, int nargs, int nresults) luaD_call(L, func, nresults); adjustresults(L, nresults); - return; } /* @@ -995,7 +966,6 @@ static void f_call(lua_State* L, void* ud) { struct CallS* c = cast_to(struct CallS*, ud); luaD_call(L, c->func, c->nresults); - return; } int lua_pcall(lua_State* L, int nargs, int nresults, int errfunc) @@ -1273,7 +1243,6 @@ void lua_concat(lua_State* L, int n) api_incr_top(L); } // else n == 1; nothing to do - return; } void* lua_newuserdatatagged(lua_State* L, size_t sz, int tag) @@ -1397,7 +1366,6 @@ void lua_unref(lua_State* L, int ref) TValue* slot = luaH_setnum(L, reg, ref); setnvalue(slot, g->registryfree); // NB: no barrier needed because value isn't collectable g->registryfree = ref; - return; } void lua_setuserdatatag(lua_State* L, int idx, int tag) diff --git a/luau/VM/src/loslib.cpp b/luau/VM/src/loslib.cpp index 91ccec0..62a5668 100644 --- a/luau/VM/src/loslib.cpp +++ b/luau/VM/src/loslib.cpp @@ -22,6 +22,21 @@ static time_t timegm(struct tm* timep) { return _mkgmtime(timep); } +#elif defined(__FreeBSD__) +static tm* gmtime_r(const time_t* timep, tm* result) +{ + return gmtime_s(timep, result) == 0 ? result : NULL; +} + +static tm* localtime_r(const time_t* timep, tm* result) +{ + return localtime_s(timep, result) == 0 ? result : NULL; +} + +static time_t timegm(struct tm* timep) +{ + return mktime(timep); +} #endif static int os_clock(lua_State* L)