Reland "[parser] Optimize directive parsing especially for preparser"
This is a reland of 9d34fa0c51
TBR=ishell@chromium.org
Original change's description:
> [parser] Optimize directive parsing especially for preparser
>
> - Avoid allocating AstRawString in the preparser
> - Use fast LiteralEquals to compare the directive.
>
> Bug: chromium:901250
> Change-Id: I178aca812f6c0ffa28d7f48b707316a5a99a2ac0
> Reviewed-on: https://chromium-review.googlesource.com/c/1314570
> Commit-Queue: Toon Verwaest <verwaest@chromium.org>
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#57217}
Bug: chromium:901250
Change-Id: I01dfd882923d3f37a08ca0be193474d38e273927
Reviewed-on: https://chromium-review.googlesource.com/c/1314578
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57220}
This commit is contained in:
parent
3530998c0d
commit
f5cf90cc14
@ -235,8 +235,6 @@ class AstBigInt {
|
||||
F(this_function, ".this_function") \
|
||||
F(throw, "throw") \
|
||||
F(undefined, "undefined") \
|
||||
F(use_asm, "use asm") \
|
||||
F(use_strict, "use strict") \
|
||||
F(value, "value")
|
||||
|
||||
class AstStringConstants final {
|
||||
|
@ -4589,16 +4589,27 @@ ParserBase<Impl>::ParseStatementList(StatementListT body,
|
||||
|
||||
DCHECK(!impl()->IsNull(body));
|
||||
|
||||
while (peek() == Token::STRING && (scanner()->HasLineTerminatorAfterNext() ||
|
||||
Token::IsAutoSemicolon(PeekAhead()))) {
|
||||
const AstRawString* symbol = scanner()->NextSymbol(ast_value_factory_);
|
||||
while (peek() == Token::STRING) {
|
||||
bool use_strict = false;
|
||||
bool use_asm = false;
|
||||
|
||||
Scanner::Location token_loc = scanner()->peek_location();
|
||||
// The length of the token is used to distinguish between strings literals
|
||||
// that evaluate equal to directives but contain either escape sequences
|
||||
// (e.g., "use \x73trict") or line continuations (e.g., "use \(newline)
|
||||
// strict").
|
||||
if (symbol == ast_value_factory()->use_strict_string() &&
|
||||
token_loc.end_pos - token_loc.beg_pos == sizeof("use strict") + 1) {
|
||||
|
||||
if (scanner()->NextLiteralEquals("use strict")) {
|
||||
use_strict = true;
|
||||
} else if (scanner()->NextLiteralEquals("use asm")) {
|
||||
use_asm = true;
|
||||
}
|
||||
|
||||
StatementT stat = ParseStatementListItem();
|
||||
body->Add(stat, zone_);
|
||||
may_abort = false;
|
||||
|
||||
RETURN_IF_PARSE_ERROR_CUSTOM(Return, kLazyParsingComplete);
|
||||
|
||||
if (!impl()->IsStringLiteral(stat)) break;
|
||||
|
||||
if (use_strict) {
|
||||
// Directive "use strict" (ES5 14.1).
|
||||
RaiseLanguageMode(LanguageMode::kStrict);
|
||||
if (!scope()->HasSimpleParameters()) {
|
||||
@ -4610,8 +4621,7 @@ ParserBase<Impl>::ParseStatementList(StatementListT body,
|
||||
"use strict");
|
||||
return kLazyParsingComplete;
|
||||
}
|
||||
} else if (symbol == ast_value_factory()->use_asm_string() &&
|
||||
token_loc.end_pos - token_loc.beg_pos == sizeof("use asm") + 1) {
|
||||
} else if (use_asm) {
|
||||
// Directive "use asm".
|
||||
impl()->SetAsmModule();
|
||||
} else {
|
||||
@ -4620,9 +4630,6 @@ ParserBase<Impl>::ParseStatementList(StatementListT body,
|
||||
// as appropriate. Ditto usages below.
|
||||
RaiseLanguageMode(LanguageMode::kSloppy);
|
||||
}
|
||||
StatementT stat = ParseStatementListItem();
|
||||
body->Add(stat, zone());
|
||||
may_abort = false;
|
||||
}
|
||||
|
||||
// Allocate a target stack to use for this set of source elements. This way,
|
||||
|
@ -260,9 +260,8 @@ class Scanner {
|
||||
Location(int b, int e) : beg_pos(b), end_pos(e) { }
|
||||
Location() : beg_pos(0), end_pos(0) { }
|
||||
|
||||
bool IsValid() const {
|
||||
return beg_pos >= 0 && end_pos >= beg_pos;
|
||||
}
|
||||
int length() const { return end_pos - beg_pos; }
|
||||
bool IsValid() const { return beg_pos >= 0 && end_pos >= beg_pos; }
|
||||
|
||||
static Location invalid() { return Location(-1, -1); }
|
||||
|
||||
@ -366,6 +365,20 @@ class Scanner {
|
||||
CurrentMatchesContextualEscaped(Token::LET);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
bool NextLiteralEquals(const char (&s)[N]) {
|
||||
DCHECK_EQ(Token::STRING, peek());
|
||||
// The length of the token is used to make sure the literal equals without
|
||||
// taking escape sequences (e.g., "use \x73trict") or line continuations
|
||||
// (e.g., "use \(newline) strict") into account.
|
||||
if (!is_next_literal_one_byte()) return false;
|
||||
if (peek_location().length() != N + 1) return false;
|
||||
|
||||
Vector<const uint8_t> next = next_literal_one_byte_string();
|
||||
const char* chars = reinterpret_cast<const char*>(next.start());
|
||||
return next.length() == N - 1 && strncmp(s, chars, N - 1) == 0;
|
||||
}
|
||||
|
||||
UnicodeCache* unicode_cache() const { return unicode_cache_; }
|
||||
|
||||
// Returns the location of the last seen octal literal.
|
||||
|
7
test/message/fail/directive.js
Normal file
7
test/message/fail/directive.js
Normal file
@ -0,0 +1,7 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
function f([a]) {
|
||||
"use strict";
|
||||
}
|
4
test/message/fail/directive.out
Normal file
4
test/message/fail/directive.out
Normal file
@ -0,0 +1,4 @@
|
||||
*%(basename)s:6: SyntaxError: Illegal 'use strict' directive in function with non-simple parameter list
|
||||
"use strict";
|
||||
^^^^^^^^^^^^
|
||||
SyntaxError: Illegal 'use strict' directive in function with non-simple parameter list
|
10
test/mjsunit/regress/regress-directive.js
Normal file
10
test/mjsunit/regress/regress-directive.js
Normal file
@ -0,0 +1,10 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
function f() {
|
||||
'use strict'
|
||||
in Number
|
||||
}
|
||||
|
||||
f.arguments
|
Loading…
Reference in New Issue
Block a user