Commit 4e18f868 authored by Florian Sattler's avatar Florian Sattler Committed by Commit Bot

[scanner] Add error state to scanner to prevent further processing.

BUG=v8:7926

Change-Id: Ib4dd3017c7d6f28025ab308063d7dedd0138dfa6
Reviewed-on: https://chromium-review.googlesource.com/c/1291470
Commit-Queue: Florian Sattler <sattlerf@google.com>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56848}
parent 98b257fe
......@@ -647,7 +647,10 @@ class ParserBase {
bool stack_overflow() const {
return pending_error_handler()->stack_overflow();
}
void set_stack_overflow() { pending_error_handler()->set_stack_overflow(); }
void set_stack_overflow() {
scanner_->set_parser_error();
pending_error_handler()->set_stack_overflow();
}
void CheckStackOverflow() {
// Any further calls to Next or peek will return the illegal token.
if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow();
......@@ -655,10 +658,7 @@ class ParserBase {
int script_id() { return script_id_; }
void set_script_id(int id) { script_id_ = id; }
V8_INLINE Token::Value peek() {
if (stack_overflow()) return Token::ILLEGAL;
return scanner()->peek();
}
V8_INLINE Token::Value peek() { return scanner()->peek(); }
// Returns the position past the following semicolon (if it exists), and the
// position past the end of the current token otherwise.
......@@ -666,15 +666,9 @@ class ParserBase {
return (peek() == Token::SEMICOLON) ? peek_end_position() : end_position();
}
V8_INLINE Token::Value PeekAhead() {
if (stack_overflow()) return Token::ILLEGAL;
return scanner()->PeekAhead();
}
V8_INLINE Token::Value PeekAhead() { return scanner()->PeekAhead(); }
V8_INLINE Token::Value Next() {
if (stack_overflow()) return Token::ILLEGAL;
return scanner()->Next();
}
V8_INLINE Token::Value Next() { return scanner()->Next(); }
V8_INLINE void Consume(Token::Value token) {
Token::Value next = scanner()->Next();
......@@ -4449,7 +4443,10 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
if (impl()->ParsingDynamicFunctionDeclaration()) {
// We don't want dynamic functions to actually declare their name
// "anonymous". We just want that name in the toString().
Consume(Token::IDENTIFIER);
// Consuming token we did not peek yet, which could lead to a ILLEGAL token
// in the case of a stackoverflow.
Expect(Token::IDENTIFIER, CHECK_OK);
DCHECK(scanner()->CurrentMatchesContextual(Token::ANONYMOUS));
} else if (peek_any_identifier()) {
type = FunctionLiteral::kNamedExpression;
......
......@@ -525,7 +525,9 @@ V8_INLINE Token::Value Scanner::ScanSingleToken() {
return Token::IDENTIFIER;
}
if (IsDecimalDigit(c0_)) return ScanNumber(false);
if (c0_ == kEndOfInput) return Token::EOS;
if (c0_ == kEndOfInput) {
return source_->has_parser_error() ? Token::ILLEGAL : Token::EOS;
}
token = SkipWhiteSpace();
continue;
}
......
......@@ -42,6 +42,13 @@ class Utf16CharacterStream {
virtual ~Utf16CharacterStream() = default;
void set_parser_error() {
buffer_cursor_ = buffer_end_;
has_parser_error_ = true;
}
bool has_parser_error() const { return has_parser_error_; }
inline uc32 Peek() {
if (V8_LIKELY(buffer_cursor_ < buffer_end_)) {
return static_cast<uc32>(*buffer_cursor_);
......@@ -145,7 +152,7 @@ class Utf16CharacterStream {
bool ReadBlockChecked() {
size_t position = pos();
USE(position);
bool success = ReadBlock();
bool success = !has_parser_error() && ReadBlock();
// Post-conditions: 1, We should always be at the right position.
// 2, Cursor should be inside the buffer.
......@@ -193,6 +200,7 @@ class Utf16CharacterStream {
const uint16_t* buffer_end_;
size_t buffer_pos_;
RuntimeCallStats* runtime_call_stats_;
bool has_parser_error_ = false;
};
// ----------------------------------------------------------------------------
......@@ -225,6 +233,11 @@ class Scanner {
DISALLOW_COPY_AND_ASSIGN(BookmarkScope);
};
// Sets the Scanner into an error state to stop further scanning and terminate
// the parsing by only returning ILLEGAL tokens after that.
void set_parser_error() { source_->set_parser_error(); }
bool has_parser_error_set() { return source_->has_parser_error(); }
// Representation of an interval of source positions.
struct Location {
Location(int b, int e) : beg_pos(b), end_pos(e) { }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment