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

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

Issue 2654423004: [async-functions] support await expressions in finally statements (Closed)
Patch Set: I'd like to build with -Wunused-variables locally, but how!? Created 3 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 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 <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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 408
409 Expression* Parser::NewTargetExpression(int pos) { 409 Expression* Parser::NewTargetExpression(int pos) {
410 auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos); 410 auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
411 proxy->set_is_new_target(); 411 proxy->set_is_new_target();
412 return proxy; 412 return proxy;
413 } 413 }
414 414
415 Expression* Parser::FunctionSentExpression(int pos) { 415 Expression* Parser::FunctionSentExpression(int pos) {
416 // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator). 416 // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
417 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 417 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
418 VariableProxy* generator = 418 InternalVariable* generator =
419 factory()->NewVariableProxy(function_state_->generator_object_variable()); 419 factory()->NewInternalVariable(InternalVariable::kGeneratorObject);
420 args->Add(generator, zone()); 420 args->Add(generator, zone());
421 return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, 421 return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
422 args, pos); 422 args, pos);
423 } 423 }
424 424
425 Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) { 425 Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
426 switch (token) { 426 switch (token) {
427 case Token::NULL_LITERAL: 427 case Token::NULL_LITERAL:
428 return factory()->NewNullLiteral(pos); 428 return factory()->NewNullLiteral(pos);
429 case Token::TRUE_LITERAL: 429 case Token::TRUE_LITERAL:
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 // Declare the special module parameter. 690 // Declare the special module parameter.
691 auto name = ast_value_factory()->empty_string(); 691 auto name = ast_value_factory()->empty_string();
692 bool is_duplicate; 692 bool is_duplicate;
693 bool is_rest = false; 693 bool is_rest = false;
694 bool is_optional = false; 694 bool is_optional = false;
695 auto var = scope->DeclareParameter(name, VAR, is_optional, is_rest, 695 auto var = scope->DeclareParameter(name, VAR, is_optional, is_rest,
696 &is_duplicate, ast_value_factory()); 696 &is_duplicate, ast_value_factory());
697 DCHECK(!is_duplicate); 697 DCHECK(!is_duplicate);
698 var->AllocateTo(VariableLocation::PARAMETER, 0); 698 var->AllocateTo(VariableLocation::PARAMETER, 0);
699 699
700 PrepareGeneratorVariables(); 700 scope->ForceContextAllocation();
701 Expression* initial_yield =
702 BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
703 body->Add(
704 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
705 zone());
706
707 ParseModuleItemList(body, &ok); 701 ParseModuleItemList(body, &ok);
708 ok = ok && 702 ok = ok &&
709 module()->Validate(this->scope()->AsModuleScope(), 703 module()->Validate(this->scope()->AsModuleScope(),
710 &pending_error_handler_, zone()); 704 &pending_error_handler_, zone());
711 } else { 705 } else {
712 // Don't count the mode in the use counters--give the program a chance 706 // Don't count the mode in the use counters--give the program a chance
713 // to enable script-wide strict mode below. 707 // to enable script-wide strict mode below.
714 this->scope()->SetLanguageMode(info->language_mode()); 708 this->scope()->SetLanguageMode(info->language_mode());
715 ParseStatementList(body, Token::EOS, &ok); 709 ParseStatementList(body, Token::EOS, &ok);
716 } 710 }
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 Expression* is_undefined = factory()->NewCompareOperation( 1593 Expression* is_undefined = factory()->NewCompareOperation(
1600 Token::EQ_STRICT, assign, 1594 Token::EQ_STRICT, assign,
1601 factory()->NewUndefinedLiteral(kNoSourcePosition), pos); 1595 factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1602 1596
1603 // is_undefined ? this : is_object_conditional 1597 // is_undefined ? this : is_object_conditional
1604 return_value = factory()->NewConditional(is_undefined, ThisExpression(pos), 1598 return_value = factory()->NewConditional(is_undefined, ThisExpression(pos),
1605 is_object_conditional, pos); 1599 is_object_conditional, pos);
1606 } 1600 }
1607 if (is_generator()) { 1601 if (is_generator()) {
1608 return_value = BuildIteratorResult(return_value, true); 1602 return_value = BuildIteratorResult(return_value, true);
1609 } else if (is_async_function()) {
1610 return_value = BuildResolvePromise(return_value, return_value->position());
1611 } 1603 }
1612 return return_value; 1604 return return_value;
1613 } 1605 }
1614 1606
1615 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) { 1607 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
1616 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); 1608 Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
1617 DoExpression* expr = factory()->NewDoExpression(body, result, pos); 1609 DoExpression* expr = factory()->NewDoExpression(body, result, pos);
1618 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { 1610 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
1619 *ok = false; 1611 *ok = false;
1620 return nullptr; 1612 return nullptr;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 DCHECK_NOT_NULL(catch_info.scope); 1739 DCHECK_NOT_NULL(catch_info.scope);
1748 DCHECK_NOT_NULL(catch_info.variable); 1740 DCHECK_NOT_NULL(catch_info.variable);
1749 return factory()->NewTryCatchStatement( 1741 return factory()->NewTryCatchStatement(
1750 try_block, catch_info.scope, catch_info.variable, catch_block, pos); 1742 try_block, catch_info.scope, catch_info.variable, catch_block, pos);
1751 } else { 1743 } else {
1752 DCHECK_NOT_NULL(finally_block); 1744 DCHECK_NOT_NULL(finally_block);
1753 return factory()->NewTryFinallyStatement(try_block, finally_block, pos); 1745 return factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1754 } 1746 }
1755 } 1747 }
1756 1748
1757 void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind, 1749 void Parser::CreateFunctionNameVariable(
1758 ZoneList<Statement*>* body,
1759 bool* ok) {
1760 // We produce:
1761 //
1762 // try { InitialYield; ...body...; return {value: undefined, done: true} }
1763 // finally { %_GeneratorClose(generator) }
1764 //
1765 // - InitialYield yields the actual generator object.
1766 // - Any return statement inside the body will have its argument wrapped
1767 // in a "done" iterator result object.
1768 // - If the generator terminates for whatever reason, we must close it.
1769 // Hence the finally clause.
1770
1771 Block* try_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
1772 Expression* initial_yield = BuildInitialYield(pos, kind);
1773 try_block->statements()->Add(
1774 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1775 zone());
1776 ParseStatementList(try_block->statements(), Token::RBRACE, ok);
1777 if (!*ok) return;
1778
1779 Statement* final_return = factory()->NewReturnStatement(
1780 BuildIteratorResult(nullptr, true), kNoSourcePosition);
1781 try_block->statements()->Add(final_return, zone());
1782
1783 Block* finally_block =
1784 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1785 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
1786 VariableProxy* call_proxy =
1787 factory()->NewVariableProxy(function_state_->generator_object_variable());
1788 args->Add(call_proxy, zone());
1789 Expression* call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose,
1790 args, kNoSourcePosition);
1791 finally_block->statements()->Add(
1792 factory()->NewExpressionStatement(call, kNoSourcePosition), zone());
1793
1794 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1795 kNoSourcePosition),
1796 zone());
1797 }
1798
1799 void Parser::CreateFunctionNameAssignment(
1800 const AstRawString* function_name, int pos, 1750 const AstRawString* function_name, int pos,
1801 FunctionLiteral::FunctionType function_type, 1751 FunctionLiteral::FunctionType function_type,
1802 DeclarationScope* function_scope, ZoneList<Statement*>* result, int index) { 1752 DeclarationScope* function_scope) {
1803 if (function_type == FunctionLiteral::kNamedExpression) { 1753 if (function_type == FunctionLiteral::kNamedExpression) {
1804 StatementT statement = factory()->NewEmptyStatement(kNoSourcePosition);
1805 if (function_scope->LookupLocal(function_name) == nullptr) { 1754 if (function_scope->LookupLocal(function_name) == nullptr) {
1806 // Now that we know the language mode, we can create the const assignment 1755 // Now that we know the language mode, we can create the const assignment
1807 // in the previously reserved spot. 1756 // in the previously reserved spot.
1808 DCHECK_EQ(function_scope, scope()); 1757 DCHECK_EQ(function_scope, scope());
1809 Variable* fvar = function_scope->DeclareFunctionVar(function_name); 1758 Variable* fvar = function_scope->DeclareFunctionVar(function_name);
1810 VariableProxy* fproxy = factory()->NewVariableProxy(fvar); 1759 DCHECK_NOT_NULL(fvar);
1811 statement = factory()->NewExpressionStatement( 1760
1812 factory()->NewAssignment(Token::INIT, fproxy, 1761 // Ensure the variable is allocated if any inner scope _may_ use it.
1813 factory()->NewThisFunction(pos), 1762 // Otherwise, lazily parsed
1814 kNoSourcePosition), 1763 if (function_scope->calls_eval() ||
1815 kNoSourcePosition); 1764 function_scope->inner_scope_calls_eval() ||
1765 function_scope->HasLazilyParsedInnerFunctionScope()) {
1766 fvar->set_is_used();
1767 return;
1768 }
1816 } 1769 }
1817 result->Set(index, statement);
1818 } 1770 }
1819 } 1771 }
1820 1772
1821 // !%_IsJSReceiver(result = iterator.next()) && 1773 // !%_IsJSReceiver(result = iterator.next()) &&
1822 // %ThrowIteratorResultNotAnObject(result) 1774 // %ThrowIteratorResultNotAnObject(result)
1823 Expression* Parser::BuildIteratorNextResult(Expression* iterator, 1775 Expression* Parser::BuildIteratorNextResult(Expression* iterator,
1824 Variable* result, int pos) { 1776 Variable* result, int pos) {
1825 Expression* next_literal = factory()->NewStringLiteral( 1777 Expression* next_literal = factory()->NewStringLiteral(
1826 ast_value_factory()->next_string(), kNoSourcePosition); 1778 ast_value_factory()->next_string(), kNoSourcePosition);
1827 Expression* next_property = 1779 Expression* next_property =
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 } 2408 }
2457 DeclareFormalParameters(parameters->scope, parameters->params); 2409 DeclareFormalParameters(parameters->scope, parameters->params);
2458 if (!this->classifier() 2410 if (!this->classifier()
2459 ->is_valid_formal_parameter_list_without_duplicates()) { 2411 ->is_valid_formal_parameter_list_without_duplicates()) {
2460 *duplicate_loc = 2412 *duplicate_loc =
2461 this->classifier()->duplicate_formal_parameter_error().location; 2413 this->classifier()->duplicate_formal_parameter_error().location;
2462 } 2414 }
2463 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters()); 2415 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
2464 } 2416 }
2465 2417
2466 void Parser::PrepareGeneratorVariables() {
2467 // For generators, allocating variables in contexts is currently a win because
2468 // it minimizes the work needed to suspend and resume an activation. The
2469 // code produced for generators relies on this forced context allocation (it
2470 // does not restore the frame's parameters upon resume).
2471 function_state_->scope()->ForceContextAllocation();
2472
2473 // Calling a generator returns a generator object. That object is stored
2474 // in a temporary variable, a definition that is used by "yield"
2475 // expressions.
2476 Variable* temp =
2477 NewTemporary(ast_value_factory()->dot_generator_object_string());
2478 function_state_->set_generator_object_variable(temp);
2479 }
2480
2481 FunctionLiteral* Parser::ParseFunctionLiteral( 2418 FunctionLiteral* Parser::ParseFunctionLiteral(
2482 const AstRawString* function_name, Scanner::Location function_name_location, 2419 const AstRawString* function_name, Scanner::Location function_name_location,
2483 FunctionNameValidity function_name_validity, FunctionKind kind, 2420 FunctionNameValidity function_name_validity, FunctionKind kind,
2484 int function_token_pos, FunctionLiteral::FunctionType function_type, 2421 int function_token_pos, FunctionLiteral::FunctionType function_type,
2485 LanguageMode language_mode, bool* ok) { 2422 LanguageMode language_mode, bool* ok) {
2486 // Function :: 2423 // Function ::
2487 // '(' FormalParameterList? ')' '{' FunctionBody '}' 2424 // '(' FormalParameterList? ')' '{' FunctionBody '}'
2488 // 2425 //
2489 // Getter :: 2426 // Getter ::
2490 // '(' ')' '{' FunctionBody '}' 2427 // '(' ')' '{' FunctionBody '}'
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2585 2522
2586 DCHECK_IMPLIES( 2523 DCHECK_IMPLIES(
2587 (is_lazy_top_level_function || 2524 (is_lazy_top_level_function ||
2588 (parse_lazily() && function_type == FunctionLiteral::kDeclaration && 2525 (parse_lazily() && function_type == FunctionLiteral::kDeclaration &&
2589 eager_compile_hint == FunctionLiteral::kShouldLazyCompile)), 2526 eager_compile_hint == FunctionLiteral::kShouldLazyCompile)),
2590 can_preparse); 2527 can_preparse);
2591 bool is_lazy_inner_function = 2528 bool is_lazy_inner_function =
2592 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function; 2529 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function;
2593 2530
2594 ZoneList<Statement*>* body = nullptr; 2531 ZoneList<Statement*>* body = nullptr;
2532 Block* parameter_init_block = nullptr;
2595 int materialized_literal_count = -1; 2533 int materialized_literal_count = -1;
2596 int expected_property_count = -1; 2534 int expected_property_count = -1;
2597 bool should_be_used_once_hint = false; 2535 bool should_be_used_once_hint = false;
2598 int num_parameters = -1; 2536 int num_parameters = -1;
2599 int function_length = -1; 2537 int function_length = -1;
2600 bool has_duplicate_parameters = false; 2538 bool has_duplicate_parameters = false;
2601 int function_literal_id = GetNextFunctionLiteralId(); 2539 int function_literal_id = GetNextFunctionLiteralId();
2602 2540
2603 Zone* outer_zone = zone(); 2541 Zone* outer_zone = zone();
2604 DeclarationScope* scope; 2542 DeclarationScope* scope;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2656 should_be_used_once_hint = true; 2594 should_be_used_once_hint = true;
2657 scope->ResetAfterPreparsing(ast_value_factory(), true); 2595 scope->ResetAfterPreparsing(ast_value_factory(), true);
2658 zone_scope.Reset(); 2596 zone_scope.Reset();
2659 use_temp_zone = false; 2597 use_temp_zone = false;
2660 } 2598 }
2661 } 2599 }
2662 2600
2663 if (!is_lazy_top_level_function && !is_lazy_inner_function) { 2601 if (!is_lazy_top_level_function && !is_lazy_inner_function) {
2664 body = ParseFunction( 2602 body = ParseFunction(
2665 function_name, pos, kind, function_type, scope, &num_parameters, 2603 function_name, pos, kind, function_type, scope, &num_parameters,
2666 &function_length, &has_duplicate_parameters, 2604 &parameter_init_block, &function_length, &has_duplicate_parameters,
2667 &materialized_literal_count, &expected_property_count, CHECK_OK); 2605 &materialized_literal_count, &expected_property_count, CHECK_OK);
2668 } 2606 }
2669 2607
2670 DCHECK(use_temp_zone || !is_lazy_top_level_function); 2608 DCHECK(use_temp_zone || !is_lazy_top_level_function);
2671 if (use_temp_zone) { 2609 if (use_temp_zone) {
2672 // If the preconditions are correct the function body should never be 2610 // If the preconditions are correct the function body should never be
2673 // accessed, but do this anyway for better behaviour if they're wrong. 2611 // accessed, but do this anyway for better behaviour if they're wrong.
2674 body = nullptr; 2612 body = nullptr;
2675 scope->AnalyzePartially(&previous_zone_ast_node_factory, 2613 scope->AnalyzePartially(&previous_zone_ast_node_factory,
2676 preparsed_scope_data_); 2614 preparsed_scope_data_);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2718 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 2656 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2719 : FunctionLiteral::kNoDuplicateParameters; 2657 : FunctionLiteral::kNoDuplicateParameters;
2720 2658
2721 // Note that the FunctionLiteral needs to be created in the main Zone again. 2659 // Note that the FunctionLiteral needs to be created in the main Zone again.
2722 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 2660 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2723 function_name, scope, body, materialized_literal_count, 2661 function_name, scope, body, materialized_literal_count,
2724 expected_property_count, num_parameters, function_length, 2662 expected_property_count, num_parameters, function_length,
2725 duplicate_parameters, function_type, eager_compile_hint, pos, true, 2663 duplicate_parameters, function_type, eager_compile_hint, pos, true,
2726 function_literal_id); 2664 function_literal_id);
2727 function_literal->set_function_token_position(function_token_pos); 2665 function_literal->set_function_token_position(function_token_pos);
2666 function_literal->set_parameter_init_block(parameter_init_block);
2728 if (should_be_used_once_hint) 2667 if (should_be_used_once_hint)
2729 function_literal->set_should_be_used_once_hint(); 2668 function_literal->set_should_be_used_once_hint();
2730 2669
2731 if (should_infer_name) { 2670 if (should_infer_name) {
2732 DCHECK_NOT_NULL(fni_); 2671 DCHECK_NOT_NULL(fni_);
2733 fni_->AddFunction(function_literal); 2672 fni_->AddFunction(function_literal);
2734 } 2673 }
2735 return function_literal; 2674 return function_literal;
2736 } 2675 }
2737 2676
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2965 if (param_scope != nullptr) { 2904 if (param_scope != nullptr) {
2966 CheckConflictingVarDeclarations(param_scope, CHECK_OK); 2905 CheckConflictingVarDeclarations(param_scope, CHECK_OK);
2967 } 2906 }
2968 init_block->statements()->Add(param_block, zone()); 2907 init_block->statements()->Add(param_block, zone());
2969 } 2908 }
2970 ++index; 2909 ++index;
2971 } 2910 }
2972 return init_block; 2911 return init_block;
2973 } 2912 }
2974 2913
2975 Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2976 // .promise = %AsyncFunctionPromiseCreate();
2977 // try {
2978 // <inner_block>
2979 // } catch (.catch) {
2980 // %RejectPromise(.promise, .catch);
2981 // return .promise;
2982 // } finally {
2983 // %AsyncFunctionPromiseRelease(.promise);
2984 // }
2985 Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition);
2986
2987 // .promise = %AsyncFunctionPromiseCreate();
2988 Statement* set_promise;
2989 {
2990 Expression* create_promise = factory()->NewCallRuntime(
2991 Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
2992 new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
2993 Assignment* assign_promise = factory()->NewAssignment(
2994 Token::INIT, factory()->NewVariableProxy(PromiseVariable()),
2995 create_promise, kNoSourcePosition);
2996 set_promise =
2997 factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
2998 }
2999 result->statements()->Add(set_promise, zone());
3000
3001 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
3002 Scope* catch_scope = NewScope(CATCH_SCOPE);
3003 catch_scope->set_is_hidden();
3004 Variable* catch_variable =
3005 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
3006 Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3007
3008 Expression* promise_reject = BuildRejectPromise(
3009 factory()->NewVariableProxy(catch_variable), kNoSourcePosition);
3010 ReturnStatement* return_promise_reject =
3011 factory()->NewReturnStatement(promise_reject, kNoSourcePosition);
3012 catch_block->statements()->Add(return_promise_reject, zone());
3013
3014 TryStatement* try_catch_statement =
3015 factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope,
3016 catch_variable, catch_block,
3017 kNoSourcePosition);
3018
3019 // There is no TryCatchFinally node, so wrap it in an outer try/finally
3020 Block* outer_try_block =
3021 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3022 outer_try_block->statements()->Add(try_catch_statement, zone());
3023
3024 // finally { %AsyncFunctionPromiseRelease(.promise) }
3025 Block* finally_block =
3026 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3027 {
3028 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3029 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3030 Expression* call_promise_release = factory()->NewCallRuntime(
3031 Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
3032 Statement* promise_release = factory()->NewExpressionStatement(
3033 call_promise_release, kNoSourcePosition);
3034 finally_block->statements()->Add(promise_release, zone());
3035 }
3036
3037 Statement* try_finally_statement = factory()->NewTryFinallyStatement(
3038 outer_try_block, finally_block, kNoSourcePosition);
3039
3040 result->statements()->Add(try_finally_statement, zone());
3041 return result;
3042 }
3043
3044 Assignment* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
3045 // .generator = %CreateJSGeneratorObject(...);
3046 DCHECK_NOT_NULL(function_state_->generator_object_variable());
3047 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3048 args->Add(factory()->NewThisFunction(pos), zone());
3049 args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos)
3050 : ThisExpression(kNoSourcePosition),
3051 zone());
3052 Expression* allocation =
3053 factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args, pos);
3054 VariableProxy* proxy =
3055 factory()->NewVariableProxy(function_state_->generator_object_variable());
3056 return factory()->NewAssignment(Token::INIT, proxy, allocation,
3057 kNoSourcePosition);
3058 }
3059
3060 Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
3061 // %ResolvePromise(.promise, value), .promise
3062 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3063 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3064 args->Add(value, zone());
3065 Expression* call_runtime =
3066 factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
3067 return factory()->NewBinaryOperation(
3068 Token::COMMA, call_runtime,
3069 factory()->NewVariableProxy(PromiseVariable()), pos);
3070 }
3071
3072 Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
3073 // %promise_internal_reject(.promise, value, false), .promise
3074 // Disables the additional debug event for the rejection since a debug event
3075 // already happened for the exception that got us here.
3076 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
3077 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3078 args->Add(value, zone());
3079 args->Add(factory()->NewBooleanLiteral(false, pos), zone());
3080 Expression* call_runtime = factory()->NewCallRuntime(
3081 Context::PROMISE_INTERNAL_REJECT_INDEX, args, pos);
3082 return factory()->NewBinaryOperation(
3083 Token::COMMA, call_runtime,
3084 factory()->NewVariableProxy(PromiseVariable()), pos);
3085 }
3086
3087 Variable* Parser::PromiseVariable() {
3088 // Based on the various compilation paths, there are many different code
3089 // paths which may be the first to access the Promise temporary. Whichever
3090 // comes first should create it and stash it in the FunctionState.
3091 Variable* promise = function_state_->promise_variable();
3092 if (function_state_->promise_variable() == nullptr) {
3093 promise = scope()->NewTemporary(ast_value_factory()->empty_string());
3094 function_state_->set_promise_variable(promise);
3095 }
3096 return promise;
3097 }
3098
3099 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
3100 Assignment* assignment = BuildCreateJSGeneratorObject(pos, kind);
3101 VariableProxy* generator =
3102 factory()->NewVariableProxy(function_state_->generator_object_variable());
3103 // The position of the yield is important for reporting the exception
3104 // caused by calling the .throw method on a generator suspended at the
3105 // initial yield (i.e. right after generator instantiation).
3106 return factory()->NewYield(generator, assignment, scope()->start_position(),
3107 Yield::kOnExceptionThrow);
3108 }
3109
3110 ZoneList<Statement*>* Parser::ParseFunction( 2914 ZoneList<Statement*>* Parser::ParseFunction(
3111 const AstRawString* function_name, int pos, FunctionKind kind, 2915 const AstRawString* function_name, int pos, FunctionKind kind,
3112 FunctionLiteral::FunctionType function_type, 2916 FunctionLiteral::FunctionType function_type,
3113 DeclarationScope* function_scope, int* num_parameters, int* function_length, 2917 DeclarationScope* function_scope, int* num_parameters,
2918 Block** parameter_init_block, int* function_length,
3114 bool* has_duplicate_parameters, int* materialized_literal_count, 2919 bool* has_duplicate_parameters, int* materialized_literal_count,
3115 int* expected_property_count, bool* ok) { 2920 int* expected_property_count, bool* ok) {
3116 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); 2921 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
3117 2922
3118 FunctionState function_state(&function_state_, &scope_state_, function_scope); 2923 FunctionState function_state(&function_state_, &scope_state_, function_scope);
3119 2924
3120 DuplicateFinder duplicate_finder; 2925 DuplicateFinder duplicate_finder;
3121 ExpressionClassifier formals_classifier(this, &duplicate_finder); 2926 ExpressionClassifier formals_classifier(this, &duplicate_finder);
3122 2927
3123 if (IsResumableFunction(kind)) PrepareGeneratorVariables(); 2928 if (IsResumableFunction(kind)) function_scope->ForceContextAllocation();
3124 2929
3125 ParserFormalParameters formals(function_scope); 2930 ParserFormalParameters formals(function_scope);
3126 ParseFormalParameterList(&formals, CHECK_OK); 2931 ParseFormalParameterList(&formals, CHECK_OK);
3127 Expect(Token::RPAREN, CHECK_OK); 2932 Expect(Token::RPAREN, CHECK_OK);
3128 int formals_end_position = scanner()->location().end_pos; 2933 int formals_end_position = scanner()->location().end_pos;
3129 *num_parameters = formals.num_parameters(); 2934 *num_parameters = formals.num_parameters();
3130 *function_length = formals.function_length; 2935 *function_length = formals.function_length;
3131 2936
3132 CheckArityRestrictions(formals.arity, kind, formals.has_rest, 2937 CheckArityRestrictions(formals.arity, kind, formals.has_rest,
3133 function_scope->start_position(), formals_end_position, 2938 function_scope->start_position(), formals_end_position,
3134 CHECK_OK); 2939 CHECK_OK);
3135 Expect(Token::LBRACE, CHECK_OK); 2940 Expect(Token::LBRACE, CHECK_OK);
3136 2941
3137 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(8, zone()); 2942 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(8, zone());
3138 ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok); 2943 ParseFunctionBody(body, parameter_init_block, function_name, pos, formals,
2944 kind, function_type, ok);
3139 2945
3140 // Validate parameter names. We can do this only after parsing the function, 2946 // Validate parameter names. We can do this only after parsing the function,
3141 // since the function can declare itself strict. 2947 // since the function can declare itself strict.
3142 const bool allow_duplicate_parameters = 2948 const bool allow_duplicate_parameters =
3143 is_sloppy(function_scope->language_mode()) && formals.is_simple && 2949 is_sloppy(function_scope->language_mode()) && formals.is_simple &&
3144 !IsConciseMethod(kind); 2950 !IsConciseMethod(kind);
3145 ValidateFormalParameters(function_scope->language_mode(), 2951 ValidateFormalParameters(function_scope->language_mode(),
3146 allow_duplicate_parameters, CHECK_OK); 2952 allow_duplicate_parameters, CHECK_OK);
3147 2953
3148 RewriteDestructuringAssignments(); 2954 RewriteDestructuringAssignments();
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
3749 3555
3750 Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) { 3556 Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
3751 Expression* expr = args->at(0); 3557 Expression* expr = args->at(0);
3752 for (int i = 1; i < args->length(); ++i) { 3558 for (int i = 1; i < args->length(); ++i) {
3753 expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i), 3559 expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
3754 expr->position()); 3560 expr->position());
3755 } 3561 }
3756 return expr; 3562 return expr;
3757 } 3563 }
3758 3564
3759 // This method intoduces the line initializing the generator object
3760 // when desugaring the body of async_function.
3761 void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
3762 FunctionKind kind, int pos) {
3763 // When parsing an async arrow function, we get here without having called
3764 // PrepareGeneratorVariables yet, so do it now.
3765 if (function_state_->generator_object_variable() == nullptr) {
3766 PrepareGeneratorVariables();
3767 }
3768 body->Add(factory()->NewExpressionStatement(
3769 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition),
3770 zone());
3771 }
3772
3773 // This method completes the desugaring of the body of async_function.
3774 void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
3775 Expression* return_value, bool* ok) {
3776 // function async_function() {
3777 // .generator_object = %CreateJSGeneratorObject();
3778 // BuildRejectPromiseOnException({
3779 // ... block ...
3780 // return %ResolvePromise(.promise, expr), .promise;
3781 // })
3782 // }
3783
3784 return_value = BuildResolvePromise(return_value, return_value->position());
3785 block->statements()->Add(
3786 factory()->NewReturnStatement(return_value, return_value->position()),
3787 zone());
3788 block = BuildRejectPromiseOnException(block);
3789 body->Add(block, zone());
3790 }
3791
3792 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
3793 // yield do {
3794 // tmp = <operand>;
3795 // %AsyncFunctionAwait(.generator_object, tmp, .promise);
3796 // .promise
3797 // }
3798 // The value of the expression is returned to the caller of the async
3799 // function for the first yield statement; for this, .promise is the
3800 // appropriate return value, being a Promise that will be fulfilled or
3801 // rejected with the appropriate value by the desugaring. Subsequent yield
3802 // occurrences will return to the AsyncFunctionNext call within the
3803 // implemementation of the intermediate throwaway Promise's then handler.
3804 // This handler has nothing useful to do with the value, as the Promise is
3805 // ignored. If we yielded the value of the throwawayPromise that
3806 // AsyncFunctionAwait creates as an intermediate, it would create a memory
3807 // leak; we must return .promise instead;
3808 // The operand needs to be evaluated on a separate statement in order to get
3809 // a break location, and the .promise needs to be read earlier so that it
3810 // doesn't insert a false location.
3811 // TODO(littledan): investigate why this ordering is needed in more detail.
3812 Variable* generator_object_variable =
3813 function_state_->generator_object_variable();
3814 DCHECK_NOT_NULL(generator_object_variable);
3815
3816 const int nopos = kNoSourcePosition;
3817
3818 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
3819
3820 Variable* promise = PromiseVariable();
3821
3822 // Wrap value evaluation to provide a break location.
3823 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
3824 Expression* value_assignment = factory()->NewAssignment(
3825 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos);
3826 do_block->statements()->Add(
3827 factory()->NewExpressionStatement(value_assignment, value->position()),
3828 zone());
3829
3830 ZoneList<Expression*>* async_function_await_args =
3831 new (zone()) ZoneList<Expression*>(3, zone());
3832 Expression* generator_object =
3833 factory()->NewVariableProxy(generator_object_variable);
3834 async_function_await_args->Add(generator_object, zone());
3835 async_function_await_args->Add(factory()->NewVariableProxy(temp_var), zone());
3836 async_function_await_args->Add(factory()->NewVariableProxy(promise), zone());
3837
3838 // The parser emits calls to AsyncFunctionAwaitCaught, but the
3839 // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught
3840 // if there is no local enclosing try/catch block.
3841 Expression* async_function_await =
3842 factory()->NewCallRuntime(Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX,
3843 async_function_await_args, nopos);
3844 do_block->statements()->Add(
3845 factory()->NewExpressionStatement(async_function_await, await_pos),
3846 zone());
3847
3848 // Wrap await to provide a break location between value evaluation and yield.
3849 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos);
3850
3851 generator_object = factory()->NewVariableProxy(generator_object_variable);
3852 return factory()->NewYield(generator_object, do_expr, nopos,
3853 Yield::kOnExceptionRethrow);
3854 }
3855
3856 class NonPatternRewriter : public AstExpressionRewriter { 3565 class NonPatternRewriter : public AstExpressionRewriter {
3857 public: 3566 public:
3858 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) 3567 NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
3859 : AstExpressionRewriter(stack_limit), parser_(parser) {} 3568 : AstExpressionRewriter(stack_limit), parser_(parser) {}
3860 ~NonPatternRewriter() override {} 3569 ~NonPatternRewriter() override {}
3861 3570
3862 private: 3571 private:
3863 bool RewriteExpression(Expression* expr) override { 3572 bool RewriteExpression(Expression* expr) override {
3864 if (expr->IsRewritableExpression()) return true; 3573 if (expr->IsRewritableExpression()) return true;
3865 // Rewrite only what could have been a pattern but is not. 3574 // Rewrite only what could have been a pattern but is not.
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
4198 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 3907 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4199 // } 3908 // }
4200 // 3909 //
4201 // IteratorClose(iterator, input, output) expands to the following: 3910 // IteratorClose(iterator, input, output) expands to the following:
4202 // 3911 //
4203 // let iteratorReturn = iterator.return; 3912 // let iteratorReturn = iterator.return;
4204 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; 3913 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
4205 // output = %_Call(iteratorReturn, iterator, input); 3914 // output = %_Call(iteratorReturn, iterator, input);
4206 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 3915 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4207 3916
4208 Expression* Parser::RewriteYieldStar(Expression* generator, 3917 Expression* Parser::RewriteYieldStar(Expression* iterable, int pos) {
4209 Expression* iterable, int pos) {
4210 const int nopos = kNoSourcePosition; 3918 const int nopos = kNoSourcePosition;
4211 3919
4212 // Forward definition for break/continue statements. 3920 // Forward definition for break/continue statements.
4213 WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos); 3921 WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
4214 3922
4215 // let input = undefined; 3923 // let input = undefined;
4216 Variable* var_input = NewTemporary(ast_value_factory()->empty_string()); 3924 Variable* var_input = NewTemporary(ast_value_factory()->empty_string());
4217 Statement* initialize_input; 3925 Statement* initialize_input;
4218 { 3926 {
4219 Expression* input_proxy = factory()->NewVariableProxy(var_input); 3927 Expression* input_proxy = factory()->NewVariableProxy(var_input);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
4398 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); 4106 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4399 Expression* assignment = 4107 Expression* assignment =
4400 factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); 4108 factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos);
4401 set_mode_return = factory()->NewExpressionStatement(assignment, nopos); 4109 set_mode_return = factory()->NewExpressionStatement(assignment, nopos);
4402 } 4110 }
4403 4111
4404 // Yield(output); 4112 // Yield(output);
4405 Statement* yield_output; 4113 Statement* yield_output;
4406 { 4114 {
4407 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4115 Expression* output_proxy = factory()->NewVariableProxy(var_output);
4408 Yield* yield = factory()->NewYield(generator, output_proxy, nopos, 4116 Yield* yield = factory()->NewYield(
4409 Yield::kOnExceptionThrow); 4117 output_proxy, nopos, Yield::kOnExceptionThrow, Yield::kNormal);
4410 yield_output = factory()->NewExpressionStatement(yield, nopos); 4118 yield_output = factory()->NewExpressionStatement(yield, nopos);
4411 } 4119 }
4412 4120
4413 // mode = kNext; 4121 // mode = kNext;
4414 Statement* set_mode_next; 4122 Statement* set_mode_next;
4415 { 4123 {
4416 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); 4124 Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4417 Expression* knext = 4125 Expression* knext =
4418 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); 4126 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4419 Expression* assignment = 4127 Expression* assignment =
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
5021 4729
5022 return final_loop; 4730 return final_loop;
5023 } 4731 }
5024 4732
5025 #undef CHECK_OK 4733 #undef CHECK_OK
5026 #undef CHECK_OK_VOID 4734 #undef CHECK_OK_VOID
5027 #undef CHECK_FAILED 4735 #undef CHECK_FAILED
5028 4736
5029 } // namespace internal 4737 } // namespace internal
5030 } // namespace v8 4738 } // 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