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

Side by Side Diff: src/parsing/parser.cc

Issue 2348403003: Revert of Fix async/await memory leak (Closed)
Patch Set: Created 4 years, 3 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 unified diff | Download patch
« no previous file with comments | « src/js/harmony-async-await.js ('k') | test/mjsunit/harmony/async-await-loop.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.h" 10 #include "src/ast/ast-expression-rewriter.h"
(...skipping 4542 matching lines...) Expand 10 before | Expand all | Expand 10 after
4553 Expression* expr = args->at(0); 4553 Expression* expr = args->at(0);
4554 for (int i = 1; i < args->length(); ++i) { 4554 for (int i = 1; i < args->length(); ++i) {
4555 expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i), 4555 expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
4556 expr->position()); 4556 expr->position());
4557 } 4557 }
4558 return expr; 4558 return expr;
4559 } 4559 }
4560 4560
4561 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) { 4561 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
4562 // yield do { 4562 // yield do {
4563 // promise_tmp = .promise;
4564 // tmp = <operand>; 4563 // tmp = <operand>;
4565 // %AsyncFunctionAwait(.generator_object, tmp); 4564 // tmp = %AsyncFunctionAwait(.generator_object, tmp);
4566 // promise_tmp
4567 // } 4565 // }
4568 // The value of the expression is returned to the caller of the async
4569 // function for the first yield statement; for this, .promise is the
4570 // appropriate return value, being a Promise that will be fulfilled or
4571 // rejected with the appropriate value by the desugaring. Subsequent yield
4572 // occurrences will return to the AsyncFunctionNext call within the
4573 // implemementation of the intermediate throwaway Promise's then handler.
4574 // This handler has nothing useful to do with the value, as the Promise is
4575 // ignored. If we yielded the value of the throwawayPromise that
4576 // AsyncFunctionAwait creates as an intermediate, it would create a memory
4577 // leak; we must return .promise instead;
4578 // The operand needs to be evaluated on a separate statement in order to get
4579 // a break location, and the .promise needs to be read earlier so that it
4580 // doesn't insert a false location.
4581 // TODO(littledan): investigate why this ordering is needed in more detail.
4582 Variable* generator_object_variable = 4566 Variable* generator_object_variable =
4583 function_state_->generator_object_variable(); 4567 function_state_->generator_object_variable();
4584 4568
4585 // If generator_object_variable is null, 4569 // If generator_object_variable is null,
4586 // TODO(littledan): Is this necessary?
4587 if (!generator_object_variable) return value; 4570 if (!generator_object_variable) return value;
4588 4571
4589 const int nopos = kNoSourcePosition; 4572 const int nopos = kNoSourcePosition;
4590 4573
4591 Block* do_block = factory()->NewBlock(nullptr, 3, false, nopos); 4574 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
4592 4575 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
4593 Variable* promise_temp_var =
4594 NewTemporary(ast_value_factory()->empty_string());
4595 Expression* promise_assignment = factory()->NewAssignment(
4596 Token::ASSIGN, factory()->NewVariableProxy(promise_temp_var),
4597 BuildDotPromise(), nopos);
4598 do_block->statements()->Add(
4599 factory()->NewExpressionStatement(promise_assignment, nopos), zone());
4600 4576
4601 // Wrap value evaluation to provide a break location. 4577 // Wrap value evaluation to provide a break location.
4602 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
4603 Expression* value_assignment = factory()->NewAssignment( 4578 Expression* value_assignment = factory()->NewAssignment(
4604 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); 4579 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos);
4605 do_block->statements()->Add( 4580 do_block->statements()->Add(
4606 factory()->NewExpressionStatement(value_assignment, value->position()), 4581 factory()->NewExpressionStatement(value_assignment, value->position()),
4607 zone()); 4582 zone());
4608 4583
4609 ZoneList<Expression*>* async_function_await_args = 4584 ZoneList<Expression*>* async_function_await_args =
4610 new (zone()) ZoneList<Expression*>(2, zone()); 4585 new (zone()) ZoneList<Expression*>(2, zone());
4611 Expression* generator_object = 4586 Expression* generator_object =
4612 factory()->NewVariableProxy(generator_object_variable); 4587 factory()->NewVariableProxy(generator_object_variable);
4613 async_function_await_args->Add(generator_object, zone()); 4588 async_function_await_args->Add(generator_object, zone());
4614 async_function_await_args->Add(factory()->NewVariableProxy(temp_var), zone()); 4589 async_function_await_args->Add(factory()->NewVariableProxy(temp_var), zone());
4615 4590
4616 // The parser emits calls to AsyncFunctionAwaitCaught, but the 4591 // The parser emits calls to AsyncFunctionAwaitCaught, but the
4617 // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught 4592 // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught
4618 // if there is no local enclosing try/catch block. 4593 // if there is no local enclosing try/catch block.
4619 Expression* async_function_await = 4594 Expression* async_function_await =
4620 factory()->NewCallRuntime(Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX, 4595 factory()->NewCallRuntime(Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX,
4621 async_function_await_args, nopos); 4596 async_function_await_args, nopos);
4622 do_block->statements()->Add(
4623 factory()->NewExpressionStatement(async_function_await, await_pos),
4624 zone());
4625 4597
4626 // Wrap await to provide a break location between value evaluation and yield. 4598 // Wrap await to provide a break location between value evaluation and yield.
4627 Expression* do_expr = 4599 Expression* await_assignment = factory()->NewAssignment(
4628 factory()->NewDoExpression(do_block, promise_temp_var, nopos); 4600 Token::ASSIGN, factory()->NewVariableProxy(temp_var),
4601 async_function_await, nopos);
4602 do_block->statements()->Add(
4603 factory()->NewExpressionStatement(await_assignment, await_pos), zone());
4604 Expression* do_expr = factory()->NewDoExpression(do_block, temp_var, nopos);
4629 4605
4630 generator_object = factory()->NewVariableProxy(generator_object_variable); 4606 generator_object = factory()->NewVariableProxy(generator_object_variable);
4631 return factory()->NewYield(generator_object, do_expr, nopos, 4607 return factory()->NewYield(generator_object, do_expr, nopos,
4632 Yield::kOnExceptionRethrow); 4608 Yield::kOnExceptionRethrow);
4633 } 4609 }
4634 4610
4635 class NonPatternRewriter : public AstExpressionRewriter { 4611 class NonPatternRewriter : public AstExpressionRewriter {
4636 public: 4612 public:
4637 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) 4613 NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
4638 : AstExpressionRewriter(stack_limit), parser_(parser) {} 4614 : AstExpressionRewriter(stack_limit), parser_(parser) {}
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after
5832 node->Print(Isolate::Current()); 5808 node->Print(Isolate::Current());
5833 } 5809 }
5834 #endif // DEBUG 5810 #endif // DEBUG
5835 5811
5836 #undef CHECK_OK 5812 #undef CHECK_OK
5837 #undef CHECK_OK_VOID 5813 #undef CHECK_OK_VOID
5838 #undef CHECK_FAILED 5814 #undef CHECK_FAILED
5839 5815
5840 } // namespace internal 5816 } // namespace internal
5841 } // namespace v8 5817 } // namespace v8
OLDNEW
« no previous file with comments | « src/js/harmony-async-await.js ('k') | test/mjsunit/harmony/async-await-loop.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698