Chromium Code Reviews| 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 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 546 info->extension() == nullptr && can_compile_lazily; | 546 info->extension() == nullptr && can_compile_lazily; |
| 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_async_iteration(FLAG_harmony_async_iteration); | |
| 556 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 557 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 557 ++feature) { | 558 ++feature) { |
| 558 use_counts_[feature] = 0; | 559 use_counts_[feature] = 0; |
| 559 } | 560 } |
| 560 if (info->ast_value_factory() == NULL) { | 561 if (info->ast_value_factory() == NULL) { |
| 561 // info takes ownership of AstValueFactory. | 562 // info takes ownership of AstValueFactory. |
| 562 info->set_ast_value_factory(new AstValueFactory( | 563 info->set_ast_value_factory(new AstValueFactory( |
| 563 zone(), info->isolate()->ast_string_constants(), info->hash_seed())); | 564 zone(), info->isolate()->ast_string_constants(), info->hash_seed())); |
| 564 info->set_ast_value_factory_owned(); | 565 info->set_ast_value_factory_owned(); |
| 565 ast_value_factory_ = info->ast_value_factory(); | 566 ast_value_factory_ = info->ast_value_factory(); |
| (...skipping 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1811 statement = factory()->NewExpressionStatement( | 1812 statement = factory()->NewExpressionStatement( |
| 1812 factory()->NewAssignment(Token::INIT, fproxy, | 1813 factory()->NewAssignment(Token::INIT, fproxy, |
| 1813 factory()->NewThisFunction(pos), | 1814 factory()->NewThisFunction(pos), |
| 1814 kNoSourcePosition), | 1815 kNoSourcePosition), |
| 1815 kNoSourcePosition); | 1816 kNoSourcePosition); |
| 1816 } | 1817 } |
| 1817 result->Set(index, statement); | 1818 result->Set(index, statement); |
| 1818 } | 1819 } |
| 1819 } | 1820 } |
| 1820 | 1821 |
| 1821 // !%_IsJSReceiver(result = iterator.next()) && | 1822 // [if (IteratorType == kNormal)] |
| 1822 // %ThrowIteratorResultNotAnObject(result) | 1823 // !%_IsJSReceiver(result = iterator.next()) && |
| 1824 // %ThrowIteratorResultNotAnObject(result) | |
| 1825 // [else if (IteratorType == kAsync)] | |
| 1826 // !%_IsJSReceiver(result = Await(iterator.next())) && | |
| 1827 // %ThrowIteratorResultNotAnObject(result) | |
| 1828 // [endif] | |
| 1823 Expression* Parser::BuildIteratorNextResult(Expression* iterator, | 1829 Expression* Parser::BuildIteratorNextResult(Expression* iterator, |
| 1824 Variable* result, int pos) { | 1830 Variable* result, IteratorType type, |
| 1831 int pos) { | |
| 1825 Expression* next_literal = factory()->NewStringLiteral( | 1832 Expression* next_literal = factory()->NewStringLiteral( |
| 1826 ast_value_factory()->next_string(), kNoSourcePosition); | 1833 ast_value_factory()->next_string(), kNoSourcePosition); |
| 1827 Expression* next_property = | 1834 Expression* next_property = |
| 1828 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); | 1835 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); |
| 1829 ZoneList<Expression*>* next_arguments = | 1836 ZoneList<Expression*>* next_arguments = |
| 1830 new (zone()) ZoneList<Expression*>(0, zone()); | 1837 new (zone()) ZoneList<Expression*>(0, zone()); |
| 1831 Expression* next_call = | 1838 Expression* next_call = |
| 1832 factory()->NewCall(next_property, next_arguments, pos); | 1839 factory()->NewCall(next_property, next_arguments, pos); |
| 1840 if (type == IteratorType::kAsync) { | |
| 1841 next_call = RewriteAwaitExpression(next_call, pos); | |
| 1842 } | |
| 1833 Expression* result_proxy = factory()->NewVariableProxy(result); | 1843 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 1834 Expression* left = | 1844 Expression* left = |
| 1835 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); | 1845 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); |
| 1836 | 1846 |
| 1837 // %_IsJSReceiver(...) | 1847 // %_IsJSReceiver(...) |
| 1838 ZoneList<Expression*>* is_spec_object_args = | 1848 ZoneList<Expression*>* is_spec_object_args = |
| 1839 new (zone()) ZoneList<Expression*>(1, zone()); | 1849 new (zone()) ZoneList<Expression*>(1, zone()); |
| 1840 is_spec_object_args->Add(left, zone()); | 1850 is_spec_object_args->Add(left, zone()); |
| 1841 Expression* is_spec_object_call = factory()->NewCallRuntime( | 1851 Expression* is_spec_object_call = factory()->NewCallRuntime( |
| 1842 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); | 1852 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1857 | 1867 |
| 1858 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, | 1868 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| 1859 Expression* each, | 1869 Expression* each, |
| 1860 Expression* subject, | 1870 Expression* subject, |
| 1861 Statement* body, | 1871 Statement* body, |
| 1862 int each_keyword_pos) { | 1872 int each_keyword_pos) { |
| 1863 ForOfStatement* for_of = stmt->AsForOfStatement(); | 1873 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 1864 if (for_of != NULL) { | 1874 if (for_of != NULL) { |
| 1865 const bool finalize = true; | 1875 const bool finalize = true; |
| 1866 return InitializeForOfStatement(for_of, each, subject, body, finalize, | 1876 return InitializeForOfStatement(for_of, each, subject, body, finalize, |
| 1867 each_keyword_pos); | 1877 IteratorType::kNormal, each_keyword_pos); |
| 1868 } else { | 1878 } else { |
| 1869 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | 1879 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| 1870 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); | 1880 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); |
| 1871 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 1881 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 1872 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( | 1882 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| 1873 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, | 1883 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, |
| 1874 kNoSourcePosition), | 1884 kNoSourcePosition), |
| 1875 scope()); | 1885 scope()); |
| 1876 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); | 1886 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); |
| 1877 block->statements()->Add( | 1887 block->statements()->Add( |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2011 // INTERNAL variable that's invisible to the debugger | 2021 // INTERNAL variable that's invisible to the debugger |
| 2012 // but visible to everything else. | 2022 // but visible to everything else. |
| 2013 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET, | 2023 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET, |
| 2014 kNoSourcePosition, CHECK_OK); | 2024 kNoSourcePosition, CHECK_OK); |
| 2015 tdz_decl->proxy()->var()->set_initializer_position(position()); | 2025 tdz_decl->proxy()->var()->set_initializer_position(position()); |
| 2016 } | 2026 } |
| 2017 } | 2027 } |
| 2018 return init_block; | 2028 return init_block; |
| 2019 } | 2029 } |
| 2020 | 2030 |
| 2021 Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of, | 2031 Statement* Parser::InitializeForOfStatement( |
| 2022 Expression* each, | 2032 ForEachStatement* for_each, Expression* each, Expression* iterable, |
| 2023 Expression* iterable, | 2033 Statement* body, bool finalize, IteratorType type, int next_result_pos) { |
| 2024 Statement* body, bool finalize, | |
| 2025 int next_result_pos) { | |
| 2026 // Create the auxiliary expressions needed for iterating over the iterable, | 2034 // Create the auxiliary expressions needed for iterating over the iterable, |
| 2027 // and initialize the given ForOfStatement with them. | 2035 // and initialize the given ForOfStatement with them. |
| 2028 // If finalize is true, also instrument the loop with code that performs the | 2036 // If finalize is true, also instrument the loop with code that performs the |
| 2029 // proper ES6 iterator finalization. In that case, the result is not | 2037 // proper ES6 iterator finalization. In that case, the result is not |
| 2030 // immediately a ForOfStatement. | 2038 // immediately a ForOfStatement. |
| 2039 DCHECK(for_each->IsForOfStatement()); | |
| 2040 ForOfStatement* for_of = for_each->AsForOfStatement(); | |
| 2031 | 2041 |
| 2032 const int nopos = kNoSourcePosition; | 2042 const int nopos = kNoSourcePosition; |
| 2033 auto avfactory = ast_value_factory(); | 2043 auto avfactory = ast_value_factory(); |
| 2034 | 2044 |
| 2035 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); | 2045 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); |
| 2036 Variable* result = NewTemporary(avfactory->dot_result_string()); | 2046 Variable* result = NewTemporary(avfactory->dot_result_string()); |
| 2037 Variable* completion = NewTemporary(avfactory->empty_string()); | 2047 Variable* completion = NewTemporary(avfactory->empty_string()); |
| 2038 | 2048 |
| 2039 // iterator = GetIterator(iterable) | 2049 // iterator = GetIterator(iterable, type) |
| 2040 Expression* assign_iterator; | 2050 Expression* assign_iterator; |
| 2041 { | 2051 { |
| 2042 assign_iterator = factory()->NewAssignment( | 2052 assign_iterator = factory()->NewAssignment( |
| 2043 Token::ASSIGN, factory()->NewVariableProxy(iterator), | 2053 Token::ASSIGN, factory()->NewVariableProxy(iterator), |
| 2044 factory()->NewGetIterator(iterable, iterable->position()), | 2054 factory()->NewGetIterator(iterable, type, iterable->position()), |
| 2045 iterable->position()); | 2055 iterable->position()); |
| 2046 } | 2056 } |
| 2047 | 2057 |
| 2048 // !%_IsJSReceiver(result = iterator.next()) && | 2058 // [if (IteratorType == kNormal)] |
| 2049 // %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] | |
| 2050 Expression* next_result; | 2065 Expression* next_result; |
| 2051 { | 2066 { |
| 2052 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2067 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2053 next_result = | 2068 next_result = |
| 2054 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); | 2069 BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos); |
| 2055 } | 2070 } |
| 2056 | 2071 |
| 2057 // result.done | 2072 // result.done |
| 2058 Expression* result_done; | 2073 Expression* result_done; |
| 2059 { | 2074 { |
| 2060 Expression* done_literal = factory()->NewStringLiteral( | 2075 Expression* done_literal = factory()->NewStringLiteral( |
| 2061 ast_value_factory()->done_string(), kNoSourcePosition); | 2076 ast_value_factory()->done_string(), kNoSourcePosition); |
| 2062 Expression* result_proxy = factory()->NewVariableProxy(result); | 2077 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2063 result_done = | 2078 result_done = |
| 2064 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... | |
| 2132 // Statement* body (gets overwritten) | 2147 // Statement* body (gets overwritten) |
| 2133 if (finalize) { | 2148 if (finalize) { |
| 2134 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | 2149 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 2135 block->statements()->Add(body, zone()); | 2150 block->statements()->Add(body, zone()); |
| 2136 block->statements()->Add(set_completion_normal, zone()); | 2151 block->statements()->Add(set_completion_normal, zone()); |
| 2137 body = block; | 2152 body = block; |
| 2138 } | 2153 } |
| 2139 | 2154 |
| 2140 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 2155 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
| 2141 assign_each); | 2156 assign_each); |
| 2142 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; | 2157 return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos) |
| 2158 : for_of; | |
| 2143 } | 2159 } |
| 2144 | 2160 |
| 2145 Statement* Parser::DesugarLexicalBindingsInForStatement( | 2161 Statement* Parser::DesugarLexicalBindingsInForStatement( |
| 2146 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 2162 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
| 2147 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { | 2163 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { |
| 2148 // 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 |
| 2149 // copied into a new environment. Moreover, the "next" statement must be | 2165 // copied into a new environment. Moreover, the "next" statement must be |
| 2150 // 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 |
| 2151 // 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. |
| 2152 // 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 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2797 reusable_preparser_ = new PreParser( | 2813 reusable_preparser_ = new PreParser( |
| 2798 zone(), &scanner_, stack_limit_, ast_value_factory(), | 2814 zone(), &scanner_, stack_limit_, ast_value_factory(), |
| 2799 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); | 2815 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); |
| 2800 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 2816 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
| 2801 SET_ALLOW(natives); | 2817 SET_ALLOW(natives); |
| 2802 SET_ALLOW(harmony_do_expressions); | 2818 SET_ALLOW(harmony_do_expressions); |
| 2803 SET_ALLOW(harmony_function_sent); | 2819 SET_ALLOW(harmony_function_sent); |
| 2804 SET_ALLOW(harmony_trailing_commas); | 2820 SET_ALLOW(harmony_trailing_commas); |
| 2805 SET_ALLOW(harmony_class_fields); | 2821 SET_ALLOW(harmony_class_fields); |
| 2806 SET_ALLOW(harmony_object_rest_spread); | 2822 SET_ALLOW(harmony_object_rest_spread); |
| 2823 SET_ALLOW(harmony_async_iteration); | |
| 2807 #undef SET_ALLOW | 2824 #undef SET_ALLOW |
| 2808 } | 2825 } |
| 2809 // Aborting inner function preparsing would leave scopes in an inconsistent | 2826 // Aborting inner function preparsing would leave scopes in an inconsistent |
| 2810 // state; we don't parse inner functions in the abortable mode anyway. | 2827 // state; we don't parse inner functions in the abortable mode anyway. |
| 2811 DCHECK(!is_inner_function || !may_abort); | 2828 DCHECK(!is_inner_function || !may_abort); |
| 2812 | 2829 |
| 2813 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( | 2830 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( |
| 2814 kind, function_scope, parsing_module_, is_inner_function, may_abort, | 2831 kind, function_scope, parsing_module_, is_inner_function, may_abort, |
| 2815 use_counts_); | 2832 use_counts_); |
| 2816 | 2833 |
| (...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4065 factory()->NewCallRuntime(Runtime::kAppendElement, | 4082 factory()->NewCallRuntime(Runtime::kAppendElement, |
| 4066 append_element_args, kNoSourcePosition), | 4083 append_element_args, kNoSourcePosition), |
| 4067 kNoSourcePosition); | 4084 kNoSourcePosition); |
| 4068 } | 4085 } |
| 4069 // for (each of spread) %AppendElement($R, each) | 4086 // for (each of spread) %AppendElement($R, each) |
| 4070 ForEachStatement* loop = factory()->NewForEachStatement( | 4087 ForEachStatement* loop = factory()->NewForEachStatement( |
| 4071 ForEachStatement::ITERATE, nullptr, kNoSourcePosition); | 4088 ForEachStatement::ITERATE, nullptr, kNoSourcePosition); |
| 4072 const bool finalize = false; | 4089 const bool finalize = false; |
| 4073 InitializeForOfStatement(loop->AsForOfStatement(), | 4090 InitializeForOfStatement(loop->AsForOfStatement(), |
| 4074 factory()->NewVariableProxy(each), subject, | 4091 factory()->NewVariableProxy(each), subject, |
| 4075 append_body, finalize); | 4092 append_body, finalize, IteratorType::kNormal); |
| 4076 do_block->statements()->Add(loop, zone()); | 4093 do_block->statements()->Add(loop, zone()); |
| 4077 } | 4094 } |
| 4078 } | 4095 } |
| 4079 // Now, rewind the original array literal to truncate everything from the | 4096 // Now, rewind the original array literal to truncate everything from the |
| 4080 // first spread (included) until the end. This fixes $R's initialization. | 4097 // first spread (included) until the end. This fixes $R's initialization. |
| 4081 lit->RewindSpreads(); | 4098 lit->RewindSpreads(); |
| 4082 return factory()->NewDoExpression(do_block, result, lit->position()); | 4099 return factory()->NewDoExpression(do_block, result, lit->position()); |
| 4083 } | 4100 } |
| 4084 | 4101 |
| 4085 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) { | 4102 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4257 Expression* assignment = | 4274 Expression* assignment = |
| 4258 factory()->NewAssignment(Token::ASSIGN, output_proxy, | 4275 factory()->NewAssignment(Token::ASSIGN, output_proxy, |
| 4259 factory()->NewUndefinedLiteral(nopos), nopos); | 4276 factory()->NewUndefinedLiteral(nopos), nopos); |
| 4260 initialize_output = factory()->NewExpressionStatement(assignment, nopos); | 4277 initialize_output = factory()->NewExpressionStatement(assignment, nopos); |
| 4261 } | 4278 } |
| 4262 | 4279 |
| 4263 // let iterator = GetIterator(iterable); | 4280 // let iterator = GetIterator(iterable); |
| 4264 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); | 4281 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); |
| 4265 Statement* get_iterator; | 4282 Statement* get_iterator; |
| 4266 { | 4283 { |
| 4267 Expression* iterator = factory()->NewGetIterator(iterable, nopos); | 4284 Expression* iterator = |
| 4285 factory()->NewGetIterator(iterable, IteratorType::kNormal, nopos); | |
| 4268 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4286 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
| 4269 Expression* assignment = factory()->NewAssignment( | 4287 Expression* assignment = factory()->NewAssignment( |
| 4270 Token::ASSIGN, iterator_proxy, iterator, nopos); | 4288 Token::ASSIGN, iterator_proxy, iterator, nopos); |
| 4271 get_iterator = factory()->NewExpressionStatement(assignment, nopos); | 4289 get_iterator = factory()->NewExpressionStatement(assignment, nopos); |
| 4272 } | 4290 } |
| 4273 | 4291 |
| 4274 // output = iterator.next(input); | 4292 // output = iterator.next(input); |
| 4275 Statement* call_next; | 4293 Statement* call_next; |
| 4276 { | 4294 { |
| 4277 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4295 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4339 Token::EQ, factory()->NewVariableProxy(var_throw), | 4357 Token::EQ, factory()->NewVariableProxy(var_throw), |
| 4340 factory()->NewNullLiteral(nopos), nopos); | 4358 factory()->NewNullLiteral(nopos), nopos); |
| 4341 Expression* call = | 4359 Expression* call = |
| 4342 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, | 4360 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, |
| 4343 ast_value_factory()->empty_string(), nopos); | 4361 ast_value_factory()->empty_string(), nopos); |
| 4344 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); | 4362 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); |
| 4345 | 4363 |
| 4346 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); | 4364 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); |
| 4347 BuildIteratorCloseForCompletion( | 4365 BuildIteratorCloseForCompletion( |
| 4348 scope(), then->statements(), var_iterator, | 4366 scope(), then->statements(), var_iterator, |
| 4349 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos)); | 4367 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), |
| 4368 IteratorType::kNormal); | |
| 4350 then->statements()->Add(throw_call, zone()); | 4369 then->statements()->Add(throw_call, zone()); |
| 4351 check_throw = factory()->NewIfStatement( | 4370 check_throw = factory()->NewIfStatement( |
| 4352 condition, then, factory()->NewEmptyStatement(nopos), nopos); | 4371 condition, then, factory()->NewEmptyStatement(nopos), nopos); |
| 4353 } | 4372 } |
| 4354 | 4373 |
| 4355 // output = %_Call(iteratorThrow, iterator, input); | 4374 // output = %_Call(iteratorThrow, iterator, input); |
| 4356 Statement* call_throw; | 4375 Statement* call_throw; |
| 4357 { | 4376 { |
| 4358 auto args = new (zone()) ZoneList<Expression*>(3, zone()); | 4377 auto args = new (zone()) ZoneList<Expression*>(3, zone()); |
| 4359 args->Add(factory()->NewVariableProxy(var_throw), zone()); | 4378 args->Add(factory()->NewVariableProxy(var_throw), zone()); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4618 Variable* iterator, Variable* input, | 4637 Variable* iterator, Variable* input, |
| 4619 Variable* var_output) { | 4638 Variable* var_output) { |
| 4620 // | 4639 // |
| 4621 // This function adds four statements to [statements], corresponding to the | 4640 // This function adds four statements to [statements], corresponding to the |
| 4622 // following code: | 4641 // following code: |
| 4623 // | 4642 // |
| 4624 // let iteratorReturn = iterator.return; | 4643 // let iteratorReturn = iterator.return; |
| 4625 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 4644 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { |
| 4626 // return {value: input, done: true}; | 4645 // return {value: input, done: true}; |
| 4627 // } | 4646 // } |
| 4628 // output = %_Call(iteratorReturn, iterator, input); | 4647 // |
| 4648 // [if (IteratorType == kAsync)] | |
| 4649 // output = Await(%_Call(iteratorReturn, iterator, input)); | |
| 4650 // [else] | |
| 4651 // output = %_Call(iteratorReturn, iterator, input); | |
| 4652 // [endif] | |
| 4653 // | |
| 4629 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 4654 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
|
neis
2017/01/25 16:11:08
Please undo the comment changes here since the cod
| |
| 4630 // | 4655 // |
| 4631 | 4656 |
| 4632 const int nopos = kNoSourcePosition; | 4657 const int nopos = kNoSourcePosition; |
| 4633 | 4658 |
| 4634 // let iteratorReturn = iterator.return; | 4659 // let iteratorReturn = iterator.return; |
| 4635 Variable* var_return = var_output; // Reusing the output variable. | 4660 Variable* var_return = var_output; // Reusing the output variable. |
| 4636 Statement* get_return; | 4661 Statement* get_return; |
| 4637 { | 4662 { |
| 4638 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 4663 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 4639 Expression* literal = factory()->NewStringLiteral( | 4664 Expression* literal = factory()->NewStringLiteral( |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4706 } | 4731 } |
| 4707 | 4732 |
| 4708 statements->Add(get_return, zone()); | 4733 statements->Add(get_return, zone()); |
| 4709 statements->Add(check_return, zone()); | 4734 statements->Add(check_return, zone()); |
| 4710 statements->Add(call_return, zone()); | 4735 statements->Add(call_return, zone()); |
| 4711 statements->Add(validate_output, zone()); | 4736 statements->Add(validate_output, zone()); |
| 4712 } | 4737 } |
| 4713 | 4738 |
| 4714 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, | 4739 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, |
| 4715 Expression* condition, Variable* iter, | 4740 Expression* condition, Variable* iter, |
| 4716 Block* iterator_use, Block* target) { | 4741 Block* iterator_use, Block* target, |
| 4742 IteratorType type) { | |
| 4717 // | 4743 // |
| 4718 // This function adds two statements to [target], corresponding to the | 4744 // This function adds two statements to [target], corresponding to the |
| 4719 // following code: | 4745 // following code: |
| 4720 // | 4746 // |
| 4721 // completion = kNormalCompletion; | 4747 // completion = kNormalCompletion; |
| 4722 // try { | 4748 // try { |
| 4723 // try { | 4749 // try { |
| 4724 // iterator_use | 4750 // iterator_use |
| 4725 // } catch(e) { | 4751 // } catch(e) { |
| 4726 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 4752 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4762 condition, statement, factory()->NewEmptyStatement(nopos), nopos); | 4788 condition, statement, factory()->NewEmptyStatement(nopos), nopos); |
| 4763 } | 4789 } |
| 4764 | 4790 |
| 4765 // if (condition) { | 4791 // if (condition) { |
| 4766 // #BuildIteratorCloseForCompletion(iter, completion) | 4792 // #BuildIteratorCloseForCompletion(iter, completion) |
| 4767 // } | 4793 // } |
| 4768 Block* maybe_close; | 4794 Block* maybe_close; |
| 4769 { | 4795 { |
| 4770 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); | 4796 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); |
| 4771 Expression* proxy = factory()->NewVariableProxy(completion); | 4797 Expression* proxy = factory()->NewVariableProxy(completion); |
| 4772 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, | 4798 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy, |
| 4773 proxy); | 4799 type); |
| 4774 DCHECK(block->statements()->length() == 2); | 4800 DCHECK(block->statements()->length() == 2); |
| 4775 | 4801 |
| 4776 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); | 4802 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); |
| 4777 maybe_close->statements()->Add( | 4803 maybe_close->statements()->Add( |
| 4778 factory()->NewIfStatement(condition, block, | 4804 factory()->NewIfStatement(condition, block, |
| 4779 factory()->NewEmptyStatement(nopos), nopos), | 4805 factory()->NewEmptyStatement(nopos), nopos), |
| 4780 zone()); | 4806 zone()); |
| 4781 } | 4807 } |
| 4782 | 4808 |
| 4783 // try { #try_block } | 4809 // try { #try_block } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4822 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); | 4848 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); |
| 4823 } | 4849 } |
| 4824 | 4850 |
| 4825 target->statements()->Add(initialize_completion, zone()); | 4851 target->statements()->Add(initialize_completion, zone()); |
| 4826 target->statements()->Add(try_finally, zone()); | 4852 target->statements()->Add(try_finally, zone()); |
| 4827 } | 4853 } |
| 4828 | 4854 |
| 4829 void Parser::BuildIteratorCloseForCompletion(Scope* scope, | 4855 void Parser::BuildIteratorCloseForCompletion(Scope* scope, |
| 4830 ZoneList<Statement*>* statements, | 4856 ZoneList<Statement*>* statements, |
| 4831 Variable* iterator, | 4857 Variable* iterator, |
| 4832 Expression* completion) { | 4858 Expression* completion, |
| 4859 IteratorType type) { | |
| 4833 // | 4860 // |
| 4834 // This function adds two statements to [statements], corresponding to the | 4861 // This function adds two statements to [statements], corresponding to the |
| 4835 // following code: | 4862 // following code: |
| 4836 // | 4863 // |
| 4837 // let iteratorReturn = iterator.return; | 4864 // let iteratorReturn = iterator.return; |
| 4838 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 4865 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |
| 4839 // if (completion === kThrowCompletion) { | 4866 // if (completion === kThrowCompletion) { |
| 4840 // if (!IS_CALLABLE(iteratorReturn)) { | 4867 // if (!IS_CALLABLE(iteratorReturn)) { |
| 4841 // throw MakeTypeError(kReturnMethodNotCallable); | 4868 // throw MakeTypeError(kReturnMethodNotCallable); |
| 4842 // } | 4869 // } |
| 4843 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 4870 // [if (IteratorType == kAsync)] |
| 4871 // try { Await(%_Call(iteratorReturn, iterator) } catch (_) { } | |
| 4872 // [else] | |
| 4873 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | |
| 4874 // [endif] | |
| 4844 // } else { | 4875 // } else { |
| 4845 // let output = %_Call(iteratorReturn, iterator); | 4876 // [if (IteratorType == kAsync)] |
| 4877 // let output = Await(%_Call(iteratorReturn, iterator)); | |
| 4878 // [else] | |
| 4879 // let output = %_Call(iteratorReturn, iterator); | |
| 4880 // [endif] | |
| 4846 // if (!IS_RECEIVER(output)) { | 4881 // if (!IS_RECEIVER(output)) { |
| 4847 // %ThrowIterResultNotAnObject(output); | 4882 // %ThrowIterResultNotAnObject(output); |
| 4848 // } | 4883 // } |
| 4849 // } | 4884 // } |
| 4850 // } | 4885 // } |
| 4851 // | 4886 // |
| 4852 | 4887 |
| 4853 const int nopos = kNoSourcePosition; | 4888 const int nopos = kNoSourcePosition; |
| 4854 // let iteratorReturn = iterator.return; | 4889 // let iteratorReturn = iterator.return; |
| 4855 Variable* var_return = NewTemporary(ast_value_factory()->empty_string()); | 4890 Variable* var_return = NewTemporary(ast_value_factory()->empty_string()); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 4880 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 4915 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
| 4881 Statement* try_call_return; | 4916 Statement* try_call_return; |
| 4882 { | 4917 { |
| 4883 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 4918 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 4884 args->Add(factory()->NewVariableProxy(var_return), zone()); | 4919 args->Add(factory()->NewVariableProxy(var_return), zone()); |
| 4885 args->Add(factory()->NewVariableProxy(iterator), zone()); | 4920 args->Add(factory()->NewVariableProxy(iterator), zone()); |
| 4886 | 4921 |
| 4887 Expression* call = | 4922 Expression* call = |
| 4888 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 4923 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 4889 | 4924 |
| 4925 if (type == IteratorType::kAsync) { | |
| 4926 call = RewriteAwaitExpression(call, nopos); | |
| 4927 } | |
| 4928 | |
| 4890 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 4929 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
| 4891 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), | 4930 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), |
| 4892 zone()); | 4931 zone()); |
| 4893 | 4932 |
| 4894 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); | 4933 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); |
| 4895 | 4934 |
| 4896 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); | 4935 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); |
| 4897 Variable* catch_variable = | 4936 Variable* catch_variable = |
| 4898 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); | 4937 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); |
| 4899 catch_scope->set_is_hidden(); | 4938 catch_scope->set_is_hidden(); |
| 4900 | 4939 |
| 4901 try_call_return = factory()->NewTryCatchStatement( | 4940 try_call_return = factory()->NewTryCatchStatement( |
| 4902 try_block, catch_scope, catch_variable, catch_block, nopos); | 4941 try_block, catch_scope, catch_variable, catch_block, nopos); |
| 4903 } | 4942 } |
| 4904 | 4943 |
| 4905 // let output = %_Call(iteratorReturn, iterator); | 4944 // let output = %_Call(iteratorReturn, iterator); |
| 4906 // if (!IS_RECEIVER(output)) { | 4945 // if (!IS_RECEIVER(output)) { |
| 4907 // %ThrowIteratorResultNotAnObject(output); | 4946 // %ThrowIteratorResultNotAnObject(output); |
| 4908 // } | 4947 // } |
| 4909 Block* validate_return; | 4948 Block* validate_return; |
| 4910 { | 4949 { |
| 4911 Variable* var_output = NewTemporary(ast_value_factory()->empty_string()); | 4950 Variable* var_output = NewTemporary(ast_value_factory()->empty_string()); |
| 4912 Statement* call_return; | 4951 Statement* call_return; |
| 4913 { | 4952 { |
| 4914 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 4953 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 4915 args->Add(factory()->NewVariableProxy(var_return), zone()); | 4954 args->Add(factory()->NewVariableProxy(var_return), zone()); |
| 4916 args->Add(factory()->NewVariableProxy(iterator), zone()); | 4955 args->Add(factory()->NewVariableProxy(iterator), zone()); |
| 4917 Expression* call = | 4956 Expression* call = |
| 4918 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 4957 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 4958 if (type == IteratorType::kAsync) { | |
| 4959 call = RewriteAwaitExpression(call, nopos); | |
| 4960 } | |
| 4919 | 4961 |
| 4920 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4962 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
| 4921 Expression* assignment = | 4963 Expression* assignment = |
| 4922 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); | 4964 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); |
| 4923 call_return = factory()->NewExpressionStatement(assignment, nopos); | 4965 call_return = factory()->NewExpressionStatement(assignment, nopos); |
| 4924 } | 4966 } |
| 4925 | 4967 |
| 4926 Expression* is_receiver_call; | 4968 Expression* is_receiver_call; |
| 4927 { | 4969 { |
| 4928 auto args = new (zone()) ZoneList<Expression*>(1, zone()); | 4970 auto args = new (zone()) ZoneList<Expression*>(1, zone()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4979 maybe_call_return = factory()->NewIfStatement( | 5021 maybe_call_return = factory()->NewIfStatement( |
| 4980 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, | 5022 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, |
| 4981 nopos); | 5023 nopos); |
| 4982 } | 5024 } |
| 4983 | 5025 |
| 4984 statements->Add(get_return, zone()); | 5026 statements->Add(get_return, zone()); |
| 4985 statements->Add(maybe_call_return, zone()); | 5027 statements->Add(maybe_call_return, zone()); |
| 4986 } | 5028 } |
| 4987 | 5029 |
| 4988 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, | 5030 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, |
| 4989 Variable* var_completion, int pos) { | 5031 Variable* var_completion, |
| 5032 IteratorType type, int pos) { | |
| 4990 // | 5033 // |
| 4991 // This function replaces the loop with the following wrapping: | 5034 // This function replaces the loop with the following wrapping: |
| 4992 // | 5035 // |
| 4993 // completion = kNormalCompletion; | 5036 // completion = kNormalCompletion; |
| 4994 // try { | 5037 // try { |
| 4995 // try { | 5038 // try { |
| 4996 // #loop; | 5039 // #loop; |
| 4997 // } catch(e) { | 5040 // } catch(e) { |
| 4998 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 5041 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
| 4999 // %ReThrow(e); | 5042 // %ReThrow(e); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 5023 { | 5066 { |
| 5024 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5067 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
| 5025 try_block->statements()->Add(loop, zone()); | 5068 try_block->statements()->Add(loop, zone()); |
| 5026 | 5069 |
| 5027 // The scope in which the parser creates this loop. | 5070 // The scope in which the parser creates this loop. |
| 5028 Scope* loop_scope = scope()->outer_scope(); | 5071 Scope* loop_scope = scope()->outer_scope(); |
| 5029 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); | 5072 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); |
| 5030 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); | 5073 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); |
| 5031 | 5074 |
| 5032 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, | 5075 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, |
| 5033 loop->iterator(), try_block, final_loop); | 5076 loop->iterator(), try_block, final_loop, type); |
| 5034 } | 5077 } |
| 5035 | 5078 |
| 5036 return final_loop; | 5079 return final_loop; |
| 5037 } | 5080 } |
| 5038 | 5081 |
| 5039 #undef CHECK_OK | 5082 #undef CHECK_OK |
| 5040 #undef CHECK_OK_VOID | 5083 #undef CHECK_OK_VOID |
| 5041 #undef CHECK_FAILED | 5084 #undef CHECK_FAILED |
| 5042 | 5085 |
| 5043 } // namespace internal | 5086 } // namespace internal |
| 5044 } // namespace v8 | 5087 } // namespace v8 |
| OLD | NEW |