| 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 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 547 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
| 548 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && | 548 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && |
| 549 info->isolate()->is_tail_call_elimination_enabled()); | 549 info->isolate()->is_tail_call_elimination_enabled()); |
| 550 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 550 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
| 551 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 551 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
| 552 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); | 552 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); |
| 553 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); | 553 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); |
| 554 set_allow_harmony_class_fields(FLAG_harmony_class_fields); | 554 set_allow_harmony_class_fields(FLAG_harmony_class_fields); |
| 555 set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread); | 555 set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread); |
| 556 set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import); | 556 set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import); |
| 557 set_allow_harmony_async_iteration(FLAG_harmony_async_iteration); |
| 557 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 558 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 558 ++feature) { | 559 ++feature) { |
| 559 use_counts_[feature] = 0; | 560 use_counts_[feature] = 0; |
| 560 } | 561 } |
| 561 if (info->ast_value_factory() == NULL) { | 562 if (info->ast_value_factory() == NULL) { |
| 562 // info takes ownership of AstValueFactory. | 563 // info takes ownership of AstValueFactory. |
| 563 info->set_ast_value_factory(new AstValueFactory( | 564 info->set_ast_value_factory(new AstValueFactory( |
| 564 zone(), info->isolate()->ast_string_constants(), info->hash_seed())); | 565 zone(), info->isolate()->ast_string_constants(), info->hash_seed())); |
| 565 info->set_ast_value_factory_owned(); | 566 info->set_ast_value_factory_owned(); |
| 566 ast_value_factory_ = info->ast_value_factory(); | 567 ast_value_factory_ = info->ast_value_factory(); |
| (...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1815 statement = factory()->NewExpressionStatement( | 1816 statement = factory()->NewExpressionStatement( |
| 1816 factory()->NewAssignment(Token::INIT, fproxy, | 1817 factory()->NewAssignment(Token::INIT, fproxy, |
| 1817 factory()->NewThisFunction(pos), | 1818 factory()->NewThisFunction(pos), |
| 1818 kNoSourcePosition), | 1819 kNoSourcePosition), |
| 1819 kNoSourcePosition); | 1820 kNoSourcePosition); |
| 1820 } | 1821 } |
| 1821 result->Set(index, statement); | 1822 result->Set(index, statement); |
| 1822 } | 1823 } |
| 1823 } | 1824 } |
| 1824 | 1825 |
| 1825 // !%_IsJSReceiver(result = iterator.next()) && | 1826 // [if (IteratorType == kNormal)] |
| 1826 // %ThrowIteratorResultNotAnObject(result) | 1827 // !%_IsJSReceiver(result = iterator.next()) && |
| 1828 // %ThrowIteratorResultNotAnObject(result) |
| 1829 // [else if (IteratorType == kAsync)] |
| 1830 // !%_IsJSReceiver(result = Await(iterator.next())) && |
| 1831 // %ThrowIteratorResultNotAnObject(result) |
| 1832 // [endif] |
| 1827 Expression* Parser::BuildIteratorNextResult(Expression* iterator, | 1833 Expression* Parser::BuildIteratorNextResult(Expression* iterator, |
| 1828 Variable* result, int pos) { | 1834 Variable* result, IteratorType type, |
| 1835 int pos) { |
| 1829 Expression* next_literal = factory()->NewStringLiteral( | 1836 Expression* next_literal = factory()->NewStringLiteral( |
| 1830 ast_value_factory()->next_string(), kNoSourcePosition); | 1837 ast_value_factory()->next_string(), kNoSourcePosition); |
| 1831 Expression* next_property = | 1838 Expression* next_property = |
| 1832 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); | 1839 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); |
| 1833 ZoneList<Expression*>* next_arguments = | 1840 ZoneList<Expression*>* next_arguments = |
| 1834 new (zone()) ZoneList<Expression*>(0, zone()); | 1841 new (zone()) ZoneList<Expression*>(0, zone()); |
| 1835 Expression* next_call = | 1842 Expression* next_call = |
| 1836 factory()->NewCall(next_property, next_arguments, pos); | 1843 factory()->NewCall(next_property, next_arguments, pos); |
| 1844 if (type == IteratorType::kAsync) { |
| 1845 next_call = RewriteAwaitExpression(next_call, pos); |
| 1846 } |
| 1837 Expression* result_proxy = factory()->NewVariableProxy(result); | 1847 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 1838 Expression* left = | 1848 Expression* left = |
| 1839 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); | 1849 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); |
| 1840 | 1850 |
| 1841 // %_IsJSReceiver(...) | 1851 // %_IsJSReceiver(...) |
| 1842 ZoneList<Expression*>* is_spec_object_args = | 1852 ZoneList<Expression*>* is_spec_object_args = |
| 1843 new (zone()) ZoneList<Expression*>(1, zone()); | 1853 new (zone()) ZoneList<Expression*>(1, zone()); |
| 1844 is_spec_object_args->Add(left, zone()); | 1854 is_spec_object_args->Add(left, zone()); |
| 1845 Expression* is_spec_object_call = factory()->NewCallRuntime( | 1855 Expression* is_spec_object_call = factory()->NewCallRuntime( |
| 1846 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); | 1856 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1861 | 1871 |
| 1862 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, | 1872 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| 1863 Expression* each, | 1873 Expression* each, |
| 1864 Expression* subject, | 1874 Expression* subject, |
| 1865 Statement* body, | 1875 Statement* body, |
| 1866 int each_keyword_pos) { | 1876 int each_keyword_pos) { |
| 1867 ForOfStatement* for_of = stmt->AsForOfStatement(); | 1877 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 1868 if (for_of != NULL) { | 1878 if (for_of != NULL) { |
| 1869 const bool finalize = true; | 1879 const bool finalize = true; |
| 1870 return InitializeForOfStatement(for_of, each, subject, body, finalize, | 1880 return InitializeForOfStatement(for_of, each, subject, body, finalize, |
| 1871 each_keyword_pos); | 1881 IteratorType::kNormal, each_keyword_pos); |
| 1872 } else { | 1882 } else { |
| 1873 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | 1883 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| 1874 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); | 1884 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); |
| 1875 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 1885 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 1876 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( | 1886 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| 1877 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, | 1887 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, |
| 1878 kNoSourcePosition), | 1888 kNoSourcePosition), |
| 1879 scope()); | 1889 scope()); |
| 1880 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); | 1890 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); |
| 1881 block->statements()->Add( | 1891 block->statements()->Add( |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2014 // INTERNAL variable that's invisible to the debugger | 2024 // INTERNAL variable that's invisible to the debugger |
| 2015 // but visible to everything else. | 2025 // but visible to everything else. |
| 2016 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET, | 2026 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET, |
| 2017 kNoSourcePosition, CHECK_OK); | 2027 kNoSourcePosition, CHECK_OK); |
| 2018 tdz_decl->proxy()->var()->set_initializer_position(position()); | 2028 tdz_decl->proxy()->var()->set_initializer_position(position()); |
| 2019 } | 2029 } |
| 2020 } | 2030 } |
| 2021 return init_block; | 2031 return init_block; |
| 2022 } | 2032 } |
| 2023 | 2033 |
| 2024 Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of, | 2034 Statement* Parser::InitializeForOfStatement( |
| 2025 Expression* each, | 2035 ForOfStatement* for_of, Expression* each, Expression* iterable, |
| 2026 Expression* iterable, | 2036 Statement* body, bool finalize, IteratorType type, int next_result_pos) { |
| 2027 Statement* body, bool finalize, | |
| 2028 int next_result_pos) { | |
| 2029 // Create the auxiliary expressions needed for iterating over the iterable, | 2037 // Create the auxiliary expressions needed for iterating over the iterable, |
| 2030 // and initialize the given ForOfStatement with them. | 2038 // and initialize the given ForOfStatement with them. |
| 2031 // If finalize is true, also instrument the loop with code that performs the | 2039 // If finalize is true, also instrument the loop with code that performs the |
| 2032 // proper ES6 iterator finalization. In that case, the result is not | 2040 // proper ES6 iterator finalization. In that case, the result is not |
| 2033 // immediately a ForOfStatement. | 2041 // immediately a ForOfStatement. |
| 2034 | |
| 2035 const int nopos = kNoSourcePosition; | 2042 const int nopos = kNoSourcePosition; |
| 2036 auto avfactory = ast_value_factory(); | 2043 auto avfactory = ast_value_factory(); |
| 2037 | 2044 |
| 2038 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); | 2045 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); |
| 2039 Variable* result = NewTemporary(avfactory->dot_result_string()); | 2046 Variable* result = NewTemporary(avfactory->dot_result_string()); |
| 2040 Variable* completion = NewTemporary(avfactory->empty_string()); | 2047 Variable* completion = NewTemporary(avfactory->empty_string()); |
| 2041 | 2048 |
| 2042 // iterator = GetIterator(iterable) | 2049 // iterator = GetIterator(iterable, type) |
| 2043 Expression* assign_iterator; | 2050 Expression* assign_iterator; |
| 2044 { | 2051 { |
| 2045 assign_iterator = factory()->NewAssignment( | 2052 assign_iterator = factory()->NewAssignment( |
| 2046 Token::ASSIGN, factory()->NewVariableProxy(iterator), | 2053 Token::ASSIGN, factory()->NewVariableProxy(iterator), |
| 2047 factory()->NewGetIterator(iterable, iterable->position()), | 2054 factory()->NewGetIterator(iterable, type, iterable->position()), |
| 2048 iterable->position()); | 2055 iterable->position()); |
| 2049 } | 2056 } |
| 2050 | 2057 |
| 2051 // !%_IsJSReceiver(result = iterator.next()) && | 2058 // [if (IteratorType == kNormal)] |
| 2052 // %ThrowIteratorResultNotAnObject(result) | 2059 // !%_IsJSReceiver(result = iterator.next()) && |
| 2060 // %ThrowIteratorResultNotAnObject(result) |
| 2061 // [else if (IteratorType == kAsync)] |
| 2062 // !%_IsJSReceiver(result = Await(iterator.next())) && |
| 2063 // %ThrowIteratorResultNotAnObject(result) |
| 2064 // [endif] |
| 2053 Expression* next_result; | 2065 Expression* next_result; |
| 2054 { | 2066 { |
| 2055 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2067 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2056 next_result = | 2068 next_result = |
| 2057 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); | 2069 BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos); |
| 2058 } | 2070 } |
| 2059 | 2071 |
| 2060 // result.done | 2072 // result.done |
| 2061 Expression* result_done; | 2073 Expression* result_done; |
| 2062 { | 2074 { |
| 2063 Expression* done_literal = factory()->NewStringLiteral( | 2075 Expression* done_literal = factory()->NewStringLiteral( |
| 2064 ast_value_factory()->done_string(), kNoSourcePosition); | 2076 ast_value_factory()->done_string(), kNoSourcePosition); |
| 2065 Expression* result_proxy = factory()->NewVariableProxy(result); | 2077 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2066 result_done = | 2078 result_done = |
| 2067 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); | 2079 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2135 // Statement* body (gets overwritten) | 2147 // Statement* body (gets overwritten) |
| 2136 if (finalize) { | 2148 if (finalize) { |
| 2137 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | 2149 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 2138 block->statements()->Add(body, zone()); | 2150 block->statements()->Add(body, zone()); |
| 2139 block->statements()->Add(set_completion_normal, zone()); | 2151 block->statements()->Add(set_completion_normal, zone()); |
| 2140 body = block; | 2152 body = block; |
| 2141 } | 2153 } |
| 2142 | 2154 |
| 2143 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 2155 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
| 2144 assign_each); | 2156 assign_each); |
| 2145 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; | 2157 return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos) |
| 2158 : for_of; |
| 2146 } | 2159 } |
| 2147 | 2160 |
| 2148 Statement* Parser::DesugarLexicalBindingsInForStatement( | 2161 Statement* Parser::DesugarLexicalBindingsInForStatement( |
| 2149 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 2162 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
| 2150 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { | 2163 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { |
| 2151 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 2164 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
| 2152 // copied into a new environment. Moreover, the "next" statement must be | 2165 // copied into a new environment. Moreover, the "next" statement must be |
| 2153 // evaluated not in the environment of the just completed iteration but in | 2166 // evaluated not in the environment of the just completed iteration but in |
| 2154 // that of the upcoming one. We achieve this with the following desugaring. | 2167 // that of the upcoming one. We achieve this with the following desugaring. |
| 2155 // Extra care is needed to preserve the completion value of the original loop. | 2168 // Extra care is needed to preserve the completion value of the original loop. |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2787 zone(), &scanner_, stack_limit_, ast_value_factory(), | 2800 zone(), &scanner_, stack_limit_, ast_value_factory(), |
| 2788 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); | 2801 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); |
| 2789 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 2802 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
| 2790 SET_ALLOW(natives); | 2803 SET_ALLOW(natives); |
| 2791 SET_ALLOW(harmony_do_expressions); | 2804 SET_ALLOW(harmony_do_expressions); |
| 2792 SET_ALLOW(harmony_function_sent); | 2805 SET_ALLOW(harmony_function_sent); |
| 2793 SET_ALLOW(harmony_trailing_commas); | 2806 SET_ALLOW(harmony_trailing_commas); |
| 2794 SET_ALLOW(harmony_class_fields); | 2807 SET_ALLOW(harmony_class_fields); |
| 2795 SET_ALLOW(harmony_object_rest_spread); | 2808 SET_ALLOW(harmony_object_rest_spread); |
| 2796 SET_ALLOW(harmony_dynamic_import); | 2809 SET_ALLOW(harmony_dynamic_import); |
| 2810 SET_ALLOW(harmony_async_iteration); |
| 2797 #undef SET_ALLOW | 2811 #undef SET_ALLOW |
| 2798 } | 2812 } |
| 2799 // Aborting inner function preparsing would leave scopes in an inconsistent | 2813 // Aborting inner function preparsing would leave scopes in an inconsistent |
| 2800 // state; we don't parse inner functions in the abortable mode anyway. | 2814 // state; we don't parse inner functions in the abortable mode anyway. |
| 2801 DCHECK(!is_inner_function || !may_abort); | 2815 DCHECK(!is_inner_function || !may_abort); |
| 2802 | 2816 |
| 2803 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( | 2817 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( |
| 2804 kind, function_scope, parsing_module_, is_inner_function, may_abort, | 2818 kind, function_scope, parsing_module_, is_inner_function, may_abort, |
| 2805 use_counts_); | 2819 use_counts_); |
| 2806 | 2820 |
| (...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4043 { | 4057 { |
| 4044 ZoneList<Expression*>* append_element_args = NewExpressionList(2); | 4058 ZoneList<Expression*>* append_element_args = NewExpressionList(2); |
| 4045 append_element_args->Add(factory()->NewVariableProxy(result), zone()); | 4059 append_element_args->Add(factory()->NewVariableProxy(result), zone()); |
| 4046 append_element_args->Add(factory()->NewVariableProxy(each), zone()); | 4060 append_element_args->Add(factory()->NewVariableProxy(each), zone()); |
| 4047 append_body = factory()->NewExpressionStatement( | 4061 append_body = factory()->NewExpressionStatement( |
| 4048 factory()->NewCallRuntime(Runtime::kAppendElement, | 4062 factory()->NewCallRuntime(Runtime::kAppendElement, |
| 4049 append_element_args, kNoSourcePosition), | 4063 append_element_args, kNoSourcePosition), |
| 4050 kNoSourcePosition); | 4064 kNoSourcePosition); |
| 4051 } | 4065 } |
| 4052 // for (each of spread) %AppendElement($R, each) | 4066 // for (each of spread) %AppendElement($R, each) |
| 4053 ForEachStatement* loop = factory()->NewForEachStatement( | 4067 ForOfStatement* loop = |
| 4054 ForEachStatement::ITERATE, nullptr, kNoSourcePosition); | 4068 factory()->NewForOfStatement(nullptr, kNoSourcePosition); |
| 4055 const bool finalize = false; | 4069 const bool finalize = false; |
| 4056 InitializeForOfStatement(loop->AsForOfStatement(), | 4070 InitializeForOfStatement(loop, factory()->NewVariableProxy(each), subject, |
| 4057 factory()->NewVariableProxy(each), subject, | 4071 append_body, finalize, IteratorType::kNormal); |
| 4058 append_body, finalize); | |
| 4059 do_block->statements()->Add(loop, zone()); | 4072 do_block->statements()->Add(loop, zone()); |
| 4060 } | 4073 } |
| 4061 } | 4074 } |
| 4062 // Now, rewind the original array literal to truncate everything from the | 4075 // Now, rewind the original array literal to truncate everything from the |
| 4063 // first spread (included) until the end. This fixes $R's initialization. | 4076 // first spread (included) until the end. This fixes $R's initialization. |
| 4064 lit->RewindSpreads(); | 4077 lit->RewindSpreads(); |
| 4065 return factory()->NewDoExpression(do_block, result, lit->position()); | 4078 return factory()->NewDoExpression(do_block, result, lit->position()); |
| 4066 } | 4079 } |
| 4067 | 4080 |
| 4068 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) { | 4081 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4240 Expression* assignment = | 4253 Expression* assignment = |
| 4241 factory()->NewAssignment(Token::ASSIGN, output_proxy, | 4254 factory()->NewAssignment(Token::ASSIGN, output_proxy, |
| 4242 factory()->NewUndefinedLiteral(nopos), nopos); | 4255 factory()->NewUndefinedLiteral(nopos), nopos); |
| 4243 initialize_output = factory()->NewExpressionStatement(assignment, nopos); | 4256 initialize_output = factory()->NewExpressionStatement(assignment, nopos); |
| 4244 } | 4257 } |
| 4245 | 4258 |
| 4246 // let iterator = GetIterator(iterable); | 4259 // let iterator = GetIterator(iterable); |
| 4247 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); | 4260 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); |
| 4248 Statement* get_iterator; | 4261 Statement* get_iterator; |
| 4249 { | 4262 { |
| 4250 Expression* iterator = factory()->NewGetIterator(iterable, nopos); | 4263 Expression* iterator = |
| 4264 factory()->NewGetIterator(iterable, IteratorType::kNormal, nopos); |
| 4251 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4265 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
| 4252 Expression* assignment = factory()->NewAssignment( | 4266 Expression* assignment = factory()->NewAssignment( |
| 4253 Token::ASSIGN, iterator_proxy, iterator, nopos); | 4267 Token::ASSIGN, iterator_proxy, iterator, nopos); |
| 4254 get_iterator = factory()->NewExpressionStatement(assignment, nopos); | 4268 get_iterator = factory()->NewExpressionStatement(assignment, nopos); |
| 4255 } | 4269 } |
| 4256 | 4270 |
| 4257 // output = iterator.next(input); | 4271 // output = iterator.next(input); |
| 4258 Statement* call_next; | 4272 Statement* call_next; |
| 4259 { | 4273 { |
| 4260 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4274 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4322 Token::EQ, factory()->NewVariableProxy(var_throw), | 4336 Token::EQ, factory()->NewVariableProxy(var_throw), |
| 4323 factory()->NewNullLiteral(nopos), nopos); | 4337 factory()->NewNullLiteral(nopos), nopos); |
| 4324 Expression* call = | 4338 Expression* call = |
| 4325 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, | 4339 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, |
| 4326 ast_value_factory()->empty_string(), nopos); | 4340 ast_value_factory()->empty_string(), nopos); |
| 4327 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); | 4341 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); |
| 4328 | 4342 |
| 4329 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); | 4343 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); |
| 4330 BuildIteratorCloseForCompletion( | 4344 BuildIteratorCloseForCompletion( |
| 4331 scope(), then->statements(), var_iterator, | 4345 scope(), then->statements(), var_iterator, |
| 4332 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos)); | 4346 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), |
| 4347 IteratorType::kNormal); |
| 4333 then->statements()->Add(throw_call, zone()); | 4348 then->statements()->Add(throw_call, zone()); |
| 4334 check_throw = factory()->NewIfStatement( | 4349 check_throw = factory()->NewIfStatement( |
| 4335 condition, then, factory()->NewEmptyStatement(nopos), nopos); | 4350 condition, then, factory()->NewEmptyStatement(nopos), nopos); |
| 4336 } | 4351 } |
| 4337 | 4352 |
| 4338 // output = %_Call(iteratorThrow, iterator, input); | 4353 // output = %_Call(iteratorThrow, iterator, input); |
| 4339 Statement* call_throw; | 4354 Statement* call_throw; |
| 4340 { | 4355 { |
| 4341 auto args = new (zone()) ZoneList<Expression*>(3, zone()); | 4356 auto args = new (zone()) ZoneList<Expression*>(3, zone()); |
| 4342 args->Add(factory()->NewVariableProxy(var_throw), zone()); | 4357 args->Add(factory()->NewVariableProxy(var_throw), zone()); |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4689 } | 4704 } |
| 4690 | 4705 |
| 4691 statements->Add(get_return, zone()); | 4706 statements->Add(get_return, zone()); |
| 4692 statements->Add(check_return, zone()); | 4707 statements->Add(check_return, zone()); |
| 4693 statements->Add(call_return, zone()); | 4708 statements->Add(call_return, zone()); |
| 4694 statements->Add(validate_output, zone()); | 4709 statements->Add(validate_output, zone()); |
| 4695 } | 4710 } |
| 4696 | 4711 |
| 4697 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, | 4712 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, |
| 4698 Expression* condition, Variable* iter, | 4713 Expression* condition, Variable* iter, |
| 4699 Block* iterator_use, Block* target) { | 4714 Block* iterator_use, Block* target, |
| 4715 IteratorType type) { |
| 4700 // | 4716 // |
| 4701 // This function adds two statements to [target], corresponding to the | 4717 // This function adds two statements to [target], corresponding to the |
| 4702 // following code: | 4718 // following code: |
| 4703 // | 4719 // |
| 4704 // completion = kNormalCompletion; | 4720 // completion = kNormalCompletion; |
| 4705 // try { | 4721 // try { |
| 4706 // try { | 4722 // try { |
| 4707 // iterator_use | 4723 // iterator_use |
| 4708 // } catch(e) { | 4724 // } catch(e) { |
| 4709 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 4725 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4745 condition, statement, factory()->NewEmptyStatement(nopos), nopos); | 4761 condition, statement, factory()->NewEmptyStatement(nopos), nopos); |
| 4746 } | 4762 } |
| 4747 | 4763 |
| 4748 // if (condition) { | 4764 // if (condition) { |
| 4749 // #BuildIteratorCloseForCompletion(iter, completion) | 4765 // #BuildIteratorCloseForCompletion(iter, completion) |
| 4750 // } | 4766 // } |
| 4751 Block* maybe_close; | 4767 Block* maybe_close; |
| 4752 { | 4768 { |
| 4753 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); | 4769 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); |
| 4754 Expression* proxy = factory()->NewVariableProxy(completion); | 4770 Expression* proxy = factory()->NewVariableProxy(completion); |
| 4755 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, | 4771 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy, |
| 4756 proxy); | 4772 type); |
| 4757 DCHECK(block->statements()->length() == 2); | 4773 DCHECK(block->statements()->length() == 2); |
| 4758 | 4774 |
| 4759 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); | 4775 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); |
| 4760 maybe_close->statements()->Add( | 4776 maybe_close->statements()->Add( |
| 4761 factory()->NewIfStatement(condition, block, | 4777 factory()->NewIfStatement(condition, block, |
| 4762 factory()->NewEmptyStatement(nopos), nopos), | 4778 factory()->NewEmptyStatement(nopos), nopos), |
| 4763 zone()); | 4779 zone()); |
| 4764 } | 4780 } |
| 4765 | 4781 |
| 4766 // try { #try_block } | 4782 // try { #try_block } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4805 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); | 4821 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); |
| 4806 } | 4822 } |
| 4807 | 4823 |
| 4808 target->statements()->Add(initialize_completion, zone()); | 4824 target->statements()->Add(initialize_completion, zone()); |
| 4809 target->statements()->Add(try_finally, zone()); | 4825 target->statements()->Add(try_finally, zone()); |
| 4810 } | 4826 } |
| 4811 | 4827 |
| 4812 void Parser::BuildIteratorCloseForCompletion(Scope* scope, | 4828 void Parser::BuildIteratorCloseForCompletion(Scope* scope, |
| 4813 ZoneList<Statement*>* statements, | 4829 ZoneList<Statement*>* statements, |
| 4814 Variable* iterator, | 4830 Variable* iterator, |
| 4815 Expression* completion) { | 4831 Expression* completion, |
| 4832 IteratorType type) { |
| 4816 // | 4833 // |
| 4817 // This function adds two statements to [statements], corresponding to the | 4834 // This function adds two statements to [statements], corresponding to the |
| 4818 // following code: | 4835 // following code: |
| 4819 // | 4836 // |
| 4820 // let iteratorReturn = iterator.return; | 4837 // let iteratorReturn = iterator.return; |
| 4821 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 4838 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |
| 4822 // if (completion === kThrowCompletion) { | 4839 // if (completion === kThrowCompletion) { |
| 4823 // if (!IS_CALLABLE(iteratorReturn)) { | 4840 // if (!IS_CALLABLE(iteratorReturn)) { |
| 4824 // throw MakeTypeError(kReturnMethodNotCallable); | 4841 // throw MakeTypeError(kReturnMethodNotCallable); |
| 4825 // } | 4842 // } |
| 4826 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 4843 // [if (IteratorType == kAsync)] |
| 4844 // try { Await(%_Call(iteratorReturn, iterator) } catch (_) { } |
| 4845 // [else] |
| 4846 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
| 4847 // [endif] |
| 4827 // } else { | 4848 // } else { |
| 4828 // let output = %_Call(iteratorReturn, iterator); | 4849 // [if (IteratorType == kAsync)] |
| 4850 // let output = Await(%_Call(iteratorReturn, iterator)); |
| 4851 // [else] |
| 4852 // let output = %_Call(iteratorReturn, iterator); |
| 4853 // [endif] |
| 4829 // if (!IS_RECEIVER(output)) { | 4854 // if (!IS_RECEIVER(output)) { |
| 4830 // %ThrowIterResultNotAnObject(output); | 4855 // %ThrowIterResultNotAnObject(output); |
| 4831 // } | 4856 // } |
| 4832 // } | 4857 // } |
| 4833 // } | 4858 // } |
| 4834 // | 4859 // |
| 4835 | 4860 |
| 4836 const int nopos = kNoSourcePosition; | 4861 const int nopos = kNoSourcePosition; |
| 4837 // let iteratorReturn = iterator.return; | 4862 // let iteratorReturn = iterator.return; |
| 4838 Variable* var_return = NewTemporary(ast_value_factory()->empty_string()); | 4863 Variable* var_return = NewTemporary(ast_value_factory()->empty_string()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4863 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 4888 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
| 4864 Statement* try_call_return; | 4889 Statement* try_call_return; |
| 4865 { | 4890 { |
| 4866 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 4891 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 4867 args->Add(factory()->NewVariableProxy(var_return), zone()); | 4892 args->Add(factory()->NewVariableProxy(var_return), zone()); |
| 4868 args->Add(factory()->NewVariableProxy(iterator), zone()); | 4893 args->Add(factory()->NewVariableProxy(iterator), zone()); |
| 4869 | 4894 |
| 4870 Expression* call = | 4895 Expression* call = |
| 4871 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 4896 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 4872 | 4897 |
| 4898 if (type == IteratorType::kAsync) { |
| 4899 call = RewriteAwaitExpression(call, nopos); |
| 4900 } |
| 4901 |
| 4873 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 4902 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
| 4874 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), | 4903 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), |
| 4875 zone()); | 4904 zone()); |
| 4876 | 4905 |
| 4877 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); | 4906 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); |
| 4878 | 4907 |
| 4879 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); | 4908 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); |
| 4880 Variable* catch_variable = | 4909 Variable* catch_variable = |
| 4881 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); | 4910 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); |
| 4882 catch_scope->set_is_hidden(); | 4911 catch_scope->set_is_hidden(); |
| 4883 | 4912 |
| 4884 try_call_return = factory()->NewTryCatchStatement( | 4913 try_call_return = factory()->NewTryCatchStatement( |
| 4885 try_block, catch_scope, catch_variable, catch_block, nopos); | 4914 try_block, catch_scope, catch_variable, catch_block, nopos); |
| 4886 } | 4915 } |
| 4887 | 4916 |
| 4888 // let output = %_Call(iteratorReturn, iterator); | 4917 // let output = %_Call(iteratorReturn, iterator); |
| 4889 // if (!IS_RECEIVER(output)) { | 4918 // if (!IS_RECEIVER(output)) { |
| 4890 // %ThrowIteratorResultNotAnObject(output); | 4919 // %ThrowIteratorResultNotAnObject(output); |
| 4891 // } | 4920 // } |
| 4892 Block* validate_return; | 4921 Block* validate_return; |
| 4893 { | 4922 { |
| 4894 Variable* var_output = NewTemporary(ast_value_factory()->empty_string()); | 4923 Variable* var_output = NewTemporary(ast_value_factory()->empty_string()); |
| 4895 Statement* call_return; | 4924 Statement* call_return; |
| 4896 { | 4925 { |
| 4897 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 4926 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 4898 args->Add(factory()->NewVariableProxy(var_return), zone()); | 4927 args->Add(factory()->NewVariableProxy(var_return), zone()); |
| 4899 args->Add(factory()->NewVariableProxy(iterator), zone()); | 4928 args->Add(factory()->NewVariableProxy(iterator), zone()); |
| 4900 Expression* call = | 4929 Expression* call = |
| 4901 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 4930 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 4931 if (type == IteratorType::kAsync) { |
| 4932 call = RewriteAwaitExpression(call, nopos); |
| 4933 } |
| 4902 | 4934 |
| 4903 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4935 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
| 4904 Expression* assignment = | 4936 Expression* assignment = |
| 4905 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); | 4937 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); |
| 4906 call_return = factory()->NewExpressionStatement(assignment, nopos); | 4938 call_return = factory()->NewExpressionStatement(assignment, nopos); |
| 4907 } | 4939 } |
| 4908 | 4940 |
| 4909 Expression* is_receiver_call; | 4941 Expression* is_receiver_call; |
| 4910 { | 4942 { |
| 4911 auto args = new (zone()) ZoneList<Expression*>(1, zone()); | 4943 auto args = new (zone()) ZoneList<Expression*>(1, zone()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4962 maybe_call_return = factory()->NewIfStatement( | 4994 maybe_call_return = factory()->NewIfStatement( |
| 4963 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, | 4995 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, |
| 4964 nopos); | 4996 nopos); |
| 4965 } | 4997 } |
| 4966 | 4998 |
| 4967 statements->Add(get_return, zone()); | 4999 statements->Add(get_return, zone()); |
| 4968 statements->Add(maybe_call_return, zone()); | 5000 statements->Add(maybe_call_return, zone()); |
| 4969 } | 5001 } |
| 4970 | 5002 |
| 4971 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, | 5003 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, |
| 4972 Variable* var_completion, int pos) { | 5004 Variable* var_completion, |
| 5005 IteratorType type, int pos) { |
| 4973 // | 5006 // |
| 4974 // This function replaces the loop with the following wrapping: | 5007 // This function replaces the loop with the following wrapping: |
| 4975 // | 5008 // |
| 4976 // completion = kNormalCompletion; | 5009 // completion = kNormalCompletion; |
| 4977 // try { | 5010 // try { |
| 4978 // try { | 5011 // try { |
| 4979 // #loop; | 5012 // #loop; |
| 4980 // } catch(e) { | 5013 // } catch(e) { |
| 4981 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 5014 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
| 4982 // %ReThrow(e); | 5015 // %ReThrow(e); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5006 { | 5039 { |
| 5007 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5040 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
| 5008 try_block->statements()->Add(loop, zone()); | 5041 try_block->statements()->Add(loop, zone()); |
| 5009 | 5042 |
| 5010 // The scope in which the parser creates this loop. | 5043 // The scope in which the parser creates this loop. |
| 5011 Scope* loop_scope = scope()->outer_scope(); | 5044 Scope* loop_scope = scope()->outer_scope(); |
| 5012 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); | 5045 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); |
| 5013 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); | 5046 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); |
| 5014 | 5047 |
| 5015 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, | 5048 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, |
| 5016 loop->iterator(), try_block, final_loop); | 5049 loop->iterator(), try_block, final_loop, type); |
| 5017 } | 5050 } |
| 5018 | 5051 |
| 5019 return final_loop; | 5052 return final_loop; |
| 5020 } | 5053 } |
| 5021 | 5054 |
| 5022 #undef CHECK_OK | 5055 #undef CHECK_OK |
| 5023 #undef CHECK_OK_VOID | 5056 #undef CHECK_OK_VOID |
| 5024 #undef CHECK_FAILED | 5057 #undef CHECK_FAILED |
| 5025 | 5058 |
| 5026 } // namespace internal | 5059 } // namespace internal |
| 5027 } // namespace v8 | 5060 } // namespace v8 |
| OLD | NEW |