From f59ac1cba5ee18b69e2bdfb1296c9bb58aa0c087 Mon Sep 17 00:00:00 2001 From: "marja@chromium.org" Date: Tue, 11 Feb 2014 11:51:01 +0000 Subject: [PATCH] Move ParseRegexpLiteral to ParserBase. R=ulan@chromium.org BUG=v8:3126 LOG=N Review URL: https://codereview.chromium.org/156423005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19273 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/parser.cc | 46 ++++++++++++++++++++++++------------------- src/parser.h | 24 +++++++++++------------ src/preparser.cc | 27 +++++-------------------- src/preparser.h | 48 ++++++++++++++++++++++++++++++++++++++++++--- test/cctest/test-parsing.cc | 32 ++++++++++++++++++++++++++++++ 5 files changed, 120 insertions(+), 57 deletions(-) diff --git a/src/parser.cc b/src/parser.cc index 0f842ad..24eaef0 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -551,6 +551,11 @@ bool ParserTraits::IsEvalOrArguments(Handle identifier) const { } +int ParserTraits::NextMaterializedLiteralIndex() { + return parser_->current_function_state_->NextMaterializedLiteralIndex(); +} + + void ParserTraits::ReportMessageAt(Scanner::Location source_location, const char* message, Vector args) { @@ -601,6 +606,27 @@ Handle ParserTraits::GetSymbol() { return parser_->LookupSymbol(symbol_id); } + +Handle ParserTraits::NextLiteralString(PretenureFlag tenured) { + Scanner& scanner = parser_->scanner(); + if (scanner.is_next_literal_ascii()) { + return parser_->isolate_->factory()->NewStringFromAscii( + scanner.next_literal_ascii_string(), tenured); + } else { + return parser_->isolate_->factory()->NewStringFromTwoByte( + scanner.next_literal_utf16_string(), tenured); + } +} + + +Expression* ParserTraits::NewRegExpLiteral(Handle js_pattern, + Handle js_flags, + int literal_index, + int pos) { + return parser_->factory()->NewRegExpLiteral( + js_pattern, js_flags, literal_index, pos); +} + Parser::Parser(CompilationInfo* info) : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit(), @@ -3834,26 +3860,6 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { } -Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { - int pos = peek_position(); - if (!scanner().ScanRegExpPattern(seen_equal)) { - Next(); - ReportMessage("unterminated_regexp", Vector::empty()); - *ok = false; - return NULL; - } - - int literal_index = current_function_state_->NextMaterializedLiteralIndex(); - - Handle js_pattern = NextLiteralString(TENURED); - scanner().ScanRegExpFlags(); - Handle js_flags = NextLiteralString(TENURED); - Next(); - - return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); -} - - ZoneList* Parser::ParseArguments(bool* ok) { // Arguments :: // '(' (AssignmentExpression)*[','] ')' diff --git a/src/parser.h b/src/parser.h index 64513d3..c2dd77f 100644 --- a/src/parser.h +++ b/src/parser.h @@ -412,6 +412,7 @@ class ParserTraits { typedef Parser* ParserType; // Return types for traversing functions. typedef Handle IdentifierType; + typedef Expression* ExpressionType; explicit ParserTraits(Parser* parser) : parser_(parser) {} @@ -419,6 +420,7 @@ class ParserTraits { bool is_classic_mode() const; bool is_generator() const; bool IsEvalOrArguments(Handle identifier) const; + int NextMaterializedLiteralIndex(); // Reporting errors. void ReportMessageAt(Scanner::Location source_location, @@ -429,12 +431,21 @@ class ParserTraits { const char* message, Vector > args); - // Identifiers: + // "null" return type creators. static IdentifierType EmptyIdentifier() { return Handle(); } + static ExpressionType EmptyExpression() { + return NULL; + } + // Producing data during the recursive descent. IdentifierType GetSymbol(); + IdentifierType NextLiteralString(PretenureFlag tenured); + ExpressionType NewRegExpLiteral(IdentifierType js_pattern, + IdentifierType js_flags, + int literal_index, + int pos); private: Parser* parser_; @@ -657,7 +668,6 @@ class Parser : public ParserBase { Expression* ParsePrimaryExpression(bool* ok); Expression* ParseArrayLiteral(bool* ok); Expression* ParseObjectLiteral(bool* ok); - Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); // Initialize the components of a for-in / for-of statement. void InitializeForEachStatement(ForEachStatement* stmt, @@ -690,16 +700,6 @@ class Parser : public ParserBase { } } - Handle NextLiteralString(PretenureFlag tenured) { - if (scanner().is_next_literal_ascii()) { - return isolate_->factory()->NewStringFromAscii( - scanner().next_literal_ascii_string(), tenured); - } else { - return isolate_->factory()->NewStringFromTwoByte( - scanner().next_literal_utf16_string(), tenured); - } - } - // Get odd-ball literals. Literal* GetLiteralUndefined(int position); Literal* GetLiteralTheHole(int position); diff --git a/src/preparser.cc b/src/preparser.cc index c01acdd..3c18490 100644 --- a/src/preparser.cc +++ b/src/preparser.cc @@ -65,6 +65,11 @@ bool PreParserTraits::is_generator() const { } +int PreParserTraits::NextMaterializedLiteralIndex() { + return pre_parser_->scope_->NextMaterializedLiteralIndex(); +} + + void PreParserTraits::ReportMessageAt(Scanner::Location location, const char* message, Vector args) { @@ -1301,28 +1306,6 @@ PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { } -PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, - bool* ok) { - if (!scanner()->ScanRegExpPattern(seen_equal)) { - Next(); - ReportMessageAt(scanner()->location(), "unterminated_regexp"); - *ok = false; - return Expression::Default(); - } - - scope_->NextMaterializedLiteralIndex(); - - if (!scanner()->ScanRegExpFlags()) { - Next(); - ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); - *ok = false; - return Expression::Default(); - } - Next(); - return Expression::Default(); -} - - PreParser::Arguments PreParser::ParseArguments(bool* ok) { // Arguments :: // '(' (AssignmentExpression)*[','] ')' diff --git a/src/preparser.h b/src/preparser.h index b6a9e84..b3f67c9 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -225,6 +225,8 @@ class ParserBase : public Traits { bool* is_set, bool* ok); + typename Traits::ExpressionType ParseRegExpLiteral(bool seen_equal, bool* ok); + // Used to detect duplicates in object literals. Each of the values // kGetterProperty, kSetterProperty and kValueProperty represents // a type of object literal property. When parsing a property, its @@ -427,6 +429,7 @@ class PreParserTraits { typedef PreParser* ParserType; // Return types for traversing functions. typedef PreParserIdentifier IdentifierType; + typedef PreParserExpression ExpressionType; explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} @@ -436,6 +439,7 @@ class PreParserTraits { static bool IsEvalOrArguments(IdentifierType identifier) { return identifier.IsEvalOrArguments(); } + int NextMaterializedLiteralIndex(); // Reporting errors. void ReportMessageAt(Scanner::Location location, @@ -449,12 +453,25 @@ class PreParserTraits { const char* type, const char* name_opt); - // Identifiers: + // "null" return type creators. static IdentifierType EmptyIdentifier() { return PreParserIdentifier::Default(); } + static ExpressionType EmptyExpression() { + return PreParserExpression::Default(); + } + // Producing data during the recursive descent. IdentifierType GetSymbol(); + static IdentifierType NextLiteralString(PretenureFlag tenured) { + return PreParserIdentifier::Default(); + } + ExpressionType NewRegExpLiteral(IdentifierType js_pattern, + IdentifierType js_flags, + int literal_index, + int pos) { + return PreParserExpression::Default(); + } private: PreParser* pre_parser_; @@ -616,7 +633,7 @@ class PreParser : public ParserBase { *variable = this; } ~Scope() { *variable_ = prev_; } - void NextMaterializedLiteralIndex() { materialized_literal_count_++; } + int NextMaterializedLiteralIndex() { return materialized_literal_count_++; } void AddProperty() { expected_properties_++; } ScopeType type() { return type_; } int expected_properties() { return expected_properties_; } @@ -701,7 +718,6 @@ class PreParser : public ParserBase { Expression ParsePrimaryExpression(bool* ok); Expression ParseArrayLiteral(bool* ok); Expression ParseObjectLiteral(bool* ok); - Expression ParseRegExpLiteral(bool seen_equal, bool* ok); Expression ParseV8Intrinsic(bool* ok); Arguments ParseArguments(bool* ok); @@ -848,6 +864,32 @@ ParserBase::ParseIdentifierNameOrGetOrSet(bool* is_get, } +template +typename Traits::ExpressionType +ParserBase::ParseRegExpLiteral(bool seen_equal, bool* ok) { + int pos = peek_position(); + if (!scanner()->ScanRegExpPattern(seen_equal)) { + Next(); + ReportMessage("unterminated_regexp", Vector::empty()); + *ok = false; + return Traits::EmptyExpression(); + } + + int literal_index = this->NextMaterializedLiteralIndex(); + + typename Traits::IdentifierType js_pattern = this->NextLiteralString(TENURED); + if (!scanner()->ScanRegExpFlags()) { + Next(); + ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); + *ok = false; + return Traits::EmptyExpression(); + } + typename Traits::IdentifierType js_flags = this->NextLiteralString(TENURED); + Next(); + return this->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); +} + + template void ParserBase::ObjectLiteralChecker::CheckProperty( Token::Value property, diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index f3f238c..3d8fc39 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -2014,3 +2014,35 @@ TEST(NoErrorsTryCatchFinally) { RunParserSyncTest(context_data, statement_data, kSuccess); } + + +TEST(ErrorsRegexpLiteral) { + const char* context_data[][2] = { + {"var r = ", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "/unterminated", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsRegexpLiteral) { + const char* context_data[][2] = { + {"var r = ", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "/foo/", + "/foo/g", + "/foo/whatever", // This is an error but not detected by the parser. + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} -- 2.7.4