Skip to content

Commit c6b98aa

Browse files
authored
[WATParser] Do not clear earlier annotations when lexing annotations (#9143)
Lexer::takeAnnotation called takeKeyword and takeLParen, which are public token methods that call advance(). Calling advance() executes annotations.clear(), wiping out any earlier annotations already collected during the same skipSpace() pass whenever a subsequent annotation contains a keyword or nested parenthesis. Use peekKeyword() + take() and takePrefix() instead.
1 parent 1447734 commit c6b98aa

2 files changed

Lines changed: 16 additions & 6 deletions

File tree

‎src/parser/lexer.h‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,8 +1113,14 @@ inline std::optional<Annotation> Lexer::takeAnnotation() {
11131113
pos = startPos;
11141114
return std::nullopt;
11151115
}
1116-
if (takeSpace() || takeKeyword() || takeInteger() || takeFloat() ||
1117-
takeStr() || takeIdent()) {
1116+
// Use peekKeyword + take rather than takeKeyword to avoid calling
1117+
// advance(), which would clear previously collected annotations.
1118+
if (auto keyword = peekKeyword()) {
1119+
take(keyword->size());
1120+
continue;
1121+
}
1122+
if (takeSpace() || takeInteger() || takeFloat() || takeStr() ||
1123+
takeIdent()) {
11181124
continue;
11191125
}
11201126
if (takePrefix("(@"sv)) {
@@ -1130,7 +1136,8 @@ inline std::optional<Annotation> Lexer::takeAnnotation() {
11301136
++depth;
11311137
continue;
11321138
}
1133-
if (takeLParen()) {
1139+
// Use takePrefix rather than takeLParen to avoid calling advance().
1140+
if (takePrefix("("sv)) {
11341141
++depth;
11351142
continue;
11361143
}

‎test/gtest/wat-lexer.cpp‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -947,14 +947,17 @@ TEST(LexerTest, LexString) {
947947
}
948948

949949
TEST(LexerTest, Annotations) {
950-
Lexer lexer(
951-
" (@metadata.code.branch_hint \"\\01\")\n (@metadata.code.branch_hint \"\\00\")\n (br_if $out"sv);
950+
Lexer lexer("(@metadata.code.branch_hint \"\\01\")\n"
951+
"(@metadata.code.branch_hint \"\\00\")\n"
952+
"(@custom (nested kw))\n"
953+
"(br_if $out"sv);
952954
// Trigger advance/skipSpace which parses annotations.
953955
lexer.takeID();
954956
auto annotations = lexer.takeAnnotations();
955-
ASSERT_EQ(annotations.size(), 2u);
957+
ASSERT_EQ(annotations.size(), 3u);
956958
EXPECT_EQ(annotations[0].contents, " \"\\01\""sv);
957959
EXPECT_EQ(annotations[1].contents, " \"\\00\""sv);
960+
EXPECT_EQ(annotations[2].contents, " (nested kw)"sv);
958961
}
959962

960963
TEST(LexerTest, LexKeywords) {

0 commit comments

Comments
 (0)