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

Unified Diff: src/parsing/parser.cc

Issue 1693523002: [es6] More efficient way of marking AST call expressions in tail positions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Removed MarkTail() from Statement Created 4 years, 10 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 cd7691efc6471fb04537166c23331427701f4578..444b20cbf87352cdd4b214938e837c2a7b3b2b52 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -2792,6 +2792,11 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
is_undefined, ThisExpression(scope_, factory(), pos),
is_object_conditional, pos);
}
+
+ // ES6 14.6.1 Static Semantics: IsInTailPosition
+ if (FLAG_harmony_tailcalls && !is_sloppy(language_mode())) {
+ function_state_->AddExpressionInTailPosition(return_value);
+ }
}
ExpectSemicolon(CHECK_OK);
@@ -2997,6 +3002,40 @@ 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 ::
@@ -3013,7 +3052,11 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
Expect(Token::TRY, CHECK_OK);
int pos = position();
- Block* try_block = ParseBlock(NULL, CHECK_OK);
+ Block* try_block;
+ {
+ DontCollectExpressionsInTailPositionScope no_tail_calls(function_state_);
+ try_block = ParseBlock(NULL, CHECK_OK);
+ }
Token::Value tok = peek();
if (tok != Token::CATCH && tok != Token::FINALLY) {
@@ -3025,6 +3068,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;
if (tok == Token::CATCH) {
Consume(Token::CATCH);
@@ -3050,6 +3094,9 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
Expect(Token::RPAREN, CHECK_OK);
{
+ CollectExpressionsInTailPositionToListScope
+ collect_expressions_in_tail_position_scope(
+ function_state_, &expressions_in_tail_position_in_catch_block);
BlockState block_state(&scope_, catch_scope);
// TODO(adamk): Make a version of ParseBlock that takes a scope and
@@ -3124,6 +3171,11 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
TryStatement* result = NULL;
if (catch_block != NULL) {
+ // For a try-catch construct append return expressions from the catch block
+ // to the list of return expressions.
+ function_state_->expressions_in_tail_position().AddAll(
+ expressions_in_tail_position_in_catch_block);
+
DCHECK(finally_block == NULL);
DCHECK(catch_scope != NULL && catch_variable != NULL);
result = factory()->NewTryCatchStatement(try_block, catch_scope,
@@ -4751,11 +4803,11 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
}
// ES6 14.6.1 Static Semantics: IsInTailPosition
- if (FLAG_harmony_tailcalls && !is_sloppy(language_mode())) {
- for (int i = 0; i < body->length(); i++) {
- Statement* stmt = body->at(i);
- stmt->MarkTail();
- }
+ // Mark collected return expressions that are in tail call position.
+ const List<Expression*>& expressions_in_tail_position =
+ function_state_->expressions_in_tail_position();
+ for (int i = 0; i < expressions_in_tail_position.length(); ++i) {
+ expressions_in_tail_position[i]->MarkTail();
}
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