Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(462)

Unified Diff: src/parsing/parser.cc

Issue 1917993004: [es8] Initial set of changes to support syntactic tail calls. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressing comments Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/parser.cc
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
index 6e05fcbb01798e39b4ba719fd1d628552d31e7a7..ea5072e27d7b5c071b0a91ee86db353b3d1e3a31 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -2573,6 +2573,13 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
function_state_->set_return_location(loc);
Token::Value tok = peek();
+ int tail_call_position = -1;
+ if (FLAG_harmony_explicit_tailcalls && tok == Token::CONTINUE) {
+ Consume(Token::CONTINUE);
+ tail_call_position = position();
+ tok = peek();
+ }
+
Statement* result;
Expression* return_value;
if (scanner()->HasAnyLineTerminatorBeforeNext() ||
@@ -2629,9 +2636,21 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
is_object_conditional, pos);
}
- // ES6 14.6.1 Static Semantics: IsInTailPosition
- if (allow_tailcalls() && !is_sloppy(language_mode())) {
- function_state_->AddExpressionInTailPosition(return_value);
+ // TODO(ishell): update chapter number.
+ // ES8 XX.YY.ZZ
+ if (tail_call_position >= 0) {
+ if (!function_state_->collect_expressions_in_tail_position()) {
+ Scanner::Location loc(tail_call_position, tail_call_position + 1);
+ ReportMessageAt(loc, MessageTemplate::kTailCallInTryBlock);
+ *ok = false;
+ return NULL;
+ }
+ function_state_->AddExpressionInTailPosition(return_value,
+ tail_call_position);
+
+ } else if (allow_tailcalls() && !is_sloppy(language_mode())) {
+ // ES6 14.6.1 Static Semantics: IsInTailPosition
+ function_state_->AddExpressionInTailPosition(return_value, pos);
}
}
ExpectSemicolon(CHECK_OK);
@@ -2811,40 +2830,6 @@ Statement* Parser::ParseThrowStatement(bool* ok) {
factory()->NewThrow(exception, pos), pos);
}
-class Parser::DontCollectExpressionsInTailPositionScope {
- public:
- DontCollectExpressionsInTailPositionScope(
- Parser::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:
- Parser::FunctionState* function_state_;
- bool old_value_;
-};
-
-// Collects all return expressions at tail call position in this scope
-// to a separate list.
-class Parser::CollectExpressionsInTailPositionToListScope {
- public:
- CollectExpressionsInTailPositionToListScope(
- Parser::FunctionState* function_state, List<Expression*>* 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:
- Parser::FunctionState* function_state_;
- List<Expression*>* list_;
-};
TryStatement* Parser::ParseTryStatement(bool* ok) {
// TryStatement ::
@@ -2877,7 +2862,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
Scope* catch_scope = NULL;
Variable* catch_variable = NULL;
Block* catch_block = NULL;
- List<Expression*> expressions_in_tail_position_in_catch_block;
+ List<TailCallExpression> expressions_in_tail_position_in_catch_block;
if (tok == Token::CATCH) {
Consume(Token::CATCH);
@@ -2993,6 +2978,16 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
result = factory()->NewTryCatchStatement(try_block, catch_scope,
catch_variable, catch_block, pos);
} else {
+ if (FLAG_harmony_explicit_tailcalls &&
+ expressions_in_tail_position_in_catch_block.length() > 0) {
+ // TODO(ishell): update chapter number.
+ // ES8 XX.YY.ZZ
+ int pos = expressions_in_tail_position_in_catch_block[0].pos;
+ ReportMessageAt(Scanner::Location(pos, pos + 1),
+ MessageTemplate::kTailCallInCatchBlock);
+ *ok = false;
+ return NULL;
+ }
DCHECK(finally_block != NULL);
result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
}
@@ -4573,10 +4568,10 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
// ES6 14.6.1 Static Semantics: IsInTailPosition
// Mark collected return expressions that are in tail call position.
- const List<Expression*>& expressions_in_tail_position =
+ const List<TailCallExpression>& expressions_in_tail_position =
function_state_->expressions_in_tail_position();
for (int i = 0; i < expressions_in_tail_position.length(); ++i) {
- MarkTailPosition(expressions_in_tail_position[i]);
+ MarkTailPosition(expressions_in_tail_position[i].expression);
}
return result;
}
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698