Update Luau to 0.555 (with patch to change LUAI_MAXCSTACK)

This commit is contained in:
Alex Orlenko 2022-12-02 22:29:58 +00:00
parent a2c416bbb9
commit 0e1249cb86
No known key found for this signature in database
GPG Key ID: 4C150C250863B96D
8 changed files with 130 additions and 69 deletions

View File

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

View File

@ -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<AstExpr*>& 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<AstType*>& result, TempVector<std:
nextLexeme();
if (FFlag::LuauCommaParenWarnings && lexer.current().type == ')')
if (lexer.current().type == ')')
{
report(lexer.current().location, "Expected type after ',' but got ')' instead");
break;
@ -2317,8 +2314,7 @@ AstExpr* Parser::parseTableConstructor()
while (lexer.current().type != '}')
{
if (FFlag::LuauTableConstructorRecovery)
lastElementIndent = lexer.current().location.begin.column;
lastElementIndent = lexer.current().location.begin.column;
if (lexer.current().type == '[')
{
@ -2364,8 +2360,7 @@ AstExpr* Parser::parseTableConstructor()
{
nextLexeme();
}
else if (FFlag::LuauTableConstructorRecovery && (lexer.current().type == '[' || lexer.current().type == Lexeme::Name) &&
lexer.current().location.begin.column == lastElementIndent)
else if ((lexer.current().type == '[' || lexer.current().type == Lexeme::Name) && lexer.current().location.begin.column == lastElementIndent)
{
report(lexer.current().location, "Expected ',' after table constructor element");
}
@ -2556,7 +2551,7 @@ std::pair<AstArray<AstGenericType>, AstArray<AstGenericTypePack>> 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<AstExpr*> 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<char> chars = copy(scratchData);
@ -2688,15 +2684,36 @@ AstExpr* Parser::parseInterpString()
if (currentLexeme.type == Lexeme::InterpStringEnd || currentLexeme.type == Lexeme::InterpStringSimple)
{
AstArray<AstArray<char>> stringsArray = copy(strings);
AstArray<AstExpr*> expressionsArray = copy(expressions);
return allocator.alloc<AstExprInterpString>(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<AstArray<char>> stringsArray = copy(strings);
AstArray<AstExpr*> expressionsArray = copy(expressions);
return allocator.alloc<AstExprInterpString>(Location{startLocation, endLocation}, stringsArray, expressionsArray);
}
AstExpr* Parser::parseNumber()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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