Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: runtime/vm/kernel_to_il.cc

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

Powered by Google App Engine
This is Rietveld 408576698