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 "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 3318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3329 result_proxy, value_literal, RelocInfo::kNoPosition); | 3329 result_proxy, value_literal, RelocInfo::kNoPosition); |
| 3330 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, | 3330 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, |
| 3331 RelocInfo::kNoPosition); | 3331 RelocInfo::kNoPosition); |
| 3332 if (is_destructuring) { | 3332 if (is_destructuring) { |
| 3333 assign_each = PatternRewriter::RewriteDestructuringAssignment( | 3333 assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| 3334 this, assign_each->AsAssignment(), scope_); | 3334 this, assign_each->AsAssignment(), scope_); |
| 3335 } | 3335 } |
| 3336 } | 3336 } |
| 3337 | 3337 |
| 3338 for_of->Initialize(each, subject, body, | 3338 for_of->Initialize(each, subject, body, |
| 3339 iterator, | |
| 3339 assign_iterator, | 3340 assign_iterator, |
| 3340 next_result, | 3341 next_result, |
| 3341 result_done, | 3342 result_done, |
| 3342 assign_each); | 3343 assign_each); |
| 3343 } else { | 3344 } else { |
| 3344 if (is_destructuring) { | 3345 if (is_destructuring) { |
| 3345 Variable* temp = | 3346 Variable* temp = |
| 3346 scope_->NewTemporary(ast_value_factory()->empty_string()); | 3347 scope_->NewTemporary(ast_value_factory()->empty_string()); |
| 3347 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 3348 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 3348 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( | 3349 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3606 inner_block->set_scope(inner_scope); | 3607 inner_block->set_scope(inner_scope); |
| 3607 } | 3608 } |
| 3608 | 3609 |
| 3609 outer_loop->Initialize(NULL, NULL, NULL, inner_block); | 3610 outer_loop->Initialize(NULL, NULL, NULL, inner_block); |
| 3610 return outer_block; | 3611 return outer_block; |
| 3611 } | 3612 } |
| 3612 | 3613 |
| 3613 | 3614 |
| 3614 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, | 3615 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
| 3615 bool* ok) { | 3616 bool* ok) { |
| 3616 // ForStatement :: | |
| 3617 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | |
| 3618 | |
| 3619 int stmt_pos = peek_position(); | 3617 int stmt_pos = peek_position(); |
| 3620 Statement* init = NULL; | 3618 Statement* init = NULL; |
| 3621 ZoneList<const AstRawString*> lexical_bindings(1, zone()); | 3619 ZoneList<const AstRawString*> lexical_bindings(1, zone()); |
| 3622 | 3620 |
| 3623 // Create an in-between scope for let-bound iteration variables. | 3621 // Create an in-between scope for let-bound iteration variables. |
| 3624 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3622 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 3625 | 3623 |
| 3626 BlockState block_state(&scope_, for_scope); | 3624 BlockState block_state(&scope_, for_scope); |
| 3627 Expect(Token::FOR, CHECK_OK); | 3625 Expect(Token::FOR, CHECK_OK); |
| 3628 Expect(Token::LPAREN, CHECK_OK); | 3626 Expect(Token::LPAREN, CHECK_OK); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3768 VariableProxy* tdz_proxy = | 3766 VariableProxy* tdz_proxy = |
| 3769 NewUnresolved(lexical_bindings[i], LET); | 3767 NewUnresolved(lexical_bindings[i], LET); |
| 3770 Declaration* tdz_decl = factory()->NewVariableDeclaration( | 3768 Declaration* tdz_decl = factory()->NewVariableDeclaration( |
| 3771 tdz_proxy, LET, scope_, RelocInfo::kNoPosition); | 3769 tdz_proxy, LET, scope_, RelocInfo::kNoPosition); |
| 3772 Variable* tdz_var = Declare( | 3770 Variable* tdz_var = Declare( |
| 3773 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 3771 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 3774 tdz_var->set_initializer_position(position()); | 3772 tdz_var->set_initializer_position(position()); |
| 3775 } | 3773 } |
| 3776 } | 3774 } |
| 3777 | 3775 |
| 3776 if (loop->IsForOfStatement()) { | |
| 3777 FinalizeForOfStatement( | |
| 3778 loop->AsForOfStatement(), RelocInfo::kNoPosition); | |
| 3779 } | |
| 3780 | |
| 3778 for_scope->set_end_position(scanner()->location().end_pos); | 3781 for_scope->set_end_position(scanner()->location().end_pos); |
| 3779 for_scope = for_scope->FinalizeBlockScope(); | 3782 for_scope = for_scope->FinalizeBlockScope(); |
| 3780 // Parsed for-in loop w/ variable declarations. | 3783 // Parsed for-in loop w/ variable declarations. |
| 3781 if (init_block != nullptr) { | 3784 if (init_block != nullptr) { |
| 3782 init_block->statements()->Add(loop, zone()); | 3785 init_block->statements()->Add(loop, zone()); |
| 3783 init_block->set_scope(for_scope); | 3786 init_block->set_scope(for_scope); |
| 3784 return init_block; | 3787 return init_block; |
| 3785 } else { | 3788 } else { |
| 3786 DCHECK_NULL(for_scope); | 3789 DCHECK_NULL(for_scope); |
| 3787 return loop; | 3790 return loop; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3854 block->statements()->Add(body, zone()); | 3857 block->statements()->Add(body, zone()); |
| 3855 InitializeForEachStatement(loop, expression, enumerable, block, | 3858 InitializeForEachStatement(loop, expression, enumerable, block, |
| 3856 is_destructuring); | 3859 is_destructuring); |
| 3857 body_scope->set_end_position(scanner()->location().end_pos); | 3860 body_scope->set_end_position(scanner()->location().end_pos); |
| 3858 body_scope = body_scope->FinalizeBlockScope(); | 3861 body_scope = body_scope->FinalizeBlockScope(); |
| 3859 block->set_scope(body_scope); | 3862 block->set_scope(body_scope); |
| 3860 for_scope->set_end_position(scanner()->location().end_pos); | 3863 for_scope->set_end_position(scanner()->location().end_pos); |
| 3861 for_scope = for_scope->FinalizeBlockScope(); | 3864 for_scope = for_scope->FinalizeBlockScope(); |
| 3862 DCHECK(for_scope == nullptr); | 3865 DCHECK(for_scope == nullptr); |
| 3863 // Parsed for-in loop. | 3866 // Parsed for-in loop. |
| 3867 if (loop->IsForOfStatement()) { | |
| 3868 FinalizeForOfStatement( | |
| 3869 loop->AsForOfStatement(), RelocInfo::kNoPosition); | |
| 3870 } | |
| 3864 return loop; | 3871 return loop; |
| 3865 | 3872 |
| 3866 } else { | 3873 } else { |
| 3867 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); | 3874 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); |
| 3868 } | 3875 } |
| 3869 } | 3876 } |
| 3870 } | 3877 } |
| 3871 | 3878 |
| 3872 // Standard 'for' loop | 3879 // Standard 'for' loop |
| 3873 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); | 3880 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); |
| (...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5734 factory()->NewCallRuntime(Runtime::kAppendElement, | 5741 factory()->NewCallRuntime(Runtime::kAppendElement, |
| 5735 append_element_args, | 5742 append_element_args, |
| 5736 RelocInfo::kNoPosition), | 5743 RelocInfo::kNoPosition), |
| 5737 RelocInfo::kNoPosition); | 5744 RelocInfo::kNoPosition); |
| 5738 } | 5745 } |
| 5739 // for (each of spread) %AppendElement($R, each) | 5746 // for (each of spread) %AppendElement($R, each) |
| 5740 ForEachStatement* loop = factory()->NewForEachStatement( | 5747 ForEachStatement* loop = factory()->NewForEachStatement( |
| 5741 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition); | 5748 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition); |
| 5742 ForOfStatement* for_of = loop->AsForOfStatement(); | 5749 ForOfStatement* for_of = loop->AsForOfStatement(); |
| 5743 for_of->Initialize(factory()->NewVariableProxy(each), subject, | 5750 for_of->Initialize(factory()->NewVariableProxy(each), subject, |
| 5744 append_body, assign_iterator, next_element, | 5751 append_body, iterator, assign_iterator, next_element, |
| 5745 element_done, assign_each); | 5752 element_done, assign_each); |
| 5746 do_block->statements()->Add(for_of, zone()); | 5753 do_block->statements()->Add(for_of, zone()); |
| 5747 } | 5754 } |
| 5748 } | 5755 } |
| 5749 // Now, rewind the original array literal to truncate everything from the | 5756 // Now, rewind the original array literal to truncate everything from the |
| 5750 // first spread (included) until the end. This fixes $R's initialization. | 5757 // first spread (included) until the end. This fixes $R's initialization. |
| 5751 lit->RewindSpreads(); | 5758 lit->RewindSpreads(); |
| 5752 return factory()->NewDoExpression(do_block, result, lit->position()); | 5759 return factory()->NewDoExpression(do_block, result, lit->position()); |
| 5753 } | 5760 } |
| 5754 | 5761 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5892 Expression* ParserTraits::RewriteYieldStar( | 5899 Expression* ParserTraits::RewriteYieldStar( |
| 5893 Expression* generator, Expression* iterable, int pos) { | 5900 Expression* generator, Expression* iterable, int pos) { |
| 5894 | 5901 |
| 5895 const int nopos = RelocInfo::kNoPosition; | 5902 const int nopos = RelocInfo::kNoPosition; |
| 5896 | 5903 |
| 5897 auto factory = parser_->factory(); | 5904 auto factory = parser_->factory(); |
| 5898 auto avfactory = parser_->ast_value_factory(); | 5905 auto avfactory = parser_->ast_value_factory(); |
| 5899 auto scope = parser_->scope_; | 5906 auto scope = parser_->scope_; |
| 5900 auto zone = parser_->zone(); | 5907 auto zone = parser_->zone(); |
| 5901 | 5908 |
| 5902 Statement* skip = factory->NewEmptyStatement(nopos); | |
| 5903 | 5909 |
|
neis
2016/02/12 12:30:13
The changes to RewriteYieldStar are unrelated.
| |
| 5904 // Forward definition for break/continue statements. | 5910 // Forward definition for break/continue statements. |
| 5905 WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos); | 5911 WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos); |
| 5906 | 5912 |
| 5907 | 5913 |
| 5908 // let input = undefined; | 5914 // let input = undefined; |
| 5909 Variable* var_input = scope->NewTemporary(avfactory->empty_string()); | 5915 Variable* var_input = scope->NewTemporary(avfactory->empty_string()); |
| 5910 Statement* initialize_input; | 5916 Statement* initialize_input; |
| 5911 { | 5917 { |
| 5912 Expression* input_proxy = factory->NewVariableProxy(var_input); | 5918 Expression* input_proxy = factory->NewVariableProxy(var_input); |
| 5913 Expression* assignment = factory->NewAssignment( | 5919 Expression* assignment = factory->NewAssignment( |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5964 } | 5970 } |
| 5965 | 5971 |
| 5966 Statement* throw_call; | 5972 Statement* throw_call; |
| 5967 { | 5973 { |
| 5968 Expression* call = NewThrowTypeError( | 5974 Expression* call = NewThrowTypeError( |
| 5969 MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(), | 5975 MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(), |
| 5970 nopos); | 5976 nopos); |
| 5971 throw_call = factory->NewExpressionStatement(call, nopos); | 5977 throw_call = factory->NewExpressionStatement(call, nopos); |
| 5972 } | 5978 } |
| 5973 | 5979 |
| 5974 validate_iterator = | 5980 validate_iterator = factory->NewIfStatement( |
| 5975 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | 5981 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |
| 5976 } | 5982 } |
| 5977 | 5983 |
| 5978 | 5984 |
| 5979 // output = iterator.next(input); | 5985 // output = iterator.next(input); |
| 5980 Statement* call_next; | 5986 Statement* call_next; |
| 5981 { | 5987 { |
| 5982 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); | 5988 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); |
| 5983 Expression* literal = | 5989 Expression* literal = |
| 5984 factory->NewStringLiteral(avfactory->next_string(), nopos); | 5990 factory->NewStringLiteral(avfactory->next_string(), nopos); |
| 5985 Expression* next_property = | 5991 Expression* next_property = |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 6008 | 6014 |
| 6009 Statement* throw_call; | 6015 Statement* throw_call; |
| 6010 { | 6016 { |
| 6011 auto args = new (zone) ZoneList<Expression*>(1, zone); | 6017 auto args = new (zone) ZoneList<Expression*>(1, zone); |
| 6012 args->Add(factory->NewVariableProxy(var_output), zone); | 6018 args->Add(factory->NewVariableProxy(var_output), zone); |
| 6013 Expression* call = factory->NewCallRuntime( | 6019 Expression* call = factory->NewCallRuntime( |
| 6014 Runtime::kThrowIteratorResultNotAnObject, args, nopos); | 6020 Runtime::kThrowIteratorResultNotAnObject, args, nopos); |
| 6015 throw_call = factory->NewExpressionStatement(call, nopos); | 6021 throw_call = factory->NewExpressionStatement(call, nopos); |
| 6016 } | 6022 } |
| 6017 | 6023 |
| 6018 validate_next_output = | 6024 validate_next_output = factory->NewIfStatement( |
| 6019 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | 6025 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |
| 6020 } | 6026 } |
| 6021 | 6027 |
| 6022 | 6028 |
| 6023 // let iteratorThrow = iterator.throw; | 6029 // let iteratorThrow = iterator.throw; |
| 6024 Variable* var_throw = scope->NewTemporary(avfactory->empty_string()); | 6030 Variable* var_throw = scope->NewTemporary(avfactory->empty_string()); |
| 6025 Statement* get_throw; | 6031 Statement* get_throw; |
| 6026 { | 6032 { |
| 6027 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); | 6033 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); |
| 6028 Expression* literal = | 6034 Expression* literal = |
| 6029 factory->NewStringLiteral(avfactory->throw_string(), nopos); | 6035 factory->NewStringLiteral(avfactory->throw_string(), nopos); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 6045 Expression* condition = factory->NewCompareOperation( | 6051 Expression* condition = factory->NewCompareOperation( |
| 6046 Token::EQ, factory->NewVariableProxy(var_throw), | 6052 Token::EQ, factory->NewVariableProxy(var_throw), |
| 6047 factory->NewNullLiteral(nopos), nopos); | 6053 factory->NewNullLiteral(nopos), nopos); |
| 6048 | 6054 |
| 6049 Expression* call = NewThrowTypeError( | 6055 Expression* call = NewThrowTypeError( |
| 6050 MessageTemplate::kThrowMethodMissing, | 6056 MessageTemplate::kThrowMethodMissing, |
| 6051 avfactory->empty_string(), nopos); | 6057 avfactory->empty_string(), nopos); |
| 6052 Statement* throw_call = factory->NewExpressionStatement(call, nopos); | 6058 Statement* throw_call = factory->NewExpressionStatement(call, nopos); |
| 6053 | 6059 |
| 6054 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); | 6060 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); |
| 6055 BuildIteratorClose(then->statements(), var_iterator, Nothing<Variable*>(), | 6061 Variable* var_tmp = scope->NewTemporary(avfactory->empty_string()); |
| 6056 Nothing<Variable*>()); | 6062 BuildIteratorClose( |
| 6063 then->statements(), var_iterator, Nothing<Variable*>(), var_tmp); | |
| 6057 then->statements()->Add(throw_call, zone); | 6064 then->statements()->Add(throw_call, zone); |
| 6058 check_throw = | 6065 check_throw = factory->NewIfStatement( |
| 6059 factory->NewIfStatement(condition, then, skip, nopos); | 6066 condition, then, factory->NewEmptyStatement(nopos), nopos); |
| 6060 } | 6067 } |
| 6061 | 6068 |
| 6062 | 6069 |
| 6063 // output = %_Call(iteratorThrow, iterator, input); | 6070 // output = %_Call(iteratorThrow, iterator, input); |
| 6064 Statement* call_throw; | 6071 Statement* call_throw; |
| 6065 { | 6072 { |
| 6066 auto args = new (zone) ZoneList<Expression*>(3, zone); | 6073 auto args = new (zone) ZoneList<Expression*>(3, zone); |
| 6067 args->Add(factory->NewVariableProxy(var_throw), zone); | 6074 args->Add(factory->NewVariableProxy(var_throw), zone); |
| 6068 args->Add(factory->NewVariableProxy(var_iterator), zone); | 6075 args->Add(factory->NewVariableProxy(var_iterator), zone); |
| 6069 args->Add(factory->NewVariableProxy(var_input), zone); | 6076 args->Add(factory->NewVariableProxy(var_input), zone); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 6088 | 6095 |
| 6089 Statement* throw_call; | 6096 Statement* throw_call; |
| 6090 { | 6097 { |
| 6091 auto args = new (zone) ZoneList<Expression*>(1, zone); | 6098 auto args = new (zone) ZoneList<Expression*>(1, zone); |
| 6092 args->Add(factory->NewVariableProxy(var_output), zone); | 6099 args->Add(factory->NewVariableProxy(var_output), zone); |
| 6093 Expression* call = factory->NewCallRuntime( | 6100 Expression* call = factory->NewCallRuntime( |
| 6094 Runtime::kThrowIteratorResultNotAnObject, args, nopos); | 6101 Runtime::kThrowIteratorResultNotAnObject, args, nopos); |
| 6095 throw_call = factory->NewExpressionStatement(call, nopos); | 6102 throw_call = factory->NewExpressionStatement(call, nopos); |
| 6096 } | 6103 } |
| 6097 | 6104 |
| 6098 validate_throw_output = | 6105 validate_throw_output = factory->NewIfStatement( |
| 6099 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | 6106 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |
| 6100 } | 6107 } |
| 6101 | 6108 |
| 6102 | 6109 |
| 6103 // if (output.done) break; | 6110 // if (output.done) break; |
| 6104 Statement* if_done; | 6111 Statement* if_done; |
| 6105 { | 6112 { |
| 6106 Expression* output_proxy = factory->NewVariableProxy(var_output); | 6113 Expression* output_proxy = factory->NewVariableProxy(var_output); |
| 6107 Expression* literal = | 6114 Expression* literal = |
| 6108 factory->NewStringLiteral(avfactory->done_string(), nopos); | 6115 factory->NewStringLiteral(avfactory->done_string(), nopos); |
| 6109 Expression* property = factory->NewProperty(output_proxy, literal, nopos); | 6116 Expression* property = factory->NewProperty(output_proxy, literal, nopos); |
| 6110 BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos); | 6117 BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos); |
| 6111 if_done = factory->NewIfStatement(property, break_loop, skip, nopos); | 6118 if_done = factory->NewIfStatement( |
| 6119 property, break_loop, factory->NewEmptyStatement(nopos), nopos); | |
| 6112 } | 6120 } |
| 6113 | 6121 |
| 6114 | 6122 |
| 6115 // mode = kReturn; | 6123 // mode = kReturn; |
| 6116 Statement* set_mode_return; | 6124 Statement* set_mode_return; |
| 6117 { | 6125 { |
| 6118 Expression* mode_proxy = factory->NewVariableProxy(var_mode); | 6126 Expression* mode_proxy = factory->NewVariableProxy(var_mode); |
| 6119 Expression* kreturn = | 6127 Expression* kreturn = |
| 6120 factory->NewSmiLiteral(JSGeneratorObject::RETURN, nopos); | 6128 factory->NewSmiLiteral(JSGeneratorObject::RETURN, nopos); |
| 6121 Expression* assignment = | 6129 Expression* assignment = |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6220 | 6228 |
| 6221 // switch (mode) { ... } | 6229 // switch (mode) { ... } |
| 6222 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); | 6230 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); |
| 6223 { | 6231 { |
| 6224 auto case_next = new (zone) ZoneList<Statement*>(3, zone); | 6232 auto case_next = new (zone) ZoneList<Statement*>(3, zone); |
| 6225 case_next->Add(call_next, zone); | 6233 case_next->Add(call_next, zone); |
| 6226 case_next->Add(validate_next_output, zone); | 6234 case_next->Add(validate_next_output, zone); |
| 6227 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 6235 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); |
| 6228 | 6236 |
| 6229 auto case_return = new (zone) ZoneList<Statement*>(5, zone); | 6237 auto case_return = new (zone) ZoneList<Statement*>(5, zone); |
| 6230 BuildIteratorClose( | 6238 BuildIteratorClose(case_return, var_iterator, Just(var_input), var_output); |
| 6231 case_return, var_iterator, Just(var_input), Just(var_output)); | |
| 6232 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 6239 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); |
| 6233 | 6240 |
| 6234 auto case_throw = new (zone) ZoneList<Statement*>(5, zone); | 6241 auto case_throw = new (zone) ZoneList<Statement*>(5, zone); |
| 6235 case_throw->Add(get_throw, zone); | 6242 case_throw->Add(get_throw, zone); |
| 6236 case_throw->Add(check_throw, zone); | 6243 case_throw->Add(check_throw, zone); |
| 6237 case_throw->Add(call_throw, zone); | 6244 case_throw->Add(call_throw, zone); |
| 6238 case_throw->Add(validate_throw_output, zone); | 6245 case_throw->Add(validate_throw_output, zone); |
| 6239 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 6246 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); |
| 6240 | 6247 |
| 6241 auto cases = new (zone) ZoneList<CaseClause*>(3, zone); | 6248 auto cases = new (zone) ZoneList<CaseClause*>(3, zone); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6285 | 6292 |
| 6286 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); | 6293 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); |
| 6287 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); | 6294 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); |
| 6288 Rewriter::Rewrite(parser_, yield_star, avfactory); | 6295 Rewriter::Rewrite(parser_, yield_star, avfactory); |
| 6289 } | 6296 } |
| 6290 | 6297 |
| 6291 return yield_star; | 6298 return yield_star; |
| 6292 } | 6299 } |
| 6293 | 6300 |
| 6294 | 6301 |
| 6295 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | 6302 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, |
|
neis
2016/02/12 12:30:13
The changes to this BuildIteratorClose are unrelat
| |
| 6296 Variable* iterator, | 6303 Variable* iterator, |
| 6297 Maybe<Variable*> input, | 6304 Maybe<Variable*> input, |
| 6298 Maybe<Variable*> output) { | 6305 Variable* var_output) { |
| 6306 // | |
| 6307 // This function adds four statements to [statements], corresponding to the | |
| 6308 // following code: | |
| 6309 // | |
| 6310 // let iteratorReturn = iterator.return; | |
| 6311 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return |input|; | |
| 6312 // output = %_Call(iteratorReturn, iterator|, input|); | |
| 6313 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | |
| 6314 // | |
| 6315 // Here, |...| denotes optional parts, depending on the presence of the | |
| 6316 // input variable. | |
| 6317 // | |
| 6318 | |
| 6299 const int nopos = RelocInfo::kNoPosition; | 6319 const int nopos = RelocInfo::kNoPosition; |
| 6300 auto factory = parser_->factory(); | 6320 auto factory = parser_->factory(); |
| 6301 auto avfactory = parser_->ast_value_factory(); | 6321 auto avfactory = parser_->ast_value_factory(); |
| 6302 auto scope = parser_->scope_; | |
| 6303 auto zone = parser_->zone(); | 6322 auto zone = parser_->zone(); |
| 6304 Statement* skip = factory->NewEmptyStatement(nopos); | 6323 |
| 6305 | 6324 |
| 6306 // let iteratorReturn = iterator.return; | 6325 // let iteratorReturn = iterator.return; |
| 6307 Variable* var = scope->NewTemporary(avfactory->empty_string()); | 6326 Variable* var_return = var_output; // Reusing the output variable. |
| 6308 Statement* get_return; | 6327 Statement* get_return; |
| 6309 { | 6328 { |
| 6310 Expression* iterator_proxy = factory->NewVariableProxy(iterator); | 6329 Expression* iterator_proxy = factory->NewVariableProxy(iterator); |
| 6311 Expression* literal = | 6330 Expression* literal = |
| 6312 factory->NewStringLiteral(avfactory->return_string(), nopos); | 6331 factory->NewStringLiteral(avfactory->return_string(), nopos); |
| 6313 Expression* property = | 6332 Expression* property = |
| 6314 factory->NewProperty(iterator_proxy, literal, nopos); | 6333 factory->NewProperty(iterator_proxy, literal, nopos); |
| 6315 Expression* return_proxy = factory->NewVariableProxy(var); | 6334 Expression* return_proxy = factory->NewVariableProxy(var_return); |
| 6316 Expression* assignment = factory->NewAssignment( | 6335 Expression* assignment = factory->NewAssignment( |
| 6317 Token::ASSIGN, return_proxy, property, nopos); | 6336 Token::ASSIGN, return_proxy, property, nopos); |
| 6318 get_return = factory->NewExpressionStatement(assignment, nopos); | 6337 get_return = factory->NewExpressionStatement(assignment, nopos); |
| 6319 } | 6338 } |
| 6320 | 6339 |
| 6321 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return; OR | 6340 |
| 6322 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input; | 6341 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return |input|; |
| 6323 Statement* check_return; | 6342 Statement* check_return; |
| 6324 { | 6343 { |
| 6325 Expression* condition = factory->NewCompareOperation( | 6344 Expression* condition = factory->NewCompareOperation( |
| 6326 Token::EQ, factory->NewVariableProxy(var), | 6345 Token::EQ, factory->NewVariableProxy(var_return), |
| 6327 factory->NewNullLiteral(nopos), nopos); | 6346 factory->NewNullLiteral(nopos), nopos); |
| 6328 | 6347 |
| 6329 Expression* value = input.IsJust() ? | 6348 Expression* value = input.IsJust() ? |
| 6330 static_cast<Expression*>(factory->NewVariableProxy(input.FromJust())) : | 6349 static_cast<Expression*>(factory->NewVariableProxy(input.FromJust())) : |
| 6331 factory->NewUndefinedLiteral(nopos); | 6350 factory->NewUndefinedLiteral(nopos); |
| 6332 | 6351 |
| 6333 Statement* return_undefined = factory->NewReturnStatement(value, nopos); | 6352 Statement* return_undefined = factory->NewReturnStatement(value, nopos); |
| 6334 | 6353 |
| 6335 check_return = | 6354 check_return = factory->NewIfStatement( |
| 6336 factory->NewIfStatement(condition, return_undefined, skip, nopos); | 6355 condition, return_undefined, factory->NewEmptyStatement(nopos), nopos); |
| 6337 } | 6356 } |
| 6338 | 6357 |
| 6339 // let output = %_Call(iteratorReturn, iterator); OR | 6358 |
| 6340 // output = %_Call(iteratorReturn, iterator, input); | 6359 // output = %_Call(iteratorReturn, iterator|, input|); |
| 6341 Statement* call_return; | 6360 Statement* call_return; |
| 6342 { | 6361 { |
| 6343 auto args = new (zone) ZoneList<Expression*>(3, zone); | 6362 auto args = new (zone) ZoneList<Expression*>(3, zone); |
| 6344 args->Add(factory->NewVariableProxy(var), zone); | 6363 args->Add(factory->NewVariableProxy(var_return), zone); |
| 6345 args->Add(factory->NewVariableProxy(iterator), zone); | 6364 args->Add(factory->NewVariableProxy(iterator), zone); |
| 6346 if (input.IsJust()) { | 6365 if (input.IsJust()) { |
| 6347 args->Add(factory->NewVariableProxy(input.FromJust()), zone); | 6366 args->Add(factory->NewVariableProxy(input.FromJust()), zone); |
| 6348 } | 6367 } |
| 6349 | 6368 |
| 6350 Expression* call = | 6369 Expression* call = |
| 6351 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 6370 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 6352 Expression* output_proxy = factory->NewVariableProxy( | 6371 Expression* output_proxy = factory->NewVariableProxy(var_output); |
| 6353 output.IsJust() ? output.FromJust() : var); | |
| 6354 Expression* assignment = factory->NewAssignment( | 6372 Expression* assignment = factory->NewAssignment( |
| 6355 Token::ASSIGN, output_proxy, call, nopos); | 6373 Token::ASSIGN, output_proxy, call, nopos); |
| 6356 call_return = factory->NewExpressionStatement(assignment, nopos); | 6374 call_return = factory->NewExpressionStatement(assignment, nopos); |
| 6357 } | 6375 } |
| 6358 | 6376 |
| 6359 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 6377 |
| 6378 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); | |
| 6360 Statement* validate_output; | 6379 Statement* validate_output; |
| 6361 { | 6380 { |
| 6362 Expression* is_receiver_call; | 6381 Expression* is_receiver_call; |
| 6363 { | 6382 { |
| 6364 auto args = new (zone) ZoneList<Expression*>(1, zone); | 6383 auto args = new (zone) ZoneList<Expression*>(1, zone); |
| 6365 args->Add(factory->NewVariableProxy(var), zone); | 6384 args->Add(factory->NewVariableProxy(var_output), zone); |
| 6366 is_receiver_call = | 6385 is_receiver_call = |
| 6367 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | 6386 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); |
| 6368 } | 6387 } |
| 6369 | 6388 |
| 6370 Statement* throw_call; | 6389 Statement* throw_call; |
| 6371 { | 6390 { |
| 6372 auto args = new (zone) ZoneList<Expression*>(1, zone); | 6391 auto args = new (zone) ZoneList<Expression*>(1, zone); |
| 6373 args->Add(factory->NewVariableProxy(var), zone); | 6392 args->Add(factory->NewVariableProxy(var_output), zone); |
| 6374 Expression* call = factory->NewCallRuntime( | 6393 Expression* call = factory->NewCallRuntime( |
| 6375 Runtime::kThrowIteratorResultNotAnObject, args, nopos); | 6394 Runtime::kThrowIteratorResultNotAnObject, args, nopos); |
| 6376 throw_call = factory->NewExpressionStatement(call, nopos); | 6395 throw_call = factory->NewExpressionStatement(call, nopos); |
| 6377 } | 6396 } |
| 6378 | 6397 |
| 6379 validate_output = | 6398 validate_output = factory->NewIfStatement( |
| 6380 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); | 6399 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |
| 6381 } | 6400 } |
| 6382 | 6401 |
| 6402 | |
| 6383 statements->Add(get_return, zone); | 6403 statements->Add(get_return, zone); |
| 6384 statements->Add(check_return, zone); | 6404 statements->Add(check_return, zone); |
| 6385 statements->Add(call_return, zone); | 6405 statements->Add(call_return, zone); |
| 6386 statements->Add(validate_output, zone); | 6406 statements->Add(validate_output, zone); |
| 6387 } | 6407 } |
| 6388 | 6408 |
| 6389 | 6409 |
| 6410 | |
| 6411 | |
| 6412 | |
| 6413 | |
| 6414 | |
| 6415 | |
| 6416 | |
| 6417 | |
| 6418 | |
| 6419 enum { THROW, RETURN_OR_BREAK, NORMAL }; | |
| 6420 | |
| 6421 | |
| 6422 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | |
| 6423 Variable* iterator, | |
| 6424 Variable* completion) { | |
| 6425 // | |
| 6426 // This function adds two statements to [statements], corresponding to the | |
| 6427 // following code: | |
| 6428 // | |
| 6429 // let iteratorReturn = iterator.return; | |
| 6430 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | |
| 6431 // let output; | |
| 6432 // if (completion === THROW) { | |
| 6433 // if (!IS_CALLABLE(iteratorReturn)) { | |
| 6434 // throw MakeTypeError(kReturnMethodNotCallable); | |
| 6435 // } | |
| 6436 // try { output = %_Call(iteratorReturn, iterator) } catch (_) { } | |
| 6437 // } else { | |
| 6438 // output = %_Call(iteratorReturn, iterator); | |
| 6439 // } | |
| 6440 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | |
| 6441 // } | |
| 6442 // | |
| 6443 | |
| 6444 const int nopos = RelocInfo::kNoPosition; | |
| 6445 auto factory = parser_->factory(); | |
| 6446 auto avfactory = parser_->ast_value_factory(); | |
| 6447 auto scope = parser_->scope_; | |
| 6448 auto zone = parser_->zone(); | |
| 6449 | |
| 6450 | |
| 6451 // let output; | |
| 6452 Variable* var_output = scope->NewTemporary(avfactory->empty_string()); | |
| 6453 | |
| 6454 | |
| 6455 // let iteratorReturn = iterator.return; | |
| 6456 Variable* var_return = var_output; // Reusing the output variable. | |
| 6457 Statement* get_return; | |
| 6458 { | |
| 6459 Expression* iterator_proxy = factory->NewVariableProxy(iterator); | |
| 6460 Expression* literal = | |
| 6461 factory->NewStringLiteral(avfactory->return_string(), nopos); | |
| 6462 Expression* property = | |
| 6463 factory->NewProperty(iterator_proxy, literal, nopos); | |
| 6464 Expression* return_proxy = factory->NewVariableProxy(var_return); | |
| 6465 Expression* assignment = factory->NewAssignment( | |
| 6466 Token::ASSIGN, return_proxy, property, nopos); | |
| 6467 get_return = factory->NewExpressionStatement(assignment, nopos); | |
| 6468 } | |
| 6469 | |
| 6470 | |
| 6471 // if (!IS_CALLABLE(iteratorReturn)) { | |
| 6472 // throw MakeTypeError(kReturnMethodNotCallable); | |
| 6473 // } | |
| 6474 Statement* check_return_callable; | |
| 6475 { | |
| 6476 Expression* type_of = factory->NewUnaryOperation( | |
| 6477 Token::TYPEOF, factory->NewVariableProxy(var_return), nopos); | |
| 6478 Expression* function_literal = factory->NewStringLiteral( | |
| 6479 avfactory->function_string(), nopos); | |
| 6480 Expression* condition = factory->NewCompareOperation( | |
| 6481 Token::EQ_STRICT, type_of, function_literal, nopos); | |
| 6482 | |
| 6483 Expression* call = NewThrowTypeError( | |
| 6484 MessageTemplate::kReturnMethodNotCallable, | |
| 6485 avfactory->empty_string(), nopos); | |
| 6486 Statement* throw_call = factory->NewExpressionStatement(call, nopos); | |
| 6487 | |
| 6488 check_return_callable = factory->NewIfStatement( | |
| 6489 condition, factory->NewEmptyStatement(nopos), throw_call, nopos); | |
| 6490 } | |
| 6491 | |
| 6492 | |
| 6493 // output = %_Call(iteratorReturn, iterator); | |
| 6494 Statement* call_return; | |
| 6495 { | |
| 6496 auto args = new (zone) ZoneList<Expression*>(2, zone); | |
| 6497 args->Add(factory->NewVariableProxy(var_return), zone); | |
| 6498 args->Add(factory->NewVariableProxy(iterator), zone); | |
| 6499 Expression* call = | |
| 6500 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | |
| 6501 | |
| 6502 Expression* output_proxy = factory->NewVariableProxy(var_output); | |
| 6503 Expression* assignment = factory->NewAssignment( | |
| 6504 Token::ASSIGN, output_proxy, call, nopos); | |
| 6505 call_return = factory->NewExpressionStatement(assignment, nopos); | |
| 6506 } | |
| 6507 | |
| 6508 | |
| 6509 // try { output = %_Call(iteratorReturn, iterator) } catch (_) { } | |
| 6510 Statement* try_call_return; | |
| 6511 { | |
| 6512 auto args = new (zone) ZoneList<Expression*>(2, zone); | |
| 6513 args->Add(factory->NewVariableProxy(var_return), zone); | |
| 6514 args->Add(factory->NewVariableProxy(iterator), zone); | |
| 6515 | |
| 6516 Expression* call = | |
| 6517 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | |
| 6518 Expression* assignment = factory->NewAssignment( | |
| 6519 Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos); | |
| 6520 | |
| 6521 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | |
| 6522 try_block->statements()->Add( | |
| 6523 factory->NewExpressionStatement(assignment, nopos), zone); | |
| 6524 | |
| 6525 Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos); | |
| 6526 | |
| 6527 Scope* catch_scope = NewScope(scope, CATCH_SCOPE); | |
| 6528 Variable* catch_variable = catch_scope->DeclareLocal( | |
| 6529 avfactory->dot_catch_string(), VAR, kCreatedInitialized, | |
| 6530 Variable::NORMAL); | |
| 6531 | |
| 6532 try_call_return = factory->NewTryCatchStatement( | |
| 6533 try_block, catch_scope, catch_variable, catch_block, nopos); | |
| 6534 } | |
| 6535 | |
| 6536 | |
| 6537 // if (completion === THROW) { | |
| 6538 // #check_return_callable; | |
| 6539 // #try_call_return; | |
| 6540 // } else { | |
| 6541 // #call_return; | |
| 6542 // } | |
| 6543 Statement* call_return_carefully; | |
| 6544 { | |
| 6545 Expression* condition = factory->NewCompareOperation( | |
| 6546 Token::EQ_STRICT, factory->NewVariableProxy(completion), | |
| 6547 factory->NewSmiLiteral(THROW, nopos), nopos); | |
| 6548 | |
| 6549 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); | |
| 6550 then_block->statements()->Add(check_return_callable, zone); | |
| 6551 then_block->statements()->Add(try_call_return, zone); | |
| 6552 | |
| 6553 call_return_carefully = | |
| 6554 factory->NewIfStatement(condition, then_block, call_return, nopos); | |
| 6555 } | |
| 6556 | |
| 6557 | |
| 6558 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); | |
| 6559 Statement* validate_output; | |
| 6560 { | |
| 6561 Expression* is_receiver_call; | |
| 6562 { | |
| 6563 auto args = new (zone) ZoneList<Expression*>(1, zone); | |
| 6564 args->Add(factory->NewVariableProxy(var_output), zone); | |
| 6565 is_receiver_call = | |
| 6566 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | |
| 6567 } | |
| 6568 | |
| 6569 Statement* throw_call; | |
| 6570 { | |
| 6571 auto args = new (zone) ZoneList<Expression*>(1, zone); | |
| 6572 args->Add(factory->NewVariableProxy(var_output), zone); | |
| 6573 Expression* call = factory->NewCallRuntime( | |
| 6574 Runtime::kThrowIteratorResultNotAnObject, args, nopos); | |
| 6575 throw_call = factory->NewExpressionStatement(call, nopos); | |
| 6576 } | |
| 6577 | |
| 6578 validate_output = factory->NewIfStatement( | |
| 6579 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); | |
| 6580 } | |
| 6581 | |
| 6582 | |
| 6583 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } | |
| 6584 Statement* maybe_call_return; | |
| 6585 { | |
| 6586 Expression* condition = factory->NewCompareOperation( | |
| 6587 Token::EQ, factory->NewVariableProxy(var_return), | |
| 6588 factory->NewNullLiteral(nopos), nopos); | |
| 6589 | |
| 6590 Block* block = factory->NewBlock(nullptr, 2, false, nopos); | |
| 6591 block->statements()->Add(call_return_carefully, zone); | |
| 6592 block->statements()->Add(validate_output, zone); // GAGA | |
| 6593 | |
| 6594 maybe_call_return = factory->NewIfStatement( | |
| 6595 condition, factory->NewEmptyStatement(nopos), block, nopos); | |
| 6596 } | |
| 6597 | |
| 6598 | |
| 6599 statements->Add(get_return, zone); | |
| 6600 statements->Add(maybe_call_return, zone); | |
| 6601 } | |
| 6602 | |
| 6603 | |
| 6604 void ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { | |
| 6605 // | |
| 6606 // This function replaces the loop's body with the following wrapping: | |
| 6607 // | |
| 6608 // let completion = RETURN_OR_BREAK; | |
| 6609 // try { | |
| 6610 // #body; | |
| 6611 // {{completion = NORMAL}}; | |
| 6612 // } catch(e) { | |
| 6613 // completion = THROW; | |
| 6614 // throw e; | |
| 6615 // } finally { | |
| 6616 // if (completion !== NORMAL) { | |
| 6617 // #BuildIteratorClose(iterator, completion) // See above. | |
| 6618 // } | |
| 6619 // } | |
| 6620 // | |
| 6621 | |
| 6622 const int nopos = RelocInfo::kNoPosition; | |
| 6623 auto factory = parser_->factory(); | |
| 6624 auto avfactory = parser_->ast_value_factory(); | |
| 6625 auto scope = parser_->scope_; | |
| 6626 auto zone = parser_->zone(); | |
| 6627 | |
| 6628 | |
| 6629 // let completion = RETURN_OR_BREAK; | |
| 6630 Variable* var_completion = scope->NewTemporary(avfactory->empty_string()); | |
| 6631 Statement* initialize_completion; | |
| 6632 { | |
| 6633 Expression* proxy = factory->NewVariableProxy(var_completion); | |
| 6634 Expression* assignment = factory->NewAssignment( | |
| 6635 Token::ASSIGN, proxy, | |
| 6636 factory->NewSmiLiteral(RETURN_OR_BREAK, nopos), nopos); | |
| 6637 initialize_completion = | |
| 6638 factory->NewExpressionStatement(assignment, nopos); | |
| 6639 } | |
| 6640 | |
| 6641 | |
| 6642 // {{completion = NORMAL}} | |
| 6643 Statement* set_completion_normal; | |
| 6644 { | |
| 6645 Expression* proxy = factory->NewVariableProxy(var_completion); | |
| 6646 Expression* assignment = factory->NewAssignment( | |
| 6647 Token::ASSIGN, proxy, factory->NewSmiLiteral(NORMAL, nopos), nopos); | |
| 6648 | |
| 6649 Block* block = factory->NewBlock(nullptr, 1, true, nopos); | |
| 6650 block->statements()->Add( | |
| 6651 factory->NewExpressionStatement(assignment, nopos), zone); | |
| 6652 set_completion_normal = block; | |
| 6653 } | |
| 6654 | |
| 6655 | |
| 6656 // completion = THROW; | |
| 6657 Statement* set_completion_throw; | |
| 6658 { | |
| 6659 Expression* proxy = factory->NewVariableProxy(var_completion); | |
| 6660 Expression* assignment = factory->NewAssignment( | |
| 6661 Token::ASSIGN, proxy, factory->NewSmiLiteral(THROW, nopos), nopos); | |
| 6662 set_completion_throw = factory->NewExpressionStatement(assignment, nopos); | |
| 6663 } | |
| 6664 | |
| 6665 | |
| 6666 // #body; | |
| 6667 // #set_completion_normal; | |
| 6668 Block* try_block; | |
| 6669 { | |
| 6670 try_block = factory->NewBlock(nullptr, 2, false, nopos); | |
| 6671 try_block->statements()->Add(loop->body(), zone); | |
| 6672 try_block->statements()->Add(set_completion_normal, zone); | |
| 6673 } | |
| 6674 | |
| 6675 | |
| 6676 // if (completion !== NORMAL) { | |
| 6677 // #BuildIteratorClose | |
| 6678 // } | |
| 6679 Block* maybe_close; | |
| 6680 { | |
| 6681 Expression* condition = factory->NewCompareOperation( | |
| 6682 Token::EQ_STRICT, factory->NewVariableProxy(var_completion), | |
| 6683 factory->NewSmiLiteral(NORMAL, nopos), nopos); | |
| 6684 | |
| 6685 Block* block = factory->NewBlock(nullptr, 2, false, nopos); | |
| 6686 BuildIteratorClose( | |
| 6687 block->statements(), loop->iterator(), var_completion); | |
| 6688 DCHECK(block->statements()->length() == 2); | |
| 6689 | |
| 6690 maybe_close = factory->NewBlock(nullptr, 1, false, nopos); | |
| 6691 maybe_close->statements()->Add(factory->NewIfStatement( | |
| 6692 condition, factory->NewEmptyStatement(nopos), block, nopos), zone); | |
| 6693 } | |
| 6694 | |
| 6695 | |
| 6696 // try { #try_block } | |
| 6697 // catch(e) { | |
| 6698 // #set_completion_throw; | |
| 6699 // throw e; | |
| 6700 // } | |
| 6701 Statement* try_catch; | |
| 6702 { | |
| 6703 Block* catch_block; | |
| 6704 Scope* catch_scope = NewScope(scope, CATCH_SCOPE); | |
| 6705 Variable* catch_variable = catch_scope->DeclareLocal( | |
| 6706 avfactory->dot_catch_string(), VAR, kCreatedInitialized, | |
| 6707 Variable::NORMAL); | |
| 6708 | |
| 6709 Statement* rethrow; | |
| 6710 { | |
| 6711 Expression* proxy = factory->NewVariableProxy(catch_variable); | |
| 6712 rethrow = factory->NewExpressionStatement( | |
| 6713 factory->NewThrow(proxy, nopos), nopos); | |
| 6714 } | |
| 6715 | |
| 6716 catch_block = factory->NewBlock(nullptr, 2, false, nopos); | |
| 6717 catch_block->statements()->Add(set_completion_throw, zone); | |
| 6718 catch_block->statements()->Add(rethrow, zone); | |
| 6719 | |
| 6720 try_catch = factory->NewTryCatchStatement( | |
| 6721 try_block, catch_scope, catch_variable, catch_block, nopos); | |
| 6722 } | |
| 6723 | |
| 6724 | |
| 6725 // try { #try_catch } finally { #maybe_close } | |
| 6726 Statement* try_finally; | |
| 6727 { | |
| 6728 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | |
| 6729 try_block->statements()->Add(try_catch, zone); | |
| 6730 | |
| 6731 try_finally = | |
| 6732 factory->NewTryFinallyStatement(try_block, maybe_close, nopos); | |
| 6733 } | |
| 6734 | |
| 6735 | |
| 6736 // #initialize_completion; | |
| 6737 // #try_finally; | |
| 6738 Statement* new_body; | |
| 6739 { | |
| 6740 Block* block = factory->NewBlock(nullptr, 2, false, nopos); | |
| 6741 block->statements()->Add(initialize_completion, zone); | |
| 6742 block->statements()->Add(try_finally, zone); | |
| 6743 new_body = block; | |
| 6744 } | |
| 6745 | |
| 6746 | |
| 6747 loop->set_body(new_body); | |
| 6748 } | |
| 6749 | |
| 6750 | |
| 6390 } // namespace internal | 6751 } // namespace internal |
| 6391 } // namespace v8 | 6752 } // namespace v8 |
| OLD | NEW |