| OLD | NEW |
| 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 1597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 Expression* is_undefined = factory()->NewCompareOperation( | 1608 Expression* is_undefined = factory()->NewCompareOperation( |
| 1609 Token::EQ_STRICT, assign, | 1609 Token::EQ_STRICT, assign, |
| 1610 factory()->NewUndefinedLiteral(kNoSourcePosition), pos); | 1610 factory()->NewUndefinedLiteral(kNoSourcePosition), pos); |
| 1611 | 1611 |
| 1612 // is_undefined ? this : is_object_conditional | 1612 // is_undefined ? this : is_object_conditional |
| 1613 return_value = factory()->NewConditional(is_undefined, ThisExpression(pos), | 1613 return_value = factory()->NewConditional(is_undefined, ThisExpression(pos), |
| 1614 is_object_conditional, pos); | 1614 is_object_conditional, pos); |
| 1615 } | 1615 } |
| 1616 if (is_generator()) { | 1616 if (is_generator()) { |
| 1617 return_value = BuildIteratorResult(return_value, true); | 1617 return_value = BuildIteratorResult(return_value, true); |
| 1618 } else if (is_async_function()) { | |
| 1619 return_value = BuildResolvePromise(return_value, return_value->position()); | |
| 1620 } | 1618 } |
| 1621 return return_value; | 1619 return return_value; |
| 1622 } | 1620 } |
| 1623 | 1621 |
| 1624 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) { | 1622 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) { |
| 1625 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); | 1623 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); |
| 1626 DoExpression* expr = factory()->NewDoExpression(body, result, pos); | 1624 DoExpression* expr = factory()->NewDoExpression(body, result, pos); |
| 1627 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { | 1625 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { |
| 1628 *ok = false; | 1626 *ok = false; |
| 1629 return nullptr; | 1627 return nullptr; |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2472 void Parser::PrepareGeneratorVariables() { | 2470 void Parser::PrepareGeneratorVariables() { |
| 2473 // For generators, allocating variables in contexts is currently a win because | 2471 // For generators, allocating variables in contexts is currently a win because |
| 2474 // it minimizes the work needed to suspend and resume an activation. The | 2472 // it minimizes the work needed to suspend and resume an activation. The |
| 2475 // code produced for generators relies on this forced context allocation (it | 2473 // code produced for generators relies on this forced context allocation (it |
| 2476 // does not restore the frame's parameters upon resume). | 2474 // does not restore the frame's parameters upon resume). |
| 2477 function_state_->scope()->ForceContextAllocation(); | 2475 function_state_->scope()->ForceContextAllocation(); |
| 2478 | 2476 |
| 2479 // Calling a generator returns a generator object. That object is stored | 2477 // Calling a generator returns a generator object. That object is stored |
| 2480 // in a temporary variable, a definition that is used by "yield" | 2478 // in a temporary variable, a definition that is used by "yield" |
| 2481 // expressions. | 2479 // expressions. |
| 2482 Variable* temp = | 2480 Variable* temp = function_state_->scope()->DeclareGeneratorObjectVar( |
| 2483 NewTemporary(ast_value_factory()->dot_generator_object_string()); | 2481 ast_value_factory()->dot_generator_object_string()); |
| 2484 function_state_->set_generator_object_variable(temp); | 2482 temp->set_is_used(); |
| 2485 } | 2483 } |
| 2486 | 2484 |
| 2487 FunctionLiteral* Parser::ParseFunctionLiteral( | 2485 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 2488 const AstRawString* function_name, Scanner::Location function_name_location, | 2486 const AstRawString* function_name, Scanner::Location function_name_location, |
| 2489 FunctionNameValidity function_name_validity, FunctionKind kind, | 2487 FunctionNameValidity function_name_validity, FunctionKind kind, |
| 2490 int function_token_pos, FunctionLiteral::FunctionType function_type, | 2488 int function_token_pos, FunctionLiteral::FunctionType function_type, |
| 2491 LanguageMode language_mode, bool* ok) { | 2489 LanguageMode language_mode, bool* ok) { |
| 2492 // Function :: | 2490 // Function :: |
| 2493 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 2491 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 2494 // | 2492 // |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3006 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise } | 3004 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise } |
| 3007 Scope* catch_scope = NewScope(CATCH_SCOPE); | 3005 Scope* catch_scope = NewScope(CATCH_SCOPE); |
| 3008 catch_scope->set_is_hidden(); | 3006 catch_scope->set_is_hidden(); |
| 3009 Variable* catch_variable = | 3007 Variable* catch_variable = |
| 3010 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); | 3008 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); |
| 3011 Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | 3009 Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); |
| 3012 | 3010 |
| 3013 Expression* promise_reject = BuildRejectPromise( | 3011 Expression* promise_reject = BuildRejectPromise( |
| 3014 factory()->NewVariableProxy(catch_variable), kNoSourcePosition); | 3012 factory()->NewVariableProxy(catch_variable), kNoSourcePosition); |
| 3015 ReturnStatement* return_promise_reject = | 3013 ReturnStatement* return_promise_reject = |
| 3016 factory()->NewReturnStatement(promise_reject, kNoSourcePosition); | 3014 factory()->NewHardReturnStatement(promise_reject, kNoSourcePosition); |
| 3017 catch_block->statements()->Add(return_promise_reject, zone()); | 3015 catch_block->statements()->Add(return_promise_reject, zone()); |
| 3018 | 3016 |
| 3019 TryStatement* try_catch_statement = | 3017 TryStatement* try_catch_statement = |
| 3020 factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope, | 3018 factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope, |
| 3021 catch_variable, catch_block, | 3019 catch_variable, catch_block, |
| 3022 kNoSourcePosition); | 3020 kNoSourcePosition); |
| 3023 | 3021 |
| 3024 // There is no TryCatchFinally node, so wrap it in an outer try/finally | 3022 // There is no TryCatchFinally node, so wrap it in an outer try/finally |
| 3025 Block* outer_try_block = | 3023 Block* outer_try_block = |
| 3026 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | 3024 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3088 Token::COMMA, call_runtime, | 3086 Token::COMMA, call_runtime, |
| 3089 factory()->NewVariableProxy(PromiseVariable()), pos); | 3087 factory()->NewVariableProxy(PromiseVariable()), pos); |
| 3090 } | 3088 } |
| 3091 | 3089 |
| 3092 Variable* Parser::PromiseVariable() { | 3090 Variable* Parser::PromiseVariable() { |
| 3093 // Based on the various compilation paths, there are many different code | 3091 // Based on the various compilation paths, there are many different code |
| 3094 // paths which may be the first to access the Promise temporary. Whichever | 3092 // paths which may be the first to access the Promise temporary. Whichever |
| 3095 // comes first should create it and stash it in the FunctionState. | 3093 // comes first should create it and stash it in the FunctionState. |
| 3096 Variable* promise = function_state_->promise_variable(); | 3094 Variable* promise = function_state_->promise_variable(); |
| 3097 if (function_state_->promise_variable() == nullptr) { | 3095 if (function_state_->promise_variable() == nullptr) { |
| 3098 promise = scope()->NewTemporary(ast_value_factory()->empty_string()); | 3096 promise = function_state_->scope()->DeclarePromiseVar( |
| 3099 function_state_->set_promise_variable(promise); | 3097 ast_value_factory()->empty_string()); |
| 3098 promise->set_is_used(); |
| 3100 } | 3099 } |
| 3101 return promise; | 3100 return promise; |
| 3102 } | 3101 } |
| 3103 | 3102 |
| 3104 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) { | 3103 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) { |
| 3105 Assignment* assignment = BuildCreateJSGeneratorObject(pos, kind); | 3104 Assignment* assignment = BuildCreateJSGeneratorObject(pos, kind); |
| 3106 VariableProxy* generator = | 3105 VariableProxy* generator = |
| 3107 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 3106 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
| 3108 // The position of the yield is important for reporting the exception | 3107 // The position of the yield is important for reporting the exception |
| 3109 // caused by calling the .throw method on a generator suspended at the | 3108 // caused by calling the .throw method on a generator suspended at the |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3781 // function async_function() { | 3780 // function async_function() { |
| 3782 // .generator_object = %CreateJSGeneratorObject(); | 3781 // .generator_object = %CreateJSGeneratorObject(); |
| 3783 // BuildRejectPromiseOnException({ | 3782 // BuildRejectPromiseOnException({ |
| 3784 // ... block ... | 3783 // ... block ... |
| 3785 // return %ResolvePromise(.promise, expr), .promise; | 3784 // return %ResolvePromise(.promise, expr), .promise; |
| 3786 // }) | 3785 // }) |
| 3787 // } | 3786 // } |
| 3788 | 3787 |
| 3789 return_value = BuildResolvePromise(return_value, return_value->position()); | 3788 return_value = BuildResolvePromise(return_value, return_value->position()); |
| 3790 block->statements()->Add( | 3789 block->statements()->Add( |
| 3791 factory()->NewReturnStatement(return_value, return_value->position()), | 3790 factory()->NewHardReturnStatement(return_value, return_value->position()), |
| 3792 zone()); | 3791 zone()); |
| 3793 block = BuildRejectPromiseOnException(block); | 3792 block = BuildRejectPromiseOnException(block); |
| 3794 body->Add(block, zone()); | 3793 body->Add(block, zone()); |
| 3795 } | 3794 } |
| 3796 | 3795 |
| 3797 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) { | 3796 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) { |
| 3798 // yield do { | 3797 // yield do { |
| 3799 // tmp = <operand>; | 3798 // tmp = <operand>; |
| 3800 // %AsyncFunctionAwait(.generator_object, tmp, .promise); | 3799 // %AsyncFunctionAwait(.generator_object, tmp, .promise); |
| 3801 // .promise | 3800 // .promise |
| (...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5026 | 5025 |
| 5027 return final_loop; | 5026 return final_loop; |
| 5028 } | 5027 } |
| 5029 | 5028 |
| 5030 #undef CHECK_OK | 5029 #undef CHECK_OK |
| 5031 #undef CHECK_OK_VOID | 5030 #undef CHECK_OK_VOID |
| 5032 #undef CHECK_FAILED | 5031 #undef CHECK_FAILED |
| 5033 | 5032 |
| 5034 } // namespace internal | 5033 } // namespace internal |
| 5035 } // namespace v8 | 5034 } // namespace v8 |
| OLD | NEW |