Skip to content

Commit ffe41a7

Browse files
committed
v0.21.1+luau737
1 parent 4e45ce5 commit ffe41a7

66 files changed

Lines changed: 1486 additions & 1723 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎luau/Ast/include/Luau/Allocator.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include "Luau/Ast.h"
55
#include "Luau/Location.h"
6-
#include "Luau/DenseHash2.h"
6+
#include "Luau/DenseHash.h"
77
#include "Luau/Common.h"
88

99
#include <vector>

‎luau/Ast/include/Luau/Ast.h‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,18 @@ class AstStatIf : public AstStat
742742
const std::optional<Location>& elseLocation
743743
);
744744

745+
AstStatIf(
746+
const Location& location,
747+
AstExpr* condition,
748+
AstStatBlock* thenbody,
749+
AstStat* elsebody,
750+
const std::optional<Location>& thenLocation,
751+
const std::optional<Location>& elseLocation,
752+
AstLocal* conditionLocal,
753+
bool conditionIsConst,
754+
const std::optional<Location>& conditionKeywordLocation
755+
);
756+
745757
void visit(AstVisitor* visitor) override;
746758

747759
AstExpr* condition;
@@ -752,6 +764,11 @@ class AstStatIf : public AstStat
752764

753765
// Active for 'elseif' as well
754766
std::optional<Location> elseLocation;
767+
768+
// Active for 'if local' and 'if const' statements
769+
AstLocal* conditionLocal = nullptr;
770+
bool conditionIsConst = false;
771+
std::optional<Location> conditionKeywordLocation;
755772
};
756773

757774
class AstStatWhile : public AstStat

‎luau/Ast/include/Luau/Lexer.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "Luau/Allocator.h"
55
#include "Luau/Ast.h"
66
#include "Luau/Location.h"
7-
#include "Luau/DenseHash2.h"
7+
#include "Luau/DenseHash.h"
88
#include "Luau/Common.h"
99

1010
#include <vector>
@@ -155,7 +155,7 @@ class AstNameTable
155155
size_t operator()(const Entry& e) const;
156156
};
157157

158-
DenseHashSet2<Entry, EntryHash> data;
158+
DenseHashSet<Entry, EntryHash> data;
159159

160160
Allocator& allocator;
161161
};

‎luau/Ast/include/Luau/ParseOptions.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#pragma once
33

44
#include "Luau/Ast.h"
5-
#include "Luau/DenseHash2.h"
5+
#include "Luau/DenseHash.h"
66

77
#include <vector>
88

@@ -19,7 +19,7 @@ enum class Mode
1919

2020
struct FragmentParseResumeSettings
2121
{
22-
DenseHashMap2<AstName, AstLocal*> localMap;
22+
DenseHashMap<AstName, AstLocal*> localMap;
2323
std::vector<AstLocal*> localStack;
2424
Position resumePosition;
2525
};

‎luau/Ast/include/Luau/ParseResult.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct Comment
5656
Location location;
5757
};
5858

59-
using CstNodeMap = DenseHashMap2<AstNode*, CstNode*>;
59+
using CstNodeMap = DenseHashMap<AstNode*, CstNode*>;
6060

