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

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

Issue 2854393002: [kernel] [partial] Streaming of kernel binary without AST nodes (Closed)
Patch Set: Address comments; small fixes; rebased. 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
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 798 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698