Index: src/parsing/parser-base.h |
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h |
index 530ce5aa18e37fad2cad1ef13015731c4889ffa7..6c0d4ab70b14c755be477a41da79577a9e7b5048 100644 |
--- a/src/parsing/parser-base.h |
+++ b/src/parsing/parser-base.h |
@@ -190,6 +190,14 @@ class ParserBase : public Traits { |
Scope* scope; |
}; |
+ struct TailCallExpression { |
+ TailCallExpression(ExpressionT expression, int pos) |
+ : expression(expression), pos(pos) {} |
+ |
+ ExpressionT expression; |
+ int pos; |
+ }; |
+ |
class FunctionState BASE_EMBEDDED { |
public: |
FunctionState(FunctionState** function_state_stack, Scope** scope_stack, |
@@ -247,12 +255,12 @@ class ParserBase : public Traits { |
return destructuring_assignments_to_rewrite_; |
} |
- List<ExpressionT>& expressions_in_tail_position() { |
+ List<TailCallExpression>& expressions_in_tail_position() { |
return expressions_in_tail_position_; |
} |
- void AddExpressionInTailPosition(ExpressionT expression) { |
+ void AddExpressionInTailPosition(ExpressionT expression, int pos) { |
if (collect_expressions_in_tail_position_) { |
- expressions_in_tail_position_.Add(expression); |
+ expressions_in_tail_position_.Add(TailCallExpression(expression, pos)); |
} |
} |
@@ -315,7 +323,7 @@ class ParserBase : public Traits { |
Scope* outer_scope_; |
List<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
- List<ExpressionT> expressions_in_tail_position_; |
+ List<TailCallExpression> expressions_in_tail_position_; |
bool collect_expressions_in_tail_position_; |
ZoneList<ExpressionT> non_patterns_to_rewrite_; |
@@ -334,6 +342,42 @@ class ParserBase : public Traits { |
friend class Checkpoint; |
}; |
+ // This scope disables collecting of expressions at tail call position. |
+ class DontCollectExpressionsInTailPositionScope { |
+ public: |
+ explicit DontCollectExpressionsInTailPositionScope( |
+ FunctionState* function_state) |
+ : function_state_(function_state), |
+ old_value_(function_state->collect_expressions_in_tail_position()) { |
+ function_state->set_collect_expressions_in_tail_position(false); |
+ } |
+ ~DontCollectExpressionsInTailPositionScope() { |
+ function_state_->set_collect_expressions_in_tail_position(old_value_); |
+ } |
+ |
+ private: |
+ FunctionState* function_state_; |
+ bool old_value_; |
+ }; |
+ |
+ // Collects all return expressions at tail call position in this scope |
+ // to a separate list. |
+ class CollectExpressionsInTailPositionToListScope { |
+ public: |
+ CollectExpressionsInTailPositionToListScope(FunctionState* function_state, |
+ List<TailCallExpression>* list) |
+ : function_state_(function_state), list_(list) { |
+ function_state->expressions_in_tail_position().Swap(list_); |
+ } |
+ ~CollectExpressionsInTailPositionToListScope() { |
+ function_state_->expressions_in_tail_position().Swap(list_); |
+ } |
+ |
+ private: |
+ FunctionState* function_state_; |
+ List<TailCallExpression>* list_; |
+ }; |
+ |
// Annoyingly, arrow functions first parse as comma expressions, then when we |
// see the => we have to go back and reinterpret the arguments as being formal |
// parameters. To do so we need to reset some of the parser state back to |
@@ -1892,6 +1936,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
// ArrowFunction |
// YieldExpression |
// LeftHandSideExpression AssignmentOperator AssignmentExpression |
+ // TailCallExpression |
bool is_destructuring_assignment = false; |
int lhs_beg_pos = peek_position(); |
@@ -2858,6 +2903,22 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
// Single-expression body |
int pos = position(); |
ExpressionClassifier classifier(this); |
+ bool is_tail_call_expression; |
+ if (FLAG_harmony_explicit_tailcalls) { |
+ // TODO(ishell): update chapter number. |
+ // ES8 XX.YY.ZZ |
+ if (peek() == Token::CONTINUE) { |
+ Consume(Token::CONTINUE); |
+ pos = position(); |
+ is_tail_call_expression = true; |
+ } else { |
+ is_tail_call_expression = false; |
+ } |
+ } else { |
+ // ES6 14.6.1 Static Semantics: IsInTailPosition |
+ is_tail_call_expression = |
+ allow_tailcalls() && !is_sloppy(language_mode()); |
+ } |
ExpressionT expression = |
ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
Traits::RewriteNonPattern(&classifier, CHECK_OK); |
@@ -2866,8 +2927,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
materialized_literal_count = function_state.materialized_literal_count(); |
expected_property_count = function_state.expected_property_count(); |
- // ES6 14.6.1 Static Semantics: IsInTailPosition |
- if (allow_tailcalls() && !is_sloppy(language_mode())) { |
+ if (is_tail_call_expression) { |
this->MarkTailPosition(expression); |
} |
} |