OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include <set> | 5 #include <set> |
6 | 6 |
7 #include "vm/kernel_to_il.h" | 7 #include "vm/kernel_to_il.h" |
8 | 8 |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/intermediate_language.h" | 10 #include "vm/intermediate_language.h" |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 Field* field = fields[i]; | 808 Field* field = fields[i]; |
809 Expression* initializer = field->initializer(); | 809 Expression* initializer = field->initializer(); |
810 if (!field->IsStatic() && (initializer != NULL)) { | 810 if (!field->IsStatic() && (initializer != NULL)) { |
811 initializer->AcceptExpressionVisitor(this); | 811 initializer->AcceptExpressionVisitor(this); |
812 } | 812 } |
813 } | 813 } |
814 node->VisitChildren(this); | 814 node->VisitChildren(this); |
815 } | 815 } |
816 | 816 |
817 | 817 |
818 class BreakableBlock { | |
819 public: | |
820 BreakableBlock(FlowGraphBuilder* builder, LabeledStatement* statement) | |
821 : builder_(builder), | |
822 labeled_statement_(statement), | |
823 outer_(builder->breakable_block_), | |
824 destination_(NULL), | |
825 outer_finally_(builder->try_finally_block_), | |
826 context_depth_(builder->context_depth_), | |
827 try_index_(builder->CurrentTryIndex()) { | |
828 builder_->breakable_block_ = this; | |
829 } | |
830 ~BreakableBlock() { builder_->breakable_block_ = outer_; } | |
831 | |
832 bool HadJumper() { return destination_ != NULL; } | |
833 | |
834 JoinEntryInstr* destination() { return destination_; } | |
835 | |
836 JoinEntryInstr* BreakDestination(LabeledStatement* label, | |
837 TryFinallyBlock** outer_finally, | |
838 intptr_t* context_depth) { | |
839 BreakableBlock* block = builder_->breakable_block_; | |
840 while (block->labeled_statement_ != label) { | |
841 block = block->outer_; | |
842 } | |
843 ASSERT(block != NULL); | |
844 *outer_finally = block->outer_finally_; | |
845 *context_depth = block->context_depth_; | |
846 return block->EnsureDestination(); | |
847 } | |
848 | |
849 private: | |
850 JoinEntryInstr* EnsureDestination() { | |
851 if (destination_ == NULL) { | |
852 destination_ = builder_->BuildJoinEntry(try_index_); | |
853 } | |
854 return destination_; | |
855 } | |
856 | |
857 FlowGraphBuilder* builder_; | |
858 LabeledStatement* labeled_statement_; | |
859 BreakableBlock* outer_; | |
860 JoinEntryInstr* destination_; | |
861 TryFinallyBlock* outer_finally_; | |
862 intptr_t context_depth_; | |
863 intptr_t try_index_; | |
864 }; | |
865 | |
866 | |
867 class SwitchBlock { | |
868 public: | |
869 SwitchBlock(FlowGraphBuilder* builder, SwitchStatement* switch_stmt) | |
870 : builder_(builder), | |
871 outer_(builder->switch_block_), | |
872 outer_finally_(builder->try_finally_block_), | |
873 switch_statement_(switch_stmt), | |
874 context_depth_(builder->context_depth_), | |
875 try_index_(builder->CurrentTryIndex()) { | |
876 builder_->switch_block_ = this; | |
877 } | |
878 ~SwitchBlock() { builder_->switch_block_ = outer_; } | |
879 | |
880 bool HadJumper(SwitchCase* switch_case) { | |
881 return destinations_.Lookup(switch_case) != NULL; | |
882 } | |
883 | |
884 JoinEntryInstr* Destination(SwitchCase* label, | |
885 TryFinallyBlock** outer_finally = NULL, | |
886 intptr_t* context_depth = NULL) { | |
887 // Find corresponding [SwitchStatement]. | |
888 SwitchBlock* block = this; | |
889 while (true) { | |
890 block->EnsureSwitchCaseMapping(); | |
891 if (block->Contains(label)) break; | |
892 block = block->outer_; | |
893 } | |
894 | |
895 // Set the outer finally block. | |
896 if (outer_finally != NULL) { | |
897 *outer_finally = block->outer_finally_; | |
898 *context_depth = block->context_depth_; | |
899 } | |
900 | |
901 // Ensure there's [JoinEntryInstr] for that [SwitchCase]. | |
902 return block->EnsureDestination(label); | |
903 } | |
904 | |
905 private: | |
906 typedef std::set<SwitchCase*> DestinationSwitches; | |
907 | |
908 JoinEntryInstr* EnsureDestination(SwitchCase* switch_case) { | |
909 JoinEntryInstr* cached_inst = destinations_.Lookup(switch_case); | |
910 if (cached_inst == NULL) { | |
911 JoinEntryInstr* inst = builder_->BuildJoinEntry(try_index_); | |
912 destinations_.Insert(switch_case, inst); | |
913 return inst; | |
914 } | |
915 return cached_inst; | |
916 } | |
917 | |
918 void EnsureSwitchCaseMapping() { | |
919 if (destination_switches_.begin() == destination_switches_.end()) { | |
920 List<SwitchCase>& cases = switch_statement_->cases(); | |
921 for (intptr_t i = 0; i < cases.length(); i++) { | |
922 destination_switches_.insert(cases[i]); | |
923 } | |
924 } | |
925 } | |
926 | |
927 bool Contains(SwitchCase* sc) { | |
928 return destination_switches_.find(sc) != destination_switches_.end(); | |
929 } | |
930 | |
931 FlowGraphBuilder* builder_; | |
932 SwitchBlock* outer_; | |
933 | |
934 Map<SwitchCase, JoinEntryInstr*> destinations_; | |
935 DestinationSwitches destination_switches_; | |
936 | |
937 TryFinallyBlock* outer_finally_; | |
938 SwitchStatement* switch_statement_; | |
939 intptr_t context_depth_; | |
940 intptr_t try_index_; | |
941 }; | |
942 | |
943 | |
944 class TryFinallyBlock { | |
945 public: | |
946 TryFinallyBlock(FlowGraphBuilder* builder, Statement* finalizer) | |
947 : builder_(builder), | |
948 outer_(builder->try_finally_block_), | |
949 finalizer_(finalizer), | |
950 context_depth_(builder->context_depth_), | |
951 // Finalizers are executed outside of the try block hence | |
952 // try depth of finalizers are one less than current try | |
953 // depth. | |
954 try_depth_(builder->try_depth_ - 1), | |
955 try_index_(builder_->CurrentTryIndex()) { | |
956 builder_->try_finally_block_ = this; | |
957 } | |
958 ~TryFinallyBlock() { builder_->try_finally_block_ = outer_; } | |
959 | |
960 Statement* finalizer() const { return finalizer_; } | |
961 intptr_t context_depth() const { return context_depth_; } | |
962 intptr_t try_depth() const { return try_depth_; } | |
963 intptr_t try_index() const { return try_index_; } | |
964 TryFinallyBlock* outer() const { return outer_; } | |
965 | |
966 private: | |
967 FlowGraphBuilder* const builder_; | |
968 TryFinallyBlock* const outer_; | |
969 Statement* const finalizer_; | |
970 const intptr_t context_depth_; | |
971 const intptr_t try_depth_; | |
972 const intptr_t try_index_; | |
973 }; | |
974 | |
975 | |
976 class TryCatchBlock { | |
977 public: | |
978 explicit TryCatchBlock(FlowGraphBuilder* builder, | |
979 intptr_t try_handler_index = -1) | |
980 : builder_(builder), | |
981 outer_(builder->try_catch_block_), | |
982 try_index_(try_handler_index) { | |
983 if (try_index_ == -1) try_index_ = builder->AllocateTryIndex(); | |
984 builder->try_catch_block_ = this; | |
985 } | |
986 ~TryCatchBlock() { builder_->try_catch_block_ = outer_; } | |
987 | |
988 intptr_t try_index() { return try_index_; } | |
989 TryCatchBlock* outer() const { return outer_; } | |
990 | |
991 private: | |
992 FlowGraphBuilder* builder_; | |
993 TryCatchBlock* outer_; | |
994 intptr_t try_index_; | |
995 }; | |
996 | |
997 | |
998 Fragment& Fragment::operator+=(const Fragment& other) { | 818 Fragment& Fragment::operator+=(const Fragment& other) { |
999 if (entry == NULL) { | 819 if (entry == NULL) { |
1000 entry = other.entry; | 820 entry = other.entry; |
1001 current = other.current; | 821 current = other.current; |
1002 } else if (current != NULL && other.entry != NULL) { | 822 } else if (current != NULL && other.entry != NULL) { |
1003 current->LinkTo(other.entry); | 823 current->LinkTo(other.entry); |
1004 current = other.current; | 824 current = other.current; |
1005 } | 825 } |
1006 return *this; | 826 return *this; |
1007 } | 827 } |
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2244 try_catch_block_ = try_catch_block_->outer(); | 2064 try_catch_block_ = try_catch_block_->outer(); |
2245 changed_try_index = true; | 2065 changed_try_index = true; |
2246 } | 2066 } |
2247 if (changed_try_index) { | 2067 if (changed_try_index) { |
2248 JoinEntryInstr* entry = BuildJoinEntry(); | 2068 JoinEntryInstr* entry = BuildJoinEntry(); |
2249 instructions += Goto(entry); | 2069 instructions += Goto(entry); |
2250 instructions = Fragment(instructions.entry, entry); | 2070 instructions = Fragment(instructions.entry, entry); |
2251 } | 2071 } |
2252 | 2072 |
2253 Statement* finalizer = try_finally_block_->finalizer(); | 2073 Statement* finalizer = try_finally_block_->finalizer(); |
| 2074 intptr_t finalizer_kernel_offset = |
| 2075 try_finally_block_->finalizer_kernel_offset(); |
2254 try_finally_block_ = try_finally_block_->outer(); | 2076 try_finally_block_ = try_finally_block_->outer(); |
2255 | 2077 if (finalizer != NULL) { |
2256 // This will potentially have exceptional cases as described in | 2078 // This will potentially have exceptional cases as described in |
2257 // [VisitTryFinally] and will handle them. | 2079 // [VisitTryFinally] and will handle them. |
2258 instructions += TranslateStatement(finalizer); | 2080 instructions += TranslateStatement(finalizer); |
| 2081 } else { |
| 2082 instructions += streaming_flow_graph_builder_->BuildStatementAt( |
| 2083 finalizer_kernel_offset); |
| 2084 } |
2259 | 2085 |
2260 // We only need to make sure that if the finalizer ended normally, we | 2086 // We only need to make sure that if the finalizer ended normally, we |
2261 // continue towards the next outer try-finally. | 2087 // continue towards the next outer try-finally. |
2262 if (!instructions.is_open()) break; | 2088 if (!instructions.is_open()) break; |
2263 } | 2089 } |
2264 | 2090 |
2265 if (instructions.is_open() && target_context_depth != -1) { | 2091 if (instructions.is_open() && target_context_depth != -1) { |
2266 // A target context depth of -1 indicates that the code after this | 2092 // A target context depth of -1 indicates that the code after this |
2267 // will not care about the context chain so we can leave it any way we | 2093 // will not care about the context chain so we can leave it any way we |
2268 // want after the last finalizer. That is used when returning. | 2094 // want after the last finalizer. That is used when returning. |
2269 instructions += AdjustContextTo(target_context_depth); | 2095 instructions += AdjustContextTo(target_context_depth); |
2270 } | 2096 } |
2271 | 2097 |
2272 try_finally_block_ = saved_block; | 2098 try_finally_block_ = saved_block; |
2273 try_catch_block_ = saved_try_catch_block; | 2099 try_catch_block_ = saved_try_catch_block; |
2274 context_depth_ = saved_depth; | 2100 context_depth_ = saved_depth; |
2275 try_depth_ = saved_try_depth; | 2101 try_depth_ = saved_try_depth; |
2276 | 2102 |
2277 return instructions; | 2103 return instructions; |
2278 } | 2104 } |
2279 | 2105 |
2280 | 2106 |
2281 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) { | 2107 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) { |
| 2108 return EnterScope(node->kernel_offset(), new_context); |
| 2109 } |
| 2110 |
| 2111 |
| 2112 Fragment FlowGraphBuilder::EnterScope(intptr_t kernel_offset, |
| 2113 bool* new_context) { |
2282 Fragment instructions; | 2114 Fragment instructions; |
2283 const intptr_t context_size = | 2115 const intptr_t context_size = |
2284 scopes_->scopes.Lookup(node->kernel_offset())->num_context_variables(); | 2116 scopes_->scopes.Lookup(kernel_offset)->num_context_variables(); |
2285 if (context_size > 0) { | 2117 if (context_size > 0) { |
2286 instructions += PushContext(context_size); | 2118 instructions += PushContext(context_size); |
2287 instructions += Drop(); | 2119 instructions += Drop(); |
2288 if (new_context != NULL) { | 2120 if (new_context != NULL) { |
2289 *new_context = true; | 2121 *new_context = true; |
2290 } | 2122 } |
2291 } | 2123 } |
2292 return instructions; | 2124 return instructions; |
2293 } | 2125 } |
2294 | 2126 |
2295 | 2127 |
2296 Fragment FlowGraphBuilder::ExitScope(TreeNode* node) { | 2128 Fragment FlowGraphBuilder::ExitScope(TreeNode* node) { |
| 2129 return ExitScope(node->kernel_offset()); |
| 2130 } |
| 2131 |
| 2132 |
| 2133 Fragment FlowGraphBuilder::ExitScope(intptr_t kernel_offset) { |
2297 Fragment instructions; | 2134 Fragment instructions; |
2298 const intptr_t context_size = | 2135 const intptr_t context_size = |
2299 scopes_->scopes.Lookup(node->kernel_offset())->num_context_variables(); | 2136 scopes_->scopes.Lookup(kernel_offset)->num_context_variables(); |
2300 if (context_size > 0) { | 2137 if (context_size > 0) { |
2301 instructions += PopContext(); | 2138 instructions += PopContext(); |
2302 } | 2139 } |
2303 return instructions; | 2140 return instructions; |
2304 } | 2141 } |
2305 | 2142 |
2306 | 2143 |
2307 Fragment FlowGraphBuilder::LoadContextAt(int depth) { | 2144 Fragment FlowGraphBuilder::LoadContextAt(int depth) { |
2308 intptr_t delta = context_depth_ - depth; | 2145 intptr_t delta = context_depth_ - depth; |
2309 ASSERT(delta >= 0); | 2146 ASSERT(delta >= 0); |
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3167 | 3004 |
3168 | 3005 |
3169 dart::LocalVariable* FlowGraphBuilder::LookupVariable( | 3006 dart::LocalVariable* FlowGraphBuilder::LookupVariable( |
3170 VariableDeclaration* var) { | 3007 VariableDeclaration* var) { |
3171 LocalVariable* local = scopes_->locals.Lookup(var->kernel_offset()); | 3008 LocalVariable* local = scopes_->locals.Lookup(var->kernel_offset()); |
3172 ASSERT(local != NULL); | 3009 ASSERT(local != NULL); |
3173 return local; | 3010 return local; |
3174 } | 3011 } |
3175 | 3012 |
3176 | 3013 |
| 3014 dart::LocalVariable* FlowGraphBuilder::LookupVariable(intptr_t kernel_offset) { |
| 3015 LocalVariable* local = scopes_->locals.Lookup(kernel_offset); |
| 3016 ASSERT(local != NULL); |
| 3017 return local; |
| 3018 } |
| 3019 |
| 3020 |
3177 void FlowGraphBuilder::SetTempIndex(Definition* definition) { | 3021 void FlowGraphBuilder::SetTempIndex(Definition* definition) { |
3178 definition->set_temp_index( | 3022 definition->set_temp_index( |
3179 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1); | 3023 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1); |
3180 } | 3024 } |
3181 | 3025 |
3182 | 3026 |
3183 void FlowGraphBuilder::Push(Definition* definition) { | 3027 void FlowGraphBuilder::Push(Definition* definition) { |
3184 SetTempIndex(definition); | 3028 SetTempIndex(definition); |
3185 Value::AddToList(new (Z) Value(definition), &stack_); | 3029 Value::AddToList(new (Z) Value(definition), &stack_); |
3186 } | 3030 } |
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3962 const AbstractType& dst_type = T.TranslateType(variable->type()); | 3806 const AbstractType& dst_type = T.TranslateType(variable->type()); |
3963 if (dst_type.IsMalformed()) { | 3807 if (dst_type.IsMalformed()) { |
3964 return ThrowTypeError(); | 3808 return ThrowTypeError(); |
3965 } | 3809 } |
3966 return CheckAssignableInCheckedMode(dst_type, | 3810 return CheckAssignableInCheckedMode(dst_type, |
3967 H.DartSymbol(variable->name())); | 3811 H.DartSymbol(variable->name())); |
3968 } | 3812 } |
3969 return Fragment(); | 3813 return Fragment(); |
3970 } | 3814 } |
3971 | 3815 |
| 3816 Fragment FlowGraphBuilder::CheckVariableTypeInCheckedMode( |
| 3817 const AbstractType& dst_type, |
| 3818 const dart::String& name_symbol) { |
| 3819 if (I->type_checks()) { |
| 3820 if (dst_type.IsMalformed()) { |
| 3821 return ThrowTypeError(); |
| 3822 } |
| 3823 return CheckAssignableInCheckedMode(dst_type, name_symbol); |
| 3824 } |
| 3825 return Fragment(); |
| 3826 } |
| 3827 |
3972 | 3828 |
3973 bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function, | 3829 bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function, |
3974 TokenPosition position) { | 3830 TokenPosition position) { |
3975 return FLAG_support_debugger && position.IsDebugPause() && | 3831 return FLAG_support_debugger && position.IsDebugPause() && |
3976 !function.is_native() && function.is_debuggable(); | 3832 !function.is_native() && function.is_debuggable(); |
3977 } | 3833 } |
3978 | 3834 |
3979 | 3835 |
3980 bool FlowGraphBuilder::NeedsDebugStepCheck(Value* value, | 3836 bool FlowGraphBuilder::NeedsDebugStepCheck(Value* value, |
3981 TokenPosition position) { | 3837 TokenPosition position) { |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4516 } | 4372 } |
4517 } | 4373 } |
4518 return instructions; | 4374 return instructions; |
4519 } | 4375 } |
4520 | 4376 |
4521 | 4377 |
4522 Fragment FlowGraphBuilder::TranslateStatement(Statement* statement) { | 4378 Fragment FlowGraphBuilder::TranslateStatement(Statement* statement) { |
4523 #ifdef DEBUG | 4379 #ifdef DEBUG |
4524 intptr_t original_context_depth = context_depth_; | 4380 intptr_t original_context_depth = context_depth_; |
4525 #endif | 4381 #endif |
4526 statement->AcceptStatementVisitor(this); | 4382 |
| 4383 // TODO(jensj): VariableDeclaration doesn't necessarily have a tag. |
| 4384 if (!statement->cannot_stream() && |
| 4385 statement->Type() != Node::kTypeVariableDeclaration) { |
| 4386 fragment_ = streaming_flow_graph_builder_->BuildStatementAt( |
| 4387 statement->kernel_offset()); |
| 4388 } else { |
| 4389 statement->AcceptStatementVisitor(this); |
| 4390 } |
4527 DEBUG_ASSERT(context_depth_ == original_context_depth); | 4391 DEBUG_ASSERT(context_depth_ == original_context_depth); |
4528 return fragment_; | 4392 return fragment_; |
4529 } | 4393 } |
4530 | 4394 |
4531 | 4395 |
4532 Fragment FlowGraphBuilder::TranslateCondition(Expression* expression, | 4396 Fragment FlowGraphBuilder::TranslateCondition(Expression* expression, |
4533 bool* negate) { | 4397 bool* negate) { |
4534 *negate = expression->IsNot(); | 4398 *negate = expression->IsNot(); |
4535 Fragment instructions; | 4399 Fragment instructions; |
4536 if (*negate) { | 4400 if (*negate) { |
4537 instructions += TranslateExpression(Not::Cast(expression)->expression()); | 4401 instructions += TranslateExpression(Not::Cast(expression)->expression()); |
4538 } else { | 4402 } else { |
4539 instructions += TranslateExpression(expression); | 4403 instructions += TranslateExpression(expression); |
4540 } | 4404 } |
4541 instructions += CheckBooleanInCheckedMode(); | 4405 instructions += CheckBooleanInCheckedMode(); |
4542 return instructions; | 4406 return instructions; |
4543 } | 4407 } |
4544 | 4408 |
4545 | 4409 |
4546 Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) { | 4410 Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) { |
4547 expression->AcceptExpressionVisitor(this); | 4411 if (!expression->cannot_stream()) { |
| 4412 fragment_ = streaming_flow_graph_builder_->BuildExpressionAt( |
| 4413 expression->kernel_offset()); |
| 4414 } else { |
| 4415 expression->AcceptExpressionVisitor(this); |
| 4416 } |
4548 return fragment_; | 4417 return fragment_; |
4549 } | 4418 } |
4550 | 4419 |
4551 | 4420 |
4552 ArgumentArray FlowGraphBuilder::GetArguments(int count) { | 4421 ArgumentArray FlowGraphBuilder::GetArguments(int count) { |
4553 ArgumentArray arguments = | 4422 ArgumentArray arguments = |
4554 new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, count); | 4423 new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, count); |
4555 arguments->SetLength(count); | 4424 arguments->SetLength(count); |
4556 for (intptr_t i = count - 1; i >= 0; --i) { | 4425 for (intptr_t i = count - 1; i >= 0; --i) { |
4557 ASSERT(stack_->definition()->IsPushArgument()); | 4426 ASSERT(stack_->definition()->IsPushArgument()); |
4558 ASSERT(!stack_->definition()->HasSSATemp()); | 4427 ASSERT(!stack_->definition()->HasSSATemp()); |
4559 arguments->data()[i] = stack_->definition()->AsPushArgument(); | 4428 arguments->data()[i] = stack_->definition()->AsPushArgument(); |
4560 Drop(); | 4429 Drop(); |
4561 } | 4430 } |
4562 pending_argument_count_ -= count; | 4431 pending_argument_count_ -= count; |
4563 ASSERT(pending_argument_count_ >= 0); | 4432 ASSERT(pending_argument_count_ >= 0); |
4564 return arguments; | 4433 return arguments; |
4565 } | 4434 } |
4566 | 4435 |
4567 | 4436 |
| 4437 #define STREAM_EXPRESSION_IF_POSSIBLE(node) \ |
| 4438 if (!node->cannot_stream()) { \ |
| 4439 fragment_ = streaming_flow_graph_builder_->BuildExpressionAt( \ |
| 4440 node->kernel_offset()); \ |
| 4441 return; \ |
| 4442 } |
| 4443 |
| 4444 |
4568 void FlowGraphBuilder::VisitInvalidExpression(InvalidExpression* node) { | 4445 void FlowGraphBuilder::VisitInvalidExpression(InvalidExpression* node) { |
4569 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4446 fragment_ = |
| 4447 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4570 } | 4448 } |
4571 | 4449 |
4572 | 4450 |
4573 void FlowGraphBuilder::VisitNullLiteral(NullLiteral* node) { | 4451 void FlowGraphBuilder::VisitNullLiteral(NullLiteral* node) { |
4574 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4452 fragment_ = |
| 4453 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4575 } | 4454 } |
4576 | 4455 |
4577 | 4456 |
4578 void FlowGraphBuilder::VisitBoolLiteral(BoolLiteral* node) { | 4457 void FlowGraphBuilder::VisitBoolLiteral(BoolLiteral* node) { |
4579 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4458 fragment_ = |
| 4459 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4580 } | 4460 } |
4581 | 4461 |
4582 | 4462 |
4583 void FlowGraphBuilder::VisitIntLiteral(IntLiteral* node) { | 4463 void FlowGraphBuilder::VisitIntLiteral(IntLiteral* node) { |
4584 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4464 fragment_ = |
| 4465 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4585 } | 4466 } |
4586 | 4467 |
4587 | 4468 |
4588 void FlowGraphBuilder::VisitBigintLiteral(BigintLiteral* node) { | 4469 void FlowGraphBuilder::VisitBigintLiteral(BigintLiteral* node) { |
4589 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4470 fragment_ = |
| 4471 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4590 } | 4472 } |
4591 | 4473 |
4592 | 4474 |
4593 void FlowGraphBuilder::VisitDoubleLiteral(DoubleLiteral* node) { | 4475 void FlowGraphBuilder::VisitDoubleLiteral(DoubleLiteral* node) { |
4594 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4476 fragment_ = |
| 4477 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4595 } | 4478 } |
4596 | 4479 |
4597 | 4480 |
4598 void FlowGraphBuilder::VisitStringLiteral(StringLiteral* node) { | 4481 void FlowGraphBuilder::VisitStringLiteral(StringLiteral* node) { |
4599 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4482 fragment_ = |
| 4483 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4600 } | 4484 } |
4601 | 4485 |
4602 | 4486 |
4603 void FlowGraphBuilder::VisitSymbolLiteral(SymbolLiteral* node) { | 4487 void FlowGraphBuilder::VisitSymbolLiteral(SymbolLiteral* node) { |
4604 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4488 fragment_ = |
| 4489 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4605 } | 4490 } |
4606 | 4491 |
4607 | 4492 |
4608 AbstractType& DartTypeTranslator::TranslateType(DartType* node) { | 4493 AbstractType& DartTypeTranslator::TranslateType(DartType* node) { |
4609 node->AcceptDartTypeVisitor(this); | 4494 node->AcceptDartTypeVisitor(this); |
4610 | 4495 |
4611 // We return a new `ZoneHandle` here on purpose: The intermediate language | 4496 // We return a new `ZoneHandle` here on purpose: The intermediate language |
4612 // instructions do not make a copy of the handle, so we do it. | 4497 // instructions do not make a copy of the handle, so we do it. |
4613 return dart::AbstractType::ZoneHandle(Z, result_.raw()); | 4498 return dart::AbstractType::ZoneHandle(Z, result_.raw()); |
4614 } | 4499 } |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4893 } | 4778 } |
4894 type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()), | 4779 type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()), |
4895 klass.token_pos()); | 4780 klass.token_pos()); |
4896 if (klass.is_type_finalized()) { | 4781 if (klass.is_type_finalized()) { |
4897 type ^= ClassFinalizer::FinalizeType(klass, type); | 4782 type ^= ClassFinalizer::FinalizeType(klass, type); |
4898 klass.SetCanonicalType(type); | 4783 klass.SetCanonicalType(type); |
4899 } | 4784 } |
4900 return type; | 4785 return type; |
4901 } | 4786 } |
4902 | 4787 |
| 4788 void FlowGraphBuilder::VisitTypeLiteral(TypeLiteral* node) { |
| 4789 STREAM_EXPRESSION_IF_POSSIBLE(node); |
4903 | 4790 |
4904 void FlowGraphBuilder::VisitTypeLiteral(TypeLiteral* node) { | |
4905 const AbstractType& type = T.TranslateType(node->type()); | 4791 const AbstractType& type = T.TranslateType(node->type()); |
4906 if (type.IsMalformed()) H.ReportError("Malformed type literal"); | 4792 if (type.IsMalformed()) H.ReportError("Malformed type literal"); |
4907 | 4793 |
4908 Fragment instructions; | 4794 Fragment instructions; |
4909 if (type.IsInstantiated()) { | 4795 if (type.IsInstantiated()) { |
4910 instructions += Constant(type); | 4796 instructions += Constant(type); |
4911 } else { | 4797 } else { |
4912 if (!type.IsInstantiated(kCurrentClass)) { | 4798 if (!type.IsInstantiated(kCurrentClass)) { |
4913 instructions += LoadInstantiatorTypeArguments(); | 4799 instructions += LoadInstantiatorTypeArguments(); |
4914 } else { | 4800 } else { |
4915 instructions += NullConstant(); | 4801 instructions += NullConstant(); |
4916 } | 4802 } |
4917 if (!type.IsInstantiated(kFunctions)) { | 4803 if (!type.IsInstantiated(kFunctions)) { |
4918 instructions += LoadFunctionTypeArguments(); | 4804 instructions += LoadFunctionTypeArguments(); |
4919 } else { | 4805 } else { |
4920 instructions += NullConstant(); | 4806 instructions += NullConstant(); |
4921 } | 4807 } |
4922 instructions += InstantiateType(type); | 4808 instructions += InstantiateType(type); |
4923 } | 4809 } |
4924 fragment_ = instructions; | 4810 fragment_ = instructions; |
4925 } | 4811 } |
4926 | 4812 |
4927 | 4813 |
4928 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { | 4814 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { |
4929 fragment_ = LoadLocal(LookupVariable(node->variable())); | 4815 fragment_ = |
| 4816 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4930 } | 4817 } |
4931 | 4818 |
4932 | 4819 |
4933 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { | 4820 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { |
| 4821 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4822 |
4934 Fragment instructions = TranslateExpression(node->expression()); | 4823 Fragment instructions = TranslateExpression(node->expression()); |
4935 if (NeedsDebugStepCheck(stack_, node->position())) { | 4824 if (NeedsDebugStepCheck(stack_, node->position())) { |
4936 instructions = DebugStepCheck(node->position()) + instructions; | 4825 instructions = DebugStepCheck(node->position()) + instructions; |
4937 } | 4826 } |
4938 instructions += CheckVariableTypeInCheckedMode(node->variable()); | 4827 instructions += CheckVariableTypeInCheckedMode(node->variable()); |
4939 instructions += | 4828 instructions += |
4940 StoreLocal(node->position(), LookupVariable(node->variable())); | 4829 StoreLocal(node->position(), LookupVariable(node->variable())); |
4941 fragment_ = instructions; | 4830 fragment_ = instructions; |
4942 } | 4831 } |
4943 | 4832 |
4944 | 4833 |
4945 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { | 4834 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { |
4946 if (node->kernel_offset() != -1) { | 4835 STREAM_EXPRESSION_IF_POSSIBLE(node); |
4947 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4836 |
4948 return; | |
4949 } | |
4950 // A StaticGet will always have a kernel_offset, except for the StaticGet that | 4837 // A StaticGet will always have a kernel_offset, except for the StaticGet that |
4951 // was manually created for _getMainClosure in dart:_builtin. Compile that | 4838 // was manually created for _getMainClosure in dart:_builtin. Compile that |
4952 // one specially here. | 4839 // one specially here. |
4953 const dart::Library& builtin = | 4840 const dart::Library& builtin = |
4954 dart::Library::Handle(Z, I->object_store()->builtin_library()); | 4841 dart::Library::Handle(Z, I->object_store()->builtin_library()); |
4955 const Object& main = | 4842 const Object& main = |
4956 Object::Handle(Z, builtin.LookupObjectAllowPrivate(dart::String::Handle( | 4843 Object::Handle(Z, builtin.LookupObjectAllowPrivate(dart::String::Handle( |
4957 Z, dart::String::New("main")))); | 4844 Z, dart::String::New("main")))); |
4958 if (main.IsField()) { | 4845 if (main.IsField()) { |
4959 UNIMPLEMENTED(); | 4846 UNIMPLEMENTED(); |
4960 } else if (main.IsFunction()) { | 4847 } else if (main.IsFunction()) { |
4961 const Function& function = Function::Cast(main); | 4848 const Function& function = Function::Cast(main); |
4962 if (function.kind() == RawFunction::kRegularFunction) { | 4849 if (function.kind() == RawFunction::kRegularFunction) { |
4963 const Function& closure_function = | 4850 const Function& closure_function = |
4964 Function::Handle(Z, function.ImplicitClosureFunction()); | 4851 Function::Handle(Z, function.ImplicitClosureFunction()); |
4965 closure_function.set_kernel_function(function.kernel_function()); | 4852 closure_function.set_kernel_function(function.kernel_function()); |
4966 const Instance& closure = | 4853 const Instance& closure = |
4967 Instance::ZoneHandle(Z, closure_function.ImplicitStaticClosure()); | 4854 Instance::ZoneHandle(Z, closure_function.ImplicitStaticClosure()); |
4968 fragment_ = Constant(closure); | 4855 fragment_ = Constant(closure); |
4969 } else { | 4856 } else { |
4970 UNIMPLEMENTED(); | 4857 UNIMPLEMENTED(); |
4971 } | 4858 } |
4972 } else { | 4859 } else { |
4973 UNIMPLEMENTED(); | 4860 UNIMPLEMENTED(); |
4974 } | 4861 } |
4975 } | 4862 } |
4976 | 4863 |
4977 | 4864 |
4978 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { | 4865 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { |
| 4866 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4867 |
4979 CanonicalName* target = node->target(); | 4868 CanonicalName* target = node->target(); |
4980 if (H.IsField(target)) { | 4869 if (H.IsField(target)) { |
4981 const dart::Field& field = | 4870 const dart::Field& field = |
4982 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(target)); | 4871 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(target)); |
4983 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); | 4872 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); |
4984 Fragment instructions = TranslateExpression(node->expression()); | 4873 Fragment instructions = TranslateExpression(node->expression()); |
4985 if (NeedsDebugStepCheck(stack_, node->position())) { | 4874 if (NeedsDebugStepCheck(stack_, node->position())) { |
4986 instructions = DebugStepCheck(node->position()) + instructions; | 4875 instructions = DebugStepCheck(node->position()) + instructions; |
4987 } | 4876 } |
4988 instructions += CheckAssignableInCheckedMode( | 4877 instructions += CheckAssignableInCheckedMode( |
(...skipping 17 matching lines...) Expand all Loading... |
5006 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target)); | 4895 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target)); |
5007 instructions += StaticCall(node->position(), function, 1); | 4896 instructions += StaticCall(node->position(), function, 1); |
5008 | 4897 |
5009 // Drop the unused result & leave the stored value on the stack. | 4898 // Drop the unused result & leave the stored value on the stack. |
5010 fragment_ = instructions + Drop(); | 4899 fragment_ = instructions + Drop(); |
5011 } | 4900 } |
5012 } | 4901 } |
5013 | 4902 |
5014 | 4903 |
5015 void FlowGraphBuilder::VisitPropertyGet(PropertyGet* node) { | 4904 void FlowGraphBuilder::VisitPropertyGet(PropertyGet* node) { |
| 4905 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4906 |
5016 Fragment instructions = TranslateExpression(node->receiver()); | 4907 Fragment instructions = TranslateExpression(node->receiver()); |
5017 instructions += PushArgument(); | 4908 instructions += PushArgument(); |
5018 const dart::String& getter_name = H.DartGetterName(node->name()); | 4909 const dart::String& getter_name = H.DartGetterName(node->name()); |
5019 fragment_ = instructions + | 4910 fragment_ = instructions + |
5020 InstanceCall(node->position(), getter_name, Token::kGET, 1); | 4911 InstanceCall(node->position(), getter_name, Token::kGET, 1); |
5021 } | 4912 } |
5022 | 4913 |
5023 | 4914 |
5024 void FlowGraphBuilder::VisitPropertySet(PropertySet* node) { | 4915 void FlowGraphBuilder::VisitPropertySet(PropertySet* node) { |
| 4916 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4917 |
5025 Fragment instructions(NullConstant()); | 4918 Fragment instructions(NullConstant()); |
5026 LocalVariable* variable = MakeTemporary(); | 4919 LocalVariable* variable = MakeTemporary(); |
5027 instructions += TranslateExpression(node->receiver()); | 4920 instructions += TranslateExpression(node->receiver()); |
5028 instructions += PushArgument(); | 4921 instructions += PushArgument(); |
5029 instructions += TranslateExpression(node->value()); | 4922 instructions += TranslateExpression(node->value()); |
5030 instructions += StoreLocal(TokenPosition::kNoSource, variable); | 4923 instructions += StoreLocal(TokenPosition::kNoSource, variable); |
5031 instructions += PushArgument(); | 4924 instructions += PushArgument(); |
5032 | 4925 |
5033 const dart::String& setter_name = H.DartSetterName(node->name()); | 4926 const dart::String& setter_name = H.DartSetterName(node->name()); |
5034 instructions += InstanceCall(node->position(), setter_name, Token::kSET, 2); | 4927 instructions += InstanceCall(node->position(), setter_name, Token::kSET, 2); |
5035 fragment_ = instructions + Drop(); | 4928 fragment_ = instructions + Drop(); |
5036 } | 4929 } |
5037 | 4930 |
5038 | 4931 |
5039 void FlowGraphBuilder::VisitDirectPropertyGet(DirectPropertyGet* node) { | 4932 void FlowGraphBuilder::VisitDirectPropertyGet(DirectPropertyGet* node) { |
| 4933 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4934 |
5040 Function& target = Function::ZoneHandle(Z); | 4935 Function& target = Function::ZoneHandle(Z); |
5041 CanonicalName* kernel_name = node->target(); | 4936 CanonicalName* kernel_name = node->target(); |
5042 if (H.IsProcedure(kernel_name)) { | 4937 if (H.IsProcedure(kernel_name)) { |
5043 if (H.IsGetter(kernel_name)) { | 4938 if (H.IsGetter(kernel_name)) { |
5044 target = LookupMethodByMember(kernel_name, H.DartGetterName(kernel_name)); | 4939 target = LookupMethodByMember(kernel_name, H.DartGetterName(kernel_name)); |
5045 } else { | 4940 } else { |
5046 target = LookupMethodByMember(kernel_name, H.DartMethodName(kernel_name)); | 4941 target = LookupMethodByMember(kernel_name, H.DartMethodName(kernel_name)); |
5047 target = target.ImplicitClosureFunction(); | 4942 target = target.ImplicitClosureFunction(); |
5048 ASSERT(!target.IsNull()); | 4943 ASSERT(!target.IsNull()); |
5049 fragment_ = BuildImplicitClosureCreation(target); | 4944 fragment_ = BuildImplicitClosureCreation(target); |
5050 return; | 4945 return; |
5051 } | 4946 } |
5052 } else { | 4947 } else { |
5053 ASSERT(H.IsField(kernel_name)); | 4948 ASSERT(H.IsField(kernel_name)); |
5054 const dart::String& getter_name = H.DartGetterName(kernel_name); | 4949 const dart::String& getter_name = H.DartGetterName(kernel_name); |
5055 target = LookupMethodByMember(kernel_name, getter_name); | 4950 target = LookupMethodByMember(kernel_name, getter_name); |
5056 ASSERT(target.IsGetterFunction() || target.IsImplicitGetterFunction()); | 4951 ASSERT(target.IsGetterFunction() || target.IsImplicitGetterFunction()); |
5057 } | 4952 } |
5058 | 4953 |
5059 Fragment instructions = TranslateExpression(node->receiver()); | 4954 Fragment instructions = TranslateExpression(node->receiver()); |
5060 instructions += PushArgument(); | 4955 instructions += PushArgument(); |
5061 fragment_ = instructions + StaticCall(node->position(), target, 1); | 4956 fragment_ = instructions + StaticCall(node->position(), target, 1); |
5062 } | 4957 } |
5063 | 4958 |
5064 | 4959 |
5065 void FlowGraphBuilder::VisitDirectPropertySet(DirectPropertySet* node) { | 4960 void FlowGraphBuilder::VisitDirectPropertySet(DirectPropertySet* node) { |
| 4961 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4962 |
5066 const dart::String& method_name = H.DartSetterName(node->target()); | 4963 const dart::String& method_name = H.DartSetterName(node->target()); |
5067 const Function& target = Function::ZoneHandle( | 4964 const Function& target = Function::ZoneHandle( |
5068 Z, LookupMethodByMember(node->target(), method_name)); | 4965 Z, LookupMethodByMember(node->target(), method_name)); |
5069 ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction()); | 4966 ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction()); |
5070 | 4967 |
5071 Fragment instructions(NullConstant()); | 4968 Fragment instructions(NullConstant()); |
5072 LocalVariable* value = MakeTemporary(); | 4969 LocalVariable* value = MakeTemporary(); |
5073 instructions += TranslateExpression(node->receiver()); | 4970 instructions += TranslateExpression(node->receiver()); |
5074 instructions += PushArgument(); | 4971 instructions += PushArgument(); |
5075 instructions += TranslateExpression(node->value()); | 4972 instructions += TranslateExpression(node->value()); |
5076 instructions += StoreLocal(TokenPosition::kNoSource, value); | 4973 instructions += StoreLocal(TokenPosition::kNoSource, value); |
5077 instructions += PushArgument(); | 4974 instructions += PushArgument(); |
5078 instructions += StaticCall(node->position(), target, 2); | 4975 instructions += StaticCall(node->position(), target, 2); |
5079 | 4976 |
5080 fragment_ = instructions + Drop(); | 4977 fragment_ = instructions + Drop(); |
5081 } | 4978 } |
5082 | 4979 |
5083 | 4980 |
5084 void FlowGraphBuilder::VisitStaticInvocation(StaticInvocation* node) { | 4981 void FlowGraphBuilder::VisitStaticInvocation(StaticInvocation* node) { |
| 4982 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4983 |
5085 const Function& target = Function::ZoneHandle( | 4984 const Function& target = Function::ZoneHandle( |
5086 Z, H.LookupStaticMethodByKernelProcedure(node->procedure())); | 4985 Z, H.LookupStaticMethodByKernelProcedure(node->procedure())); |
5087 const dart::Class& klass = dart::Class::ZoneHandle(Z, target.Owner()); | 4986 const dart::Class& klass = dart::Class::ZoneHandle(Z, target.Owner()); |
5088 intptr_t argument_count = node->arguments()->count(); | 4987 intptr_t argument_count = node->arguments()->count(); |
5089 if (target.IsGenerativeConstructor() || target.IsFactory()) { | 4988 if (target.IsGenerativeConstructor() || target.IsFactory()) { |
5090 // The VM requires a TypeArguments object as first parameter for | 4989 // The VM requires a TypeArguments object as first parameter for |
5091 // every factory constructor. | 4990 // every factory constructor. |
5092 ++argument_count; | 4991 ++argument_count; |
5093 } | 4992 } |
5094 | 4993 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5194 fragment_ = instructions + StrictCompare(strict_cmp_kind, | 5093 fragment_ = instructions + StrictCompare(strict_cmp_kind, |
5195 /*number_check = */ true); | 5094 /*number_check = */ true); |
5196 return true; | 5095 return true; |
5197 } | 5096 } |
5198 } | 5097 } |
5199 return false; | 5098 return false; |
5200 } | 5099 } |
5201 | 5100 |
5202 | 5101 |
5203 void FlowGraphBuilder::VisitMethodInvocation(MethodInvocation* node) { | 5102 void FlowGraphBuilder::VisitMethodInvocation(MethodInvocation* node) { |
| 5103 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5104 |
5204 const dart::String& name = H.DartMethodName(node->name()); | 5105 const dart::String& name = H.DartMethodName(node->name()); |
5205 const intptr_t argument_count = node->arguments()->count() + 1; | 5106 const intptr_t argument_count = node->arguments()->count() + 1; |
5206 const Token::Kind token_kind = MethodKind(name); | 5107 const Token::Kind token_kind = MethodKind(name); |
5207 if (IsNumberLiteral(node->receiver())) { | 5108 if (IsNumberLiteral(node->receiver())) { |
5208 if ((argument_count == 1) && (token_kind == Token::kNEGATE)) { | 5109 if ((argument_count == 1) && (token_kind == Token::kNEGATE)) { |
5209 const Object& result = constant_evaluator_.EvaluateExpressionSafe(node); | 5110 const Object& result = constant_evaluator_.EvaluateExpressionSafe(node); |
5210 if (!result.IsError()) { | 5111 if (!result.IsError()) { |
5211 fragment_ = Constant(result); | 5112 fragment_ = Constant(result); |
5212 return; | 5113 return; |
5213 } | 5114 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5248 // actually produce any value. See http://dartbug.com/29135 for more details. | 5149 // actually produce any value. See http://dartbug.com/29135 for more details. |
5249 if (name.raw() == Symbols::AssignIndexToken().raw()) { | 5150 if (name.raw() == Symbols::AssignIndexToken().raw()) { |
5250 fragment_ += Drop(); | 5151 fragment_ += Drop(); |
5251 fragment_ += NullConstant(); | 5152 fragment_ += NullConstant(); |
5252 } | 5153 } |
5253 } | 5154 } |
5254 | 5155 |
5255 | 5156 |
5256 void FlowGraphBuilder::VisitDirectMethodInvocation( | 5157 void FlowGraphBuilder::VisitDirectMethodInvocation( |
5257 DirectMethodInvocation* node) { | 5158 DirectMethodInvocation* node) { |
| 5159 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5160 |
5258 const dart::String& method_name = H.DartProcedureName(node->target()); | 5161 const dart::String& method_name = H.DartProcedureName(node->target()); |
5259 const Token::Kind token_kind = MethodKind(method_name); | 5162 const Token::Kind token_kind = MethodKind(method_name); |
5260 | 5163 |
5261 if (RecognizeComparisonWithNull(token_kind, node)) return; | 5164 if (RecognizeComparisonWithNull(token_kind, node)) return; |
5262 | 5165 |
5263 const Function& target = Function::ZoneHandle( | 5166 const Function& target = Function::ZoneHandle( |
5264 Z, LookupMethodByMember(node->target(), method_name)); | 5167 Z, LookupMethodByMember(node->target(), method_name)); |
5265 | 5168 |
5266 intptr_t argument_count = node->arguments()->count() + 1; | 5169 intptr_t argument_count = node->arguments()->count() + 1; |
5267 Array& argument_names = Array::ZoneHandle(Z); | 5170 Array& argument_names = Array::ZoneHandle(Z); |
5268 | 5171 |
5269 // TODO(28109) Support generic methods in the VM or reify them away. | 5172 // TODO(28109) Support generic methods in the VM or reify them away. |
5270 Fragment instructions = TranslateExpression(node->receiver()); | 5173 Fragment instructions = TranslateExpression(node->receiver()); |
5271 instructions += PushArgument(); | 5174 instructions += PushArgument(); |
5272 instructions += TranslateArguments(node->arguments(), &argument_names); | 5175 instructions += TranslateArguments(node->arguments(), &argument_names); |
5273 fragment_ = instructions + StaticCall(node->position(), target, | 5176 fragment_ = instructions + StaticCall(node->position(), target, |
5274 argument_count, argument_names); | 5177 argument_count, argument_names); |
5275 } | 5178 } |
5276 | 5179 |
5277 | 5180 |
5278 void FlowGraphBuilder::VisitConstructorInvocation(ConstructorInvocation* node) { | 5181 void FlowGraphBuilder::VisitConstructorInvocation(ConstructorInvocation* node) { |
| 5182 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5183 |
5279 if (node->is_const()) { | 5184 if (node->is_const()) { |
5280 fragment_ = | 5185 fragment_ = |
5281 Constant(constant_evaluator_.EvaluateConstructorInvocation(node)); | 5186 Constant(constant_evaluator_.EvaluateConstructorInvocation(node)); |
5282 return; | 5187 return; |
5283 } | 5188 } |
5284 | 5189 |
5285 dart::Class& klass = dart::Class::ZoneHandle( | 5190 dart::Class& klass = dart::Class::ZoneHandle( |
5286 Z, H.LookupClassByKernelClass(H.EnclosingName(node->target()))); | 5191 Z, H.LookupClassByKernelClass(H.EnclosingName(node->target()))); |
5287 | 5192 |
5288 Fragment instructions; | 5193 Fragment instructions; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5357 const Function& target = Function::ZoneHandle( | 5262 const Function& target = Function::ZoneHandle( |
5358 Z, H.LookupConstructorByKernelConstructor(klass, node->target())); | 5263 Z, H.LookupConstructorByKernelConstructor(klass, node->target())); |
5359 intptr_t argument_count = node->arguments()->count() + 1; | 5264 intptr_t argument_count = node->arguments()->count() + 1; |
5360 instructions += | 5265 instructions += |
5361 StaticCall(node->position(), target, argument_count, argument_names); | 5266 StaticCall(node->position(), target, argument_count, argument_names); |
5362 fragment_ = instructions + Drop(); | 5267 fragment_ = instructions + Drop(); |
5363 } | 5268 } |
5364 | 5269 |
5365 | 5270 |
5366 void FlowGraphBuilder::VisitIsExpression(IsExpression* node) { | 5271 void FlowGraphBuilder::VisitIsExpression(IsExpression* node) { |
| 5272 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5273 |
5367 Fragment instructions = TranslateExpression(node->operand()); | 5274 Fragment instructions = TranslateExpression(node->operand()); |
5368 | 5275 |
5369 // The VM does not like an instanceOf call with a dynamic type. We need to | 5276 // The VM does not like an instanceOf call with a dynamic type. We need to |
5370 // special case this situation. | 5277 // special case this situation. |
5371 const Type& object_type = Type::Handle(Z, Type::ObjectType()); | 5278 const Type& object_type = Type::Handle(Z, Type::ObjectType()); |
5372 const AbstractType& type = T.TranslateType(node->type()); | 5279 const AbstractType& type = T.TranslateType(node->type()); |
5373 if (type.IsMalformed()) { | 5280 if (type.IsMalformed()) { |
5374 instructions += Drop(); | 5281 instructions += Drop(); |
5375 instructions += ThrowTypeError(); | 5282 instructions += ThrowTypeError(); |
5376 fragment_ = instructions; | 5283 fragment_ = instructions; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5420 InstanceCall(node->position(), | 5327 InstanceCall(node->position(), |
5421 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), | 5328 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), |
5422 Token::kIS, 4); | 5329 Token::kIS, 4); |
5423 } | 5330 } |
5424 | 5331 |
5425 fragment_ = instructions; | 5332 fragment_ = instructions; |
5426 } | 5333 } |
5427 | 5334 |
5428 | 5335 |
5429 void FlowGraphBuilder::VisitAsExpression(AsExpression* node) { | 5336 void FlowGraphBuilder::VisitAsExpression(AsExpression* node) { |
| 5337 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5338 |
5430 Fragment instructions = TranslateExpression(node->operand()); | 5339 Fragment instructions = TranslateExpression(node->operand()); |
5431 | 5340 |
5432 // The VM does not like an Object_as call with a dynamic type. We need to | 5341 // The VM does not like an Object_as call with a dynamic type. We need to |
5433 // special case this situation. | 5342 // special case this situation. |
5434 const Type& object_type = Type::Handle(Z, Type::ObjectType()); | 5343 const Type& object_type = Type::Handle(Z, Type::ObjectType()); |
5435 const AbstractType& type = T.TranslateType(node->type()); | 5344 const AbstractType& type = T.TranslateType(node->type()); |
5436 if (type.IsMalformed()) { | 5345 if (type.IsMalformed()) { |
5437 instructions += Drop(); | 5346 instructions += Drop(); |
5438 instructions += ThrowTypeError(); | 5347 instructions += ThrowTypeError(); |
5439 fragment_ = instructions; | 5348 fragment_ = instructions; |
(...skipping 27 matching lines...) Expand all Loading... |
5467 instructions += InstanceCall( | 5376 instructions += InstanceCall( |
5468 node->position(), dart::Library::PrivateCoreLibName(Symbols::_as()), | 5377 node->position(), dart::Library::PrivateCoreLibName(Symbols::_as()), |
5469 Token::kAS, 4); | 5378 Token::kAS, 4); |
5470 } | 5379 } |
5471 | 5380 |
5472 fragment_ = instructions; | 5381 fragment_ = instructions; |
5473 } | 5382 } |
5474 | 5383 |
5475 | 5384 |
5476 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { | 5385 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { |
| 5386 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5387 |
5477 bool negate; | 5388 bool negate; |
5478 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5389 Fragment instructions = TranslateCondition(node->condition(), &negate); |
5479 | 5390 |
5480 TargetEntryInstr* then_entry; | 5391 TargetEntryInstr* then_entry; |
5481 TargetEntryInstr* otherwise_entry; | 5392 TargetEntryInstr* otherwise_entry; |
5482 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); | 5393 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); |
5483 | 5394 |
5484 Value* top = stack_; | 5395 Value* top = stack_; |
5485 Fragment then_fragment(then_entry); | 5396 Fragment then_fragment(then_entry); |
5486 then_fragment += TranslateExpression(node->then()); | 5397 then_fragment += TranslateExpression(node->then()); |
(...skipping 12 matching lines...) Expand all Loading... |
5499 JoinEntryInstr* join = BuildJoinEntry(); | 5410 JoinEntryInstr* join = BuildJoinEntry(); |
5500 then_fragment += Goto(join); | 5411 then_fragment += Goto(join); |
5501 otherwise_fragment += Goto(join); | 5412 otherwise_fragment += Goto(join); |
5502 | 5413 |
5503 fragment_ = Fragment(instructions.entry, join) + | 5414 fragment_ = Fragment(instructions.entry, join) + |
5504 LoadLocal(parsed_function_->expression_temp_var()); | 5415 LoadLocal(parsed_function_->expression_temp_var()); |
5505 } | 5416 } |
5506 | 5417 |
5507 | 5418 |
5508 void FlowGraphBuilder::VisitLogicalExpression(LogicalExpression* node) { | 5419 void FlowGraphBuilder::VisitLogicalExpression(LogicalExpression* node) { |
| 5420 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5421 |
5509 bool negate; | 5422 bool negate; |
5510 Fragment instructions = TranslateCondition(node->left(), &negate); | 5423 Fragment instructions = TranslateCondition(node->left(), &negate); |
5511 TargetEntryInstr* right_entry; | 5424 TargetEntryInstr* right_entry; |
5512 TargetEntryInstr* constant_entry; | 5425 TargetEntryInstr* constant_entry; |
5513 | 5426 |
5514 if (node->op() == LogicalExpression::kAnd) { | 5427 if (node->op() == LogicalExpression::kAnd) { |
5515 instructions += BranchIfTrue(&right_entry, &constant_entry, negate); | 5428 instructions += BranchIfTrue(&right_entry, &constant_entry, negate); |
5516 } else { | 5429 } else { |
5517 instructions += BranchIfTrue(&constant_entry, &right_entry, negate); | 5430 instructions += BranchIfTrue(&constant_entry, &right_entry, negate); |
5518 } | 5431 } |
(...skipping 19 matching lines...) Expand all Loading... |
5538 JoinEntryInstr* join = BuildJoinEntry(); | 5451 JoinEntryInstr* join = BuildJoinEntry(); |
5539 right_fragment += Goto(join); | 5452 right_fragment += Goto(join); |
5540 constant_fragment += Goto(join); | 5453 constant_fragment += Goto(join); |
5541 | 5454 |
5542 fragment_ = Fragment(instructions.entry, join) + | 5455 fragment_ = Fragment(instructions.entry, join) + |
5543 LoadLocal(parsed_function_->expression_temp_var()); | 5456 LoadLocal(parsed_function_->expression_temp_var()); |
5544 } | 5457 } |
5545 | 5458 |
5546 | 5459 |
5547 void FlowGraphBuilder::VisitNot(Not* node) { | 5460 void FlowGraphBuilder::VisitNot(Not* node) { |
| 5461 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5462 |
5548 Fragment instructions = TranslateExpression(node->expression()); | 5463 Fragment instructions = TranslateExpression(node->expression()); |
5549 instructions += CheckBooleanInCheckedMode(); | 5464 instructions += CheckBooleanInCheckedMode(); |
5550 instructions += BooleanNegate(); | 5465 instructions += BooleanNegate(); |
5551 fragment_ = instructions; | 5466 fragment_ = instructions; |
5552 } | 5467 } |
5553 | 5468 |
5554 | 5469 |
5555 void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) { | 5470 void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) { |
5556 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 5471 fragment_ = |
| 5472 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
5557 } | 5473 } |
5558 | 5474 |
5559 | 5475 |
5560 void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) { | 5476 void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) { |
| 5477 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5478 |
5561 List<Expression>& expressions = node->expressions(); | 5479 List<Expression>& expressions = node->expressions(); |
5562 | 5480 |
5563 Fragment instructions; | 5481 Fragment instructions; |
5564 | 5482 |
5565 if (node->expressions().length() == 1) { | 5483 if (node->expressions().length() == 1) { |
5566 instructions += TranslateExpression(node->expressions()[0]); | 5484 instructions += TranslateExpression(node->expressions()[0]); |
5567 instructions += StringInterpolateSingle(node->position()); | 5485 instructions += StringInterpolateSingle(node->position()); |
5568 } else { | 5486 } else { |
5569 // The type arguments for CreateArray. | 5487 // The type arguments for CreateArray. |
5570 instructions += Constant(TypeArguments::ZoneHandle(Z)); | 5488 instructions += Constant(TypeArguments::ZoneHandle(Z)); |
5571 instructions += IntConstant(expressions.length()); | 5489 instructions += IntConstant(expressions.length()); |
5572 instructions += CreateArray(); | 5490 instructions += CreateArray(); |
5573 LocalVariable* array = MakeTemporary(); | 5491 LocalVariable* array = MakeTemporary(); |
5574 | 5492 |
5575 for (intptr_t i = 0; i < node->expressions().length(); i++) { | 5493 for (intptr_t i = 0; i < node->expressions().length(); i++) { |
5576 instructions += LoadLocal(array); | 5494 instructions += LoadLocal(array); |
5577 instructions += IntConstant(i); | 5495 instructions += IntConstant(i); |
5578 instructions += TranslateExpression(node->expressions()[i]); | 5496 instructions += TranslateExpression(node->expressions()[i]); |
5579 instructions += StoreIndexed(kArrayCid); | 5497 instructions += StoreIndexed(kArrayCid); |
5580 instructions += Drop(); | 5498 instructions += Drop(); |
5581 } | 5499 } |
5582 | 5500 |
5583 instructions += StringInterpolate(node->position()); | 5501 instructions += StringInterpolate(node->position()); |
5584 } | 5502 } |
5585 fragment_ = instructions; | 5503 fragment_ = instructions; |
5586 } | 5504 } |
5587 | 5505 |
5588 | 5506 |
5589 void FlowGraphBuilder::VisitListLiteral(ListLiteral* node) { | 5507 void FlowGraphBuilder::VisitListLiteral(ListLiteral* node) { |
| 5508 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5509 |
5590 if (node->is_const()) { | 5510 if (node->is_const()) { |
5591 fragment_ = Constant(constant_evaluator_.EvaluateListLiteral(node)); | 5511 fragment_ = Constant(constant_evaluator_.EvaluateListLiteral(node)); |
5592 return; | 5512 return; |
5593 } | 5513 } |
5594 | 5514 |
5595 DartType* types[] = {node->type()}; | 5515 DartType* types[] = {node->type()}; |
5596 const TypeArguments& type_arguments = T.TranslateTypeArguments(types, 1); | 5516 const TypeArguments& type_arguments = T.TranslateTypeArguments(types, 1); |
5597 | 5517 |
5598 // The type argument for the factory call. | 5518 // The type argument for the factory call. |
5599 Fragment instructions = TranslateInstantiatedTypeArguments(type_arguments); | 5519 Fragment instructions = TranslateInstantiatedTypeArguments(type_arguments); |
(...skipping 21 matching lines...) Expand all Loading... |
5621 const dart::Class& factory_class = | 5541 const dart::Class& factory_class = |
5622 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::List())); | 5542 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::List())); |
5623 const Function& factory_method = Function::ZoneHandle( | 5543 const Function& factory_method = Function::ZoneHandle( |
5624 Z, factory_class.LookupFactory( | 5544 Z, factory_class.LookupFactory( |
5625 dart::Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); | 5545 dart::Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); |
5626 fragment_ = instructions + StaticCall(node->position(), factory_method, 2); | 5546 fragment_ = instructions + StaticCall(node->position(), factory_method, 2); |
5627 } | 5547 } |
5628 | 5548 |
5629 | 5549 |
5630 void FlowGraphBuilder::VisitMapLiteral(MapLiteral* node) { | 5550 void FlowGraphBuilder::VisitMapLiteral(MapLiteral* node) { |
| 5551 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5552 |
5631 if (node->is_const()) { | 5553 if (node->is_const()) { |
5632 fragment_ = Constant(constant_evaluator_.EvaluateMapLiteral(node)); | 5554 fragment_ = Constant(constant_evaluator_.EvaluateMapLiteral(node)); |
5633 return; | 5555 return; |
5634 } | 5556 } |
5635 | 5557 |
5636 const dart::Class& map_class = | 5558 const dart::Class& map_class = |
5637 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map())); | 5559 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map())); |
5638 const Function& factory_method = Function::ZoneHandle( | 5560 const Function& factory_method = Function::ZoneHandle( |
5639 Z, map_class.LookupFactory( | 5561 Z, map_class.LookupFactory( |
5640 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); | 5562 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5677 fragment_ = instructions + StaticCall(node->position(), factory_method, 2); | 5599 fragment_ = instructions + StaticCall(node->position(), factory_method, 2); |
5678 } | 5600 } |
5679 | 5601 |
5680 | 5602 |
5681 void FlowGraphBuilder::VisitFunctionExpression(FunctionExpression* node) { | 5603 void FlowGraphBuilder::VisitFunctionExpression(FunctionExpression* node) { |
5682 fragment_ = TranslateFunctionNode(node->function(), node); | 5604 fragment_ = TranslateFunctionNode(node->function(), node); |
5683 } | 5605 } |
5684 | 5606 |
5685 | 5607 |
5686 void FlowGraphBuilder::VisitLet(Let* node) { | 5608 void FlowGraphBuilder::VisitLet(Let* node) { |
| 5609 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5610 |
5687 Fragment instructions = TranslateStatement(node->variable()); | 5611 Fragment instructions = TranslateStatement(node->variable()); |
5688 instructions += TranslateExpression(node->body()); | 5612 instructions += TranslateExpression(node->body()); |
5689 fragment_ = instructions; | 5613 fragment_ = instructions; |
5690 } | 5614 } |
5691 | 5615 |
5692 | 5616 |
5693 void FlowGraphBuilder::VisitThrow(Throw* node) { | 5617 void FlowGraphBuilder::VisitThrow(Throw* node) { |
| 5618 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5619 |
5694 Fragment instructions; | 5620 Fragment instructions; |
5695 | 5621 |
5696 instructions += TranslateExpression(node->expression()); | 5622 instructions += TranslateExpression(node->expression()); |
5697 if (NeedsDebugStepCheck(stack_, node->position())) { | 5623 if (NeedsDebugStepCheck(stack_, node->position())) { |
5698 instructions = DebugStepCheck(node->position()) + instructions; | 5624 instructions = DebugStepCheck(node->position()) + instructions; |
5699 } | 5625 } |
5700 instructions += PushArgument(); | 5626 instructions += PushArgument(); |
5701 instructions += ThrowException(node->position()); | 5627 instructions += ThrowException(node->position()); |
5702 ASSERT(instructions.is_closed()); | 5628 ASSERT(instructions.is_closed()); |
5703 | 5629 |
5704 fragment_ = instructions; | 5630 fragment_ = instructions; |
5705 } | 5631 } |
5706 | 5632 |
5707 | 5633 |
5708 void FlowGraphBuilder::VisitRethrow(Rethrow* node) { | 5634 void FlowGraphBuilder::VisitRethrow(Rethrow* node) { |
5709 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 5635 fragment_ = |
| 5636 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
5710 } | 5637 } |
5711 | 5638 |
5712 | 5639 |
5713 Fragment FlowGraphBuilder::TranslateArguments(Arguments* node, | 5640 Fragment FlowGraphBuilder::TranslateArguments(Arguments* node, |
5714 Array* argument_names) { | 5641 Array* argument_names) { |
5715 Fragment instructions; | 5642 Fragment instructions; |
5716 | 5643 |
5717 List<Expression>& positional = node->positional(); | 5644 List<Expression>& positional = node->positional(); |
5718 for (intptr_t i = 0; i < positional.length(); ++i) { | 5645 for (intptr_t i = 0; i < positional.length(); ++i) { |
5719 instructions += TranslateExpression(positional[i]); | 5646 instructions += TranslateExpression(positional[i]); |
5720 instructions += PushArgument(); | 5647 instructions += PushArgument(); |
5721 } | 5648 } |
5722 | 5649 |
5723 List<NamedExpression>& named = node->named(); | 5650 List<NamedExpression>& named = node->named(); |
5724 if (argument_names != NULL) { | 5651 if (argument_names != NULL) { |
5725 *argument_names = H.ArgumentNames(&named).raw(); | 5652 *argument_names = H.ArgumentNames(&named).raw(); |
5726 } | 5653 } |
5727 for (intptr_t i = 0; i < named.length(); ++i) { | 5654 for (intptr_t i = 0; i < named.length(); ++i) { |
5728 NamedExpression* named_expression = named[i]; | 5655 NamedExpression* named_expression = named[i]; |
5729 instructions += TranslateExpression(named_expression->expression()); | 5656 instructions += TranslateExpression(named_expression->expression()); |
5730 instructions += PushArgument(); | 5657 instructions += PushArgument(); |
5731 } | 5658 } |
5732 return instructions; | 5659 return instructions; |
5733 } | 5660 } |
5734 | 5661 |
| 5662 #define STREAM_STATEMENT_IF_POSSIBLE(node) \ |
| 5663 if (!node->cannot_stream()) { \ |
| 5664 fragment_ = streaming_flow_graph_builder_->BuildStatementAt( \ |
| 5665 node->kernel_offset()); \ |
| 5666 return; \ |
| 5667 } |
| 5668 |
5735 | 5669 |
5736 void FlowGraphBuilder::VisitInvalidStatement(InvalidStatement* node) { | 5670 void FlowGraphBuilder::VisitInvalidStatement(InvalidStatement* node) { |
5737 H.ReportError("Invalid statements not implemented yet!"); | 5671 fragment_ = |
| 5672 streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset()); |
5738 } | 5673 } |
5739 | 5674 |
5740 | 5675 |
5741 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* node) { | 5676 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* node) { |
5742 fragment_ = Fragment(); | 5677 fragment_ = |
| 5678 streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset()); |
5743 } | 5679 } |
5744 | 5680 |
5745 | 5681 |
5746 void FlowGraphBuilder::VisitBlock(Block* node) { | 5682 void FlowGraphBuilder::VisitBlock(Block* node) { |
| 5683 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5684 |
5747 Fragment instructions; | 5685 Fragment instructions; |
5748 | 5686 |
5749 instructions += EnterScope(node); | 5687 instructions += EnterScope(node); |
5750 List<Statement>& statements = node->statements(); | 5688 List<Statement>& statements = node->statements(); |
5751 for (intptr_t i = 0; (i < statements.length()) && instructions.is_open(); | 5689 for (intptr_t i = 0; (i < statements.length()) && instructions.is_open(); |
5752 ++i) { | 5690 ++i) { |
5753 instructions += TranslateStatement(statements[i]); | 5691 instructions += TranslateStatement(statements[i]); |
5754 } | 5692 } |
5755 instructions += ExitScope(node); | 5693 instructions += ExitScope(node); |
5756 | 5694 |
5757 fragment_ = instructions; | 5695 fragment_ = instructions; |
5758 } | 5696 } |
5759 | 5697 |
5760 | 5698 |
5761 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { | 5699 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { |
| 5700 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5701 |
5762 bool inside_try_finally = try_finally_block_ != NULL; | 5702 bool inside_try_finally = try_finally_block_ != NULL; |
5763 | 5703 |
5764 Fragment instructions = node->expression() == NULL | 5704 Fragment instructions = node->expression() == NULL |
5765 ? NullConstant() | 5705 ? NullConstant() |
5766 : TranslateExpression(node->expression()); | 5706 : TranslateExpression(node->expression()); |
5767 if (instructions.is_open()) { | 5707 if (instructions.is_open()) { |
5768 if (inside_try_finally) { | 5708 if (inside_try_finally) { |
5769 ASSERT(scopes_->finally_return_variable != NULL); | 5709 ASSERT(scopes_->finally_return_variable != NULL); |
5770 const Function& function = parsed_function_->function(); | 5710 const Function& function = parsed_function_->function(); |
5771 if (NeedsDebugStepCheck(function, node->position())) { | 5711 if (NeedsDebugStepCheck(function, node->position())) { |
(...skipping 11 matching lines...) Expand all Loading... |
5783 instructions += Return(node->position()); | 5723 instructions += Return(node->position()); |
5784 } | 5724 } |
5785 } else { | 5725 } else { |
5786 Pop(); | 5726 Pop(); |
5787 } | 5727 } |
5788 fragment_ = instructions; | 5728 fragment_ = instructions; |
5789 } | 5729 } |
5790 | 5730 |
5791 | 5731 |
5792 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* node) { | 5732 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* node) { |
| 5733 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5734 |
5793 Fragment instructions = TranslateExpression(node->expression()); | 5735 Fragment instructions = TranslateExpression(node->expression()); |
5794 instructions += Drop(); | 5736 instructions += Drop(); |
5795 fragment_ = instructions; | 5737 fragment_ = instructions; |
5796 } | 5738 } |
5797 | 5739 |
5798 | 5740 |
5799 void FlowGraphBuilder::VisitVariableDeclaration(VariableDeclaration* node) { | 5741 void FlowGraphBuilder::VisitVariableDeclaration(VariableDeclaration* node) { |
5800 LocalVariable* variable = LookupVariable(node); | 5742 LocalVariable* variable = LookupVariable(node); |
5801 Expression* initializer = node->initializer(); | 5743 Expression* initializer = node->initializer(); |
5802 | 5744 |
(...skipping 28 matching lines...) Expand all Loading... |
5831 Fragment instructions = DebugStepCheck(node->position()); | 5773 Fragment instructions = DebugStepCheck(node->position()); |
5832 instructions += TranslateFunctionNode(node->function(), node); | 5774 instructions += TranslateFunctionNode(node->function(), node); |
5833 instructions += | 5775 instructions += |
5834 StoreLocal(node->position(), LookupVariable(node->variable())); | 5776 StoreLocal(node->position(), LookupVariable(node->variable())); |
5835 instructions += Drop(); | 5777 instructions += Drop(); |
5836 fragment_ = instructions; | 5778 fragment_ = instructions; |
5837 } | 5779 } |
5838 | 5780 |
5839 | 5781 |
5840 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { | 5782 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { |
| 5783 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5784 |
5841 bool negate; | 5785 bool negate; |
5842 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5786 Fragment instructions = TranslateCondition(node->condition(), &negate); |
5843 TargetEntryInstr* then_entry; | 5787 TargetEntryInstr* then_entry; |
5844 TargetEntryInstr* otherwise_entry; | 5788 TargetEntryInstr* otherwise_entry; |
5845 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); | 5789 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); |
5846 | 5790 |
5847 Fragment then_fragment(then_entry); | 5791 Fragment then_fragment(then_entry); |
5848 then_fragment += TranslateStatement(node->then()); | 5792 then_fragment += TranslateStatement(node->then()); |
5849 | 5793 |
5850 Fragment otherwise_fragment(otherwise_entry); | 5794 Fragment otherwise_fragment(otherwise_entry); |
(...skipping 10 matching lines...) Expand all Loading... |
5861 } | 5805 } |
5862 } else if (otherwise_fragment.is_open()) { | 5806 } else if (otherwise_fragment.is_open()) { |
5863 fragment_ = Fragment(instructions.entry, otherwise_fragment.current); | 5807 fragment_ = Fragment(instructions.entry, otherwise_fragment.current); |
5864 } else { | 5808 } else { |
5865 fragment_ = instructions.closed(); | 5809 fragment_ = instructions.closed(); |
5866 } | 5810 } |
5867 } | 5811 } |
5868 | 5812 |
5869 | 5813 |
5870 void FlowGraphBuilder::VisitWhileStatement(WhileStatement* node) { | 5814 void FlowGraphBuilder::VisitWhileStatement(WhileStatement* node) { |
| 5815 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5816 |
5871 ++loop_depth_; | 5817 ++loop_depth_; |
5872 bool negate; | 5818 bool negate; |
5873 Fragment condition = TranslateCondition(node->condition(), &negate); | 5819 Fragment condition = TranslateCondition(node->condition(), &negate); |
5874 TargetEntryInstr* body_entry; | 5820 TargetEntryInstr* body_entry; |
5875 TargetEntryInstr* loop_exit; | 5821 TargetEntryInstr* loop_exit; |
5876 condition += BranchIfTrue(&body_entry, &loop_exit, negate); | 5822 condition += BranchIfTrue(&body_entry, &loop_exit, negate); |
5877 | 5823 |
5878 Fragment body(body_entry); | 5824 Fragment body(body_entry); |
5879 body += TranslateStatement(node->body()); | 5825 body += TranslateStatement(node->body()); |
5880 | 5826 |
(...skipping 10 matching lines...) Expand all Loading... |
5891 entry = condition.entry; | 5837 entry = condition.entry; |
5892 } | 5838 } |
5893 | 5839 |
5894 | 5840 |
5895 fragment_ = Fragment(entry, loop_exit); | 5841 fragment_ = Fragment(entry, loop_exit); |
5896 --loop_depth_; | 5842 --loop_depth_; |
5897 } | 5843 } |
5898 | 5844 |
5899 | 5845 |
5900 void FlowGraphBuilder::VisitDoStatement(DoStatement* node) { | 5846 void FlowGraphBuilder::VisitDoStatement(DoStatement* node) { |
| 5847 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5848 |
5901 ++loop_depth_; | 5849 ++loop_depth_; |
5902 Fragment body = TranslateStatement(node->body()); | 5850 Fragment body = TranslateStatement(node->body()); |
5903 | 5851 |
5904 if (body.is_closed()) { | 5852 if (body.is_closed()) { |
5905 fragment_ = body; | 5853 fragment_ = body; |
5906 --loop_depth_; | 5854 --loop_depth_; |
5907 return; | 5855 return; |
5908 } | 5856 } |
5909 | 5857 |
5910 bool negate; | 5858 bool negate; |
5911 JoinEntryInstr* join = BuildJoinEntry(); | 5859 JoinEntryInstr* join = BuildJoinEntry(); |
5912 Fragment loop(join); | 5860 Fragment loop(join); |
5913 loop += CheckStackOverflow(); | 5861 loop += CheckStackOverflow(); |
5914 loop += body; | 5862 loop += body; |
5915 loop += TranslateCondition(node->condition(), &negate); | 5863 loop += TranslateCondition(node->condition(), &negate); |
5916 TargetEntryInstr* loop_repeat; | 5864 TargetEntryInstr* loop_repeat; |
5917 TargetEntryInstr* loop_exit; | 5865 TargetEntryInstr* loop_exit; |
5918 loop += BranchIfTrue(&loop_repeat, &loop_exit, negate); | 5866 loop += BranchIfTrue(&loop_repeat, &loop_exit, negate); |
5919 | 5867 |
5920 Fragment repeat(loop_repeat); | 5868 Fragment repeat(loop_repeat); |
5921 repeat += Goto(join); | 5869 repeat += Goto(join); |
5922 | 5870 |
5923 fragment_ = Fragment(new (Z) GotoInstr(join), loop_exit); | 5871 fragment_ = Fragment(new (Z) GotoInstr(join), loop_exit); |
5924 --loop_depth_; | 5872 --loop_depth_; |
5925 } | 5873 } |
5926 | 5874 |
5927 | 5875 |
5928 void FlowGraphBuilder::VisitForStatement(ForStatement* node) { | 5876 void FlowGraphBuilder::VisitForStatement(ForStatement* node) { |
| 5877 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5878 |
5929 Fragment declarations; | 5879 Fragment declarations; |
5930 | 5880 |
5931 bool new_context = false; | 5881 bool new_context = false; |
5932 declarations += EnterScope(node, &new_context); | 5882 declarations += EnterScope(node, &new_context); |
5933 | 5883 |
5934 List<VariableDeclaration>& variables = node->variables(); | 5884 List<VariableDeclaration>& variables = node->variables(); |
5935 for (intptr_t i = 0; i < variables.length(); ++i) { | 5885 for (intptr_t i = 0; i < variables.length(); ++i) { |
5936 declarations += TranslateStatement(variables[i]); | 5886 declarations += TranslateStatement(variables[i]); |
5937 } | 5887 } |
5938 | 5888 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5975 Fragment loop(declarations.entry, loop_exit); | 5925 Fragment loop(declarations.entry, loop_exit); |
5976 --loop_depth_; | 5926 --loop_depth_; |
5977 | 5927 |
5978 loop += ExitScope(node); | 5928 loop += ExitScope(node); |
5979 | 5929 |
5980 fragment_ = loop; | 5930 fragment_ = loop; |
5981 } | 5931 } |
5982 | 5932 |
5983 | 5933 |
5984 void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) { | 5934 void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) { |
| 5935 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5936 |
5985 Fragment instructions = TranslateExpression(node->iterable()); | 5937 Fragment instructions = TranslateExpression(node->iterable()); |
5986 instructions += PushArgument(); | 5938 instructions += PushArgument(); |
5987 | 5939 |
5988 const dart::String& iterator_getter = dart::String::ZoneHandle( | 5940 const dart::String& iterator_getter = dart::String::ZoneHandle( |
5989 Z, dart::Field::GetterSymbol(Symbols::Iterator())); | 5941 Z, dart::Field::GetterSymbol(Symbols::Iterator())); |
5990 instructions += InstanceCall(node->iterable()->position(), iterator_getter, | 5942 instructions += InstanceCall(node->iterable()->position(), iterator_getter, |
5991 Token::kGET, 1); | 5943 Token::kGET, 1); |
5992 LocalVariable* iterator = scopes_->iterator_variables[for_in_depth_]; | 5944 LocalVariable* iterator = scopes_->iterator_variables[for_in_depth_]; |
5993 instructions += StoreLocal(TokenPosition::kNoSource, iterator); | 5945 instructions += StoreLocal(TokenPosition::kNoSource, iterator); |
5994 instructions += Drop(); | 5946 instructions += Drop(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6028 instructions += condition; | 5980 instructions += condition; |
6029 } | 5981 } |
6030 | 5982 |
6031 fragment_ = Fragment(instructions.entry, loop_exit); | 5983 fragment_ = Fragment(instructions.entry, loop_exit); |
6032 --loop_depth_; | 5984 --loop_depth_; |
6033 --for_in_depth_; | 5985 --for_in_depth_; |
6034 } | 5986 } |
6035 | 5987 |
6036 | 5988 |
6037 void FlowGraphBuilder::VisitLabeledStatement(LabeledStatement* node) { | 5989 void FlowGraphBuilder::VisitLabeledStatement(LabeledStatement* node) { |
| 5990 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5991 |
6038 // There can be serveral cases: | 5992 // There can be serveral cases: |
6039 // | 5993 // |
6040 // * the body contains a break | 5994 // * the body contains a break |
6041 // * the body doesn't contain a break | 5995 // * the body doesn't contain a break |
6042 // | 5996 // |
6043 // * translating the body results in a closed fragment | 5997 // * translating the body results in a closed fragment |
6044 // * translating the body results in a open fragment | 5998 // * translating the body results in a open fragment |
6045 // | 5999 // |
6046 // => We will only know which case we are in after the body has been | 6000 // => We will only know which case we are in after the body has been |
6047 // traversed. | 6001 // traversed. |
6048 | 6002 |
6049 BreakableBlock block(this, node); | 6003 BreakableBlock block(this); |
6050 Fragment instructions = TranslateStatement(node->body()); | 6004 Fragment instructions = TranslateStatement(node->body()); |
6051 if (block.HadJumper()) { | 6005 if (block.HadJumper()) { |
6052 if (instructions.is_open()) { | 6006 if (instructions.is_open()) { |
6053 instructions += Goto(block.destination()); | 6007 instructions += Goto(block.destination()); |
6054 } | 6008 } |
6055 fragment_ = Fragment(instructions.entry, block.destination()); | 6009 fragment_ = Fragment(instructions.entry, block.destination()); |
6056 } else { | 6010 } else { |
6057 fragment_ = instructions; | 6011 fragment_ = instructions; |
6058 } | 6012 } |
6059 } | 6013 } |
6060 | 6014 |
6061 | 6015 |
6062 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) { | 6016 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) { |
6063 TryFinallyBlock* outer_finally = NULL; | 6017 fragment_ = |
6064 intptr_t target_context_depth = -1; | 6018 streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset()); |
6065 JoinEntryInstr* destination = breakable_block_->BreakDestination( | |
6066 node->target(), &outer_finally, &target_context_depth); | |
6067 | |
6068 Fragment instructions; | |
6069 instructions += | |
6070 TranslateFinallyFinalizers(outer_finally, target_context_depth); | |
6071 if (instructions.is_open()) { | |
6072 if (NeedsDebugStepCheck(parsed_function_->function(), node->position())) { | |
6073 instructions += DebugStepCheck(node->position()); | |
6074 } | |
6075 instructions += Goto(destination); | |
6076 } | |
6077 fragment_ = instructions; | |
6078 } | 6019 } |
6079 | 6020 |
6080 | 6021 |
6081 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { | 6022 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { |
6082 SwitchBlock block(this, node); | 6023 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6024 |
| 6025 SwitchBlock block(this, node->cases().length()); |
6083 | 6026 |
6084 // Instead of using a variable we should reuse the expression on the stack, | 6027 // Instead of using a variable we should reuse the expression on the stack, |
6085 // since it won't be assigned again, we don't need phi nodes. | 6028 // since it won't be assigned again, we don't need phi nodes. |
6086 Fragment head_instructions = TranslateExpression(node->condition()); | 6029 Fragment head_instructions = TranslateExpression(node->condition()); |
6087 head_instructions += | 6030 head_instructions += |
6088 StoreLocal(TokenPosition::kNoSource, scopes_->switch_variable); | 6031 StoreLocal(TokenPosition::kNoSource, scopes_->switch_variable); |
6089 head_instructions += Drop(); | 6032 head_instructions += Drop(); |
6090 | 6033 |
6091 // Phase 1: Generate bodies and try to find out whether a body will be target | 6034 // Phase 1: Generate bodies and try to find out whether a body will be target |
6092 // of a jump due to: | 6035 // of a jump due to: |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6150 // switch(expr) { | 6093 // switch(expr) { |
6151 // case a: | 6094 // case a: |
6152 // case b: | 6095 // case b: |
6153 // <stmt-body> | 6096 // <stmt-body> |
6154 // } | 6097 // } |
6155 // | 6098 // |
6156 // This means that the <stmt-body> will have more than 1 incoming edge (one | 6099 // This means that the <stmt-body> will have more than 1 incoming edge (one |
6157 // from `a == expr` and one from `a != expr && b == expr`). The | 6100 // from `a == expr` and one from `a != expr && b == expr`). The |
6158 // `block.Destination()` records the additional jump. | 6101 // `block.Destination()` records the additional jump. |
6159 if (switch_case->expressions().length() > 1) { | 6102 if (switch_case->expressions().length() > 1) { |
6160 block.Destination(switch_case); | 6103 block.DestinationDirect(i); |
6161 } | 6104 } |
6162 } | 6105 } |
6163 | 6106 |
6164 // Phase 2: Generate everything except the real bodies: | 6107 // Phase 2: Generate everything except the real bodies: |
6165 // * jump directly to a body (if there is no jumper) | 6108 // * jump directly to a body (if there is no jumper) |
6166 // * jump to a wrapper block which jumps to the body (if there is a jumper) | 6109 // * jump to a wrapper block which jumps to the body (if there is a jumper) |
6167 Fragment current_instructions = head_instructions; | 6110 Fragment current_instructions = head_instructions; |
6168 for (intptr_t i = 0; i < num_cases; i++) { | 6111 for (intptr_t i = 0; i < num_cases; i++) { |
6169 SwitchCase* switch_case = node->cases()[i]; | 6112 SwitchCase* switch_case = node->cases()[i]; |
6170 | 6113 |
6171 if (switch_case->is_default()) { | 6114 if (switch_case->is_default()) { |
6172 ASSERT(i == (node->cases().length() - 1)); | 6115 ASSERT(i == (node->cases().length() - 1)); |
6173 | 6116 |
6174 // Evaluate the conditions for the default [SwitchCase] just for the | 6117 // Evaluate the conditions for the default [SwitchCase] just for the |
6175 // purpose of potentially triggering a compile-time error. | 6118 // purpose of potentially triggering a compile-time error. |
6176 for (intptr_t k = 0; k < switch_case->expressions().length(); k++) { | 6119 for (intptr_t k = 0; k < switch_case->expressions().length(); k++) { |
6177 constant_evaluator_.EvaluateExpression(switch_case->expressions()[k]); | 6120 constant_evaluator_.EvaluateExpression(switch_case->expressions()[k]); |
6178 } | 6121 } |
6179 | 6122 |
6180 if (block.HadJumper(switch_case)) { | 6123 if (block.HadJumper(i)) { |
6181 // There are several branches to the body, so we will make a goto to | 6124 // There are several branches to the body, so we will make a goto to |
6182 // the join block (and prepend a join instruction to the real body). | 6125 // the join block (and prepend a join instruction to the real body). |
6183 JoinEntryInstr* join = block.Destination(switch_case); | 6126 JoinEntryInstr* join = block.DestinationDirect(i); |
6184 current_instructions += Goto(join); | 6127 current_instructions += Goto(join); |
6185 | 6128 |
6186 current_instructions = Fragment(current_instructions.entry, join); | 6129 current_instructions = Fragment(current_instructions.entry, join); |
6187 current_instructions += body_fragments[i]; | 6130 current_instructions += body_fragments[i]; |
6188 } else { | 6131 } else { |
6189 current_instructions += body_fragments[i]; | 6132 current_instructions += body_fragments[i]; |
6190 } | 6133 } |
6191 } else { | 6134 } else { |
6192 JoinEntryInstr* body_join = NULL; | 6135 JoinEntryInstr* body_join = NULL; |
6193 if (block.HadJumper(switch_case)) { | 6136 if (block.HadJumper(i)) { |
6194 body_join = block.Destination(switch_case); | 6137 body_join = block.DestinationDirect(i); |
6195 body_fragments[i] = Fragment(body_join) + body_fragments[i]; | 6138 body_fragments[i] = Fragment(body_join) + body_fragments[i]; |
6196 } | 6139 } |
6197 | 6140 |
6198 for (intptr_t j = 0; j < switch_case->expressions().length(); j++) { | 6141 for (intptr_t j = 0; j < switch_case->expressions().length(); j++) { |
6199 TargetEntryInstr* then; | 6142 TargetEntryInstr* then; |
6200 TargetEntryInstr* otherwise; | 6143 TargetEntryInstr* otherwise; |
6201 | 6144 |
6202 Expression* expression = switch_case->expressions()[j]; | 6145 Expression* expression = switch_case->expressions()[j]; |
6203 current_instructions += | 6146 current_instructions += |
6204 Constant(constant_evaluator_.EvaluateExpression(expression)); | 6147 Constant(constant_evaluator_.EvaluateExpression(expression)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6256 } | 6199 } |
6257 | 6200 |
6258 delete[] body_fragments; | 6201 delete[] body_fragments; |
6259 | 6202 |
6260 fragment_ = Fragment(head_instructions.entry, current_instructions.current); | 6203 fragment_ = Fragment(head_instructions.entry, current_instructions.current); |
6261 } | 6204 } |
6262 | 6205 |
6263 | 6206 |
6264 void FlowGraphBuilder::VisitContinueSwitchStatement( | 6207 void FlowGraphBuilder::VisitContinueSwitchStatement( |
6265 ContinueSwitchStatement* node) { | 6208 ContinueSwitchStatement* node) { |
6266 TryFinallyBlock* outer_finally = NULL; | 6209 fragment_ = |
6267 intptr_t target_context_depth = -1; | 6210 streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset()); |
6268 JoinEntryInstr* entry = switch_block_->Destination( | |
6269 node->target(), &outer_finally, &target_context_depth); | |
6270 | |
6271 Fragment instructions; | |
6272 instructions += | |
6273 TranslateFinallyFinalizers(outer_finally, target_context_depth); | |
6274 if (instructions.is_open()) { | |
6275 instructions += Goto(entry); | |
6276 } | |
6277 fragment_ = instructions; | |
6278 } | 6211 } |
6279 | 6212 |
6280 | 6213 |
6281 void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) { | 6214 void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) { |
| 6215 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6216 |
6282 if (!I->asserts()) { | 6217 if (!I->asserts()) { |
6283 fragment_ = Fragment(); | 6218 fragment_ = Fragment(); |
6284 return; | 6219 return; |
6285 } | 6220 } |
6286 | 6221 |
6287 TargetEntryInstr* then; | 6222 TargetEntryInstr* then; |
6288 TargetEntryInstr* otherwise; | 6223 TargetEntryInstr* otherwise; |
6289 | 6224 |
6290 Fragment instructions; | 6225 Fragment instructions; |
6291 // Asserts can be of the following two kinds: | 6226 // Asserts can be of the following two kinds: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6347 // Throw _AssertionError exception. | 6282 // Throw _AssertionError exception. |
6348 otherwise_fragment += PushArgument(); | 6283 otherwise_fragment += PushArgument(); |
6349 otherwise_fragment += ThrowException(TokenPosition::kNoSource); | 6284 otherwise_fragment += ThrowException(TokenPosition::kNoSource); |
6350 otherwise_fragment += Drop(); | 6285 otherwise_fragment += Drop(); |
6351 | 6286 |
6352 fragment_ = Fragment(instructions.entry, then); | 6287 fragment_ = Fragment(instructions.entry, then); |
6353 } | 6288 } |
6354 | 6289 |
6355 | 6290 |
6356 void FlowGraphBuilder::VisitTryFinally(TryFinally* node) { | 6291 void FlowGraphBuilder::VisitTryFinally(TryFinally* node) { |
| 6292 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6293 |
6357 InlineBailout("kernel::FlowgraphBuilder::VisitTryFinally"); | 6294 InlineBailout("kernel::FlowgraphBuilder::VisitTryFinally"); |
6358 | 6295 |
6359 // There are 5 different cases where we need to execute the finally block: | 6296 // There are 5 different cases where we need to execute the finally block: |
6360 // | 6297 // |
6361 // a) 1/2/3th case: Special control flow going out of `node->body()`: | 6298 // a) 1/2/3th case: Special control flow going out of `node->body()`: |
6362 // | 6299 // |
6363 // * [BreakStatement] transfers control to a [LabledStatement] | 6300 // * [BreakStatement] transfers control to a [LabledStatement] |
6364 // * [ContinueSwitchStatement] transfers control to a [SwitchCase] | 6301 // * [ContinueSwitchStatement] transfers control to a [SwitchCase] |
6365 // * [ReturnStatement] returns a value | 6302 // * [ReturnStatement] returns a value |
6366 // | 6303 // |
(...skipping 11 matching lines...) Expand all Loading... |
6378 // | 6315 // |
6379 // => We are responsible for catching it, executing the finally block and | 6316 // => We are responsible for catching it, executing the finally block and |
6380 // rethrowing the exception. | 6317 // rethrowing the exception. |
6381 intptr_t try_handler_index = AllocateTryIndex(); | 6318 intptr_t try_handler_index = AllocateTryIndex(); |
6382 Fragment try_body = TryCatch(try_handler_index); | 6319 Fragment try_body = TryCatch(try_handler_index); |
6383 JoinEntryInstr* after_try = BuildJoinEntry(); | 6320 JoinEntryInstr* after_try = BuildJoinEntry(); |
6384 | 6321 |
6385 // Fill in the body of the try. | 6322 // Fill in the body of the try. |
6386 ++try_depth_; | 6323 ++try_depth_; |
6387 { | 6324 { |
6388 TryFinallyBlock tfb(this, node->finalizer()); | 6325 TryFinallyBlock tfb(this, node->finalizer(), -1); |
6389 TryCatchBlock tcb(this, try_handler_index); | 6326 TryCatchBlock tcb(this, try_handler_index); |
6390 try_body += TranslateStatement(node->body()); | 6327 try_body += TranslateStatement(node->body()); |
6391 } | 6328 } |
6392 --try_depth_; | 6329 --try_depth_; |
6393 | 6330 |
6394 if (try_body.is_open()) { | 6331 if (try_body.is_open()) { |
6395 // Please note: The try index will be on level out of this block, | 6332 // Please note: The try index will be on level out of this block, |
6396 // thereby ensuring if there's an exception in the finally block we | 6333 // thereby ensuring if there's an exception in the finally block we |
6397 // won't run it twice. | 6334 // won't run it twice. |
6398 JoinEntryInstr* finally_entry = BuildJoinEntry(); | 6335 JoinEntryInstr* finally_entry = BuildJoinEntry(); |
(...skipping 22 matching lines...) Expand all Loading... |
6421 RethrowException(TokenPosition::kNoSource, try_handler_index); | 6358 RethrowException(TokenPosition::kNoSource, try_handler_index); |
6422 Drop(); | 6359 Drop(); |
6423 } | 6360 } |
6424 --catch_depth_; | 6361 --catch_depth_; |
6425 | 6362 |
6426 fragment_ = Fragment(try_body.entry, after_try); | 6363 fragment_ = Fragment(try_body.entry, after_try); |
6427 } | 6364 } |
6428 | 6365 |
6429 | 6366 |
6430 void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) { | 6367 void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) { |
| 6368 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6369 |
6431 InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch"); | 6370 InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch"); |
6432 | 6371 |
6433 intptr_t try_handler_index = AllocateTryIndex(); | 6372 intptr_t try_handler_index = AllocateTryIndex(); |
6434 Fragment try_body = TryCatch(try_handler_index); | 6373 Fragment try_body = TryCatch(try_handler_index); |
6435 JoinEntryInstr* after_try = BuildJoinEntry(); | 6374 JoinEntryInstr* after_try = BuildJoinEntry(); |
6436 | 6375 |
6437 // Fill in the body of the try. | 6376 // Fill in the body of the try. |
6438 ++try_depth_; | 6377 ++try_depth_; |
6439 { | 6378 { |
6440 TryCatchBlock block(this, try_handler_index); | 6379 TryCatchBlock block(this, try_handler_index); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6540 catch_body += RethrowException(TokenPosition::kNoSource, try_handler_index); | 6479 catch_body += RethrowException(TokenPosition::kNoSource, try_handler_index); |
6541 Drop(); | 6480 Drop(); |
6542 } | 6481 } |
6543 --catch_depth_; | 6482 --catch_depth_; |
6544 | 6483 |
6545 fragment_ = Fragment(try_body.entry, after_try); | 6484 fragment_ = Fragment(try_body.entry, after_try); |
6546 } | 6485 } |
6547 | 6486 |
6548 | 6487 |
6549 void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) { | 6488 void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) { |
| 6489 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6490 |
6550 ASSERT(node->is_native()); // Must have been desugared. | 6491 ASSERT(node->is_native()); // Must have been desugared. |
6551 // Setup yield/continue point: | 6492 // Setup yield/continue point: |
6552 // | 6493 // |
6553 // ... | 6494 // ... |
6554 // :await_jump_var = index; | 6495 // :await_jump_var = index; |
6555 // :await_ctx_var = :current_context_var | 6496 // :await_ctx_var = :current_context_var |
6556 // return <expr> | 6497 // return <expr> |
6557 // | 6498 // |
6558 // Continuation<index>: | 6499 // Continuation<index>: |
6559 // Drop(1) | 6500 // Drop(1) |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6848 thread->clear_sticky_error(); | 6789 thread->clear_sticky_error(); |
6849 return error.raw(); | 6790 return error.raw(); |
6850 } | 6791 } |
6851 } | 6792 } |
6852 | 6793 |
6853 | 6794 |
6854 } // namespace kernel | 6795 } // namespace kernel |
6855 } // namespace dart | 6796 } // namespace dart |
6856 | 6797 |
6857 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6798 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |