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