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