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

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

Issue 2917263002: Move generator-close on exception from the generator function to the GeneratorResume builtin. (Closed)
Patch Set: Add register allocation scope Created 3 years, 6 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/parsing/parser.h ('k') | src/parsing/parser-base.h » ('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 <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 9
10 #include "src/api.h" 10 #include "src/api.h"
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 Token::MUL, expression, factory()->NewNumberLiteral(-1, pos), pos); 345 Token::MUL, expression, factory()->NewNumberLiteral(-1, pos), pos);
346 } 346 }
347 // ...and one more time for '~foo' => 'foo^(~0)'. 347 // ...and one more time for '~foo' => 'foo^(~0)'.
348 if (op == Token::BIT_NOT) { 348 if (op == Token::BIT_NOT) {
349 return factory()->NewBinaryOperation( 349 return factory()->NewBinaryOperation(
350 Token::BIT_XOR, expression, factory()->NewNumberLiteral(~0, pos), pos); 350 Token::BIT_XOR, expression, factory()->NewNumberLiteral(~0, pos), pos);
351 } 351 }
352 return factory()->NewUnaryOperation(op, expression, pos); 352 return factory()->NewUnaryOperation(op, expression, pos);
353 } 353 }
354 354
355 Expression* Parser::BuildIteratorResult(Expression* value, bool done) {
356 int pos = kNoSourcePosition;
357
358 if (value == nullptr) value = factory()->NewUndefinedLiteral(pos);
359
360 auto args = new (zone()) ZoneList<Expression*>(2, zone());
361 args->Add(value, zone());
362 args->Add(factory()->NewBooleanLiteral(done, pos), zone());
363
364 return factory()->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args,
365 pos);
366 }
367
368 Expression* Parser::NewThrowError(Runtime::FunctionId id, 355 Expression* Parser::NewThrowError(Runtime::FunctionId id,
369 MessageTemplate::Template message, 356 MessageTemplate::Template message,
370 const AstRawString* arg, int pos) { 357 const AstRawString* arg, int pos) {
371 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 358 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
372 args->Add(factory()->NewSmiLiteral(message, pos), zone()); 359 args->Add(factory()->NewSmiLiteral(message, pos), zone());
373 args->Add(factory()->NewStringLiteral(arg, pos), zone()); 360 args->Add(factory()->NewStringLiteral(arg, pos), zone());
374 CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos); 361 CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
375 return factory()->NewThrow(call_constructor, pos); 362 return factory()->NewThrow(call_constructor, pos);
376 } 363 }
377 364
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1771 catch_block, pos); 1758 catch_block, pos);
1772 } else { 1759 } else {
1773 DCHECK_NOT_NULL(finally_block); 1760 DCHECK_NOT_NULL(finally_block);
1774 return factory()->NewTryFinallyStatement(try_block, finally_block, pos); 1761 return factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1775 } 1762 }
1776 } 1763 }
1777 1764
1778 void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind, 1765 void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
1779 ZoneList<Statement*>* body, 1766 ZoneList<Statement*>* body,
1780 bool* ok) { 1767 bool* ok) {
1781 // For ES6 Generators, we produce: 1768 // For ES6 Generators, we just prepend the initial yield.
1782 // 1769 Expression* initial_yield = BuildInitialYield(pos, kind);
1783 // try { InitialYield; ...body...; return {value: undefined, done: true} } 1770 body->Add(factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1784 // finally { %_GeneratorClose(generator) } 1771 zone());
1785 // 1772 ParseStatementList(body, Token::RBRACE, ok);
1773 }
1774
1775 void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1776 int pos, FunctionKind kind, ZoneList<Statement*>* body, bool* ok) {
1786 // For ES2017 Async Generators, we produce: 1777 // For ES2017 Async Generators, we produce:
1787 // 1778 //
1788 // try { 1779 // try {
1789 // InitialYield; 1780 // InitialYield;
1790 // ...body...; 1781 // ...body...;
1791 // return undefined; // See comment below 1782 // return undefined; // See comment below
1792 // } catch (.catch) { 1783 // } catch (.catch) {
1793 // %AsyncGeneratorReject(generator, .catch); 1784 // %AsyncGeneratorReject(generator, .catch);
1794 // } finally { 1785 // } finally {
1795 // %_GeneratorClose(generator); 1786 // %_GeneratorClose(generator);
1796 // } 1787 // }
1797 // 1788 //
1798 // - InitialYield yields the actual generator object. 1789 // - InitialYield yields the actual generator object.
1799 // - Any return statement inside the body will have its argument wrapped 1790 // - Any return statement inside the body will have its argument wrapped
1800 // in an iterator result object with a "done" property set to `true`. 1791 // in an iterator result object with a "done" property set to `true`.
1801 // - If the generator terminates for whatever reason, we must close it. 1792 // - If the generator terminates for whatever reason, we must close it.
1802 // Hence the finally clause. 1793 // Hence the finally clause.
1803 // - BytecodeGenerator performs special handling for ReturnStatements in 1794 // - BytecodeGenerator performs special handling for ReturnStatements in
1804 // async generator functions, resolving the appropriate Promise with an 1795 // async generator functions, resolving the appropriate Promise with an
1805 // "done" iterator result object containing a Promise-unwrapped value. 1796 // "done" iterator result object containing a Promise-unwrapped value.
1797 DCHECK(IsAsyncGeneratorFunction(kind));
1806 1798
1807 Block* try_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition); 1799 Block* try_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
1808 Expression* initial_yield = BuildInitialYield(pos, kind); 1800 Expression* initial_yield = BuildInitialYield(pos, kind);
1809 try_block->statements()->Add( 1801 try_block->statements()->Add(
1810 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), 1802 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1811 zone()); 1803 zone());
1812 ParseStatementList(try_block->statements(), Token::RBRACE, ok); 1804 ParseStatementList(try_block->statements(), Token::RBRACE, ok);
1813 if (!*ok) return; 1805 if (!*ok) return;
1814 1806
1815 if (IsAsyncGeneratorFunction(kind)) { 1807 // Don't create iterator result for async generators, as the resume methods
1816 // Don't create iterator result for async generators, as the resume methods 1808 // will create it.
1817 // will create it. 1809 Statement* final_return = BuildReturnStatement(
1818 Statement* final_return = BuildReturnStatement( 1810 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
1819 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition); 1811 try_block->statements()->Add(final_return, zone());
1820 try_block->statements()->Add(final_return, zone());
1821 1812
1822 // For AsyncGenerators, a top-level catch block will reject the Promise. 1813 // For AsyncGenerators, a top-level catch block will reject the Promise.
1823 Scope* catch_scope = NewHiddenCatchScopeWithParent(scope()); 1814 Scope* catch_scope = NewHiddenCatchScopeWithParent(scope());
1824 1815
1825 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 1816 ZoneList<Expression*>* reject_args =
1826 args->Add(factory()->NewVariableProxy( 1817 new (zone()) ZoneList<Expression*>(2, zone());
1827 function_state_->generator_object_variable()), 1818 reject_args->Add(
1828 zone()); 1819 factory()->NewVariableProxy(function_state_->generator_object_variable()),
1829 args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()), 1820 zone());
1830 zone()); 1821 reject_args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
1822 zone());
1831 1823
1832 Expression* call = factory()->NewCallRuntime( 1824 Expression* reject_call = factory()->NewCallRuntime(
1833 Runtime::kInlineAsyncGeneratorReject, args, kNoSourcePosition); 1825 Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
1834 Block* catch_block = IgnoreCompletion( 1826 Block* catch_block = IgnoreCompletion(
1835 factory()->NewReturnStatement(call, kNoSourcePosition)); 1827 factory()->NewReturnStatement(reject_call, kNoSourcePosition));
1836 1828
1837 TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait( 1829 TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
1838 try_block, catch_scope, catch_block, kNoSourcePosition); 1830 try_block, catch_scope, catch_block, kNoSourcePosition);
1839 1831
1840 try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 1832 try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1841 try_block->statements()->Add(try_catch, zone()); 1833 try_block->statements()->Add(try_catch, zone());
1842 } else {
1843 Statement* final_return = factory()->NewReturnStatement(
1844 BuildIteratorResult(nullptr, true), kNoSourcePosition);
1845 try_block->statements()->Add(final_return, zone());
1846 }
1847 1834
1848 Block* finally_block = 1835 Block* finally_block =
1849 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 1836 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1850 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 1837 ZoneList<Expression*>* close_args =
1838 new (zone()) ZoneList<Expression*>(1, zone());
1851 VariableProxy* call_proxy = 1839 VariableProxy* call_proxy =
1852 factory()->NewVariableProxy(function_state_->generator_object_variable()); 1840 factory()->NewVariableProxy(function_state_->generator_object_variable());
1853 args->Add(call_proxy, zone()); 1841 close_args->Add(call_proxy, zone());
1854 Expression* call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose, 1842 Expression* close_call = factory()->NewCallRuntime(
1855 args, kNoSourcePosition); 1843 Runtime::kInlineGeneratorClose, close_args, kNoSourcePosition);
1856 finally_block->statements()->Add( 1844 finally_block->statements()->Add(
1857 factory()->NewExpressionStatement(call, kNoSourcePosition), zone()); 1845 factory()->NewExpressionStatement(close_call, kNoSourcePosition), zone());
1858 1846
1859 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block, 1847 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1860 kNoSourcePosition), 1848 kNoSourcePosition),
1861 zone()); 1849 zone());
1862 } 1850 }
1863 1851
1864 void Parser::CreateFunctionNameAssignment( 1852 void Parser::CreateFunctionNameAssignment(
1865 const AstRawString* function_name, int pos, 1853 const AstRawString* function_name, int pos,
1866 FunctionLiteral::FunctionType function_type, 1854 FunctionLiteral::FunctionType function_type,
1867 DeclarationScope* function_scope, ZoneList<Statement*>* result, int index) { 1855 DeclarationScope* function_scope, ZoneList<Statement*>* result, int index) {
(...skipping 3248 matching lines...) Expand 10 before | Expand all | Expand 10 after
5116 literal->SetShouldEagerCompile(); 5104 literal->SetShouldEagerCompile();
5117 } 5105 }
5118 } 5106 }
5119 5107
5120 #undef CHECK_OK 5108 #undef CHECK_OK
5121 #undef CHECK_OK_VOID 5109 #undef CHECK_OK_VOID
5122 #undef CHECK_FAILED 5110 #undef CHECK_FAILED
5123 5111
5124 } // namespace internal 5112 } // namespace internal
5125 } // namespace v8 5113 } // namespace v8
OLDNEW
« 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