6161
struct ParseResult
6262
{

‎luau/Ast/include/Luau/Parser.h‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "Luau/Lexer.h"
66
#include "Luau/ParseOptions.h"
77
#include "Luau/ParseResult.h"
8-
#include "Luau/DenseHash2.h"
8+
#include "Luau/DenseHash.h"
99
#include "Luau/Common.h"
1010
#include "Luau/Cst.h"
1111

@@ -122,6 +122,12 @@ class Parser
122122
// if exp then block {elseif exp then block} [else block] end
123123
AstStat* parseIf();
124124

125+
// (`if' | `elseif') (`local' | `const') binding `=' exp then block ... end -- parses an entire `if local`/`if const`
126+
AstStat* parseIfLocalCondition(const Location& start);
127+
128+
// Parse the trailing `{elseif exp then block} [else block] end` shared by `parseIf` and `parseIfLocalCondition`
129+
AstStat* parseElseBody(const Location& start, const Lexeme& matchThen, AstStatBlock* thenbody, Location& end, std::optional<Location>& elseLocation);
130+
125131
// while exp do block end
126132
AstStat* parseWhile();
127133

@@ -543,15 +549,15 @@ class Parser
543549
std::vector<Function> functionStack;
544550
size_t typeFunctionDepth = 0;
545551

546-
DenseHashMap2<AstName, AstLocal*> localMap;
552+
DenseHashMap<AstName, AstLocal*> localMap;
547553
std::vector<AstLocal*> localStack;
548-
DenseHashMap2<AstName, AstStatClass*> classesWithinModule;
554+
DenseHashMap<AstName, AstStatClass*> classesWithinModule;
549555

550556
std::vector<ParseError> parseErrors;
551557

552558
std::vector<unsigned int> matchRecoveryStopOnToken;
553559

554-
DenseHashMap2<AstName, Location> declaredExportBindings;
560+
DenseHashMap<AstName, Location> declaredExportBindings;
555561
bool hasModuleReturn = false;
556562

557563
std::vector<AstAttr*> scratchAttr;

‎luau/Ast/src/Ast.cpp‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,29 @@ AstStatIf::AstStatIf(
612612
{
613613
}
614614

615+
AstStatIf::AstStatIf(
616+
const Location& location,
617+
AstExpr* condition,
618+
AstStatBlock* thenbody,
619+
AstStat* elsebody,
620+
const std::optional<Location>& thenLocation,
621+
const std::optional<Location>& elseLocation,
622+
AstLocal* conditionLocal,
623+
bool conditionIsConst,
624+
const std::optional<Location>& conditionKeywordLocation
625+
)
626+
: AstStat(ClassIndex(), location)
627+
, condition(condition)
628+
, thenbody(thenbody)
629+
, elsebody(elsebody)
630+
, thenLocation(thenLocation)
631+
, elseLocation(elseLocation)
632+
, conditionLocal(conditionLocal)
633+
, conditionIsConst(conditionIsConst)
634+
, conditionKeywordLocation(conditionKeywordLocation)
635+
{
636+
}
637+
615638
void AstStatIf::visit(AstVisitor* visitor)
616639
{
617640
if (visitor->visit(this))

‎luau/Ast/src/Parser.cpp‎

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ LUAU_FLAGVERSION(LuauExportValueSyntax, 4)
2828
LUAU_FASTFLAGVARIABLE(DebugLuauNoInline)
2929
LUAU_FASTFLAGVARIABLE(DebugLuauUserDefinedClasses)
3030
LUAU_FASTFLAGVARIABLE(LuauAllowGlobalDeclarationToBeCalledClass)
31-
LUAU_FASTFLAGVARIABLE(LuauStoreConstKeywordBegin)
3231
LUAU_FASTFLAGVARIABLE(LuauTrackPrefixLocal)
3332
LUAU_FASTFLAGVARIABLE(LuauNoDuplicateBinaryPrefix)
3433
LUAU_FASTFLAGVARIABLE(LuauSingleTypeOptionalPackReturnsAttributeParens)
34+
LUAU_FASTFLAGVARIABLE(DebugLuauIfLocalSyntax)
3535

3636
// Clip with DebugLuauReportReturnTypeVariadicWithTypeSuffix
3737
bool luau_telemetry_parsed_return_type_variadic_with_type_suffix = false;
@@ -580,6 +580,10 @@ AstStat* Parser::parseIf()
580580

581581
nextLexeme(); // if / elseif
582582

583+
if (FFlag::DebugLuauIfLocalSyntax &&
584+
(lexer.current().type == Lexeme::ReservedLocal || (lexer.current().type == Lexeme::Name && AstName(lexer.current().name) == "const")))
585+
return parseIfLocalCondition(start);
586+
583587
AstExpr* cond = parseExpr();
584588

585589
Lexeme matchThen = lexer.current();
@@ -589,9 +593,62 @@ AstStat* Parser::parseIf()
589593

590594
AstStatBlock* thenbody = parseBlock();
591595

592-
AstStat* elsebody = nullptr;
593596
Location end = start;
594597
std::optional<Location> elseLocation;
598+
AstStat* elsebody = parseElseBody(start, matchThen, thenbody, end, elseLocation);
599+
600+
return allocator.alloc<AstStatIf>(Location(start, end), cond, thenbody, elsebody, thenLocation, elseLocation);
601+
}
602+
603+
// (`if' | `elseif') (`local' | `const') binding `=' exp then block {elseif exp then block} [else block] end
604+
//
605+
// LUAU_NOINLINE keeps the `if local`/`if const` locals off parseIf's frame: parseIf recurses through
606+
// long if/elseif chains and this variant is rarely taken. `start` is the location of the already-
607+
// consumed `if`/`elseif` keyword; the current lexeme is the `local`/`const` keyword.
608+
LUAU_NOINLINE AstStat* Parser::parseIfLocalCondition(const Location& start)
609+
{
610+
LUAU_ASSERT(FFlag::DebugLuauIfLocalSyntax);
611+
612+
bool condIsConst = (lexer.current().type == Lexeme::Name && AstName(lexer.current().name) == "const");
613+
std::optional<Location> condKeywordLocation = lexer.current().location;
614+
nextLexeme(); // consume 'local' or 'const'
615+
616+
Binding binding = parseBinding(condIsConst);
617+
618+
if (lexer.current().type == ',')
619+
report(lexer.current().location, "Expected '=' after variable name in 'if local', got ','; only a single binding is allowed");
620+
621+
expectAndConsume('=', "if local declaration");
622+
623+
AstExpr* cond = parseExpr();
624+
625+
unsigned int localsBegin = saveLocals();
626+
AstLocal* condLocal = pushLocal(binding);
627+
628+
Lexeme matchThen = lexer.current();
629+
std::optional<Location> thenLocation;
630+
if (expectAndConsume(Lexeme::ReservedThen, "if statement"))
631+
thenLocation = matchThen.location;
632+
633+
AstStatBlock* thenbody = parseBlock();
634+
635+
// Restore locals after then-block so condLocal is not visible in else/elseif
636+
restoreLocals(localsBegin);
637+
638+
Location end = start;
639+
std::optional<Location> elseLocation;
640+
AstStat* elsebody = parseElseBody(start, matchThen, thenbody, end, elseLocation);
641+
642+
return allocator.alloc<AstStatIf>(
643+
Location(start, end), cond, thenbody, elsebody, thenLocation, elseLocation, condLocal, condIsConst, condKeywordLocation
644+
);
645+
}
646+
647+
AstStat* Parser::parseElseBody(const Location& start, const Lexeme& matchThen, AstStatBlock* thenbody, Location& end, std::optional<Location>& elseLocation)
648+
{
649+
AstStat* elsebody = nullptr;
650+
end = start;
651+
elseLocation = std::nullopt;
595652

596653
if (lexer.current().type == Lexeme::ReservedElseif)
597654
{
@@ -631,7 +688,7 @@ AstStat* Parser::parseIf()
631688
thenbody->hasEnd = hasEnd;
632689
}
633690

634-
return allocator.alloc<AstStatIf>(Location(start, end), cond, thenbody, elsebody, thenLocation, elseLocation);
691+
return elsebody;
635692
}
636693

637694
// while exp do block end
@@ -1285,9 +1342,7 @@ AstStat* Parser::parseLocal(
12851342

12861343
Location location{start.begin, body->location.end};
12871344

1288-
AstStatLocalFunction* node = allocator.alloc<AstStatLocalFunction>(
1289-
location, var, body, isConst, isConst && FFlag::LuauStoreConstKeywordBegin ? keywordPosition : Position::missing()
1290-
);
1345+
AstStatLocalFunction* node = allocator.alloc<AstStatLocalFunction>(location, var, body, isConst, isConst ? keywordPosition : Position::missing());
12911346
if (options.storeCstData)
12921347
{
12931348
cstNodeMap[node] = cstAttrLists != nullptr
@@ -1502,7 +1557,7 @@ LUAU_NOINLINE AstStat* Parser::parseClassStat(const Location& start, bool export
15021557
//
15031558
// ... must fail. This gets the job done but maybe we can do something
15041559
// slightly more performant here (e.g.: a "scratch" set).
1505-
DenseHashSet2<AstName> classMemberNamespace;
1560+
DenseHashSet<AstName> classMemberNamespace;
15061561

15071562
while (lexer.current().type != Lexeme::ReservedEnd && lexer.current().type != Lexeme::Eof)
15081563
{
@@ -1593,14 +1648,6 @@ LUAU_NOINLINE AstStat* Parser::parseClassStat(const Location& start, bool export
15931648
report(name.location, "Cannot use '%s' as a method name: names starting with '__' are reserved", name.name.value);
15941649
}
15951650

1596-
if (name.name == "__init")
1597-
{
1598-
if (body->args.size < 1)
1599-
report(name.location, "__init must have at least one parameter");
1600-
else if (body->args.data[0]->name != "self")
1601-
report(body->args.data[0]->location, "__init's first parameter must be named self");
1602-
}
1603-
16041651
// TODO CLI-200853: We should support attributes, we do not need
16051652
// to support them prior to the full launch.
16061653
if (classMemberNamespace.contains(name.name))

‎luau/Ast/src/PrettyPrinter.cpp‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
LUAU_FASTFLAG(DebugLuauUserDefinedClasses)
1414
LUAU_FASTFLAG(LuauExportValueSyntax)
1515
LUAU_FASTFLAGVARIABLE(LuauPrettyPrintVisualizeIndexerAccess)
16+
LUAU_FASTFLAG(DebugLuauIfLocalSyntax)
1617

1718
namespace
1819
{
@@ -1546,7 +1547,22 @@ struct Printer
15461547

15471548
void visualizeElseIf(AstStatIf& elseif)
15481549
{
1549-
visualize(*elseif.condition);
1550+
if (FFlag::DebugLuauIfLocalSyntax && elseif.conditionLocal)
1551+
{
1552+
writer.keyword(elseif.conditionIsConst ? "const" : "local");
1553+
writer.write(elseif.conditionLocal->name.value);
1554+
if (elseif.conditionLocal->annotation)
1555+
{
1556+
writer.symbol(":");
1557+
visualizeTypeAnnotation(*elseif.conditionLocal->annotation);
1558+
}
1559+
writer.symbol("=");
1560+
visualize(*elseif.condition);
1561+
}
1562+
else
1563+
{
1564+
visualize(*elseif.condition);
1565+
}
15501566
if (elseif.thenLocation)
15511567
advance(elseif.thenLocation->begin);
15521568
writer.keyword("then");

‎luau/Bytecode/include/Luau/BytecodeBuilder.h‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,26 @@
22
#pragma once
33

44
#include "Luau/Bytecode.h"
5-
#include "Luau/DenseHash2.h"
5+
#include "Luau/DenseHash.h"
66
#include "Luau/StringUtils.h"
77

88
#include <string>
99

1010
namespace Luau
1111
{
1212

13+
static const uint32_t kMaxRegisterCount = 255;
14+
static const uint32_t kMaxUpvalueCount = 200;
15+
static const uint32_t kMaxLocalCount = 200;
16+
static const uint32_t kMaxInstructionCount = 1'000'000'000;
17+
18+
static const uint8_t kInvalidReg = 255;
19+
20+
static const uint32_t kMaxConstantCount = 1 << 23;
21+
static const uint32_t kMaxClosureCount = 1 << 15;
22+
23+
static const int kMaxJumpDistance = 1 << 23;
24+
1325
class BytecodeEncoder
1426
{
1527
public:
@@ -95,7 +107,7 @@ class BytecodeBuilder
95107
void patchAux(size_t targetAux, int32_t newValue);
96108

97109
void foldJumps();
98-
std::vector<uint32_t> expandJumps();
110+
std::vector<uint32_t> expandJumps(bool& hasLongJumpError);
99111

100112
void setFunctionTypeInfo(std::string value);
101113
void pushLocalTypeInfo(LuauBytecodeType type, uint8_t reg, uint32_t startpc, uint32_t endpc);
@@ -328,9 +340,9 @@ class BytecodeBuilder
328340

329341
bool hasLongJumps = false;
330342

331-
DenseHashMap2<ConstantKey, int32_t, ConstantKeyHash> constantMap;
332-
DenseHashMap2<TableShape, int32_t, TableShapeHash> tableShapeMap;
333-
DenseHashMap2<uint32_t, int16_t> protoMap;
343+
DenseHashMap<ConstantKey, int32_t, ConstantKeyHash> constantMap;
344+
DenseHashMap<TableShape, int32_t, TableShapeHash> tableShapeMap;
345+
DenseHashMap<uint32_t, int16_t> protoMap;
334346

335347
int debugLine = 0;
336348

@@ -342,7 +354,7 @@ class BytecodeBuilder
342354

343355
std::vector<UserdataType> userdataTypes;
344356

345-
DenseHashMap2<StringRef, unsigned int, StringRefHash> stringTable;
357+
DenseHashMap<StringRef, unsigned int, StringRefHash> stringTable;
346358
std::vector<StringRef> debugStrings;
347359

348360
std::vector<std::pair<uint32_t, uint32_t>> debugRemarks;
@@ -362,6 +374,7 @@ class BytecodeBuilder
362374
void validate() const;
363375
void validateInstructions() const;
364376
void validateVariadic() const;
377+
void validateCaptures() const;
365378
virtual void validateConst(int32_t cid) const;
366379
virtual void validateConst(int32_t cid, Constant::Type constType) const;
367380
virtual uint8_t validateProto(int32_t pid) const;

0 commit comments

Comments
 (0)