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 :: |