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 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 Field* field = fields[i]; | 809 Field* field = fields[i]; |
810 Expression* initializer = field->initializer(); | 810 Expression* initializer = field->initializer(); |
811 if (!field->IsStatic() && (initializer != NULL)) { | 811 if (!field->IsStatic() && (initializer != NULL)) { |
812 initializer->AcceptExpressionVisitor(this); | 812 initializer->AcceptExpressionVisitor(this); |
813 } | 813 } |
814 } | 814 } |
815 node->VisitChildren(this); | 815 node->VisitChildren(this); |
816 } | 816 } |
817 | 817 |
818 | 818 |
819 class BreakableBlock { | |
820 public: | |
821 BreakableBlock(FlowGraphBuilder* builder, LabeledStatement* statement) | |
822 : builder_(builder), | |
823 labeled_statement_(statement), | |
824 outer_(builder->breakable_block_), | |
825 destination_(NULL), | |
826 outer_finally_(builder->try_finally_block_), | |
827 context_depth_(builder->context_depth_), | |
828 try_index_(builder->CurrentTryIndex()) { | |
829 builder_->breakable_block_ = this; | |
830 } | |
831 ~BreakableBlock() { builder_->breakable_block_ = outer_; } | |
832 | |
833 bool HadJumper() { return destination_ != NULL; } | |
834 | |
835 JoinEntryInstr* destination() { return destination_; } | |
836 | |
837 JoinEntryInstr* BreakDestination(LabeledStatement* label, | |
838 TryFinallyBlock** outer_finally, | |
839 intptr_t* context_depth) { | |
840 BreakableBlock* block = builder_->breakable_block_; | |
841 while (block->labeled_statement_ != label) { | |
842 block = block->outer_; | |
843 } | |
844 ASSERT(block != NULL); | |
845 *outer_finally = block->outer_finally_; | |
846 *context_depth = block->context_depth_; | |
847 return block->EnsureDestination(); | |
848 } | |
849 | |
850 private: | |
851 JoinEntryInstr* EnsureDestination() { | |
852 if (destination_ == NULL) { | |
853 destination_ = builder_->BuildJoinEntry(try_index_); | |
854 } | |
855 return destination_; | |
856 } | |
857 | |
858 FlowGraphBuilder* builder_; | |
859 LabeledStatement* labeled_statement_; | |
860 BreakableBlock* outer_; | |
861 JoinEntryInstr* destination_; | |
862 TryFinallyBlock* outer_finally_; | |
863 intptr_t context_depth_; | |
864 intptr_t try_index_; | |
865 }; | |
866 | |
867 | |
868 class SwitchBlock { | |
869 public: | |
870 SwitchBlock(FlowGraphBuilder* builder, SwitchStatement* switch_stmt) | |
871 : builder_(builder), | |
872 outer_(builder->switch_block_), | |
873 outer_finally_(builder->try_finally_block_), | |
874 switch_statement_(switch_stmt), | |
875 context_depth_(builder->context_depth_), | |
876 try_index_(builder->CurrentTryIndex()) { | |
877 builder_->switch_block_ = this; | |
878 } | |
879 ~SwitchBlock() { builder_->switch_block_ = outer_; } | |
880 | |
881 bool HadJumper(SwitchCase* switch_case) { | |
882 return destinations_.Lookup(switch_case) != NULL; | |
883 } | |
884 | |
885 JoinEntryInstr* Destination(SwitchCase* label, | |
886 TryFinallyBlock** outer_finally = NULL, | |
887 intptr_t* context_depth = NULL) { | |
888 // Find corresponding [SwitchStatement]. | |
889 SwitchBlock* block = this; | |
890 while (true) { | |
891 block->EnsureSwitchCaseMapping(); | |
892 if (block->Contains(label)) break; | |
893 block = block->outer_; | |
894 } | |
895 | |
896 // Set the outer finally block. | |
897 if (outer_finally != NULL) { | |
898 *outer_finally = block->outer_finally_; | |
899 *context_depth = block->context_depth_; | |
900 } | |
901 | |
902 // Ensure there's [JoinEntryInstr] for that [SwitchCase]. | |
903 return block->EnsureDestination(label); | |
904 } | |
905 | |
906 private: | |
907 typedef std::set<SwitchCase*> DestinationSwitches; | |
908 | |
909 JoinEntryInstr* EnsureDestination(SwitchCase* switch_case) { | |
910 JoinEntryInstr* cached_inst = destinations_.Lookup(switch_case); | |
911 if (cached_inst == NULL) { | |
912 JoinEntryInstr* inst = builder_->BuildJoinEntry(try_index_); | |
913 destinations_.Insert(switch_case, inst); | |
914 return inst; | |
915 } | |
916 return cached_inst; | |
917 } | |
918 | |
919 void EnsureSwitchCaseMapping() { | |
920 if (destination_switches_.begin() == destination_switches_.end()) { | |
921 List<SwitchCase>& cases = switch_statement_->cases(); | |
922 for (intptr_t i = 0; i < cases.length(); i++) { | |
923 destination_switches_.insert(cases[i]); | |
924 } | |
925 } | |
926 } | |
927 | |
928 bool Contains(SwitchCase* sc) { | |
929 return destination_switches_.find(sc) != destination_switches_.end(); | |
930 } | |
931 | |
932 FlowGraphBuilder* builder_; | |
933 SwitchBlock* outer_; | |
934 | |
935 Map<SwitchCase, JoinEntryInstr*> destinations_; | |
936 DestinationSwitches destination_switches_; | |
937 | |
938 TryFinallyBlock* outer_finally_; | |
939 SwitchStatement* switch_statement_; | |
940 intptr_t context_depth_; | |
941 intptr_t try_index_; | |
942 }; | |
943 | |
944 | |
945 class TryFinallyBlock { | |
946 public: | |
947 TryFinallyBlock(FlowGraphBuilder* builder, Statement* finalizer) | |
948 : builder_(builder), | |
949 outer_(builder->try_finally_block_), | |
950 finalizer_(finalizer), | |
951 context_depth_(builder->context_depth_), | |
952 // Finalizers are executed outside of the try block hence | |
953 // try depth of finalizers are one less than current try | |
954 // depth. | |
955 try_depth_(builder->try_depth_ - 1), | |
956 try_index_(builder_->CurrentTryIndex()) { | |
957 builder_->try_finally_block_ = this; | |
958 } | |
959 ~TryFinallyBlock() { builder_->try_finally_block_ = outer_; } | |
960 | |
961 Statement* finalizer() const { return finalizer_; } | |
962 intptr_t context_depth() const { return context_depth_; } | |
963 intptr_t try_depth() const { return try_depth_; } | |
964 intptr_t try_index() const { return try_index_; } | |
965 TryFinallyBlock* outer() const { return outer_; } | |
966 | |
967 private: | |
968 FlowGraphBuilder* const builder_; | |
969 TryFinallyBlock* const outer_; | |
970 Statement* const finalizer_; | |
971 const intptr_t context_depth_; | |
972 const intptr_t try_depth_; | |
973 const intptr_t try_index_; | |
974 }; | |
975 | |
976 | |
977 class TryCatchBlock { | |
978 public: | |
979 explicit TryCatchBlock(FlowGraphBuilder* builder, | |
980 intptr_t try_handler_index = -1) | |
981 : builder_(builder), | |
982 outer_(builder->try_catch_block_), | |
983 try_index_(try_handler_index) { | |
984 if (try_index_ == -1) try_index_ = builder->AllocateTryIndex(); | |
985 builder->try_catch_block_ = this; | |
986 } | |
987 ~TryCatchBlock() { builder_->try_catch_block_ = outer_; } | |
988 | |
989 intptr_t try_index() { return try_index_; } | |
990 TryCatchBlock* outer() const { return outer_; } | |
991 | |
992 private: | |
993 FlowGraphBuilder* builder_; | |
994 TryCatchBlock* outer_; | |
995 intptr_t try_index_; | |
996 }; | |
997 | |
998 | |
999 Fragment& Fragment::operator+=(const Fragment& other) { | 819 Fragment& Fragment::operator+=(const Fragment& other) { |
1000 if (entry == NULL) { | 820 if (entry == NULL) { |
1001 entry = other.entry; | 821 entry = other.entry; |
1002 current = other.current; | 822 current = other.current; |
1003 } else if (current != NULL && other.entry != NULL) { | 823 } else if (current != NULL && other.entry != NULL) { |
1004 current->LinkTo(other.entry); | 824 current->LinkTo(other.entry); |
1005 current = other.current; | 825 current = other.current; |
1006 } | 826 } |
1007 return *this; | 827 return *this; |
1008 } | 828 } |
(...skipping 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2264 try_catch_block_ = try_catch_block_->outer(); | 2084 try_catch_block_ = try_catch_block_->outer(); |
2265 changed_try_index = true; | 2085 changed_try_index = true; |
2266 } | 2086 } |
2267 if (changed_try_index) { | 2087 if (changed_try_index) { |
2268 JoinEntryInstr* entry = BuildJoinEntry(); | 2088 JoinEntryInstr* entry = BuildJoinEntry(); |
2269 instructions += Goto(entry); | 2089 instructions += Goto(entry); |
2270 instructions = Fragment(instructions.entry, entry); | 2090 instructions = Fragment(instructions.entry, entry); |
2271 } | 2091 } |
2272 | 2092 |
2273 Statement* finalizer = try_finally_block_->finalizer(); | 2093 Statement* finalizer = try_finally_block_->finalizer(); |
| 2094 intptr_t finalizer_kernel_offset = |
| 2095 try_finally_block_->finalizer_kernel_offset(); |
2274 try_finally_block_ = try_finally_block_->outer(); | 2096 try_finally_block_ = try_finally_block_->outer(); |
2275 | 2097 if (finalizer != NULL) { |
2276 // This will potentially have exceptional cases as described in | 2098 // This will potentially have exceptional cases as described in |
2277 // [VisitTryFinally] and will handle them. | 2099 // [VisitTryFinally] and will handle them. |
2278 instructions += TranslateStatement(finalizer); | 2100 instructions += TranslateStatement(finalizer); |
| 2101 } else { |
| 2102 instructions += streaming_flow_graph_builder_->BuildStatementAt( |
| 2103 finalizer_kernel_offset); |
| 2104 } |
2279 | 2105 |
2280 // We only need to make sure that if the finalizer ended normally, we | 2106 // We only need to make sure that if the finalizer ended normally, we |
2281 // continue towards the next outer try-finally. | 2107 // continue towards the next outer try-finally. |
2282 if (!instructions.is_open()) break; | 2108 if (!instructions.is_open()) break; |
2283 } | 2109 } |
2284 | 2110 |
2285 if (instructions.is_open() && target_context_depth != -1) { | 2111 if (instructions.is_open() && target_context_depth != -1) { |
2286 // A target context depth of -1 indicates that the code after this | 2112 // A target context depth of -1 indicates that the code after this |
2287 // will not care about the context chain so we can leave it any way we | 2113 // will not care about the context chain so we can leave it any way we |
2288 // want after the last finalizer. That is used when returning. | 2114 // want after the last finalizer. That is used when returning. |
2289 instructions += AdjustContextTo(target_context_depth); | 2115 instructions += AdjustContextTo(target_context_depth); |
2290 } | 2116 } |
2291 | 2117 |
2292 try_finally_block_ = saved_block; | 2118 try_finally_block_ = saved_block; |
2293 try_catch_block_ = saved_try_catch_block; | 2119 try_catch_block_ = saved_try_catch_block; |
2294 context_depth_ = saved_depth; | 2120 context_depth_ = saved_depth; |
2295 try_depth_ = saved_try_depth; | 2121 try_depth_ = saved_try_depth; |
2296 | 2122 |
2297 return instructions; | 2123 return instructions; |
2298 } | 2124 } |
2299 | 2125 |
2300 | 2126 |
2301 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) { | 2127 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) { |
| 2128 return EnterScope(node->kernel_offset(), new_context); |
| 2129 } |
| 2130 |
| 2131 |
| 2132 Fragment FlowGraphBuilder::EnterScope(intptr_t kernel_offset, |
| 2133 bool* new_context) { |
2302 Fragment instructions; | 2134 Fragment instructions; |
2303 const intptr_t context_size = | 2135 const intptr_t context_size = |
2304 scopes_->scopes.Lookup(node->kernel_offset())->num_context_variables(); | 2136 scopes_->scopes.Lookup(kernel_offset)->num_context_variables(); |
2305 if (context_size > 0) { | 2137 if (context_size > 0) { |
2306 instructions += PushContext(context_size); | 2138 instructions += PushContext(context_size); |
2307 instructions += Drop(); | 2139 instructions += Drop(); |
2308 if (new_context != NULL) { | 2140 if (new_context != NULL) { |
2309 *new_context = true; | 2141 *new_context = true; |
2310 } | 2142 } |
2311 } | 2143 } |
2312 return instructions; | 2144 return instructions; |
2313 } | 2145 } |
2314 | 2146 |
2315 | 2147 |
2316 Fragment FlowGraphBuilder::ExitScope(TreeNode* node) { | 2148 Fragment FlowGraphBuilder::ExitScope(TreeNode* node) { |
| 2149 return ExitScope(node->kernel_offset()); |
| 2150 } |
| 2151 |
| 2152 |
| 2153 Fragment FlowGraphBuilder::ExitScope(intptr_t kernel_offset) { |
2317 Fragment instructions; | 2154 Fragment instructions; |
2318 const intptr_t context_size = | 2155 const intptr_t context_size = |
2319 scopes_->scopes.Lookup(node->kernel_offset())->num_context_variables(); | 2156 scopes_->scopes.Lookup(kernel_offset)->num_context_variables(); |
2320 if (context_size > 0) { | 2157 if (context_size > 0) { |
2321 instructions += PopContext(); | 2158 instructions += PopContext(); |
2322 } | 2159 } |
2323 return instructions; | 2160 return instructions; |
2324 } | 2161 } |
2325 | 2162 |
2326 | 2163 |
2327 Fragment FlowGraphBuilder::LoadContextAt(int depth) { | 2164 Fragment FlowGraphBuilder::LoadContextAt(int depth) { |
2328 intptr_t delta = context_depth_ - depth; | 2165 intptr_t delta = context_depth_ - depth; |
2329 ASSERT(delta >= 0); | 2166 ASSERT(delta >= 0); |
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3186 } | 3023 } |
3187 | 3024 |
3188 | 3025 |
3189 LocalVariable* FlowGraphBuilder::LookupVariable(VariableDeclaration* var) { | 3026 LocalVariable* FlowGraphBuilder::LookupVariable(VariableDeclaration* var) { |
3190 LocalVariable* local = scopes_->locals.Lookup(var->kernel_offset()); | 3027 LocalVariable* local = scopes_->locals.Lookup(var->kernel_offset()); |
3191 ASSERT(local != NULL); | 3028 ASSERT(local != NULL); |
3192 return local; | 3029 return local; |
3193 } | 3030 } |
3194 | 3031 |
3195 | 3032 |
| 3033 dart::LocalVariable* FlowGraphBuilder::LookupVariable(intptr_t kernel_offset) { |
| 3034 LocalVariable* local = scopes_->locals.Lookup(kernel_offset); |
| 3035 ASSERT(local != NULL); |
| 3036 return local; |
| 3037 } |
| 3038 |
| 3039 |
3196 void FlowGraphBuilder::SetTempIndex(Definition* definition) { | 3040 void FlowGraphBuilder::SetTempIndex(Definition* definition) { |
3197 definition->set_temp_index( | 3041 definition->set_temp_index( |
3198 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1); | 3042 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1); |
3199 } | 3043 } |
3200 | 3044 |
3201 | 3045 |
3202 void FlowGraphBuilder::Push(Definition* definition) { | 3046 void FlowGraphBuilder::Push(Definition* definition) { |
3203 SetTempIndex(definition); | 3047 SetTempIndex(definition); |
3204 Value::AddToList(new (Z) Value(definition), &stack_); | 3048 Value::AddToList(new (Z) Value(definition), &stack_); |
3205 } | 3049 } |
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3981 const AbstractType& dst_type = T.TranslateType(variable->type()); | 3825 const AbstractType& dst_type = T.TranslateType(variable->type()); |
3982 if (dst_type.IsMalformed()) { | 3826 if (dst_type.IsMalformed()) { |
3983 return ThrowTypeError(); | 3827 return ThrowTypeError(); |
3984 } | 3828 } |
3985 return CheckAssignableInCheckedMode(dst_type, | 3829 return CheckAssignableInCheckedMode(dst_type, |
3986 H.DartSymbol(variable->name())); | 3830 H.DartSymbol(variable->name())); |
3987 } | 3831 } |
3988 return Fragment(); | 3832 return Fragment(); |
3989 } | 3833 } |
3990 | 3834 |
| 3835 Fragment FlowGraphBuilder::CheckVariableTypeInCheckedMode( |
| 3836 const AbstractType& dst_type, |
| 3837 const dart::String& name_symbol) { |
| 3838 if (I->type_checks()) { |
| 3839 if (dst_type.IsMalformed()) { |
| 3840 return ThrowTypeError(); |
| 3841 } |
| 3842 return CheckAssignableInCheckedMode(dst_type, name_symbol); |
| 3843 } |
| 3844 return Fragment(); |
| 3845 } |
| 3846 |
3991 | 3847 |
3992 bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function, | 3848 bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function, |
3993 TokenPosition position) { | 3849 TokenPosition position) { |
3994 return FLAG_support_debugger && position.IsDebugPause() && | 3850 return FLAG_support_debugger && position.IsDebugPause() && |
3995 !function.is_native() && function.is_debuggable(); | 3851 !function.is_native() && function.is_debuggable(); |
3996 } | 3852 } |
3997 | 3853 |
3998 | 3854 |
3999 bool FlowGraphBuilder::NeedsDebugStepCheck(Value* value, | 3855 bool FlowGraphBuilder::NeedsDebugStepCheck(Value* value, |
4000 TokenPosition position) { | 3856 TokenPosition position) { |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4534 } | 4390 } |
4535 } | 4391 } |
4536 return instructions; | 4392 return instructions; |
4537 } | 4393 } |
4538 | 4394 |
4539 | 4395 |
4540 Fragment FlowGraphBuilder::TranslateStatement(Statement* statement) { | 4396 Fragment FlowGraphBuilder::TranslateStatement(Statement* statement) { |
4541 #ifdef DEBUG | 4397 #ifdef DEBUG |
4542 intptr_t original_context_depth = context_depth_; | 4398 intptr_t original_context_depth = context_depth_; |
4543 #endif | 4399 #endif |
4544 statement->AcceptStatementVisitor(this); | 4400 |
| 4401 // TODO(jensj): VariableDeclaration doesn't necessarily have a tag. |
| 4402 if (statement->can_stream() && |
| 4403 statement->Type() != Node::kTypeVariableDeclaration) { |
| 4404 fragment_ = streaming_flow_graph_builder_->BuildStatementAt( |
| 4405 statement->kernel_offset()); |
| 4406 } else { |
| 4407 statement->AcceptStatementVisitor(this); |
| 4408 } |
4545 DEBUG_ASSERT(context_depth_ == original_context_depth); | 4409 DEBUG_ASSERT(context_depth_ == original_context_depth); |
4546 return fragment_; | 4410 return fragment_; |
4547 } | 4411 } |
4548 | 4412 |
4549 | 4413 |
4550 Fragment FlowGraphBuilder::TranslateCondition(Expression* expression, | 4414 Fragment FlowGraphBuilder::TranslateCondition(Expression* expression, |
4551 bool* negate) { | 4415 bool* negate) { |
4552 *negate = expression->IsNot(); | 4416 *negate = expression->IsNot(); |
4553 Fragment instructions; | 4417 Fragment instructions; |
4554 if (*negate) { | 4418 if (*negate) { |
4555 instructions += TranslateExpression(Not::Cast(expression)->expression()); | 4419 instructions += TranslateExpression(Not::Cast(expression)->expression()); |
4556 } else { | 4420 } else { |
4557 instructions += TranslateExpression(expression); | 4421 instructions += TranslateExpression(expression); |
4558 } | 4422 } |
4559 instructions += CheckBooleanInCheckedMode(); | 4423 instructions += CheckBooleanInCheckedMode(); |
4560 return instructions; | 4424 return instructions; |
4561 } | 4425 } |
4562 | 4426 |
4563 | 4427 |
4564 Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) { | 4428 Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) { |
4565 expression->AcceptExpressionVisitor(this); | 4429 if (expression->can_stream()) { |
| 4430 fragment_ = streaming_flow_graph_builder_->BuildExpressionAt( |
| 4431 expression->kernel_offset()); |
| 4432 } else { |
| 4433 expression->AcceptExpressionVisitor(this); |
| 4434 } |
4566 return fragment_; | 4435 return fragment_; |
4567 } | 4436 } |
4568 | 4437 |
4569 | 4438 |
4570 ArgumentArray FlowGraphBuilder::GetArguments(int count) { | 4439 ArgumentArray FlowGraphBuilder::GetArguments(int count) { |
4571 ArgumentArray arguments = | 4440 ArgumentArray arguments = |
4572 new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, count); | 4441 new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, count); |
4573 arguments->SetLength(count); | 4442 arguments->SetLength(count); |
4574 for (intptr_t i = count - 1; i >= 0; --i) { | 4443 for (intptr_t i = count - 1; i >= 0; --i) { |
4575 ASSERT(stack_->definition()->IsPushArgument()); | 4444 ASSERT(stack_->definition()->IsPushArgument()); |
4576 ASSERT(!stack_->definition()->HasSSATemp()); | 4445 ASSERT(!stack_->definition()->HasSSATemp()); |
4577 arguments->data()[i] = stack_->definition()->AsPushArgument(); | 4446 arguments->data()[i] = stack_->definition()->AsPushArgument(); |
4578 Drop(); | 4447 Drop(); |
4579 } | 4448 } |
4580 pending_argument_count_ -= count; | 4449 pending_argument_count_ -= count; |
4581 ASSERT(pending_argument_count_ >= 0); | 4450 ASSERT(pending_argument_count_ >= 0); |
4582 return arguments; | 4451 return arguments; |
4583 } | 4452 } |
4584 | 4453 |
4585 | 4454 |
| 4455 #define STREAM_EXPRESSION_IF_POSSIBLE(node) \ |
| 4456 if (node->can_stream()) { \ |
| 4457 fragment_ = streaming_flow_graph_builder_->BuildExpressionAt( \ |
| 4458 node->kernel_offset()); \ |
| 4459 return; \ |
| 4460 } |
| 4461 |
| 4462 |
4586 void FlowGraphBuilder::VisitInvalidExpression(InvalidExpression* node) { | 4463 void FlowGraphBuilder::VisitInvalidExpression(InvalidExpression* node) { |
4587 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4464 fragment_ = |
| 4465 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4588 } | 4466 } |
4589 | 4467 |
4590 | 4468 |
4591 void FlowGraphBuilder::VisitNullLiteral(NullLiteral* node) { | 4469 void FlowGraphBuilder::VisitNullLiteral(NullLiteral* node) { |
4592 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4470 fragment_ = |
| 4471 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4593 } | 4472 } |
4594 | 4473 |
4595 | 4474 |
4596 void FlowGraphBuilder::VisitBoolLiteral(BoolLiteral* node) { | 4475 void FlowGraphBuilder::VisitBoolLiteral(BoolLiteral* node) { |
4597 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4476 fragment_ = |
| 4477 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4598 } | 4478 } |
4599 | 4479 |
4600 | 4480 |
4601 void FlowGraphBuilder::VisitIntLiteral(IntLiteral* node) { | 4481 void FlowGraphBuilder::VisitIntLiteral(IntLiteral* node) { |
4602 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4482 fragment_ = |
| 4483 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4603 } | 4484 } |
4604 | 4485 |
4605 | 4486 |
4606 void FlowGraphBuilder::VisitBigintLiteral(BigintLiteral* node) { | 4487 void FlowGraphBuilder::VisitBigintLiteral(BigintLiteral* node) { |
4607 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4488 fragment_ = |
| 4489 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4608 } | 4490 } |
4609 | 4491 |
4610 | 4492 |
4611 void FlowGraphBuilder::VisitDoubleLiteral(DoubleLiteral* node) { | 4493 void FlowGraphBuilder::VisitDoubleLiteral(DoubleLiteral* node) { |
4612 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4494 fragment_ = |
| 4495 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4613 } | 4496 } |
4614 | 4497 |
4615 | 4498 |
4616 void FlowGraphBuilder::VisitStringLiteral(StringLiteral* node) { | 4499 void FlowGraphBuilder::VisitStringLiteral(StringLiteral* node) { |
4617 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4500 fragment_ = |
| 4501 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4618 } | 4502 } |
4619 | 4503 |
4620 | 4504 |
4621 void FlowGraphBuilder::VisitSymbolLiteral(SymbolLiteral* node) { | 4505 void FlowGraphBuilder::VisitSymbolLiteral(SymbolLiteral* node) { |
4622 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4506 fragment_ = |
| 4507 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4623 } | 4508 } |
4624 | 4509 |
4625 | 4510 |
4626 AbstractType& DartTypeTranslator::TranslateType(DartType* node) { | 4511 AbstractType& DartTypeTranslator::TranslateType(DartType* node) { |
4627 node->AcceptDartTypeVisitor(this); | 4512 node->AcceptDartTypeVisitor(this); |
4628 | 4513 |
4629 // We return a new `ZoneHandle` here on purpose: The intermediate language | 4514 // We return a new `ZoneHandle` here on purpose: The intermediate language |
4630 // instructions do not make a copy of the handle, so we do it. | 4515 // instructions do not make a copy of the handle, so we do it. |
4631 return AbstractType::ZoneHandle(Z, result_.raw()); | 4516 return AbstractType::ZoneHandle(Z, result_.raw()); |
4632 } | 4517 } |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4915 } | 4800 } |
4916 type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()), | 4801 type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()), |
4917 klass.token_pos()); | 4802 klass.token_pos()); |
4918 if (klass.is_type_finalized()) { | 4803 if (klass.is_type_finalized()) { |
4919 type ^= ClassFinalizer::FinalizeType(klass, type); | 4804 type ^= ClassFinalizer::FinalizeType(klass, type); |
4920 klass.SetCanonicalType(type); | 4805 klass.SetCanonicalType(type); |
4921 } | 4806 } |
4922 return type; | 4807 return type; |
4923 } | 4808 } |
4924 | 4809 |
| 4810 void FlowGraphBuilder::VisitTypeLiteral(TypeLiteral* node) { |
| 4811 STREAM_EXPRESSION_IF_POSSIBLE(node); |
4925 | 4812 |
4926 void FlowGraphBuilder::VisitTypeLiteral(TypeLiteral* node) { | |
4927 const AbstractType& type = T.TranslateType(node->type()); | 4813 const AbstractType& type = T.TranslateType(node->type()); |
4928 if (type.IsMalformed()) H.ReportError("Malformed type literal"); | 4814 if (type.IsMalformed()) H.ReportError("Malformed type literal"); |
4929 | 4815 |
4930 Fragment instructions; | 4816 Fragment instructions; |
4931 if (type.IsInstantiated()) { | 4817 if (type.IsInstantiated()) { |
4932 instructions += Constant(type); | 4818 instructions += Constant(type); |
4933 } else { | 4819 } else { |
4934 if (!type.IsInstantiated(kCurrentClass)) { | 4820 if (!type.IsInstantiated(kCurrentClass)) { |
4935 instructions += LoadInstantiatorTypeArguments(); | 4821 instructions += LoadInstantiatorTypeArguments(); |
4936 } else { | 4822 } else { |
4937 instructions += NullConstant(); | 4823 instructions += NullConstant(); |
4938 } | 4824 } |
4939 if (!type.IsInstantiated(kFunctions)) { | 4825 if (!type.IsInstantiated(kFunctions)) { |
4940 instructions += LoadFunctionTypeArguments(); | 4826 instructions += LoadFunctionTypeArguments(); |
4941 } else { | 4827 } else { |
4942 instructions += NullConstant(); | 4828 instructions += NullConstant(); |
4943 } | 4829 } |
4944 instructions += InstantiateType(type); | 4830 instructions += InstantiateType(type); |
4945 } | 4831 } |
4946 fragment_ = instructions; | 4832 fragment_ = instructions; |
4947 } | 4833 } |
4948 | 4834 |
4949 | 4835 |
4950 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { | 4836 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { |
4951 fragment_ = LoadLocal(LookupVariable(node->variable())); | 4837 fragment_ = |
| 4838 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
4952 } | 4839 } |
4953 | 4840 |
4954 | 4841 |
4955 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { | 4842 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { |
| 4843 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4844 |
4956 Fragment instructions = TranslateExpression(node->expression()); | 4845 Fragment instructions = TranslateExpression(node->expression()); |
4957 if (NeedsDebugStepCheck(stack_, node->position())) { | 4846 if (NeedsDebugStepCheck(stack_, node->position())) { |
4958 instructions = DebugStepCheck(node->position()) + instructions; | 4847 instructions = DebugStepCheck(node->position()) + instructions; |
4959 } | 4848 } |
4960 instructions += CheckVariableTypeInCheckedMode(node->variable()); | 4849 instructions += CheckVariableTypeInCheckedMode(node->variable()); |
4961 instructions += | 4850 instructions += |
4962 StoreLocal(node->position(), LookupVariable(node->variable())); | 4851 StoreLocal(node->position(), LookupVariable(node->variable())); |
4963 fragment_ = instructions; | 4852 fragment_ = instructions; |
4964 } | 4853 } |
4965 | 4854 |
4966 | 4855 |
4967 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { | 4856 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { |
4968 if (node->kernel_offset() != -1) { | 4857 STREAM_EXPRESSION_IF_POSSIBLE(node); |
4969 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 4858 |
4970 return; | |
4971 } | |
4972 // A StaticGet will always have a kernel_offset, except for the StaticGet that | 4859 // A StaticGet will always have a kernel_offset, except for the StaticGet that |
4973 // was manually created for _getMainClosure in dart:_builtin. Compile that | 4860 // was manually created for _getMainClosure in dart:_builtin. Compile that |
4974 // one specially here. | 4861 // one specially here. |
4975 const dart::Library& builtin = | 4862 const dart::Library& builtin = |
4976 dart::Library::Handle(Z, I->object_store()->builtin_library()); | 4863 dart::Library::Handle(Z, I->object_store()->builtin_library()); |
4977 const Object& main = | 4864 const Object& main = |
4978 Object::Handle(Z, builtin.LookupObjectAllowPrivate(dart::String::Handle( | 4865 Object::Handle(Z, builtin.LookupObjectAllowPrivate(dart::String::Handle( |
4979 Z, dart::String::New("main")))); | 4866 Z, dart::String::New("main")))); |
4980 if (main.IsField()) { | 4867 if (main.IsField()) { |
4981 UNIMPLEMENTED(); | 4868 UNIMPLEMENTED(); |
4982 } else if (main.IsFunction()) { | 4869 } else if (main.IsFunction()) { |
4983 const Function& function = Function::Cast(main); | 4870 const Function& function = Function::Cast(main); |
4984 if (function.kind() == RawFunction::kRegularFunction) { | 4871 if (function.kind() == RawFunction::kRegularFunction) { |
4985 const Function& closure_function = | 4872 const Function& closure_function = |
4986 Function::Handle(Z, function.ImplicitClosureFunction()); | 4873 Function::Handle(Z, function.ImplicitClosureFunction()); |
4987 closure_function.set_kernel_function(function.kernel_function()); | 4874 closure_function.set_kernel_function(function.kernel_function()); |
4988 const Instance& closure = | 4875 const Instance& closure = |
4989 Instance::ZoneHandle(Z, closure_function.ImplicitStaticClosure()); | 4876 Instance::ZoneHandle(Z, closure_function.ImplicitStaticClosure()); |
4990 fragment_ = Constant(closure); | 4877 fragment_ = Constant(closure); |
4991 } else { | 4878 } else { |
4992 UNIMPLEMENTED(); | 4879 UNIMPLEMENTED(); |
4993 } | 4880 } |
4994 } else { | 4881 } else { |
4995 UNIMPLEMENTED(); | 4882 UNIMPLEMENTED(); |
4996 } | 4883 } |
4997 } | 4884 } |
4998 | 4885 |
4999 | 4886 |
5000 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { | 4887 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { |
| 4888 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4889 |
5001 NameIndex target = node->target(); | 4890 NameIndex target = node->target(); |
5002 if (H.IsField(target)) { | 4891 if (H.IsField(target)) { |
5003 const dart::Field& field = | 4892 const dart::Field& field = |
5004 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(target)); | 4893 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(target)); |
5005 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); | 4894 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); |
5006 Fragment instructions = TranslateExpression(node->expression()); | 4895 Fragment instructions = TranslateExpression(node->expression()); |
5007 if (NeedsDebugStepCheck(stack_, node->position())) { | 4896 if (NeedsDebugStepCheck(stack_, node->position())) { |
5008 instructions = DebugStepCheck(node->position()) + instructions; | 4897 instructions = DebugStepCheck(node->position()) + instructions; |
5009 } | 4898 } |
5010 instructions += CheckAssignableInCheckedMode( | 4899 instructions += CheckAssignableInCheckedMode( |
(...skipping 17 matching lines...) Expand all Loading... |
5028 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target)); | 4917 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target)); |
5029 instructions += StaticCall(node->position(), function, 1); | 4918 instructions += StaticCall(node->position(), function, 1); |
5030 | 4919 |
5031 // Drop the unused result & leave the stored value on the stack. | 4920 // Drop the unused result & leave the stored value on the stack. |
5032 fragment_ = instructions + Drop(); | 4921 fragment_ = instructions + Drop(); |
5033 } | 4922 } |
5034 } | 4923 } |
5035 | 4924 |
5036 | 4925 |
5037 void FlowGraphBuilder::VisitPropertyGet(PropertyGet* node) { | 4926 void FlowGraphBuilder::VisitPropertyGet(PropertyGet* node) { |
| 4927 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4928 |
5038 Fragment instructions = TranslateExpression(node->receiver()); | 4929 Fragment instructions = TranslateExpression(node->receiver()); |
5039 instructions += PushArgument(); | 4930 instructions += PushArgument(); |
5040 const dart::String& getter_name = H.DartGetterName(node->name()); | 4931 const dart::String& getter_name = H.DartGetterName(node->name()); |
5041 fragment_ = instructions + | 4932 fragment_ = instructions + |
5042 InstanceCall(node->position(), getter_name, Token::kGET, 1); | 4933 InstanceCall(node->position(), getter_name, Token::kGET, 1); |
5043 } | 4934 } |
5044 | 4935 |
5045 | 4936 |
5046 void FlowGraphBuilder::VisitPropertySet(PropertySet* node) { | 4937 void FlowGraphBuilder::VisitPropertySet(PropertySet* node) { |
| 4938 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4939 |
5047 Fragment instructions(NullConstant()); | 4940 Fragment instructions(NullConstant()); |
5048 LocalVariable* variable = MakeTemporary(); | 4941 LocalVariable* variable = MakeTemporary(); |
5049 instructions += TranslateExpression(node->receiver()); | 4942 instructions += TranslateExpression(node->receiver()); |
5050 instructions += PushArgument(); | 4943 instructions += PushArgument(); |
5051 instructions += TranslateExpression(node->value()); | 4944 instructions += TranslateExpression(node->value()); |
5052 instructions += StoreLocal(TokenPosition::kNoSource, variable); | 4945 instructions += StoreLocal(TokenPosition::kNoSource, variable); |
5053 instructions += PushArgument(); | 4946 instructions += PushArgument(); |
5054 | 4947 |
5055 const dart::String& setter_name = H.DartSetterName(node->name()); | 4948 const dart::String& setter_name = H.DartSetterName(node->name()); |
5056 instructions += InstanceCall(node->position(), setter_name, Token::kSET, 2); | 4949 instructions += InstanceCall(node->position(), setter_name, Token::kSET, 2); |
5057 fragment_ = instructions + Drop(); | 4950 fragment_ = instructions + Drop(); |
5058 } | 4951 } |
5059 | 4952 |
5060 | 4953 |
5061 void FlowGraphBuilder::VisitDirectPropertyGet(DirectPropertyGet* node) { | 4954 void FlowGraphBuilder::VisitDirectPropertyGet(DirectPropertyGet* node) { |
| 4955 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4956 |
5062 Function& target = Function::ZoneHandle(Z); | 4957 Function& target = Function::ZoneHandle(Z); |
5063 NameIndex kernel_name = node->target(); | 4958 NameIndex kernel_name = node->target(); |
5064 if (H.IsProcedure(kernel_name)) { | 4959 if (H.IsProcedure(kernel_name)) { |
5065 if (H.IsGetter(kernel_name)) { | 4960 if (H.IsGetter(kernel_name)) { |
5066 target = LookupMethodByMember(kernel_name, H.DartGetterName(kernel_name)); | 4961 target = LookupMethodByMember(kernel_name, H.DartGetterName(kernel_name)); |
5067 } else { | 4962 } else { |
5068 target = LookupMethodByMember(kernel_name, H.DartMethodName(kernel_name)); | 4963 target = LookupMethodByMember(kernel_name, H.DartMethodName(kernel_name)); |
5069 target = target.ImplicitClosureFunction(); | 4964 target = target.ImplicitClosureFunction(); |
5070 ASSERT(!target.IsNull()); | 4965 ASSERT(!target.IsNull()); |
5071 fragment_ = BuildImplicitClosureCreation(target); | 4966 fragment_ = BuildImplicitClosureCreation(target); |
5072 return; | 4967 return; |
5073 } | 4968 } |
5074 } else { | 4969 } else { |
5075 ASSERT(H.IsField(kernel_name)); | 4970 ASSERT(H.IsField(kernel_name)); |
5076 const dart::String& getter_name = H.DartGetterName(kernel_name); | 4971 const dart::String& getter_name = H.DartGetterName(kernel_name); |
5077 target = LookupMethodByMember(kernel_name, getter_name); | 4972 target = LookupMethodByMember(kernel_name, getter_name); |
5078 ASSERT(target.IsGetterFunction() || target.IsImplicitGetterFunction()); | 4973 ASSERT(target.IsGetterFunction() || target.IsImplicitGetterFunction()); |
5079 } | 4974 } |
5080 | 4975 |
5081 Fragment instructions = TranslateExpression(node->receiver()); | 4976 Fragment instructions = TranslateExpression(node->receiver()); |
5082 instructions += PushArgument(); | 4977 instructions += PushArgument(); |
5083 fragment_ = instructions + StaticCall(node->position(), target, 1); | 4978 fragment_ = instructions + StaticCall(node->position(), target, 1); |
5084 } | 4979 } |
5085 | 4980 |
5086 | 4981 |
5087 void FlowGraphBuilder::VisitDirectPropertySet(DirectPropertySet* node) { | 4982 void FlowGraphBuilder::VisitDirectPropertySet(DirectPropertySet* node) { |
| 4983 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 4984 |
5088 const dart::String& method_name = H.DartSetterName(node->target()); | 4985 const dart::String& method_name = H.DartSetterName(node->target()); |
5089 const Function& target = Function::ZoneHandle( | 4986 const Function& target = Function::ZoneHandle( |
5090 Z, LookupMethodByMember(node->target(), method_name)); | 4987 Z, LookupMethodByMember(node->target(), method_name)); |
5091 ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction()); | 4988 ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction()); |
5092 | 4989 |
5093 Fragment instructions(NullConstant()); | 4990 Fragment instructions(NullConstant()); |
5094 LocalVariable* value = MakeTemporary(); | 4991 LocalVariable* value = MakeTemporary(); |
5095 instructions += TranslateExpression(node->receiver()); | 4992 instructions += TranslateExpression(node->receiver()); |
5096 instructions += PushArgument(); | 4993 instructions += PushArgument(); |
5097 instructions += TranslateExpression(node->value()); | 4994 instructions += TranslateExpression(node->value()); |
5098 instructions += StoreLocal(TokenPosition::kNoSource, value); | 4995 instructions += StoreLocal(TokenPosition::kNoSource, value); |
5099 instructions += PushArgument(); | 4996 instructions += PushArgument(); |
5100 instructions += StaticCall(node->position(), target, 2); | 4997 instructions += StaticCall(node->position(), target, 2); |
5101 | 4998 |
5102 fragment_ = instructions + Drop(); | 4999 fragment_ = instructions + Drop(); |
5103 } | 5000 } |
5104 | 5001 |
5105 | 5002 |
5106 void FlowGraphBuilder::VisitStaticInvocation(StaticInvocation* node) { | 5003 void FlowGraphBuilder::VisitStaticInvocation(StaticInvocation* node) { |
| 5004 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5005 |
5107 const Function& target = Function::ZoneHandle( | 5006 const Function& target = Function::ZoneHandle( |
5108 Z, H.LookupStaticMethodByKernelProcedure(node->procedure())); | 5007 Z, H.LookupStaticMethodByKernelProcedure(node->procedure())); |
5109 const dart::Class& klass = dart::Class::ZoneHandle(Z, target.Owner()); | 5008 const dart::Class& klass = dart::Class::ZoneHandle(Z, target.Owner()); |
5110 intptr_t argument_count = node->arguments()->count(); | 5009 intptr_t argument_count = node->arguments()->count(); |
5111 if (target.IsGenerativeConstructor() || target.IsFactory()) { | 5010 if (target.IsGenerativeConstructor() || target.IsFactory()) { |
5112 // The VM requires a TypeArguments object as first parameter for | 5011 // The VM requires a TypeArguments object as first parameter for |
5113 // every factory constructor. | 5012 // every factory constructor. |
5114 ++argument_count; | 5013 ++argument_count; |
5115 } | 5014 } |
5116 | 5015 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5216 fragment_ = instructions + StrictCompare(strict_cmp_kind, | 5115 fragment_ = instructions + StrictCompare(strict_cmp_kind, |
5217 /*number_check = */ true); | 5116 /*number_check = */ true); |
5218 return true; | 5117 return true; |
5219 } | 5118 } |
5220 } | 5119 } |
5221 return false; | 5120 return false; |
5222 } | 5121 } |
5223 | 5122 |
5224 | 5123 |
5225 void FlowGraphBuilder::VisitMethodInvocation(MethodInvocation* node) { | 5124 void FlowGraphBuilder::VisitMethodInvocation(MethodInvocation* node) { |
| 5125 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5126 |
5226 const dart::String& name = H.DartMethodName(node->name()); | 5127 const dart::String& name = H.DartMethodName(node->name()); |
5227 const intptr_t argument_count = node->arguments()->count() + 1; | 5128 const intptr_t argument_count = node->arguments()->count() + 1; |
5228 const Token::Kind token_kind = MethodKind(name); | 5129 const Token::Kind token_kind = MethodKind(name); |
5229 if (IsNumberLiteral(node->receiver())) { | 5130 if (IsNumberLiteral(node->receiver())) { |
5230 if ((argument_count == 1) && (token_kind == Token::kNEGATE)) { | 5131 if ((argument_count == 1) && (token_kind == Token::kNEGATE)) { |
5231 const Object& result = constant_evaluator_.EvaluateExpressionSafe(node); | 5132 const Object& result = constant_evaluator_.EvaluateExpressionSafe(node); |
5232 if (!result.IsError()) { | 5133 if (!result.IsError()) { |
5233 fragment_ = Constant(result); | 5134 fragment_ = Constant(result); |
5234 return; | 5135 return; |
5235 } | 5136 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5270 // actually produce any value. See http://dartbug.com/29135 for more details. | 5171 // actually produce any value. See http://dartbug.com/29135 for more details. |
5271 if (name.raw() == Symbols::AssignIndexToken().raw()) { | 5172 if (name.raw() == Symbols::AssignIndexToken().raw()) { |
5272 fragment_ += Drop(); | 5173 fragment_ += Drop(); |
5273 fragment_ += NullConstant(); | 5174 fragment_ += NullConstant(); |
5274 } | 5175 } |
5275 } | 5176 } |
5276 | 5177 |
5277 | 5178 |
5278 void FlowGraphBuilder::VisitDirectMethodInvocation( | 5179 void FlowGraphBuilder::VisitDirectMethodInvocation( |
5279 DirectMethodInvocation* node) { | 5180 DirectMethodInvocation* node) { |
| 5181 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5182 |
5280 const dart::String& method_name = H.DartProcedureName(node->target()); | 5183 const dart::String& method_name = H.DartProcedureName(node->target()); |
5281 const Token::Kind token_kind = MethodKind(method_name); | 5184 const Token::Kind token_kind = MethodKind(method_name); |
5282 | 5185 |
5283 if (RecognizeComparisonWithNull(token_kind, node)) return; | 5186 if (RecognizeComparisonWithNull(token_kind, node)) return; |
5284 | 5187 |
5285 const Function& target = Function::ZoneHandle( | 5188 const Function& target = Function::ZoneHandle( |
5286 Z, LookupMethodByMember(node->target(), method_name)); | 5189 Z, LookupMethodByMember(node->target(), method_name)); |
5287 | 5190 |
5288 intptr_t argument_count = node->arguments()->count() + 1; | 5191 intptr_t argument_count = node->arguments()->count() + 1; |
5289 Array& argument_names = Array::ZoneHandle(Z); | 5192 Array& argument_names = Array::ZoneHandle(Z); |
5290 | 5193 |
5291 // TODO(28109) Support generic methods in the VM or reify them away. | 5194 // TODO(28109) Support generic methods in the VM or reify them away. |
5292 Fragment instructions = TranslateExpression(node->receiver()); | 5195 Fragment instructions = TranslateExpression(node->receiver()); |
5293 instructions += PushArgument(); | 5196 instructions += PushArgument(); |
5294 instructions += TranslateArguments(node->arguments(), &argument_names); | 5197 instructions += TranslateArguments(node->arguments(), &argument_names); |
5295 fragment_ = instructions + StaticCall(node->position(), target, | 5198 fragment_ = instructions + StaticCall(node->position(), target, |
5296 argument_count, argument_names); | 5199 argument_count, argument_names); |
5297 } | 5200 } |
5298 | 5201 |
5299 | 5202 |
5300 void FlowGraphBuilder::VisitConstructorInvocation(ConstructorInvocation* node) { | 5203 void FlowGraphBuilder::VisitConstructorInvocation(ConstructorInvocation* node) { |
| 5204 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5205 |
5301 if (node->is_const()) { | 5206 if (node->is_const()) { |
5302 fragment_ = | 5207 fragment_ = |
5303 Constant(constant_evaluator_.EvaluateConstructorInvocation(node)); | 5208 Constant(constant_evaluator_.EvaluateConstructorInvocation(node)); |
5304 return; | 5209 return; |
5305 } | 5210 } |
5306 | 5211 |
5307 dart::Class& klass = dart::Class::ZoneHandle( | 5212 dart::Class& klass = dart::Class::ZoneHandle( |
5308 Z, H.LookupClassByKernelClass(H.EnclosingName(node->target()))); | 5213 Z, H.LookupClassByKernelClass(H.EnclosingName(node->target()))); |
5309 | 5214 |
5310 Fragment instructions; | 5215 Fragment instructions; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5379 const Function& target = Function::ZoneHandle( | 5284 const Function& target = Function::ZoneHandle( |
5380 Z, H.LookupConstructorByKernelConstructor(klass, node->target())); | 5285 Z, H.LookupConstructorByKernelConstructor(klass, node->target())); |
5381 intptr_t argument_count = node->arguments()->count() + 1; | 5286 intptr_t argument_count = node->arguments()->count() + 1; |
5382 instructions += | 5287 instructions += |
5383 StaticCall(node->position(), target, argument_count, argument_names); | 5288 StaticCall(node->position(), target, argument_count, argument_names); |
5384 fragment_ = instructions + Drop(); | 5289 fragment_ = instructions + Drop(); |
5385 } | 5290 } |
5386 | 5291 |
5387 | 5292 |
5388 void FlowGraphBuilder::VisitIsExpression(IsExpression* node) { | 5293 void FlowGraphBuilder::VisitIsExpression(IsExpression* node) { |
| 5294 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5295 |
5389 Fragment instructions = TranslateExpression(node->operand()); | 5296 Fragment instructions = TranslateExpression(node->operand()); |
5390 | 5297 |
5391 // The VM does not like an instanceOf call with a dynamic type. We need to | 5298 // The VM does not like an instanceOf call with a dynamic type. We need to |
5392 // special case this situation. | 5299 // special case this situation. |
5393 const Type& object_type = Type::Handle(Z, Type::ObjectType()); | 5300 const Type& object_type = Type::Handle(Z, Type::ObjectType()); |
5394 const AbstractType& type = T.TranslateType(node->type()); | 5301 const AbstractType& type = T.TranslateType(node->type()); |
5395 if (type.IsMalformed()) { | 5302 if (type.IsMalformed()) { |
5396 instructions += Drop(); | 5303 instructions += Drop(); |
5397 instructions += ThrowTypeError(); | 5304 instructions += ThrowTypeError(); |
5398 fragment_ = instructions; | 5305 fragment_ = instructions; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5442 InstanceCall(node->position(), | 5349 InstanceCall(node->position(), |
5443 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), | 5350 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), |
5444 Token::kIS, 4); | 5351 Token::kIS, 4); |
5445 } | 5352 } |
5446 | 5353 |
5447 fragment_ = instructions; | 5354 fragment_ = instructions; |
5448 } | 5355 } |
5449 | 5356 |
5450 | 5357 |
5451 void FlowGraphBuilder::VisitAsExpression(AsExpression* node) { | 5358 void FlowGraphBuilder::VisitAsExpression(AsExpression* node) { |
| 5359 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5360 |
5452 Fragment instructions = TranslateExpression(node->operand()); | 5361 Fragment instructions = TranslateExpression(node->operand()); |
5453 | 5362 |
5454 // The VM does not like an Object_as call with a dynamic type. We need to | 5363 // The VM does not like an Object_as call with a dynamic type. We need to |
5455 // special case this situation. | 5364 // special case this situation. |
5456 const Type& object_type = Type::Handle(Z, Type::ObjectType()); | 5365 const Type& object_type = Type::Handle(Z, Type::ObjectType()); |
5457 const AbstractType& type = T.TranslateType(node->type()); | 5366 const AbstractType& type = T.TranslateType(node->type()); |
5458 if (type.IsMalformed()) { | 5367 if (type.IsMalformed()) { |
5459 instructions += Drop(); | 5368 instructions += Drop(); |
5460 instructions += ThrowTypeError(); | 5369 instructions += ThrowTypeError(); |
5461 fragment_ = instructions; | 5370 fragment_ = instructions; |
(...skipping 27 matching lines...) Expand all Loading... |
5489 instructions += InstanceCall( | 5398 instructions += InstanceCall( |
5490 node->position(), dart::Library::PrivateCoreLibName(Symbols::_as()), | 5399 node->position(), dart::Library::PrivateCoreLibName(Symbols::_as()), |
5491 Token::kAS, 4); | 5400 Token::kAS, 4); |
5492 } | 5401 } |
5493 | 5402 |
5494 fragment_ = instructions; | 5403 fragment_ = instructions; |
5495 } | 5404 } |
5496 | 5405 |
5497 | 5406 |
5498 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { | 5407 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { |
| 5408 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5409 |
5499 bool negate; | 5410 bool negate; |
5500 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5411 Fragment instructions = TranslateCondition(node->condition(), &negate); |
5501 | 5412 |
5502 TargetEntryInstr* then_entry; | 5413 TargetEntryInstr* then_entry; |
5503 TargetEntryInstr* otherwise_entry; | 5414 TargetEntryInstr* otherwise_entry; |
5504 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); | 5415 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); |
5505 | 5416 |
5506 Value* top = stack_; | 5417 Value* top = stack_; |
5507 Fragment then_fragment(then_entry); | 5418 Fragment then_fragment(then_entry); |
5508 then_fragment += TranslateExpression(node->then()); | 5419 then_fragment += TranslateExpression(node->then()); |
(...skipping 12 matching lines...) Expand all Loading... |
5521 JoinEntryInstr* join = BuildJoinEntry(); | 5432 JoinEntryInstr* join = BuildJoinEntry(); |
5522 then_fragment += Goto(join); | 5433 then_fragment += Goto(join); |
5523 otherwise_fragment += Goto(join); | 5434 otherwise_fragment += Goto(join); |
5524 | 5435 |
5525 fragment_ = Fragment(instructions.entry, join) + | 5436 fragment_ = Fragment(instructions.entry, join) + |
5526 LoadLocal(parsed_function_->expression_temp_var()); | 5437 LoadLocal(parsed_function_->expression_temp_var()); |
5527 } | 5438 } |
5528 | 5439 |
5529 | 5440 |
5530 void FlowGraphBuilder::VisitLogicalExpression(LogicalExpression* node) { | 5441 void FlowGraphBuilder::VisitLogicalExpression(LogicalExpression* node) { |
| 5442 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5443 |
5531 bool negate; | 5444 bool negate; |
5532 Fragment instructions = TranslateCondition(node->left(), &negate); | 5445 Fragment instructions = TranslateCondition(node->left(), &negate); |
5533 TargetEntryInstr* right_entry; | 5446 TargetEntryInstr* right_entry; |
5534 TargetEntryInstr* constant_entry; | 5447 TargetEntryInstr* constant_entry; |
5535 | 5448 |
5536 if (node->op() == LogicalExpression::kAnd) { | 5449 if (node->op() == LogicalExpression::kAnd) { |
5537 instructions += BranchIfTrue(&right_entry, &constant_entry, negate); | 5450 instructions += BranchIfTrue(&right_entry, &constant_entry, negate); |
5538 } else { | 5451 } else { |
5539 instructions += BranchIfTrue(&constant_entry, &right_entry, negate); | 5452 instructions += BranchIfTrue(&constant_entry, &right_entry, negate); |
5540 } | 5453 } |
(...skipping 19 matching lines...) Expand all Loading... |
5560 JoinEntryInstr* join = BuildJoinEntry(); | 5473 JoinEntryInstr* join = BuildJoinEntry(); |
5561 right_fragment += Goto(join); | 5474 right_fragment += Goto(join); |
5562 constant_fragment += Goto(join); | 5475 constant_fragment += Goto(join); |
5563 | 5476 |
5564 fragment_ = Fragment(instructions.entry, join) + | 5477 fragment_ = Fragment(instructions.entry, join) + |
5565 LoadLocal(parsed_function_->expression_temp_var()); | 5478 LoadLocal(parsed_function_->expression_temp_var()); |
5566 } | 5479 } |
5567 | 5480 |
5568 | 5481 |
5569 void FlowGraphBuilder::VisitNot(Not* node) { | 5482 void FlowGraphBuilder::VisitNot(Not* node) { |
| 5483 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5484 |
5570 Fragment instructions = TranslateExpression(node->expression()); | 5485 Fragment instructions = TranslateExpression(node->expression()); |
5571 instructions += CheckBooleanInCheckedMode(); | 5486 instructions += CheckBooleanInCheckedMode(); |
5572 instructions += BooleanNegate(); | 5487 instructions += BooleanNegate(); |
5573 fragment_ = instructions; | 5488 fragment_ = instructions; |
5574 } | 5489 } |
5575 | 5490 |
5576 | 5491 |
5577 void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) { | 5492 void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) { |
5578 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 5493 fragment_ = |
| 5494 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
5579 } | 5495 } |
5580 | 5496 |
5581 | 5497 |
5582 void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) { | 5498 void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) { |
| 5499 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5500 |
5583 List<Expression>& expressions = node->expressions(); | 5501 List<Expression>& expressions = node->expressions(); |
5584 | 5502 |
5585 Fragment instructions; | 5503 Fragment instructions; |
5586 | 5504 |
5587 if (node->expressions().length() == 1) { | 5505 if (node->expressions().length() == 1) { |
5588 instructions += TranslateExpression(node->expressions()[0]); | 5506 instructions += TranslateExpression(node->expressions()[0]); |
5589 instructions += StringInterpolateSingle(node->position()); | 5507 instructions += StringInterpolateSingle(node->position()); |
5590 } else { | 5508 } else { |
5591 // The type arguments for CreateArray. | 5509 // The type arguments for CreateArray. |
5592 instructions += Constant(TypeArguments::ZoneHandle(Z)); | 5510 instructions += Constant(TypeArguments::ZoneHandle(Z)); |
5593 instructions += IntConstant(expressions.length()); | 5511 instructions += IntConstant(expressions.length()); |
5594 instructions += CreateArray(); | 5512 instructions += CreateArray(); |
5595 LocalVariable* array = MakeTemporary(); | 5513 LocalVariable* array = MakeTemporary(); |
5596 | 5514 |
5597 for (intptr_t i = 0; i < node->expressions().length(); i++) { | 5515 for (intptr_t i = 0; i < node->expressions().length(); i++) { |
5598 instructions += LoadLocal(array); | 5516 instructions += LoadLocal(array); |
5599 instructions += IntConstant(i); | 5517 instructions += IntConstant(i); |
5600 instructions += TranslateExpression(node->expressions()[i]); | 5518 instructions += TranslateExpression(node->expressions()[i]); |
5601 instructions += StoreIndexed(kArrayCid); | 5519 instructions += StoreIndexed(kArrayCid); |
5602 instructions += Drop(); | 5520 instructions += Drop(); |
5603 } | 5521 } |
5604 | 5522 |
5605 instructions += StringInterpolate(node->position()); | 5523 instructions += StringInterpolate(node->position()); |
5606 } | 5524 } |
5607 fragment_ = instructions; | 5525 fragment_ = instructions; |
5608 } | 5526 } |
5609 | 5527 |
5610 | 5528 |
5611 void FlowGraphBuilder::VisitListLiteral(ListLiteral* node) { | 5529 void FlowGraphBuilder::VisitListLiteral(ListLiteral* node) { |
| 5530 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5531 |
5612 if (node->is_const()) { | 5532 if (node->is_const()) { |
5613 fragment_ = Constant(constant_evaluator_.EvaluateListLiteral(node)); | 5533 fragment_ = Constant(constant_evaluator_.EvaluateListLiteral(node)); |
5614 return; | 5534 return; |
5615 } | 5535 } |
5616 | 5536 |
5617 DartType* types[] = {node->type()}; | 5537 DartType* types[] = {node->type()}; |
5618 const TypeArguments& type_arguments = T.TranslateTypeArguments(types, 1); | 5538 const TypeArguments& type_arguments = T.TranslateTypeArguments(types, 1); |
5619 | 5539 |
5620 // The type argument for the factory call. | 5540 // The type argument for the factory call. |
5621 Fragment instructions = TranslateInstantiatedTypeArguments(type_arguments); | 5541 Fragment instructions = TranslateInstantiatedTypeArguments(type_arguments); |
(...skipping 21 matching lines...) Expand all Loading... |
5643 const dart::Class& factory_class = | 5563 const dart::Class& factory_class = |
5644 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::List())); | 5564 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::List())); |
5645 const Function& factory_method = Function::ZoneHandle( | 5565 const Function& factory_method = Function::ZoneHandle( |
5646 Z, factory_class.LookupFactory( | 5566 Z, factory_class.LookupFactory( |
5647 dart::Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); | 5567 dart::Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); |
5648 fragment_ = instructions + StaticCall(node->position(), factory_method, 2); | 5568 fragment_ = instructions + StaticCall(node->position(), factory_method, 2); |
5649 } | 5569 } |
5650 | 5570 |
5651 | 5571 |
5652 void FlowGraphBuilder::VisitMapLiteral(MapLiteral* node) { | 5572 void FlowGraphBuilder::VisitMapLiteral(MapLiteral* node) { |
| 5573 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5574 |
5653 if (node->is_const()) { | 5575 if (node->is_const()) { |
5654 fragment_ = Constant(constant_evaluator_.EvaluateMapLiteral(node)); | 5576 fragment_ = Constant(constant_evaluator_.EvaluateMapLiteral(node)); |
5655 return; | 5577 return; |
5656 } | 5578 } |
5657 | 5579 |
5658 const dart::Class& map_class = | 5580 const dart::Class& map_class = |
5659 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map())); | 5581 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map())); |
5660 const Function& factory_method = Function::ZoneHandle( | 5582 const Function& factory_method = Function::ZoneHandle( |
5661 Z, map_class.LookupFactory( | 5583 Z, map_class.LookupFactory( |
5662 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); | 5584 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5699 fragment_ = instructions + StaticCall(node->position(), factory_method, 2); | 5621 fragment_ = instructions + StaticCall(node->position(), factory_method, 2); |
5700 } | 5622 } |
5701 | 5623 |
5702 | 5624 |
5703 void FlowGraphBuilder::VisitFunctionExpression(FunctionExpression* node) { | 5625 void FlowGraphBuilder::VisitFunctionExpression(FunctionExpression* node) { |
5704 fragment_ = TranslateFunctionNode(node->function(), node); | 5626 fragment_ = TranslateFunctionNode(node->function(), node); |
5705 } | 5627 } |
5706 | 5628 |
5707 | 5629 |
5708 void FlowGraphBuilder::VisitLet(Let* node) { | 5630 void FlowGraphBuilder::VisitLet(Let* node) { |
| 5631 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5632 |
5709 Fragment instructions = TranslateStatement(node->variable()); | 5633 Fragment instructions = TranslateStatement(node->variable()); |
5710 instructions += TranslateExpression(node->body()); | 5634 instructions += TranslateExpression(node->body()); |
5711 fragment_ = instructions; | 5635 fragment_ = instructions; |
5712 } | 5636 } |
5713 | 5637 |
5714 | 5638 |
5715 void FlowGraphBuilder::VisitThrow(Throw* node) { | 5639 void FlowGraphBuilder::VisitThrow(Throw* node) { |
| 5640 STREAM_EXPRESSION_IF_POSSIBLE(node); |
| 5641 |
5716 Fragment instructions; | 5642 Fragment instructions; |
5717 | 5643 |
5718 instructions += TranslateExpression(node->expression()); | 5644 instructions += TranslateExpression(node->expression()); |
5719 if (NeedsDebugStepCheck(stack_, node->position())) { | 5645 if (NeedsDebugStepCheck(stack_, node->position())) { |
5720 instructions = DebugStepCheck(node->position()) + instructions; | 5646 instructions = DebugStepCheck(node->position()) + instructions; |
5721 } | 5647 } |
5722 instructions += PushArgument(); | 5648 instructions += PushArgument(); |
5723 instructions += ThrowException(node->position()); | 5649 instructions += ThrowException(node->position()); |
5724 ASSERT(instructions.is_closed()); | 5650 ASSERT(instructions.is_closed()); |
5725 | 5651 |
5726 fragment_ = instructions; | 5652 fragment_ = instructions; |
5727 } | 5653 } |
5728 | 5654 |
5729 | 5655 |
5730 void FlowGraphBuilder::VisitRethrow(Rethrow* node) { | 5656 void FlowGraphBuilder::VisitRethrow(Rethrow* node) { |
5731 fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset()); | 5657 fragment_ = |
| 5658 streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset()); |
5732 } | 5659 } |
5733 | 5660 |
5734 | 5661 |
5735 Fragment FlowGraphBuilder::TranslateArguments(Arguments* node, | 5662 Fragment FlowGraphBuilder::TranslateArguments(Arguments* node, |
5736 Array* argument_names) { | 5663 Array* argument_names) { |
5737 Fragment instructions; | 5664 Fragment instructions; |
5738 | 5665 |
5739 List<Expression>& positional = node->positional(); | 5666 List<Expression>& positional = node->positional(); |
5740 for (intptr_t i = 0; i < positional.length(); ++i) { | 5667 for (intptr_t i = 0; i < positional.length(); ++i) { |
5741 instructions += TranslateExpression(positional[i]); | 5668 instructions += TranslateExpression(positional[i]); |
5742 instructions += PushArgument(); | 5669 instructions += PushArgument(); |
5743 } | 5670 } |
5744 | 5671 |
5745 List<NamedExpression>& named = node->named(); | 5672 List<NamedExpression>& named = node->named(); |
5746 if (argument_names != NULL) { | 5673 if (argument_names != NULL) { |
5747 *argument_names = H.ArgumentNames(&named).raw(); | 5674 *argument_names = H.ArgumentNames(&named).raw(); |
5748 } | 5675 } |
5749 for (intptr_t i = 0; i < named.length(); ++i) { | 5676 for (intptr_t i = 0; i < named.length(); ++i) { |
5750 NamedExpression* named_expression = named[i]; | 5677 NamedExpression* named_expression = named[i]; |
5751 instructions += TranslateExpression(named_expression->expression()); | 5678 instructions += TranslateExpression(named_expression->expression()); |
5752 instructions += PushArgument(); | 5679 instructions += PushArgument(); |
5753 } | 5680 } |
5754 return instructions; | 5681 return instructions; |
5755 } | 5682 } |
5756 | 5683 |
| 5684 #define STREAM_STATEMENT_IF_POSSIBLE(node) \ |
| 5685 if (node->can_stream()) { \ |
| 5686 fragment_ = streaming_flow_graph_builder_->BuildStatementAt( \ |
| 5687 node->kernel_offset()); \ |
| 5688 return; \ |
| 5689 } |
| 5690 |
5757 | 5691 |
5758 void FlowGraphBuilder::VisitInvalidStatement(InvalidStatement* node) { | 5692 void FlowGraphBuilder::VisitInvalidStatement(InvalidStatement* node) { |
5759 H.ReportError("Invalid statements not implemented yet!"); | 5693 fragment_ = |
| 5694 streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset()); |
5760 } | 5695 } |
5761 | 5696 |
5762 | 5697 |
5763 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* node) { | 5698 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* node) { |
5764 fragment_ = Fragment(); | 5699 fragment_ = |
| 5700 streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset()); |
5765 } | 5701 } |
5766 | 5702 |
5767 | 5703 |
5768 void FlowGraphBuilder::VisitBlock(Block* node) { | 5704 void FlowGraphBuilder::VisitBlock(Block* node) { |
| 5705 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5706 |
5769 Fragment instructions; | 5707 Fragment instructions; |
5770 | 5708 |
5771 instructions += EnterScope(node); | 5709 instructions += EnterScope(node); |
5772 List<Statement>& statements = node->statements(); | 5710 List<Statement>& statements = node->statements(); |
5773 for (intptr_t i = 0; (i < statements.length()) && instructions.is_open(); | 5711 for (intptr_t i = 0; (i < statements.length()) && instructions.is_open(); |
5774 ++i) { | 5712 ++i) { |
5775 instructions += TranslateStatement(statements[i]); | 5713 instructions += TranslateStatement(statements[i]); |
5776 } | 5714 } |
5777 instructions += ExitScope(node); | 5715 instructions += ExitScope(node); |
5778 | 5716 |
5779 fragment_ = instructions; | 5717 fragment_ = instructions; |
5780 } | 5718 } |
5781 | 5719 |
5782 | 5720 |
5783 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { | 5721 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { |
| 5722 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5723 |
5784 bool inside_try_finally = try_finally_block_ != NULL; | 5724 bool inside_try_finally = try_finally_block_ != NULL; |
5785 | 5725 |
5786 Fragment instructions = node->expression() == NULL | 5726 Fragment instructions = node->expression() == NULL |
5787 ? NullConstant() | 5727 ? NullConstant() |
5788 : TranslateExpression(node->expression()); | 5728 : TranslateExpression(node->expression()); |
5789 if (instructions.is_open()) { | 5729 if (instructions.is_open()) { |
5790 if (inside_try_finally) { | 5730 if (inside_try_finally) { |
5791 ASSERT(scopes_->finally_return_variable != NULL); | 5731 ASSERT(scopes_->finally_return_variable != NULL); |
5792 const Function& function = parsed_function_->function(); | 5732 const Function& function = parsed_function_->function(); |
5793 if (NeedsDebugStepCheck(function, node->position())) { | 5733 if (NeedsDebugStepCheck(function, node->position())) { |
(...skipping 11 matching lines...) Expand all Loading... |
5805 instructions += Return(node->position()); | 5745 instructions += Return(node->position()); |
5806 } | 5746 } |
5807 } else { | 5747 } else { |
5808 Pop(); | 5748 Pop(); |
5809 } | 5749 } |
5810 fragment_ = instructions; | 5750 fragment_ = instructions; |
5811 } | 5751 } |
5812 | 5752 |
5813 | 5753 |
5814 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* node) { | 5754 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* node) { |
| 5755 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5756 |
5815 Fragment instructions = TranslateExpression(node->expression()); | 5757 Fragment instructions = TranslateExpression(node->expression()); |
5816 instructions += Drop(); | 5758 instructions += Drop(); |
5817 fragment_ = instructions; | 5759 fragment_ = instructions; |
5818 } | 5760 } |
5819 | 5761 |
5820 | 5762 |
5821 void FlowGraphBuilder::VisitVariableDeclaration(VariableDeclaration* node) { | 5763 void FlowGraphBuilder::VisitVariableDeclaration(VariableDeclaration* node) { |
5822 LocalVariable* variable = LookupVariable(node); | 5764 LocalVariable* variable = LookupVariable(node); |
5823 Expression* initializer = node->initializer(); | 5765 Expression* initializer = node->initializer(); |
5824 | 5766 |
(...skipping 28 matching lines...) Expand all Loading... |
5853 Fragment instructions = DebugStepCheck(node->position()); | 5795 Fragment instructions = DebugStepCheck(node->position()); |
5854 instructions += TranslateFunctionNode(node->function(), node); | 5796 instructions += TranslateFunctionNode(node->function(), node); |
5855 instructions += | 5797 instructions += |
5856 StoreLocal(node->position(), LookupVariable(node->variable())); | 5798 StoreLocal(node->position(), LookupVariable(node->variable())); |
5857 instructions += Drop(); | 5799 instructions += Drop(); |
5858 fragment_ = instructions; | 5800 fragment_ = instructions; |
5859 } | 5801 } |
5860 | 5802 |
5861 | 5803 |
5862 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { | 5804 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { |
| 5805 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5806 |
5863 bool negate; | 5807 bool negate; |
5864 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5808 Fragment instructions = TranslateCondition(node->condition(), &negate); |
5865 TargetEntryInstr* then_entry; | 5809 TargetEntryInstr* then_entry; |
5866 TargetEntryInstr* otherwise_entry; | 5810 TargetEntryInstr* otherwise_entry; |
5867 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); | 5811 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); |
5868 | 5812 |
5869 Fragment then_fragment(then_entry); | 5813 Fragment then_fragment(then_entry); |
5870 then_fragment += TranslateStatement(node->then()); | 5814 then_fragment += TranslateStatement(node->then()); |
5871 | 5815 |
5872 Fragment otherwise_fragment(otherwise_entry); | 5816 Fragment otherwise_fragment(otherwise_entry); |
(...skipping 10 matching lines...) Expand all Loading... |
5883 } | 5827 } |
5884 } else if (otherwise_fragment.is_open()) { | 5828 } else if (otherwise_fragment.is_open()) { |
5885 fragment_ = Fragment(instructions.entry, otherwise_fragment.current); | 5829 fragment_ = Fragment(instructions.entry, otherwise_fragment.current); |
5886 } else { | 5830 } else { |
5887 fragment_ = instructions.closed(); | 5831 fragment_ = instructions.closed(); |
5888 } | 5832 } |
5889 } | 5833 } |
5890 | 5834 |
5891 | 5835 |
5892 void FlowGraphBuilder::VisitWhileStatement(WhileStatement* node) { | 5836 void FlowGraphBuilder::VisitWhileStatement(WhileStatement* node) { |
| 5837 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5838 |
5893 ++loop_depth_; | 5839 ++loop_depth_; |
5894 bool negate; | 5840 bool negate; |
5895 Fragment condition = TranslateCondition(node->condition(), &negate); | 5841 Fragment condition = TranslateCondition(node->condition(), &negate); |
5896 TargetEntryInstr* body_entry; | 5842 TargetEntryInstr* body_entry; |
5897 TargetEntryInstr* loop_exit; | 5843 TargetEntryInstr* loop_exit; |
5898 condition += BranchIfTrue(&body_entry, &loop_exit, negate); | 5844 condition += BranchIfTrue(&body_entry, &loop_exit, negate); |
5899 | 5845 |
5900 Fragment body(body_entry); | 5846 Fragment body(body_entry); |
5901 body += TranslateStatement(node->body()); | 5847 body += TranslateStatement(node->body()); |
5902 | 5848 |
(...skipping 10 matching lines...) Expand all Loading... |
5913 entry = condition.entry; | 5859 entry = condition.entry; |
5914 } | 5860 } |
5915 | 5861 |
5916 | 5862 |
5917 fragment_ = Fragment(entry, loop_exit); | 5863 fragment_ = Fragment(entry, loop_exit); |
5918 --loop_depth_; | 5864 --loop_depth_; |
5919 } | 5865 } |
5920 | 5866 |
5921 | 5867 |
5922 void FlowGraphBuilder::VisitDoStatement(DoStatement* node) { | 5868 void FlowGraphBuilder::VisitDoStatement(DoStatement* node) { |
| 5869 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5870 |
5923 ++loop_depth_; | 5871 ++loop_depth_; |
5924 Fragment body = TranslateStatement(node->body()); | 5872 Fragment body = TranslateStatement(node->body()); |
5925 | 5873 |
5926 if (body.is_closed()) { | 5874 if (body.is_closed()) { |
5927 fragment_ = body; | 5875 fragment_ = body; |
5928 --loop_depth_; | 5876 --loop_depth_; |
5929 return; | 5877 return; |
5930 } | 5878 } |
5931 | 5879 |
5932 bool negate; | 5880 bool negate; |
5933 JoinEntryInstr* join = BuildJoinEntry(); | 5881 JoinEntryInstr* join = BuildJoinEntry(); |
5934 Fragment loop(join); | 5882 Fragment loop(join); |
5935 loop += CheckStackOverflow(); | 5883 loop += CheckStackOverflow(); |
5936 loop += body; | 5884 loop += body; |
5937 loop += TranslateCondition(node->condition(), &negate); | 5885 loop += TranslateCondition(node->condition(), &negate); |
5938 TargetEntryInstr* loop_repeat; | 5886 TargetEntryInstr* loop_repeat; |
5939 TargetEntryInstr* loop_exit; | 5887 TargetEntryInstr* loop_exit; |
5940 loop += BranchIfTrue(&loop_repeat, &loop_exit, negate); | 5888 loop += BranchIfTrue(&loop_repeat, &loop_exit, negate); |
5941 | 5889 |
5942 Fragment repeat(loop_repeat); | 5890 Fragment repeat(loop_repeat); |
5943 repeat += Goto(join); | 5891 repeat += Goto(join); |
5944 | 5892 |
5945 fragment_ = Fragment(new (Z) GotoInstr(join), loop_exit); | 5893 fragment_ = Fragment(new (Z) GotoInstr(join), loop_exit); |
5946 --loop_depth_; | 5894 --loop_depth_; |
5947 } | 5895 } |
5948 | 5896 |
5949 | 5897 |
5950 void FlowGraphBuilder::VisitForStatement(ForStatement* node) { | 5898 void FlowGraphBuilder::VisitForStatement(ForStatement* node) { |
| 5899 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5900 |
5951 Fragment declarations; | 5901 Fragment declarations; |
5952 | 5902 |
5953 bool new_context = false; | 5903 bool new_context = false; |
5954 declarations += EnterScope(node, &new_context); | 5904 declarations += EnterScope(node, &new_context); |
5955 | 5905 |
5956 List<VariableDeclaration>& variables = node->variables(); | 5906 List<VariableDeclaration>& variables = node->variables(); |
5957 for (intptr_t i = 0; i < variables.length(); ++i) { | 5907 for (intptr_t i = 0; i < variables.length(); ++i) { |
5958 declarations += TranslateStatement(variables[i]); | 5908 declarations += TranslateStatement(variables[i]); |
5959 } | 5909 } |
5960 | 5910 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5997 Fragment loop(declarations.entry, loop_exit); | 5947 Fragment loop(declarations.entry, loop_exit); |
5998 --loop_depth_; | 5948 --loop_depth_; |
5999 | 5949 |
6000 loop += ExitScope(node); | 5950 loop += ExitScope(node); |
6001 | 5951 |
6002 fragment_ = loop; | 5952 fragment_ = loop; |
6003 } | 5953 } |
6004 | 5954 |
6005 | 5955 |
6006 void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) { | 5956 void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) { |
| 5957 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 5958 |
6007 Fragment instructions = TranslateExpression(node->iterable()); | 5959 Fragment instructions = TranslateExpression(node->iterable()); |
6008 instructions += PushArgument(); | 5960 instructions += PushArgument(); |
6009 | 5961 |
6010 const dart::String& iterator_getter = dart::String::ZoneHandle( | 5962 const dart::String& iterator_getter = dart::String::ZoneHandle( |
6011 Z, dart::Field::GetterSymbol(Symbols::Iterator())); | 5963 Z, dart::Field::GetterSymbol(Symbols::Iterator())); |
6012 instructions += InstanceCall(node->iterable()->position(), iterator_getter, | 5964 instructions += InstanceCall(node->iterable()->position(), iterator_getter, |
6013 Token::kGET, 1); | 5965 Token::kGET, 1); |
6014 LocalVariable* iterator = scopes_->iterator_variables[for_in_depth_]; | 5966 LocalVariable* iterator = scopes_->iterator_variables[for_in_depth_]; |
6015 instructions += StoreLocal(TokenPosition::kNoSource, iterator); | 5967 instructions += StoreLocal(TokenPosition::kNoSource, iterator); |
6016 instructions += Drop(); | 5968 instructions += Drop(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6050 instructions += condition; | 6002 instructions += condition; |
6051 } | 6003 } |
6052 | 6004 |
6053 fragment_ = Fragment(instructions.entry, loop_exit); | 6005 fragment_ = Fragment(instructions.entry, loop_exit); |
6054 --loop_depth_; | 6006 --loop_depth_; |
6055 --for_in_depth_; | 6007 --for_in_depth_; |
6056 } | 6008 } |
6057 | 6009 |
6058 | 6010 |
6059 void FlowGraphBuilder::VisitLabeledStatement(LabeledStatement* node) { | 6011 void FlowGraphBuilder::VisitLabeledStatement(LabeledStatement* node) { |
| 6012 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6013 |
6060 // There can be serveral cases: | 6014 // There can be serveral cases: |
6061 // | 6015 // |
6062 // * the body contains a break | 6016 // * the body contains a break |
6063 // * the body doesn't contain a break | 6017 // * the body doesn't contain a break |
6064 // | 6018 // |
6065 // * translating the body results in a closed fragment | 6019 // * translating the body results in a closed fragment |
6066 // * translating the body results in a open fragment | 6020 // * translating the body results in a open fragment |
6067 // | 6021 // |
6068 // => We will only know which case we are in after the body has been | 6022 // => We will only know which case we are in after the body has been |
6069 // traversed. | 6023 // traversed. |
6070 | 6024 |
6071 BreakableBlock block(this, node); | 6025 BreakableBlock block(this); |
6072 Fragment instructions = TranslateStatement(node->body()); | 6026 Fragment instructions = TranslateStatement(node->body()); |
6073 if (block.HadJumper()) { | 6027 if (block.HadJumper()) { |
6074 if (instructions.is_open()) { | 6028 if (instructions.is_open()) { |
6075 instructions += Goto(block.destination()); | 6029 instructions += Goto(block.destination()); |
6076 } | 6030 } |
6077 fragment_ = Fragment(instructions.entry, block.destination()); | 6031 fragment_ = Fragment(instructions.entry, block.destination()); |
6078 } else { | 6032 } else { |
6079 fragment_ = instructions; | 6033 fragment_ = instructions; |
6080 } | 6034 } |
6081 } | 6035 } |
6082 | 6036 |
6083 | 6037 |
6084 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) { | 6038 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) { |
6085 TryFinallyBlock* outer_finally = NULL; | 6039 fragment_ = |
6086 intptr_t target_context_depth = -1; | 6040 streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset()); |
6087 JoinEntryInstr* destination = breakable_block_->BreakDestination( | |
6088 node->target(), &outer_finally, &target_context_depth); | |
6089 | |
6090 Fragment instructions; | |
6091 instructions += | |
6092 TranslateFinallyFinalizers(outer_finally, target_context_depth); | |
6093 if (instructions.is_open()) { | |
6094 if (NeedsDebugStepCheck(parsed_function_->function(), node->position())) { | |
6095 instructions += DebugStepCheck(node->position()); | |
6096 } | |
6097 instructions += Goto(destination); | |
6098 } | |
6099 fragment_ = instructions; | |
6100 } | 6041 } |
6101 | 6042 |
6102 | 6043 |
6103 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { | 6044 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { |
6104 SwitchBlock block(this, node); | 6045 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6046 |
| 6047 SwitchBlock block(this, node->cases().length()); |
6105 | 6048 |
6106 // Instead of using a variable we should reuse the expression on the stack, | 6049 // Instead of using a variable we should reuse the expression on the stack, |
6107 // since it won't be assigned again, we don't need phi nodes. | 6050 // since it won't be assigned again, we don't need phi nodes. |
6108 Fragment head_instructions = TranslateExpression(node->condition()); | 6051 Fragment head_instructions = TranslateExpression(node->condition()); |
6109 head_instructions += | 6052 head_instructions += |
6110 StoreLocal(TokenPosition::kNoSource, scopes_->switch_variable); | 6053 StoreLocal(TokenPosition::kNoSource, scopes_->switch_variable); |
6111 head_instructions += Drop(); | 6054 head_instructions += Drop(); |
6112 | 6055 |
6113 // Phase 1: Generate bodies and try to find out whether a body will be target | 6056 // Phase 1: Generate bodies and try to find out whether a body will be target |
6114 // of a jump due to: | 6057 // of a jump due to: |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6172 // switch(expr) { | 6115 // switch(expr) { |
6173 // case a: | 6116 // case a: |
6174 // case b: | 6117 // case b: |
6175 // <stmt-body> | 6118 // <stmt-body> |
6176 // } | 6119 // } |
6177 // | 6120 // |
6178 // This means that the <stmt-body> will have more than 1 incoming edge (one | 6121 // This means that the <stmt-body> will have more than 1 incoming edge (one |
6179 // from `a == expr` and one from `a != expr && b == expr`). The | 6122 // from `a == expr` and one from `a != expr && b == expr`). The |
6180 // `block.Destination()` records the additional jump. | 6123 // `block.Destination()` records the additional jump. |
6181 if (switch_case->expressions().length() > 1) { | 6124 if (switch_case->expressions().length() > 1) { |
6182 block.Destination(switch_case); | 6125 block.DestinationDirect(i); |
6183 } | 6126 } |
6184 } | 6127 } |
6185 | 6128 |
6186 // Phase 2: Generate everything except the real bodies: | 6129 // Phase 2: Generate everything except the real bodies: |
6187 // * jump directly to a body (if there is no jumper) | 6130 // * jump directly to a body (if there is no jumper) |
6188 // * jump to a wrapper block which jumps to the body (if there is a jumper) | 6131 // * jump to a wrapper block which jumps to the body (if there is a jumper) |
6189 Fragment current_instructions = head_instructions; | 6132 Fragment current_instructions = head_instructions; |
6190 for (intptr_t i = 0; i < num_cases; i++) { | 6133 for (intptr_t i = 0; i < num_cases; i++) { |
6191 SwitchCase* switch_case = node->cases()[i]; | 6134 SwitchCase* switch_case = node->cases()[i]; |
6192 | 6135 |
6193 if (switch_case->is_default()) { | 6136 if (switch_case->is_default()) { |
6194 ASSERT(i == (node->cases().length() - 1)); | 6137 ASSERT(i == (node->cases().length() - 1)); |
6195 | 6138 |
6196 // Evaluate the conditions for the default [SwitchCase] just for the | 6139 // Evaluate the conditions for the default [SwitchCase] just for the |
6197 // purpose of potentially triggering a compile-time error. | 6140 // purpose of potentially triggering a compile-time error. |
6198 for (intptr_t k = 0; k < switch_case->expressions().length(); k++) { | 6141 for (intptr_t k = 0; k < switch_case->expressions().length(); k++) { |
6199 constant_evaluator_.EvaluateExpression(switch_case->expressions()[k]); | 6142 constant_evaluator_.EvaluateExpression(switch_case->expressions()[k]); |
6200 } | 6143 } |
6201 | 6144 |
6202 if (block.HadJumper(switch_case)) { | 6145 if (block.HadJumper(i)) { |
6203 // There are several branches to the body, so we will make a goto to | 6146 // There are several branches to the body, so we will make a goto to |
6204 // the join block (and prepend a join instruction to the real body). | 6147 // the join block (and prepend a join instruction to the real body). |
6205 JoinEntryInstr* join = block.Destination(switch_case); | 6148 JoinEntryInstr* join = block.DestinationDirect(i); |
6206 current_instructions += Goto(join); | 6149 current_instructions += Goto(join); |
6207 | 6150 |
6208 current_instructions = Fragment(current_instructions.entry, join); | 6151 current_instructions = Fragment(current_instructions.entry, join); |
6209 current_instructions += body_fragments[i]; | 6152 current_instructions += body_fragments[i]; |
6210 } else { | 6153 } else { |
6211 current_instructions += body_fragments[i]; | 6154 current_instructions += body_fragments[i]; |
6212 } | 6155 } |
6213 } else { | 6156 } else { |
6214 JoinEntryInstr* body_join = NULL; | 6157 JoinEntryInstr* body_join = NULL; |
6215 if (block.HadJumper(switch_case)) { | 6158 if (block.HadJumper(i)) { |
6216 body_join = block.Destination(switch_case); | 6159 body_join = block.DestinationDirect(i); |
6217 body_fragments[i] = Fragment(body_join) + body_fragments[i]; | 6160 body_fragments[i] = Fragment(body_join) + body_fragments[i]; |
6218 } | 6161 } |
6219 | 6162 |
6220 for (intptr_t j = 0; j < switch_case->expressions().length(); j++) { | 6163 for (intptr_t j = 0; j < switch_case->expressions().length(); j++) { |
6221 TargetEntryInstr* then; | 6164 TargetEntryInstr* then; |
6222 TargetEntryInstr* otherwise; | 6165 TargetEntryInstr* otherwise; |
6223 | 6166 |
6224 Expression* expression = switch_case->expressions()[j]; | 6167 Expression* expression = switch_case->expressions()[j]; |
6225 current_instructions += | 6168 current_instructions += |
6226 Constant(constant_evaluator_.EvaluateExpression(expression)); | 6169 Constant(constant_evaluator_.EvaluateExpression(expression)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6278 } | 6221 } |
6279 | 6222 |
6280 delete[] body_fragments; | 6223 delete[] body_fragments; |
6281 | 6224 |
6282 fragment_ = Fragment(head_instructions.entry, current_instructions.current); | 6225 fragment_ = Fragment(head_instructions.entry, current_instructions.current); |
6283 } | 6226 } |
6284 | 6227 |
6285 | 6228 |
6286 void FlowGraphBuilder::VisitContinueSwitchStatement( | 6229 void FlowGraphBuilder::VisitContinueSwitchStatement( |
6287 ContinueSwitchStatement* node) { | 6230 ContinueSwitchStatement* node) { |
6288 TryFinallyBlock* outer_finally = NULL; | 6231 fragment_ = |
6289 intptr_t target_context_depth = -1; | 6232 streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset()); |
6290 JoinEntryInstr* entry = switch_block_->Destination( | |
6291 node->target(), &outer_finally, &target_context_depth); | |
6292 | |
6293 Fragment instructions; | |
6294 instructions += | |
6295 TranslateFinallyFinalizers(outer_finally, target_context_depth); | |
6296 if (instructions.is_open()) { | |
6297 instructions += Goto(entry); | |
6298 } | |
6299 fragment_ = instructions; | |
6300 } | 6233 } |
6301 | 6234 |
6302 | 6235 |
6303 void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) { | 6236 void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) { |
| 6237 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6238 |
6304 if (!I->asserts()) { | 6239 if (!I->asserts()) { |
6305 fragment_ = Fragment(); | 6240 fragment_ = Fragment(); |
6306 return; | 6241 return; |
6307 } | 6242 } |
6308 | 6243 |
6309 TargetEntryInstr* then; | 6244 TargetEntryInstr* then; |
6310 TargetEntryInstr* otherwise; | 6245 TargetEntryInstr* otherwise; |
6311 | 6246 |
6312 Fragment instructions; | 6247 Fragment instructions; |
6313 // Asserts can be of the following two kinds: | 6248 // Asserts can be of the following two kinds: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6369 // Throw _AssertionError exception. | 6304 // Throw _AssertionError exception. |
6370 otherwise_fragment += PushArgument(); | 6305 otherwise_fragment += PushArgument(); |
6371 otherwise_fragment += ThrowException(TokenPosition::kNoSource); | 6306 otherwise_fragment += ThrowException(TokenPosition::kNoSource); |
6372 otherwise_fragment += Drop(); | 6307 otherwise_fragment += Drop(); |
6373 | 6308 |
6374 fragment_ = Fragment(instructions.entry, then); | 6309 fragment_ = Fragment(instructions.entry, then); |
6375 } | 6310 } |
6376 | 6311 |
6377 | 6312 |
6378 void FlowGraphBuilder::VisitTryFinally(TryFinally* node) { | 6313 void FlowGraphBuilder::VisitTryFinally(TryFinally* node) { |
| 6314 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6315 |
6379 InlineBailout("kernel::FlowgraphBuilder::VisitTryFinally"); | 6316 InlineBailout("kernel::FlowgraphBuilder::VisitTryFinally"); |
6380 | 6317 |
6381 // There are 5 different cases where we need to execute the finally block: | 6318 // There are 5 different cases where we need to execute the finally block: |
6382 // | 6319 // |
6383 // a) 1/2/3th case: Special control flow going out of `node->body()`: | 6320 // a) 1/2/3th case: Special control flow going out of `node->body()`: |
6384 // | 6321 // |
6385 // * [BreakStatement] transfers control to a [LabledStatement] | 6322 // * [BreakStatement] transfers control to a [LabledStatement] |
6386 // * [ContinueSwitchStatement] transfers control to a [SwitchCase] | 6323 // * [ContinueSwitchStatement] transfers control to a [SwitchCase] |
6387 // * [ReturnStatement] returns a value | 6324 // * [ReturnStatement] returns a value |
6388 // | 6325 // |
(...skipping 11 matching lines...) Expand all Loading... |
6400 // | 6337 // |
6401 // => We are responsible for catching it, executing the finally block and | 6338 // => We are responsible for catching it, executing the finally block and |
6402 // rethrowing the exception. | 6339 // rethrowing the exception. |
6403 intptr_t try_handler_index = AllocateTryIndex(); | 6340 intptr_t try_handler_index = AllocateTryIndex(); |
6404 Fragment try_body = TryCatch(try_handler_index); | 6341 Fragment try_body = TryCatch(try_handler_index); |
6405 JoinEntryInstr* after_try = BuildJoinEntry(); | 6342 JoinEntryInstr* after_try = BuildJoinEntry(); |
6406 | 6343 |
6407 // Fill in the body of the try. | 6344 // Fill in the body of the try. |
6408 ++try_depth_; | 6345 ++try_depth_; |
6409 { | 6346 { |
6410 TryFinallyBlock tfb(this, node->finalizer()); | 6347 TryFinallyBlock tfb(this, node->finalizer(), -1); |
6411 TryCatchBlock tcb(this, try_handler_index); | 6348 TryCatchBlock tcb(this, try_handler_index); |
6412 try_body += TranslateStatement(node->body()); | 6349 try_body += TranslateStatement(node->body()); |
6413 } | 6350 } |
6414 --try_depth_; | 6351 --try_depth_; |
6415 | 6352 |
6416 if (try_body.is_open()) { | 6353 if (try_body.is_open()) { |
6417 // Please note: The try index will be on level out of this block, | 6354 // Please note: The try index will be on level out of this block, |
6418 // thereby ensuring if there's an exception in the finally block we | 6355 // thereby ensuring if there's an exception in the finally block we |
6419 // won't run it twice. | 6356 // won't run it twice. |
6420 JoinEntryInstr* finally_entry = BuildJoinEntry(); | 6357 JoinEntryInstr* finally_entry = BuildJoinEntry(); |
(...skipping 22 matching lines...) Expand all Loading... |
6443 RethrowException(TokenPosition::kNoSource, try_handler_index); | 6380 RethrowException(TokenPosition::kNoSource, try_handler_index); |
6444 Drop(); | 6381 Drop(); |
6445 } | 6382 } |
6446 --catch_depth_; | 6383 --catch_depth_; |
6447 | 6384 |
6448 fragment_ = Fragment(try_body.entry, after_try); | 6385 fragment_ = Fragment(try_body.entry, after_try); |
6449 } | 6386 } |
6450 | 6387 |
6451 | 6388 |
6452 void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) { | 6389 void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) { |
| 6390 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6391 |
6453 InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch"); | 6392 InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch"); |
6454 | 6393 |
6455 intptr_t try_handler_index = AllocateTryIndex(); | 6394 intptr_t try_handler_index = AllocateTryIndex(); |
6456 Fragment try_body = TryCatch(try_handler_index); | 6395 Fragment try_body = TryCatch(try_handler_index); |
6457 JoinEntryInstr* after_try = BuildJoinEntry(); | 6396 JoinEntryInstr* after_try = BuildJoinEntry(); |
6458 | 6397 |
6459 // Fill in the body of the try. | 6398 // Fill in the body of the try. |
6460 ++try_depth_; | 6399 ++try_depth_; |
6461 { | 6400 { |
6462 TryCatchBlock block(this, try_handler_index); | 6401 TryCatchBlock block(this, try_handler_index); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6562 catch_body += RethrowException(TokenPosition::kNoSource, try_handler_index); | 6501 catch_body += RethrowException(TokenPosition::kNoSource, try_handler_index); |
6563 Drop(); | 6502 Drop(); |
6564 } | 6503 } |
6565 --catch_depth_; | 6504 --catch_depth_; |
6566 | 6505 |
6567 fragment_ = Fragment(try_body.entry, after_try); | 6506 fragment_ = Fragment(try_body.entry, after_try); |
6568 } | 6507 } |
6569 | 6508 |
6570 | 6509 |
6571 void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) { | 6510 void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) { |
| 6511 STREAM_STATEMENT_IF_POSSIBLE(node); |
| 6512 |
6572 ASSERT(node->is_native()); // Must have been desugared. | 6513 ASSERT(node->is_native()); // Must have been desugared. |
6573 // Setup yield/continue point: | 6514 // Setup yield/continue point: |
6574 // | 6515 // |
6575 // ... | 6516 // ... |
6576 // :await_jump_var = index; | 6517 // :await_jump_var = index; |
6577 // :await_ctx_var = :current_context_var | 6518 // :await_ctx_var = :current_context_var |
6578 // return <expr> | 6519 // return <expr> |
6579 // | 6520 // |
6580 // Continuation<index>: | 6521 // Continuation<index>: |
6581 // Drop(1) | 6522 // Drop(1) |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6874 thread->clear_sticky_error(); | 6815 thread->clear_sticky_error(); |
6875 return error.raw(); | 6816 return error.raw(); |
6876 } | 6817 } |
6877 } | 6818 } |
6878 | 6819 |
6879 | 6820 |
6880 } // namespace kernel | 6821 } // namespace kernel |
6881 } // namespace dart | 6822 } // namespace dart |
6882 | 6823 |
6883 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6824 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |