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_async_await(FLAG_harmony_async_await); | 552 set_allow_harmony_async_await(FLAG_harmony_async_await); |
553 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); | 553 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); |
554 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); | 554 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); |
555 set_allow_harmony_class_fields(FLAG_harmony_class_fields); | 555 set_allow_harmony_class_fields(FLAG_harmony_class_fields); |
556 set_allow_harmony_object_spread(FLAG_harmony_object_spread); | 556 set_allow_harmony_object_spread(FLAG_harmony_object_spread); |
| 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(zone(), info->hash_seed())); | 564 info->set_ast_value_factory(new AstValueFactory(zone(), 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(); |
566 ast_node_factory_.set_ast_value_factory(ast_value_factory_); | 567 ast_node_factory_.set_ast_value_factory(ast_value_factory_); |
(...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2085 block->statements()->Add(body, zone()); | 2086 block->statements()->Add(body, zone()); |
2086 block->statements()->Add(set_completion_normal, zone()); | 2087 block->statements()->Add(set_completion_normal, zone()); |
2087 body = block; | 2088 body = block; |
2088 } | 2089 } |
2089 | 2090 |
2090 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 2091 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
2091 assign_each); | 2092 assign_each); |
2092 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; | 2093 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; |
2093 } | 2094 } |
2094 | 2095 |
| 2096 Statement* Parser::InitializeForAwaitOfStatement(ForEachStatement* stmt, |
| 2097 Expression* each, |
| 2098 Expression* iterable, |
| 2099 Statement* body, bool finalize, |
| 2100 int next_result_pos) { |
| 2101 DCHECK(stmt->IsForOfStatement()); |
| 2102 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 2103 |
| 2104 // Create the auxiliary expressions needed for iterating over the iterable, |
| 2105 // and initialize the given ForOfStatement with them. |
| 2106 // If finalize is true, also instrument the loop with code that performs the |
| 2107 // proper ES6 iterator finalization. In that case, the result is not |
| 2108 // immediately a ForOfStatement. |
| 2109 |
| 2110 const int nopos = kNoSourcePosition; |
| 2111 auto avfactory = ast_value_factory(); |
| 2112 |
| 2113 Variable* iterator = NewTemporary(ast_value_factory()->dot_iterator_string()); |
| 2114 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); |
| 2115 Variable* completion = NewTemporary(avfactory->empty_string()); |
| 2116 |
| 2117 // iterator = iterable[Symbol.iterator]() |
| 2118 Expression* assign_iterator; |
| 2119 { |
| 2120 assign_iterator = factory()->NewAssignment( |
| 2121 Token::ASSIGN, factory()->NewVariableProxy(iterator), |
| 2122 factory()->NewGetIterator(iterable, GetIterator::kAsync, |
| 2123 iterable->position()), |
| 2124 iterable->position()); |
| 2125 } |
| 2126 |
| 2127 // !%_IsJSReceiver(result = iterator.next()) && |
| 2128 // %ThrowIteratorResultNotAnObject(result) |
| 2129 Expression* next_result; |
| 2130 { |
| 2131 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2132 next_result = |
| 2133 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); |
| 2134 } |
| 2135 |
| 2136 // result.done |
| 2137 Expression* result_done; |
| 2138 { |
| 2139 Expression* done_literal = factory()->NewStringLiteral( |
| 2140 ast_value_factory()->done_string(), kNoSourcePosition); |
| 2141 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2142 result_done = |
| 2143 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); |
| 2144 } |
| 2145 |
| 2146 // result.value |
| 2147 Expression* result_value; |
| 2148 { |
| 2149 Expression* value_literal = |
| 2150 factory()->NewStringLiteral(avfactory->value_string(), nopos); |
| 2151 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2152 result_value = factory()->NewProperty(result_proxy, value_literal, nopos); |
| 2153 } |
| 2154 |
| 2155 // {{completion = kAbruptCompletion;}} |
| 2156 Statement* set_completion_abrupt; |
| 2157 if (finalize) { |
| 2158 Expression* proxy = factory()->NewVariableProxy(completion); |
| 2159 Expression* assignment = factory()->NewAssignment( |
| 2160 Token::ASSIGN, proxy, |
| 2161 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); |
| 2162 |
| 2163 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); |
| 2164 block->statements()->Add( |
| 2165 factory()->NewExpressionStatement(assignment, nopos), zone()); |
| 2166 set_completion_abrupt = block; |
| 2167 } |
| 2168 |
| 2169 // do { let tmp = #result_value; #set_completion_abrupt; tmp } |
| 2170 // Expression* result_value (gets overwritten) |
| 2171 if (finalize) { |
| 2172 Variable* var_tmp = NewTemporary(avfactory->empty_string()); |
| 2173 Expression* tmp = factory()->NewVariableProxy(var_tmp); |
| 2174 Expression* assignment = |
| 2175 factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos); |
| 2176 |
| 2177 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 2178 block->statements()->Add( |
| 2179 factory()->NewExpressionStatement(assignment, nopos), zone()); |
| 2180 block->statements()->Add(set_completion_abrupt, zone()); |
| 2181 |
| 2182 result_value = factory()->NewDoExpression(block, var_tmp, nopos); |
| 2183 } |
| 2184 |
| 2185 // each = #result_value; |
| 2186 Expression* assign_each; |
| 2187 { |
| 2188 assign_each = |
| 2189 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); |
| 2190 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| 2191 assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| 2192 this, assign_each->AsAssignment(), scope()); |
| 2193 } |
| 2194 } |
| 2195 |
| 2196 // {{completion = kNormalCompletion;}} |
| 2197 Statement* set_completion_normal; |
| 2198 if (finalize) { |
| 2199 Expression* proxy = factory()->NewVariableProxy(completion); |
| 2200 Expression* assignment = factory()->NewAssignment( |
| 2201 Token::ASSIGN, proxy, |
| 2202 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
| 2203 |
| 2204 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); |
| 2205 block->statements()->Add( |
| 2206 factory()->NewExpressionStatement(assignment, nopos), zone()); |
| 2207 set_completion_normal = block; |
| 2208 } |
| 2209 |
| 2210 // { #loop-body; #set_completion_normal } |
| 2211 // Statement* body (gets overwritten) |
| 2212 if (finalize) { |
| 2213 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 2214 block->statements()->Add(body, zone()); |
| 2215 block->statements()->Add(set_completion_normal, zone()); |
| 2216 body = block; |
| 2217 } |
| 2218 |
| 2219 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
| 2220 assign_each); |
| 2221 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; |
| 2222 } |
| 2223 |
2095 Statement* Parser::DesugarLexicalBindingsInForStatement( | 2224 Statement* Parser::DesugarLexicalBindingsInForStatement( |
2096 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 2225 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
2097 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { | 2226 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { |
2098 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 2227 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
2099 // copied into a new environment. Moreover, the "next" statement must be | 2228 // copied into a new environment. Moreover, the "next" statement must be |
2100 // evaluated not in the environment of the just completed iteration but in | 2229 // evaluated not in the environment of the just completed iteration but in |
2101 // that of the upcoming one. We achieve this with the following desugaring. | 2230 // that of the upcoming one. We achieve this with the following desugaring. |
2102 // Extra care is needed to preserve the completion value of the original loop. | 2231 // Extra care is needed to preserve the completion value of the original loop. |
2103 // | 2232 // |
2104 // We are given a for statement of the form | 2233 // We are given a for statement of the form |
(...skipping 1813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3918 // The operand needs to be evaluated on a separate statement in order to get | 4047 // The operand needs to be evaluated on a separate statement in order to get |
3919 // a break location, and the .promise needs to be read earlier so that it | 4048 // a break location, and the .promise needs to be read earlier so that it |
3920 // doesn't insert a false location. | 4049 // doesn't insert a false location. |
3921 // TODO(littledan): investigate why this ordering is needed in more detail. | 4050 // TODO(littledan): investigate why this ordering is needed in more detail. |
3922 Variable* generator_object_variable = | 4051 Variable* generator_object_variable = |
3923 function_state_->generator_object_variable(); | 4052 function_state_->generator_object_variable(); |
3924 DCHECK_NOT_NULL(generator_object_variable); | 4053 DCHECK_NOT_NULL(generator_object_variable); |
3925 | 4054 |
3926 const int nopos = kNoSourcePosition; | 4055 const int nopos = kNoSourcePosition; |
3927 | 4056 |
| 4057 if (is_async_generator()) { |
| 4058 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 4059 Expression* generator_object = |
| 4060 factory()->NewVariableProxy(generator_object_variable); |
| 4061 args->Add(generator_object, zone()); |
| 4062 args->Add(value, zone()); |
| 4063 |
| 4064 Expression* await = factory()->NewCallRuntime( |
| 4065 Context::ASYNC_GENERATOR_AWAIT_CAUGHT, args, nopos); |
| 4066 |
| 4067 return factory()->NewYield(generator_object, await, nopos, |
| 4068 Yield::kOnExceptionRethrow, Yield::kAwait); |
| 4069 } |
| 4070 |
3928 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); | 4071 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); |
3929 | 4072 |
3930 Variable* promise = PromiseVariable(); | 4073 Variable* promise = PromiseVariable(); |
3931 | 4074 |
3932 // Wrap value evaluation to provide a break location. | 4075 // Wrap value evaluation to provide a break location. |
3933 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); | 4076 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); |
3934 Expression* value_assignment = factory()->NewAssignment( | 4077 Expression* value_assignment = factory()->NewAssignment( |
3935 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); | 4078 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); |
3936 do_block->statements()->Add( | 4079 do_block->statements()->Add( |
3937 factory()->NewExpressionStatement(value_assignment, value->position()), | 4080 factory()->NewExpressionStatement(value_assignment, value->position()), |
(...skipping 15 matching lines...) Expand all Loading... |
3953 async_function_await_args, nopos); | 4096 async_function_await_args, nopos); |
3954 do_block->statements()->Add( | 4097 do_block->statements()->Add( |
3955 factory()->NewExpressionStatement(async_function_await, await_pos), | 4098 factory()->NewExpressionStatement(async_function_await, await_pos), |
3956 zone()); | 4099 zone()); |
3957 | 4100 |
3958 // Wrap await to provide a break location between value evaluation and yield. | 4101 // Wrap await to provide a break location between value evaluation and yield. |
3959 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); | 4102 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); |
3960 | 4103 |
3961 generator_object = factory()->NewVariableProxy(generator_object_variable); | 4104 generator_object = factory()->NewVariableProxy(generator_object_variable); |
3962 return factory()->NewYield(generator_object, do_expr, nopos, | 4105 return factory()->NewYield(generator_object, do_expr, nopos, |
3963 Yield::kOnExceptionRethrow); | 4106 Yield::kOnExceptionRethrow, Yield::kAwait); |
3964 } | 4107 } |
3965 | 4108 |
3966 class NonPatternRewriter : public AstExpressionRewriter { | 4109 class NonPatternRewriter : public AstExpressionRewriter { |
3967 public: | 4110 public: |
3968 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) | 4111 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) |
3969 : AstExpressionRewriter(stack_limit), parser_(parser) {} | 4112 : AstExpressionRewriter(stack_limit), parser_(parser) {} |
3970 ~NonPatternRewriter() override {} | 4113 ~NonPatternRewriter() override {} |
3971 | 4114 |
3972 private: | 4115 private: |
3973 bool RewriteExpression(Expression* expr) override { | 4116 bool RewriteExpression(Expression* expr) override { |
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5134 | 5277 |
5135 return final_loop; | 5278 return final_loop; |
5136 } | 5279 } |
5137 | 5280 |
5138 #undef CHECK_OK | 5281 #undef CHECK_OK |
5139 #undef CHECK_OK_VOID | 5282 #undef CHECK_OK_VOID |
5140 #undef CHECK_FAILED | 5283 #undef CHECK_FAILED |
5141 | 5284 |
5142 } // namespace internal | 5285 } // namespace internal |
5143 } // namespace v8 | 5286 } // namespace v8 |
OLD | NEW |