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 "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 5791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5802 // | 5802 // |
5803 // while (true) { | 5803 // while (true) { |
5804 // // From the generator to the iterator: | 5804 // // From the generator to the iterator: |
5805 // // Forward input according to resume mode and obtain output. | 5805 // // Forward input according to resume mode and obtain output. |
5806 // switch (mode) { | 5806 // switch (mode) { |
5807 // case kNext: | 5807 // case kNext: |
5808 // output = iterator.next(input); | 5808 // output = iterator.next(input); |
5809 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 5809 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
5810 // break; | 5810 // break; |
5811 // case kReturn: | 5811 // case kReturn: |
5812 // IteratorClose(iterator, input); // See below. | 5812 // IteratorClose(iterator, input, output); // See below. |
5813 // break; | 5813 // break; |
5814 // case kThrow: | 5814 // case kThrow: |
5815 // let iteratorThrow = iterator.throw; | 5815 // let iteratorThrow = iterator.throw; |
5816 // if (IS_NULL_OR_UNDEFINED(iteratorThrow)) { | 5816 // if (IS_NULL_OR_UNDEFINED(iteratorThrow)) { |
5817 // IteratorClose(iterator); // See below. | 5817 // IteratorClose(iterator); // See below. |
5818 // throw MakeTypeError(kThrowMethodMissing); | 5818 // throw MakeTypeError(kThrowMethodMissing); |
5819 // } | 5819 // } |
5820 // output = %_Call(iteratorThrow, iterator, input); | 5820 // output = %_Call(iteratorThrow, iterator, input); |
5821 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 5821 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
5822 // break; | 5822 // break; |
(...skipping 16 matching lines...) Expand all Loading... |
5839 // } | 5839 // } |
5840 // } | 5840 // } |
5841 // | 5841 // |
5842 // output.value; | 5842 // output.value; |
5843 // } | 5843 // } |
5844 // | 5844 // |
5845 // IteratorClose(iterator) expands to the following: | 5845 // IteratorClose(iterator) expands to the following: |
5846 // | 5846 // |
5847 // let iteratorReturn = iterator.return; | 5847 // let iteratorReturn = iterator.return; |
5848 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return; | 5848 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return; |
5849 // let result = %_Call(iteratorReturn, iterator); | 5849 // let output = %_Call(iteratorReturn, iterator); |
5850 // if (!IS_RECEIVER(result)) %ThrowIterResultNotAnObject(result); | 5850 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
5851 // | 5851 // |
5852 // IteratorClose(iterator, input) expands to the following: | 5852 // IteratorClose(iterator, input, output) expands to the following: |
5853 // | 5853 // |
5854 // let iteratorReturn = iterator.return; | 5854 // let iteratorReturn = iterator.return; |
5855 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; | 5855 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; |
5856 // let result = %_Call(iteratorReturn, iterator, input); | 5856 // output = %_Call(iteratorReturn, iterator, input); |
5857 // if (!IS_RECEIVER(result)) %ThrowIterResultNotAnObject(result); | 5857 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
5858 | 5858 |
5859 | 5859 |
5860 Expression* ParserTraits::RewriteYieldStar( | 5860 Expression* ParserTraits::RewriteYieldStar( |
5861 Expression* generator, Expression* iterable, int pos) { | 5861 Expression* generator, Expression* iterable, int pos) { |
5862 | 5862 |
5863 const int nopos = RelocInfo::kNoPosition; | 5863 const int nopos = RelocInfo::kNoPosition; |
5864 | 5864 |
5865 auto factory = parser_->factory(); | 5865 auto factory = parser_->factory(); |
5866 auto avfactory = parser_->ast_value_factory(); | 5866 auto avfactory = parser_->ast_value_factory(); |
5867 auto scope = parser_->scope_; | 5867 auto scope = parser_->scope_; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6016 Expression* condition = factory->NewCompareOperation( | 6016 Expression* condition = factory->NewCompareOperation( |
6017 Token::EQ, factory->NewVariableProxy(var_throw), | 6017 Token::EQ, factory->NewVariableProxy(var_throw), |
6018 factory->NewNullLiteral(nopos), nopos); | 6018 factory->NewNullLiteral(nopos), nopos); |
6019 | 6019 |
6020 Expression* call = NewThrowTypeError( | 6020 Expression* call = NewThrowTypeError( |
6021 MessageTemplate::kThrowMethodMissing, | 6021 MessageTemplate::kThrowMethodMissing, |
6022 avfactory->empty_string(), nopos); | 6022 avfactory->empty_string(), nopos); |
6023 Statement* throw_call = factory->NewExpressionStatement(call, nopos); | 6023 Statement* throw_call = factory->NewExpressionStatement(call, nopos); |
6024 | 6024 |
6025 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); | 6025 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); |
6026 BuildIteratorClose(then->statements(), var_iterator, Nothing<Variable*>()); | 6026 BuildIteratorClose(then->statements(), var_iterator, Nothing<Variable*>(), |
| 6027 Nothing<Variable*>()); |
6027 then->statements()->Add(throw_call, zone); | 6028 then->statements()->Add(throw_call, zone); |
6028 check_throw = | 6029 check_throw = |
6029 factory->NewIfStatement(condition, then, skip, nopos); | 6030 factory->NewIfStatement(condition, then, skip, nopos); |
6030 } | 6031 } |
6031 | 6032 |
6032 | 6033 |
6033 // output = %_Call(iteratorThrow, iterator, input); | 6034 // output = %_Call(iteratorThrow, iterator, input); |
6034 Statement* call_throw; | 6035 Statement* call_throw; |
6035 { | 6036 { |
6036 auto args = new (zone) ZoneList<Expression*>(3, zone); | 6037 auto args = new (zone) ZoneList<Expression*>(3, zone); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6188 | 6189 |
6189 // switch (mode) { ... } | 6190 // switch (mode) { ... } |
6190 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); | 6191 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); |
6191 { | 6192 { |
6192 auto case_next = new (zone) ZoneList<Statement*>(3, zone); | 6193 auto case_next = new (zone) ZoneList<Statement*>(3, zone); |
6193 case_next->Add(call_next, zone); | 6194 case_next->Add(call_next, zone); |
6194 case_next->Add(validate_next_output, zone); | 6195 case_next->Add(validate_next_output, zone); |
6195 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 6196 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); |
6196 | 6197 |
6197 auto case_return = new (zone) ZoneList<Statement*>(5, zone); | 6198 auto case_return = new (zone) ZoneList<Statement*>(5, zone); |
6198 BuildIteratorClose(case_return, var_iterator, Just(var_input)); | 6199 BuildIteratorClose( |
| 6200 case_return, var_iterator, Just(var_input), Just(var_output)); |
6199 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 6201 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); |
6200 | 6202 |
6201 auto case_throw = new (zone) ZoneList<Statement*>(5, zone); | 6203 auto case_throw = new (zone) ZoneList<Statement*>(5, zone); |
6202 case_throw->Add(get_throw, zone); | 6204 case_throw->Add(get_throw, zone); |
6203 case_throw->Add(check_throw, zone); | 6205 case_throw->Add(check_throw, zone); |
6204 case_throw->Add(call_throw, zone); | 6206 case_throw->Add(call_throw, zone); |
6205 case_throw->Add(validate_throw_output, zone); | 6207 case_throw->Add(validate_throw_output, zone); |
6206 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 6208 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); |
6207 | 6209 |
6208 auto cases = new (zone) ZoneList<CaseClause*>(3, zone); | 6210 auto cases = new (zone) ZoneList<CaseClause*>(3, zone); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6252 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); | 6254 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); |
6253 Rewriter::Rewrite(parser_, yield_star, avfactory); | 6255 Rewriter::Rewrite(parser_, yield_star, avfactory); |
6254 } | 6256 } |
6255 | 6257 |
6256 return yield_star; | 6258 return yield_star; |
6257 } | 6259 } |
6258 | 6260 |
6259 | 6261 |
6260 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | 6262 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, |
6261 Variable* iterator, | 6263 Variable* iterator, |
6262 Maybe<Variable*> input) { | 6264 Maybe<Variable*> input, |
| 6265 Maybe<Variable*> output) { |
6263 const int nopos = RelocInfo::kNoPosition; | 6266 const int nopos = RelocInfo::kNoPosition; |
6264 auto factory = parser_->factory(); | 6267 auto factory = parser_->factory(); |
6265 auto avfactory = parser_->ast_value_factory(); | 6268 auto avfactory = parser_->ast_value_factory(); |
6266 auto scope = parser_->scope_; | 6269 auto scope = parser_->scope_; |
6267 auto zone = parser_->zone(); | 6270 auto zone = parser_->zone(); |
6268 Statement* skip = factory->NewEmptyStatement(nopos); | 6271 Statement* skip = factory->NewEmptyStatement(nopos); |
6269 | 6272 |
6270 // let iteratorReturn = iterator.return; | 6273 // let iteratorReturn = iterator.return; |
6271 Variable* var = scope->NewTemporary(avfactory->empty_string()); | 6274 Variable* var = scope->NewTemporary(avfactory->empty_string()); |
6272 Statement* get_return; | 6275 Statement* get_return; |
(...skipping 20 matching lines...) Expand all Loading... |
6293 Expression* value = input.IsJust() ? | 6296 Expression* value = input.IsJust() ? |
6294 static_cast<Expression*>(factory->NewVariableProxy(input.FromJust())) : | 6297 static_cast<Expression*>(factory->NewVariableProxy(input.FromJust())) : |
6295 factory->NewUndefinedLiteral(nopos); | 6298 factory->NewUndefinedLiteral(nopos); |
6296 | 6299 |
6297 Statement* return_undefined = factory->NewReturnStatement(value, nopos); | 6300 Statement* return_undefined = factory->NewReturnStatement(value, nopos); |
6298 | 6301 |
6299 check_return = | 6302 check_return = |
6300 factory->NewIfStatement(condition, return_undefined, skip, nopos); | 6303 factory->NewIfStatement(condition, return_undefined, skip, nopos); |
6301 } | 6304 } |
6302 | 6305 |
6303 // let result = %_Call(iteratorReturn, iterator); OR | 6306 // let output = %_Call(iteratorReturn, iterator); OR |
6304 // let result = %_Call(iteratorReturn, iterator, input); | 6307 // output = %_Call(iteratorReturn, iterator, input); |
6305 Statement* call_return; | 6308 Statement* call_return; |
6306 { | 6309 { |
6307 auto args = new (zone) ZoneList<Expression*>(3, zone); | 6310 auto args = new (zone) ZoneList<Expression*>(3, zone); |
6308 args->Add(factory->NewVariableProxy(var), zone); | 6311 args->Add(factory->NewVariableProxy(var), zone); |
6309 args->Add(factory->NewVariableProxy(iterator), zone); | 6312 args->Add(factory->NewVariableProxy(iterator), zone); |
6310 if (input.IsJust()) { | 6313 if (input.IsJust()) { |
6311 args->Add(factory->NewVariableProxy(input.FromJust()), zone); | 6314 args->Add(factory->NewVariableProxy(input.FromJust()), zone); |
6312 } | 6315 } |
6313 | 6316 |
6314 Expression* call = | 6317 Expression* call = |
6315 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 6318 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 6319 Expression* output_proxy = factory->NewVariableProxy( |
| 6320 output.IsJust() ? output.FromJust() : var); |
6316 Expression* assignment = factory->NewAssignment( | 6321 Expression* assignment = factory->NewAssignment( |
6317 Token::ASSIGN, factory->NewVariableProxy(var), call, nopos); | 6322 Token::ASSIGN, output_proxy, call, nopos); |
6318 call_return = factory->NewExpressionStatement(assignment, nopos); | 6323 call_return = factory->NewExpressionStatement(assignment, nopos); |
6319 } | 6324 } |
6320 | 6325 |
6321 // if (!IS_RECEIVER(result)) %ThrowIterResultNotAnObject(result); | 6326 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
6322 Statement* validate_result; | 6327 Statement* validate_output; |
6323 { | 6328 { |
6324 Expression* is_receiver_call; | 6329 Expression* is_receiver_call; |
6325 { | 6330 { |
6326 auto args = new (zone) ZoneList<Expression*>(1, zone); | 6331 auto args = new (zone) ZoneList<Expression*>(1, zone); |
6327 args->Add(factory->NewVariableProxy(var), zone); | 6332 args->Add(factory->NewVariableProxy(var), zone); |
6328 is_receiver_call = | 6333 is_receiver_call = |
6329 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | 6334 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); |
6330 } | 6335 } |
6331 | 6336 |
6332 Statement* throw_call; | 6337 Statement* throw_call; |
6333 { | 6338 { |
6334 auto args = new (zone) ZoneList<Expression*>(1, zone); | 6339 auto args = new (zone) ZoneList<Expression*>(1, zone); |
6335 args->Add(factory->NewVariableProxy(var), zone); | 6340 args->Add(factory->NewVariableProxy(var), zone); |
6336 Expression* call = factory->NewCallRuntime( | 6341 Expression* call = factory->NewCallRuntime( |
6337 Runtime::kThrowIteratorResultNotAnObject, args, nopos); | 6342 Runtime::kThrowIteratorResultNotAnObject, args, nopos); |
6338 throw_call = factory->NewExpressionStatement(call, nopos); | 6343 throw_call = factory->NewExpressionStatement(call, nopos); |
6339 } | 6344 } |
6340 | 6345 |
6341 validate_result = | 6346 validate_output = |
6342 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | 6347 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); |
6343 } | 6348 } |
6344 | 6349 |
6345 statements->Add(get_return, zone); | 6350 statements->Add(get_return, zone); |
6346 statements->Add(check_return, zone); | 6351 statements->Add(check_return, zone); |
6347 statements->Add(call_return, zone); | 6352 statements->Add(call_return, zone); |
6348 statements->Add(validate_result, zone); | 6353 statements->Add(validate_output, zone); |
6349 } | 6354 } |
6350 | 6355 |
6351 | 6356 |
6352 } // namespace internal | 6357 } // namespace internal |
6353 } // namespace v8 | 6358 } // namespace v8 |
OLD | NEW |