Chromium Code Reviews| Index: src/preparser.h |
| diff --git a/src/preparser.h b/src/preparser.h |
| index d890ae5c216d7b497d0f3801288bd2fe7c4123fb..ee36f05c6dbbfaf5589f1e654b78c4c0bd52daf4 100644 |
| --- a/src/preparser.h |
| +++ b/src/preparser.h |
| @@ -88,6 +88,7 @@ class ParserBase : public Traits { |
| typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
| typedef typename Traits::Type::Literal LiteralT; |
| typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; |
| + typedef typename Traits::Type::StatementList StatementListT; |
| ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
| v8::Extension* extension, AstValueFactory* ast_value_factory, |
| @@ -117,7 +118,8 @@ class ParserBase : public Traits { |
| allow_harmony_spread_arrays_(false), |
| allow_harmony_new_target_(false), |
| allow_strong_mode_(false), |
| - allow_legacy_const_(true) {} |
| + allow_legacy_const_(true), |
| + allow_do_expression_parsing_(false) {} |
| #define ALLOW_ACCESSORS(name) \ |
| bool allow_##name() const { return allow_##name##_; } \ |
| @@ -136,8 +138,16 @@ class ParserBase : public Traits { |
| ALLOW_ACCESSORS(harmony_new_target); |
| ALLOW_ACCESSORS(strong_mode); |
| ALLOW_ACCESSORS(legacy_const); |
| + ALLOW_ACCESSORS(do_expression_parsing); |
| #undef ALLOW_ACCESSORS |
| + INLINE(bool CheckStackOverflow()) { |
| + if (stack_overflow_) return true; |
| + if (GetCurrentStackPosition() >= stack_limit_) return false; |
| + stack_overflow_ = true; |
| + return true; |
| + } |
| + |
| protected: |
| enum AllowRestrictedIdentifiers { |
| kAllowRestrictedIdentifiers, |
| @@ -683,6 +693,7 @@ class ParserBase : public Traits { |
| ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
| bool* ok); |
| + ExpressionT ParseDoExpression(bool* ok); |
| ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
| ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| bool* is_static, bool* is_computed_name, |
| @@ -841,6 +852,7 @@ class ParserBase : public Traits { |
| bool allow_harmony_new_target_; |
| bool allow_strong_mode_; |
| bool allow_legacy_const_; |
| + bool allow_do_expression_parsing_; |
| }; |
| @@ -1351,6 +1363,12 @@ class PreParserFactory { |
| return PreParserExpression::Default(); |
| } |
| + PreParserExpression NewDoExpression(Scope* scope, |
| + PreParserStatementList statements, |
| + int pos, int end_pos) { |
| + return PreParserExpression::Default(); |
| + } |
| + |
| // Return the object itself as AstVisitor and implement the needed |
| // dummy method right in this class. |
| PreParserFactory* visitor() { return this; } |
| @@ -1704,6 +1722,9 @@ class PreParserTraits { |
| FunctionLiteral::ArityRestriction arity_restriction, |
| LanguageMode language_mode, bool* ok); |
| + inline PreParserStatementList ParseStatementList(Token::Value end_token, |
| + bool* ok); |
| + |
| PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
| Scanner::Location class_name_location, |
| bool name_is_strict_reserved, int pos, |
| @@ -1722,6 +1743,8 @@ class PreParserTraits { |
| PreParserExpressionList args, |
| int pos); |
| + inline void RewriteDoExpression(PreParserExpression expr, bool* ok) {} |
| + |
| private: |
| PreParser* pre_parser_; |
| }; |
| @@ -1925,6 +1948,13 @@ PreParserStatementList PreParserTraits::ParseEagerFunctionBody( |
| } |
| +inline PreParserStatementList PreParserTraits::ParseStatementList( |
| + Token::Value end_token, bool* ok) { |
| + pre_parser_->ParseStatementList(end_token, ok); |
| + return PreParserStatementList(); |
| +} |
| + |
| + |
| template <class Traits> |
| ParserBase<Traits>::FunctionState::FunctionState( |
| FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
| @@ -2222,6 +2252,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
| // ClassLiteral |
| // '(' Expression ')' |
| // TemplateLiteral |
| + // do Block |
| int beg_pos = scanner()->peek_location().beg_pos; |
| int end_pos = scanner()->peek_location().end_pos; |
| @@ -2402,6 +2433,13 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
| result = this->ParseV8Intrinsic(CHECK_OK); |
| break; |
| } |
| + |
| + case Token::DO: |
| + if (token == Token::DO && allow_do_expression_parsing()) { |
| + BindingPatternUnexpectedToken(classifier); |
| + result = this->ParseDoExpression(ok); |
| + break; |
| + } |
| // If we're not allowing special syntax we fall-through to the |
| // default case. |
| @@ -2477,6 +2515,31 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| template <class Traits> |
| +typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseDoExpression( |
| + bool* ok) { |
| + // AssignmentExpression :: |
| + // do '{' StatementList '}' |
| + int pos = peek_position(); |
| + Expect(Token::DO, CHECK_OK); |
| + Expect(Token::LBRACE, CHECK_OK); |
|
rossberg
2015/10/12 13:52:40
Can't you just invoke ParseScopedBlock here?
caitp (gmail)
2015/10/12 18:23:00
Done, sort of.
ParseScopedBlock only exists in th
|
| + Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
| + { |
| + BlockState block_state(&scope_, block_scope); |
| + StatementListT statements = |
| + Traits::ParseStatementList(Token::RBRACE, CHECK_OK); |
| + Expect(Token::RBRACE, CHECK_OK); |
| + int end_pos = scanner()->location().end_pos; |
| + block_scope->set_start_position(pos); |
| + block_scope->set_end_position(end_pos); |
| + ExpressionT expr = |
| + factory()->NewDoExpression(block_scope, statements, pos, end_pos); |
| + Traits::RewriteDoExpression(expr, CHECK_OK); |
| + return expr; |
| + } |
| +} |
| + |
| + |
| +template <class Traits> |
| typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| ExpressionClassifier* classifier, bool* ok) { |
| // ArrayLiteral :: |