OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
6 | 6 |
7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 new LoadLocalComp(variable, owner()->context_level()); | 153 new LoadLocalComp(variable, owner()->context_level()); |
154 AddInstruction(new BindInstr(start_index, load_saved_context)); | 154 AddInstruction(new BindInstr(start_index, load_saved_context)); |
155 StoreContextComp* store_context = | 155 StoreContextComp* store_context = |
156 new StoreContextComp(new TempVal(start_index)); | 156 new StoreContextComp(new TempVal(start_index)); |
157 AddInstruction(new DoInstr(store_context)); | 157 AddInstruction(new DoInstr(store_context)); |
158 } | 158 } |
159 | 159 |
160 | 160 |
161 | 161 |
162 void TestGraphVisitor::ReturnValue(Value* value) { | 162 void TestGraphVisitor::ReturnValue(Value* value) { |
| 163 if (FLAG_enable_type_checks) { |
| 164 AssertBooleanComp* assert_boolean = |
| 165 new AssertBooleanComp(node_id(), |
| 166 token_index(), |
| 167 owner()->try_index(), |
| 168 value); |
| 169 AddInstruction(new BindInstr(temp_index(), assert_boolean)); |
| 170 value = new TempVal(temp_index()); |
| 171 } |
163 BranchInstr* branch = new BranchInstr(value); | 172 BranchInstr* branch = new BranchInstr(value); |
164 AddInstruction(branch); | 173 AddInstruction(branch); |
165 CloseFragment(); | 174 CloseFragment(); |
166 true_successor_address_ = branch->true_successor_address(); | 175 true_successor_address_ = branch->true_successor_address(); |
167 false_successor_address_ = branch->false_successor_address(); | 176 false_successor_address_ = branch->false_successor_address(); |
168 } | 177 } |
169 | 178 |
170 | 179 |
171 void ArgumentGraphVisitor::ReturnValue(Value* value) { | 180 void ArgumentGraphVisitor::ReturnValue(Value* value) { |
172 value_ = value; | 181 value_ = value; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 301 |
293 // <Expression> :: BinaryOp { kind: Token::Kind | 302 // <Expression> :: BinaryOp { kind: Token::Kind |
294 // left: <Expression> | 303 // left: <Expression> |
295 // right: <Expression> } | 304 // right: <Expression> } |
296 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 305 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
297 // Operators "&&" and "||" cannot be overloaded therefore do not call | 306 // Operators "&&" and "||" cannot be overloaded therefore do not call |
298 // operator. | 307 // operator. |
299 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 308 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
300 // See ValueGraphVisitor::VisitBinaryOpNode. | 309 // See ValueGraphVisitor::VisitBinaryOpNode. |
301 TestGraphVisitor for_left(owner(), temp_index()); | 310 TestGraphVisitor for_left(owner(), temp_index()); |
| 311 if (FLAG_enable_type_checks) { |
| 312 for_left.set_node_id(node->left()->id()); |
| 313 for_left.set_token_index(node->left()->token_index()); |
| 314 } |
302 node->left()->Visit(&for_left); | 315 node->left()->Visit(&for_left); |
303 EffectGraphVisitor for_right(owner(), temp_index()); | 316 EffectGraphVisitor for_right(owner(), temp_index()); |
304 node->right()->Visit(&for_right); | 317 node->right()->Visit(&for_right); |
305 EffectGraphVisitor empty(owner(), temp_index()); | 318 EffectGraphVisitor empty(owner(), temp_index()); |
306 if (node->kind() == Token::kAND) { | 319 if (node->kind() == Token::kAND) { |
307 Join(for_left, for_right, empty); | 320 Join(for_left, for_right, empty); |
308 } else { | 321 } else { |
309 Join(for_left, empty, for_right); | 322 Join(for_left, empty, for_right); |
310 } | 323 } |
311 return; | 324 return; |
(...skipping 25 matching lines...) Expand all Loading... |
337 // operator. | 350 // operator. |
338 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 351 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
339 // Implement short-circuit logic: do not evaluate right if evaluation | 352 // Implement short-circuit logic: do not evaluate right if evaluation |
340 // of left is sufficient. | 353 // of left is sufficient. |
341 // AND: left ? right === true : false; | 354 // AND: left ? right === true : false; |
342 // OR: left ? true : right === true; | 355 // OR: left ? true : right === true; |
343 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 356 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
344 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 357 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
345 | 358 |
346 TestGraphVisitor for_test(owner(), temp_index()); | 359 TestGraphVisitor for_test(owner(), temp_index()); |
| 360 if (FLAG_enable_type_checks) { |
| 361 for_test.set_node_id(node->left()->id()); |
| 362 for_test.set_token_index(node->left()->token_index()); |
| 363 } |
347 node->left()->Visit(&for_test); | 364 node->left()->Visit(&for_test); |
348 if (FLAG_enable_type_checks) { | |
349 Bailout("GenerateConditionTypeCheck in kAND/kOR"); | |
350 } | |
351 | 365 |
352 ValueGraphVisitor for_right(owner(), temp_index()); | 366 ValueGraphVisitor for_right(owner(), temp_index()); |
353 node->right()->Visit(&for_right); | 367 node->right()->Visit(&for_right); |
| 368 Value* right_value = for_right.value(); |
354 if (FLAG_enable_type_checks) { | 369 if (FLAG_enable_type_checks) { |
355 Bailout("GenerateConditionTypeCheck in kAND/kOR"); | 370 AssertBooleanComp* assert_boolean = |
| 371 new AssertBooleanComp(node->right()->id(), |
| 372 node->right()->token_index(), |
| 373 owner()->try_index(), |
| 374 right_value); |
| 375 for_right.AddInstruction(new BindInstr(temp_index(), assert_boolean)); |
| 376 right_value = new TempVal(temp_index()); |
356 } | 377 } |
357 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, | 378 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, |
358 for_right.value(), new ConstantVal(bool_true)); | 379 right_value, new ConstantVal(bool_true)); |
359 for_right.AddInstruction(new BindInstr(temp_index(), comp)); | 380 for_right.AddInstruction(new BindInstr(temp_index(), comp)); |
360 | 381 |
361 if (node->kind() == Token::kAND) { | 382 if (node->kind() == Token::kAND) { |
362 ValueGraphVisitor for_false(owner(), temp_index()); | 383 ValueGraphVisitor for_false(owner(), temp_index()); |
363 for_false.AddInstruction( | 384 for_false.AddInstruction( |
364 new BindInstr(temp_index(), new ConstantVal(bool_false))); | 385 new BindInstr(temp_index(), new ConstantVal(bool_false))); |
365 Join(for_test, for_right, for_false); | 386 Join(for_test, for_right, for_false); |
366 } else { | 387 } else { |
367 ASSERT(node->kind() == Token::kOR); | 388 ASSERT(node->kind() == Token::kOR); |
368 ValueGraphVisitor for_true(owner(), temp_index()); | 389 ValueGraphVisitor for_true(owner(), temp_index()); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 node->right()->Visit(&for_right_value); | 583 node->right()->Visit(&for_right_value); |
563 Append(for_right_value); | 584 Append(for_right_value); |
564 EqualityCompareComp* comp = new EqualityCompareComp( | 585 EqualityCompareComp* comp = new EqualityCompareComp( |
565 node->id(), node->token_index(), owner()->try_index(), | 586 node->id(), node->token_index(), owner()->try_index(), |
566 for_left_value.value(), for_right_value.value()); | 587 for_left_value.value(), for_right_value.value()); |
567 if (node->kind() == Token::kEQ) { | 588 if (node->kind() == Token::kEQ) { |
568 ReturnComputation(comp); | 589 ReturnComputation(comp); |
569 } else { | 590 } else { |
570 AddInstruction(new BindInstr(temp_index(), comp)); | 591 AddInstruction(new BindInstr(temp_index(), comp)); |
571 Value* eq_result = new TempVal(temp_index()); | 592 Value* eq_result = new TempVal(temp_index()); |
| 593 if (FLAG_enable_type_checks) { |
| 594 AssertBooleanComp* assert_boolean = |
| 595 new AssertBooleanComp(node->id(), |
| 596 node->token_index(), |
| 597 owner()->try_index(), |
| 598 eq_result); |
| 599 AddInstruction(new BindInstr(temp_index(), assert_boolean)); |
| 600 eq_result = new TempVal(temp_index()); |
| 601 } |
572 BooleanNegateComp* negate = new BooleanNegateComp(eq_result); | 602 BooleanNegateComp* negate = new BooleanNegateComp(eq_result); |
573 ReturnComputation(negate); | 603 ReturnComputation(negate); |
574 } | 604 } |
575 return; | 605 return; |
576 } | 606 } |
577 | 607 |
578 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | 608 ArgumentGraphVisitor for_left_value(owner(), temp_index()); |
579 node->left()->Visit(&for_left_value); | 609 node->left()->Visit(&for_left_value); |
580 Append(for_left_value); | 610 Append(for_left_value); |
581 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 611 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
582 node->right()->Visit(&for_right_value); | 612 node->right()->Visit(&for_right_value); |
583 Append(for_right_value); | 613 Append(for_right_value); |
584 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 614 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
585 arguments->Add(for_left_value.value()); | 615 arguments->Add(for_left_value.value()); |
586 arguments->Add(for_right_value.value()); | 616 arguments->Add(for_right_value.value()); |
587 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 617 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
588 InstanceCallComp* call = new InstanceCallComp( | 618 InstanceCallComp* call = new InstanceCallComp( |
589 node->id(), node->token_index(), owner()->try_index(), name, | 619 node->id(), node->token_index(), owner()->try_index(), name, |
590 arguments, Array::ZoneHandle(), 2); | 620 arguments, Array::ZoneHandle(), 2); |
591 ReturnComputation(call); | 621 ReturnComputation(call); |
592 } | 622 } |
593 | 623 |
594 | 624 |
595 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 625 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
596 // "!" cannot be overloaded, therefore do not call operator. | 626 // "!" cannot be overloaded, therefore do not call operator. |
597 if (node->kind() == Token::kNOT) { | 627 if (node->kind() == Token::kNOT) { |
598 ValueGraphVisitor for_value(owner(), temp_index()); | 628 ValueGraphVisitor for_value(owner(), temp_index()); |
599 node->operand()->Visit(&for_value); | 629 node->operand()->Visit(&for_value); |
600 Append(for_value); | 630 Append(for_value); |
| 631 Value* value = for_value.value(); |
601 if (FLAG_enable_type_checks) { | 632 if (FLAG_enable_type_checks) { |
602 Bailout("GenerateConditionTypeCheck in kNOT"); | 633 AssertBooleanComp* assert_boolean = |
| 634 new AssertBooleanComp(node->operand()->id(), |
| 635 node->operand()->token_index(), |
| 636 owner()->try_index(), |
| 637 value); |
| 638 AddInstruction(new BindInstr(temp_index(), assert_boolean)); |
| 639 value = new TempVal(temp_index()); |
603 } | 640 } |
604 BooleanNegateComp* negate = new BooleanNegateComp(for_value.value()); | 641 BooleanNegateComp* negate = new BooleanNegateComp(value); |
605 ReturnComputation(negate); | 642 ReturnComputation(negate); |
606 return; | 643 return; |
607 } | 644 } |
608 ArgumentGraphVisitor for_value(owner(), temp_index()); | 645 ArgumentGraphVisitor for_value(owner(), temp_index()); |
609 node->operand()->Visit(&for_value); | 646 node->operand()->Visit(&for_value); |
610 Append(for_value); | 647 Append(for_value); |
611 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 648 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
612 arguments->Add(for_value.value()); | 649 arguments->Add(for_value.value()); |
613 const String& name = | 650 const String& name = |
614 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) | 651 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 InstanceCallComp* store = new InstanceCallComp( | 896 InstanceCallComp* store = new InstanceCallComp( |
860 node->store_id(), node->token_index(), owner()->try_index(), | 897 node->store_id(), node->token_index(), owner()->try_index(), |
861 store_name, arguments, Array::ZoneHandle(), 1); | 898 store_name, arguments, Array::ZoneHandle(), 1); |
862 AddInstruction(new DoInstr(store)); | 899 AddInstruction(new DoInstr(store)); |
863 ReturnValue(new TempVal(AllocateTempIndex())); | 900 ReturnValue(new TempVal(AllocateTempIndex())); |
864 } | 901 } |
865 | 902 |
866 | 903 |
867 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 904 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
868 TestGraphVisitor for_test(owner(), temp_index()); | 905 TestGraphVisitor for_test(owner(), temp_index()); |
| 906 if (FLAG_enable_type_checks) { |
| 907 for_test.set_node_id(node->condition()->id()); |
| 908 for_test.set_token_index(node->condition()->token_index()); |
| 909 } |
869 node->condition()->Visit(&for_test); | 910 node->condition()->Visit(&for_test); |
870 if (FLAG_enable_type_checks) { | |
871 Bailout("GenerateConditionTypeCheck in conditional expr"); | |
872 } | |
873 | 911 |
874 // Translate the subexpressions for their effects. | 912 // Translate the subexpressions for their effects. |
875 EffectGraphVisitor for_true(owner(), temp_index()); | 913 EffectGraphVisitor for_true(owner(), temp_index()); |
876 node->true_expr()->Visit(&for_true); | 914 node->true_expr()->Visit(&for_true); |
877 EffectGraphVisitor for_false(owner(), temp_index()); | 915 EffectGraphVisitor for_false(owner(), temp_index()); |
878 node->false_expr()->Visit(&for_false); | 916 node->false_expr()->Visit(&for_false); |
879 | 917 |
880 Join(for_test, for_true, for_false); | 918 Join(for_test, for_true, for_false); |
881 } | 919 } |
882 | 920 |
883 | 921 |
884 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 922 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
885 TestGraphVisitor for_test(owner(), temp_index()); | 923 TestGraphVisitor for_test(owner(), temp_index()); |
| 924 if (FLAG_enable_type_checks) { |
| 925 for_test.set_node_id(node->condition()->id()); |
| 926 for_test.set_token_index(node->condition()->token_index()); |
| 927 } |
886 node->condition()->Visit(&for_test); | 928 node->condition()->Visit(&for_test); |
887 if (FLAG_enable_type_checks) { | |
888 Bailout("GenerateConditionTypeCheck in conditional expr"); | |
889 } | |
890 | 929 |
891 // Ensure that the value of the true/false subexpressions are named with | 930 // Ensure that the value of the true/false subexpressions are named with |
892 // the same temporary name. | 931 // the same temporary name. |
893 ValueGraphVisitor for_true(owner(), temp_index()); | 932 ValueGraphVisitor for_true(owner(), temp_index()); |
894 node->true_expr()->Visit(&for_true); | 933 node->true_expr()->Visit(&for_true); |
895 ASSERT(for_true.is_open()); | 934 ASSERT(for_true.is_open()); |
896 if (for_true.value()->IsTemp()) { | 935 if (for_true.value()->IsTemp()) { |
897 ASSERT(for_true.value()->AsTemp()->index() == temp_index()); | 936 ASSERT(for_true.value()->AsTemp()->index() == temp_index()); |
898 } else { | 937 } else { |
899 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value())); | 938 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value())); |
(...skipping 11 matching lines...) Expand all Loading... |
911 Join(for_test, for_true, for_false); | 950 Join(for_test, for_true, for_false); |
912 ReturnValue(new TempVal(AllocateTempIndex())); | 951 ReturnValue(new TempVal(AllocateTempIndex())); |
913 } | 952 } |
914 | 953 |
915 | 954 |
916 // <Statement> ::= If { condition: <Expression> | 955 // <Statement> ::= If { condition: <Expression> |
917 // true_branch: <Sequence> | 956 // true_branch: <Sequence> |
918 // false_branch: <Sequence> } | 957 // false_branch: <Sequence> } |
919 void EffectGraphVisitor::VisitIfNode(IfNode* node) { | 958 void EffectGraphVisitor::VisitIfNode(IfNode* node) { |
920 TestGraphVisitor for_test(owner(), temp_index()); | 959 TestGraphVisitor for_test(owner(), temp_index()); |
| 960 if (FLAG_enable_type_checks) { |
| 961 for_test.set_node_id(node->condition()->id()); |
| 962 for_test.set_token_index(node->condition()->token_index()); |
| 963 } |
921 node->condition()->Visit(&for_test); | 964 node->condition()->Visit(&for_test); |
922 if (FLAG_enable_type_checks) { | |
923 Bailout("GenerateConditionTypeCheck in if"); | |
924 } | |
925 | 965 |
926 EffectGraphVisitor for_true(owner(), temp_index()); | 966 EffectGraphVisitor for_true(owner(), temp_index()); |
927 EffectGraphVisitor for_false(owner(), temp_index()); | 967 EffectGraphVisitor for_false(owner(), temp_index()); |
928 | 968 |
929 node->true_branch()->Visit(&for_true); | 969 node->true_branch()->Visit(&for_true); |
930 // The for_false graph fragment will be empty (default graph fragment) if | 970 // The for_false graph fragment will be empty (default graph fragment) if |
931 // we do not call Visit. | 971 // we do not call Visit. |
932 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); | 972 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); |
933 Join(for_test, for_true, for_false); | 973 Join(for_test, for_true, for_false); |
934 } | 974 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1082 // The fragment is composed as follows: | 1122 // The fragment is composed as follows: |
1083 // a) continue-join (optional) | 1123 // a) continue-join (optional) |
1084 // b) loop-join | 1124 // b) loop-join |
1085 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1125 // c) [ test ] -> (body-entry-target, loop-exit-target) |
1086 // d) body-entry-target | 1126 // d) body-entry-target |
1087 // e) [ body ] -> (loop-join) | 1127 // e) [ body ] -> (loop-join) |
1088 // f) loop-exit-target | 1128 // f) loop-exit-target |
1089 // g) break-join (optional) | 1129 // g) break-join (optional) |
1090 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1130 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
1091 TestGraphVisitor for_test(owner(), temp_index()); | 1131 TestGraphVisitor for_test(owner(), temp_index()); |
| 1132 if (FLAG_enable_type_checks) { |
| 1133 for_test.set_node_id(node->condition()->id()); |
| 1134 for_test.set_token_index(node->condition()->token_index()); |
| 1135 } |
1092 node->condition()->Visit(&for_test); | 1136 node->condition()->Visit(&for_test); |
1093 ASSERT(!for_test.is_empty()); // Language spec. | 1137 ASSERT(!for_test.is_empty()); // Language spec. |
1094 | 1138 |
1095 if (FLAG_enable_type_checks) { | |
1096 Bailout("GenerateConditionTypeCheck in while"); | |
1097 } | |
1098 | |
1099 EffectGraphVisitor for_body(owner(), temp_index()); | 1139 EffectGraphVisitor for_body(owner(), temp_index()); |
1100 node->body()->Visit(&for_body); | 1140 node->body()->Visit(&for_body); |
1101 | 1141 |
1102 // Labels are set after body traversal. | 1142 // Labels are set after body traversal. |
1103 SourceLabel* lbl = node->label(); | 1143 SourceLabel* lbl = node->label(); |
1104 ASSERT(lbl != NULL); | 1144 ASSERT(lbl != NULL); |
1105 if (lbl->join_for_continue() != NULL) { | 1145 if (lbl->join_for_continue() != NULL) { |
1106 AddInstruction(lbl->join_for_continue()); | 1146 AddInstruction(lbl->join_for_continue()); |
1107 } | 1147 } |
1108 TieLoop(for_test, for_body); | 1148 TieLoop(for_test, for_body); |
(...skipping 10 matching lines...) Expand all Loading... |
1119 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1159 // d) [ test-entry ] -> (back-target, loop-exit-target) |
1120 // e) back-target -> (body-entry-join) | 1160 // e) back-target -> (body-entry-join) |
1121 // f) loop-exit-target | 1161 // f) loop-exit-target |
1122 // g) break-join | 1162 // g) break-join |
1123 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1163 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
1124 // Traverse body first in order to generate continue and break labels. | 1164 // Traverse body first in order to generate continue and break labels. |
1125 EffectGraphVisitor for_body(owner(), temp_index()); | 1165 EffectGraphVisitor for_body(owner(), temp_index()); |
1126 node->body()->Visit(&for_body); | 1166 node->body()->Visit(&for_body); |
1127 | 1167 |
1128 TestGraphVisitor for_test(owner(), temp_index()); | 1168 TestGraphVisitor for_test(owner(), temp_index()); |
| 1169 if (FLAG_enable_type_checks) { |
| 1170 for_test.set_node_id(node->condition()->id()); |
| 1171 for_test.set_token_index(node->condition()->token_index()); |
| 1172 } |
1129 node->condition()->Visit(&for_test); | 1173 node->condition()->Visit(&for_test); |
1130 ASSERT(is_open()); | 1174 ASSERT(is_open()); |
1131 | 1175 |
1132 if (FLAG_enable_type_checks) { | |
1133 Bailout("GenerateConditionTypeCheck in do while"); | |
1134 } | |
1135 | |
1136 // Tie do-while loop (test is after the body). | 1176 // Tie do-while loop (test is after the body). |
1137 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); | 1177 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); |
1138 AddInstruction(body_entry_join); | 1178 AddInstruction(body_entry_join); |
1139 body_entry_join->SetSuccessor(for_body.entry()); | 1179 body_entry_join->SetSuccessor(for_body.entry()); |
1140 Instruction* body_exit = | 1180 Instruction* body_exit = |
1141 for_body.is_empty() ? body_entry_join : for_body.exit(); | 1181 for_body.is_empty() ? body_entry_join : for_body.exit(); |
1142 | 1182 |
1143 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { | 1183 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { |
1144 BlockEntryInstr* test_entry = NULL; | 1184 BlockEntryInstr* test_entry = NULL; |
1145 if (node->label()->join_for_continue() == NULL) { | 1185 if (node->label()->join_for_continue() == NULL) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 Append(for_body); | 1269 Append(for_body); |
1230 if (node->label()->join_for_break() == NULL) { | 1270 if (node->label()->join_for_break() == NULL) { |
1231 CloseFragment(); | 1271 CloseFragment(); |
1232 } else { | 1272 } else { |
1233 // Control flow of ForLoop continues into join_for_break. | 1273 // Control flow of ForLoop continues into join_for_break. |
1234 exit_ = node->label()->join_for_break(); | 1274 exit_ = node->label()->join_for_break(); |
1235 } | 1275 } |
1236 } else { | 1276 } else { |
1237 TargetEntryInstr* loop_exit = new TargetEntryInstr(); | 1277 TargetEntryInstr* loop_exit = new TargetEntryInstr(); |
1238 TestGraphVisitor for_test(owner(), temp_index()); | 1278 TestGraphVisitor for_test(owner(), temp_index()); |
| 1279 if (FLAG_enable_type_checks) { |
| 1280 for_test.set_node_id(node->condition()->id()); |
| 1281 for_test.set_token_index(node->condition()->token_index()); |
| 1282 } |
1239 node->condition()->Visit(&for_test); | 1283 node->condition()->Visit(&for_test); |
1240 Append(for_test); | 1284 Append(for_test); |
1241 if (FLAG_enable_type_checks) { | |
1242 Bailout("GenerateConditionTypeCheck in for"); | |
1243 } | |
1244 *for_test.true_successor_address() = body_entry; | 1285 *for_test.true_successor_address() = body_entry; |
1245 *for_test.false_successor_address() = loop_exit; | 1286 *for_test.false_successor_address() = loop_exit; |
1246 if (node->label()->join_for_break() == NULL) { | 1287 if (node->label()->join_for_break() == NULL) { |
1247 exit_ = loop_exit; | 1288 exit_ = loop_exit; |
1248 } else { | 1289 } else { |
1249 loop_exit->SetSuccessor(node->label()->join_for_break()); | 1290 loop_exit->SetSuccessor(node->label()->join_for_break()); |
1250 exit_ = node->label()->join_for_break(); | 1291 exit_ = node->label()->join_for_break(); |
1251 } | 1292 } |
1252 } | 1293 } |
1253 } | 1294 } |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1764 | 1805 |
1765 Value* value = for_value.value(); | 1806 Value* value = for_value.value(); |
1766 if (FLAG_enable_type_checks) { | 1807 if (FLAG_enable_type_checks) { |
1767 Value* type_arguments = NULL; | 1808 Value* type_arguments = NULL; |
1768 if (!node->local().type().IsInstantiated()) { | 1809 if (!node->local().type().IsInstantiated()) { |
1769 type_arguments = BuildInstantiatorTypeArguments( | 1810 type_arguments = BuildInstantiatorTypeArguments( |
1770 node->token_index(), for_value.temp_index()); | 1811 node->token_index(), for_value.temp_index()); |
1771 } | 1812 } |
1772 AssertAssignableComp* assert_assignable = | 1813 AssertAssignableComp* assert_assignable = |
1773 new AssertAssignableComp(node->id(), | 1814 new AssertAssignableComp(node->id(), |
1774 node->local().token_index(), | 1815 node->value()->token_index(), |
1775 owner()->try_index(), | 1816 owner()->try_index(), |
1776 value, | 1817 value, |
1777 type_arguments, | 1818 type_arguments, |
1778 node->local().type(), | 1819 node->local().type(), |
1779 node->local().name()); | 1820 node->local().name()); |
1780 AddInstruction(new BindInstr(temp_index(), assert_assignable)); | 1821 AddInstruction(new BindInstr(temp_index(), assert_assignable)); |
1781 value = new TempVal(temp_index()); | 1822 value = new TempVal(temp_index()); |
1782 } | 1823 } |
1783 | 1824 |
1784 StoreLocalComp* store = | 1825 StoreLocalComp* store = |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1844 Value* store_value = for_value.value(); | 1885 Value* store_value = for_value.value(); |
1845 if (FLAG_enable_type_checks) { | 1886 if (FLAG_enable_type_checks) { |
1846 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1887 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
1847 Value* type_arguments = NULL; | 1888 Value* type_arguments = NULL; |
1848 if (!type.IsInstantiated()) { | 1889 if (!type.IsInstantiated()) { |
1849 type_arguments = BuildInstantiatorTypeArguments( | 1890 type_arguments = BuildInstantiatorTypeArguments( |
1850 node->token_index(), for_value.temp_index()); | 1891 node->token_index(), for_value.temp_index()); |
1851 } | 1892 } |
1852 AssertAssignableComp* assert_assignable = | 1893 AssertAssignableComp* assert_assignable = |
1853 new AssertAssignableComp(node->id(), | 1894 new AssertAssignableComp(node->id(), |
1854 node->field().token_index(), | 1895 node->value()->token_index(), |
1855 owner()->try_index(), | 1896 owner()->try_index(), |
1856 store_value, | 1897 store_value, |
1857 type_arguments, | 1898 type_arguments, |
1858 type, | 1899 type, |
1859 String::ZoneHandle(node->field().name())); | 1900 String::ZoneHandle(node->field().name())); |
1860 AddInstruction(new BindInstr(temp_index(), assert_assignable)); | 1901 AddInstruction(new BindInstr(temp_index(), assert_assignable)); |
1861 store_value = new TempVal(temp_index()); | 1902 store_value = new TempVal(temp_index()); |
1862 } | 1903 } |
1863 StoreStaticFieldComp* store = | 1904 StoreStaticFieldComp* store = |
1864 new StoreStaticFieldComp(node->field(), store_value); | 1905 new StoreStaticFieldComp(node->field(), store_value); |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2261 | 2302 |
2262 void FlowGraphPrinter::VisitConstant(ConstantVal* val) { | 2303 void FlowGraphPrinter::VisitConstant(ConstantVal* val) { |
2263 OS::Print("#%s", val->value().ToCString()); | 2304 OS::Print("#%s", val->value().ToCString()); |
2264 } | 2305 } |
2265 | 2306 |
2266 | 2307 |
2267 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { | 2308 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { |
2268 OS::Print("AssertAssignable("); | 2309 OS::Print("AssertAssignable("); |
2269 comp->value()->Accept(this); | 2310 comp->value()->Accept(this); |
2270 OS::Print(", %s, '%s'", | 2311 OS::Print(", %s, '%s'", |
2271 comp->dst_type().ToCString(), | 2312 String::Handle(comp->dst_type().Name()).ToCString(), |
2272 comp->dst_name().ToCString()); | 2313 comp->dst_name().ToCString()); |
2273 if (comp->type_arguments() != NULL) { | 2314 if (comp->type_arguments() != NULL) { |
2274 OS::Print(" (type-arg:"); | 2315 OS::Print(" (type-arg:"); |
2275 comp->type_arguments()->Accept(this); | 2316 comp->type_arguments()->Accept(this); |
2276 } | 2317 } |
2277 OS::Print(")"); | 2318 OS::Print(")"); |
2278 } | 2319 } |
2279 | 2320 |
2280 | 2321 |
2281 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) { | 2322 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) { |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2734 char* chars = reinterpret_cast<char*>( | 2775 char* chars = reinterpret_cast<char*>( |
2735 Isolate::Current()->current_zone()->Allocate(len)); | 2776 Isolate::Current()->current_zone()->Allocate(len)); |
2736 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2777 OS::SNPrint(chars, len, kFormat, function_name, reason); |
2737 const Error& error = Error::Handle( | 2778 const Error& error = Error::Handle( |
2738 LanguageError::New(String::Handle(String::New(chars)))); | 2779 LanguageError::New(String::Handle(String::New(chars)))); |
2739 Isolate::Current()->long_jump_base()->Jump(1, error); | 2780 Isolate::Current()->long_jump_base()->Jump(1, error); |
2740 } | 2781 } |
2741 | 2782 |
2742 | 2783 |
2743 } // namespace dart | 2784 } // namespace dart |
OLD | NEW |