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(condition_node_id(), |
| 166 condition_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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 | 300 |
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(), |
| 311 temp_index(), |
| 312 node->left()->id(), |
| 313 node->left()->token_index()); |
302 node->left()->Visit(&for_left); | 314 node->left()->Visit(&for_left); |
303 EffectGraphVisitor for_right(owner(), temp_index()); | 315 EffectGraphVisitor for_right(owner(), temp_index()); |
304 node->right()->Visit(&for_right); | 316 node->right()->Visit(&for_right); |
305 EffectGraphVisitor empty(owner(), temp_index()); | 317 EffectGraphVisitor empty(owner(), temp_index()); |
306 if (node->kind() == Token::kAND) { | 318 if (node->kind() == Token::kAND) { |
307 Join(for_left, for_right, empty); | 319 Join(for_left, for_right, empty); |
308 } else { | 320 } else { |
309 Join(for_left, empty, for_right); | 321 Join(for_left, empty, for_right); |
310 } | 322 } |
311 return; | 323 return; |
(...skipping 24 matching lines...) Expand all Loading... |
336 // Operators "&&" and "||" cannot be overloaded therefore do not call | 348 // Operators "&&" and "||" cannot be overloaded therefore do not call |
337 // operator. | 349 // operator. |
338 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 350 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
339 // Implement short-circuit logic: do not evaluate right if evaluation | 351 // Implement short-circuit logic: do not evaluate right if evaluation |
340 // of left is sufficient. | 352 // of left is sufficient. |
341 // AND: left ? right === true : false; | 353 // AND: left ? right === true : false; |
342 // OR: left ? true : right === true; | 354 // OR: left ? true : right === true; |
343 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 355 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
344 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 356 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
345 | 357 |
346 TestGraphVisitor for_test(owner(), temp_index()); | 358 TestGraphVisitor for_test(owner(), |
| 359 temp_index(), |
| 360 node->left()->id(), |
| 361 node->left()->token_index()); |
347 node->left()->Visit(&for_test); | 362 node->left()->Visit(&for_test); |
348 if (FLAG_enable_type_checks) { | |
349 Bailout("GenerateConditionTypeCheck in kAND/kOR"); | |
350 } | |
351 | 363 |
352 ValueGraphVisitor for_right(owner(), temp_index()); | 364 ValueGraphVisitor for_right(owner(), temp_index()); |
353 node->right()->Visit(&for_right); | 365 node->right()->Visit(&for_right); |
| 366 Value* right_value = for_right.value(); |
354 if (FLAG_enable_type_checks) { | 367 if (FLAG_enable_type_checks) { |
355 Bailout("GenerateConditionTypeCheck in kAND/kOR"); | 368 AssertBooleanComp* assert_boolean = |
| 369 new AssertBooleanComp(node->right()->id(), |
| 370 node->right()->token_index(), |
| 371 owner()->try_index(), |
| 372 right_value); |
| 373 for_right.AddInstruction(new BindInstr(temp_index(), assert_boolean)); |
| 374 right_value = new TempVal(temp_index()); |
356 } | 375 } |
357 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, | 376 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, |
358 for_right.value(), new ConstantVal(bool_true)); | 377 right_value, new ConstantVal(bool_true)); |
359 for_right.AddInstruction(new BindInstr(temp_index(), comp)); | 378 for_right.AddInstruction(new BindInstr(temp_index(), comp)); |
360 | 379 |
361 if (node->kind() == Token::kAND) { | 380 if (node->kind() == Token::kAND) { |
362 ValueGraphVisitor for_false(owner(), temp_index()); | 381 ValueGraphVisitor for_false(owner(), temp_index()); |
363 for_false.AddInstruction( | 382 for_false.AddInstruction( |
364 new BindInstr(temp_index(), new ConstantVal(bool_false))); | 383 new BindInstr(temp_index(), new ConstantVal(bool_false))); |
365 Join(for_test, for_right, for_false); | 384 Join(for_test, for_right, for_false); |
366 } else { | 385 } else { |
367 ASSERT(node->kind() == Token::kOR); | 386 ASSERT(node->kind() == Token::kOR); |
368 ValueGraphVisitor for_true(owner(), temp_index()); | 387 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); | 581 node->right()->Visit(&for_right_value); |
563 Append(for_right_value); | 582 Append(for_right_value); |
564 EqualityCompareComp* comp = new EqualityCompareComp( | 583 EqualityCompareComp* comp = new EqualityCompareComp( |
565 node->id(), node->token_index(), owner()->try_index(), | 584 node->id(), node->token_index(), owner()->try_index(), |
566 for_left_value.value(), for_right_value.value()); | 585 for_left_value.value(), for_right_value.value()); |
567 if (node->kind() == Token::kEQ) { | 586 if (node->kind() == Token::kEQ) { |
568 ReturnComputation(comp); | 587 ReturnComputation(comp); |
569 } else { | 588 } else { |
570 AddInstruction(new BindInstr(temp_index(), comp)); | 589 AddInstruction(new BindInstr(temp_index(), comp)); |
571 Value* eq_result = new TempVal(temp_index()); | 590 Value* eq_result = new TempVal(temp_index()); |
| 591 if (FLAG_enable_type_checks) { |
| 592 AssertBooleanComp* assert_boolean = |
| 593 new AssertBooleanComp(node->id(), |
| 594 node->token_index(), |
| 595 owner()->try_index(), |
| 596 eq_result); |
| 597 AddInstruction(new BindInstr(temp_index(), assert_boolean)); |
| 598 eq_result = new TempVal(temp_index()); |
| 599 } |
572 BooleanNegateComp* negate = new BooleanNegateComp(eq_result); | 600 BooleanNegateComp* negate = new BooleanNegateComp(eq_result); |
573 ReturnComputation(negate); | 601 ReturnComputation(negate); |
574 } | 602 } |
575 return; | 603 return; |
576 } | 604 } |
577 | 605 |
578 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | 606 ArgumentGraphVisitor for_left_value(owner(), temp_index()); |
579 node->left()->Visit(&for_left_value); | 607 node->left()->Visit(&for_left_value); |
580 Append(for_left_value); | 608 Append(for_left_value); |
581 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 609 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
582 node->right()->Visit(&for_right_value); | 610 node->right()->Visit(&for_right_value); |
583 Append(for_right_value); | 611 Append(for_right_value); |
584 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 612 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
585 arguments->Add(for_left_value.value()); | 613 arguments->Add(for_left_value.value()); |
586 arguments->Add(for_right_value.value()); | 614 arguments->Add(for_right_value.value()); |
587 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 615 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
588 InstanceCallComp* call = new InstanceCallComp( | 616 InstanceCallComp* call = new InstanceCallComp( |
589 node->id(), node->token_index(), owner()->try_index(), name, | 617 node->id(), node->token_index(), owner()->try_index(), name, |
590 arguments, Array::ZoneHandle(), 2); | 618 arguments, Array::ZoneHandle(), 2); |
591 ReturnComputation(call); | 619 ReturnComputation(call); |
592 } | 620 } |
593 | 621 |
594 | 622 |
595 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 623 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
596 // "!" cannot be overloaded, therefore do not call operator. | 624 // "!" cannot be overloaded, therefore do not call operator. |
597 if (node->kind() == Token::kNOT) { | 625 if (node->kind() == Token::kNOT) { |
598 ValueGraphVisitor for_value(owner(), temp_index()); | 626 ValueGraphVisitor for_value(owner(), temp_index()); |
599 node->operand()->Visit(&for_value); | 627 node->operand()->Visit(&for_value); |
600 Append(for_value); | 628 Append(for_value); |
| 629 Value* value = for_value.value(); |
601 if (FLAG_enable_type_checks) { | 630 if (FLAG_enable_type_checks) { |
602 Bailout("GenerateConditionTypeCheck in kNOT"); | 631 AssertBooleanComp* assert_boolean = |
| 632 new AssertBooleanComp(node->operand()->id(), |
| 633 node->operand()->token_index(), |
| 634 owner()->try_index(), |
| 635 value); |
| 636 AddInstruction(new BindInstr(temp_index(), assert_boolean)); |
| 637 value = new TempVal(temp_index()); |
603 } | 638 } |
604 BooleanNegateComp* negate = new BooleanNegateComp(for_value.value()); | 639 BooleanNegateComp* negate = new BooleanNegateComp(value); |
605 ReturnComputation(negate); | 640 ReturnComputation(negate); |
606 return; | 641 return; |
607 } | 642 } |
608 ArgumentGraphVisitor for_value(owner(), temp_index()); | 643 ArgumentGraphVisitor for_value(owner(), temp_index()); |
609 node->operand()->Visit(&for_value); | 644 node->operand()->Visit(&for_value); |
610 Append(for_value); | 645 Append(for_value); |
611 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 646 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
612 arguments->Add(for_value.value()); | 647 arguments->Add(for_value.value()); |
613 const String& name = | 648 const String& name = |
614 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) | 649 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 arguments->Add(new TempVal(value_index)); | 893 arguments->Add(new TempVal(value_index)); |
859 InstanceCallComp* store = new InstanceCallComp( | 894 InstanceCallComp* store = new InstanceCallComp( |
860 node->store_id(), node->token_index(), owner()->try_index(), | 895 node->store_id(), node->token_index(), owner()->try_index(), |
861 store_name, arguments, Array::ZoneHandle(), 1); | 896 store_name, arguments, Array::ZoneHandle(), 1); |
862 AddInstruction(new DoInstr(store)); | 897 AddInstruction(new DoInstr(store)); |
863 ReturnValue(new TempVal(AllocateTempIndex())); | 898 ReturnValue(new TempVal(AllocateTempIndex())); |
864 } | 899 } |
865 | 900 |
866 | 901 |
867 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 902 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
868 TestGraphVisitor for_test(owner(), temp_index()); | 903 TestGraphVisitor for_test(owner(), |
| 904 temp_index(), |
| 905 node->condition()->id(), |
| 906 node->condition()->token_index()); |
869 node->condition()->Visit(&for_test); | 907 node->condition()->Visit(&for_test); |
870 if (FLAG_enable_type_checks) { | |
871 Bailout("GenerateConditionTypeCheck in conditional expr"); | |
872 } | |
873 | 908 |
874 // Translate the subexpressions for their effects. | 909 // Translate the subexpressions for their effects. |
875 EffectGraphVisitor for_true(owner(), temp_index()); | 910 EffectGraphVisitor for_true(owner(), temp_index()); |
876 node->true_expr()->Visit(&for_true); | 911 node->true_expr()->Visit(&for_true); |
877 EffectGraphVisitor for_false(owner(), temp_index()); | 912 EffectGraphVisitor for_false(owner(), temp_index()); |
878 node->false_expr()->Visit(&for_false); | 913 node->false_expr()->Visit(&for_false); |
879 | 914 |
880 Join(for_test, for_true, for_false); | 915 Join(for_test, for_true, for_false); |
881 } | 916 } |
882 | 917 |
883 | 918 |
884 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 919 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
885 TestGraphVisitor for_test(owner(), temp_index()); | 920 TestGraphVisitor for_test(owner(), |
| 921 temp_index(), |
| 922 node->condition()->id(), |
| 923 node->condition()->token_index()); |
886 node->condition()->Visit(&for_test); | 924 node->condition()->Visit(&for_test); |
887 if (FLAG_enable_type_checks) { | |
888 Bailout("GenerateConditionTypeCheck in conditional expr"); | |
889 } | |
890 | 925 |
891 // Ensure that the value of the true/false subexpressions are named with | 926 // Ensure that the value of the true/false subexpressions are named with |
892 // the same temporary name. | 927 // the same temporary name. |
893 ValueGraphVisitor for_true(owner(), temp_index()); | 928 ValueGraphVisitor for_true(owner(), temp_index()); |
894 node->true_expr()->Visit(&for_true); | 929 node->true_expr()->Visit(&for_true); |
895 ASSERT(for_true.is_open()); | 930 ASSERT(for_true.is_open()); |
896 if (for_true.value()->IsTemp()) { | 931 if (for_true.value()->IsTemp()) { |
897 ASSERT(for_true.value()->AsTemp()->index() == temp_index()); | 932 ASSERT(for_true.value()->AsTemp()->index() == temp_index()); |
898 } else { | 933 } else { |
899 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value())); | 934 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value())); |
(...skipping 10 matching lines...) Expand all Loading... |
910 | 945 |
911 Join(for_test, for_true, for_false); | 946 Join(for_test, for_true, for_false); |
912 ReturnValue(new TempVal(AllocateTempIndex())); | 947 ReturnValue(new TempVal(AllocateTempIndex())); |
913 } | 948 } |
914 | 949 |
915 | 950 |
916 // <Statement> ::= If { condition: <Expression> | 951 // <Statement> ::= If { condition: <Expression> |
917 // true_branch: <Sequence> | 952 // true_branch: <Sequence> |
918 // false_branch: <Sequence> } | 953 // false_branch: <Sequence> } |
919 void EffectGraphVisitor::VisitIfNode(IfNode* node) { | 954 void EffectGraphVisitor::VisitIfNode(IfNode* node) { |
920 TestGraphVisitor for_test(owner(), temp_index()); | 955 TestGraphVisitor for_test(owner(), |
| 956 temp_index(), |
| 957 node->condition()->id(), |
| 958 node->condition()->token_index()); |
921 node->condition()->Visit(&for_test); | 959 node->condition()->Visit(&for_test); |
922 if (FLAG_enable_type_checks) { | |
923 Bailout("GenerateConditionTypeCheck in if"); | |
924 } | |
925 | 960 |
926 EffectGraphVisitor for_true(owner(), temp_index()); | 961 EffectGraphVisitor for_true(owner(), temp_index()); |
927 EffectGraphVisitor for_false(owner(), temp_index()); | 962 EffectGraphVisitor for_false(owner(), temp_index()); |
928 | 963 |
929 node->true_branch()->Visit(&for_true); | 964 node->true_branch()->Visit(&for_true); |
930 // The for_false graph fragment will be empty (default graph fragment) if | 965 // The for_false graph fragment will be empty (default graph fragment) if |
931 // we do not call Visit. | 966 // we do not call Visit. |
932 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); | 967 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); |
933 Join(for_test, for_true, for_false); | 968 Join(for_test, for_true, for_false); |
934 } | 969 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 return; | 1036 return; |
1002 } | 1037 } |
1003 | 1038 |
1004 // Generate instructions for all case expressions and collect data to | 1039 // Generate instructions for all case expressions and collect data to |
1005 // connect them. | 1040 // connect them. |
1006 GrowableArray<TargetEntryInstr**> case_true_addresses; | 1041 GrowableArray<TargetEntryInstr**> case_true_addresses; |
1007 GrowableArray<TargetEntryInstr**> case_false_addresses; | 1042 GrowableArray<TargetEntryInstr**> case_false_addresses; |
1008 GrowableArray<TargetEntryInstr*> case_entries; | 1043 GrowableArray<TargetEntryInstr*> case_entries; |
1009 for (intptr_t i = 0; i < len; i++) { | 1044 for (intptr_t i = 0; i < len; i++) { |
1010 AstNode* case_expr = node->case_expressions()->NodeAt(i); | 1045 AstNode* case_expr = node->case_expressions()->NodeAt(i); |
1011 TestGraphVisitor for_case_expression(owner(), temp_index()); | 1046 TestGraphVisitor for_case_expression(owner(), |
| 1047 temp_index(), |
| 1048 case_expr->id(), |
| 1049 case_expr->token_index()); |
1012 if (i == 0) { | 1050 if (i == 0) { |
1013 case_entries.Add(NULL); // Not to be used | 1051 case_entries.Add(NULL); // Not to be used |
1014 case_expr->Visit(&for_case_expression); | 1052 case_expr->Visit(&for_case_expression); |
1015 // Append only the first one, everything else is connected from it. | 1053 // Append only the first one, everything else is connected from it. |
1016 Append(for_case_expression); | 1054 Append(for_case_expression); |
1017 } else { | 1055 } else { |
1018 TargetEntryInstr* case_entry_target = new TargetEntryInstr(); | 1056 TargetEntryInstr* case_entry_target = new TargetEntryInstr(); |
1019 case_entries.Add(case_entry_target); | 1057 case_entries.Add(case_entry_target); |
1020 for_case_expression.AddInstruction(case_entry_target); | 1058 for_case_expression.AddInstruction(case_entry_target); |
1021 case_expr->Visit(&for_case_expression); | 1059 case_expr->Visit(&for_case_expression); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 // body: <Sequence> } | 1119 // body: <Sequence> } |
1082 // The fragment is composed as follows: | 1120 // The fragment is composed as follows: |
1083 // a) continue-join (optional) | 1121 // a) continue-join (optional) |
1084 // b) loop-join | 1122 // b) loop-join |
1085 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1123 // c) [ test ] -> (body-entry-target, loop-exit-target) |
1086 // d) body-entry-target | 1124 // d) body-entry-target |
1087 // e) [ body ] -> (loop-join) | 1125 // e) [ body ] -> (loop-join) |
1088 // f) loop-exit-target | 1126 // f) loop-exit-target |
1089 // g) break-join (optional) | 1127 // g) break-join (optional) |
1090 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1128 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
1091 TestGraphVisitor for_test(owner(), temp_index()); | 1129 TestGraphVisitor for_test(owner(), |
| 1130 temp_index(), |
| 1131 node->condition()->id(), |
| 1132 node->condition()->token_index()); |
1092 node->condition()->Visit(&for_test); | 1133 node->condition()->Visit(&for_test); |
1093 ASSERT(!for_test.is_empty()); // Language spec. | 1134 ASSERT(!for_test.is_empty()); // Language spec. |
1094 | 1135 |
1095 if (FLAG_enable_type_checks) { | |
1096 Bailout("GenerateConditionTypeCheck in while"); | |
1097 } | |
1098 | |
1099 EffectGraphVisitor for_body(owner(), temp_index()); | 1136 EffectGraphVisitor for_body(owner(), temp_index()); |
1100 node->body()->Visit(&for_body); | 1137 node->body()->Visit(&for_body); |
1101 | 1138 |
1102 // Labels are set after body traversal. | 1139 // Labels are set after body traversal. |
1103 SourceLabel* lbl = node->label(); | 1140 SourceLabel* lbl = node->label(); |
1104 ASSERT(lbl != NULL); | 1141 ASSERT(lbl != NULL); |
1105 if (lbl->join_for_continue() != NULL) { | 1142 if (lbl->join_for_continue() != NULL) { |
1106 AddInstruction(lbl->join_for_continue()); | 1143 AddInstruction(lbl->join_for_continue()); |
1107 } | 1144 } |
1108 TieLoop(for_test, for_body); | 1145 TieLoop(for_test, for_body); |
1109 if (lbl->join_for_break() != NULL) { | 1146 if (lbl->join_for_break() != NULL) { |
1110 AddInstruction(lbl->join_for_break()); | 1147 AddInstruction(lbl->join_for_break()); |
1111 } | 1148 } |
1112 } | 1149 } |
1113 | 1150 |
1114 | 1151 |
1115 // The fragment is composed as follows: | 1152 // The fragment is composed as follows: |
1116 // a) body-entry-join | 1153 // a) body-entry-join |
1117 // b) [ body ] | 1154 // b) [ body ] |
1118 // c) test-entry (continue-join or body-exit-target) | 1155 // c) test-entry (continue-join or body-exit-target) |
1119 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1156 // d) [ test-entry ] -> (back-target, loop-exit-target) |
1120 // e) back-target -> (body-entry-join) | 1157 // e) back-target -> (body-entry-join) |
1121 // f) loop-exit-target | 1158 // f) loop-exit-target |
1122 // g) break-join | 1159 // g) break-join |
1123 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1160 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
1124 // Traverse body first in order to generate continue and break labels. | 1161 // Traverse body first in order to generate continue and break labels. |
1125 EffectGraphVisitor for_body(owner(), temp_index()); | 1162 EffectGraphVisitor for_body(owner(), temp_index()); |
1126 node->body()->Visit(&for_body); | 1163 node->body()->Visit(&for_body); |
1127 | 1164 |
1128 TestGraphVisitor for_test(owner(), temp_index()); | 1165 TestGraphVisitor for_test(owner(), |
| 1166 temp_index(), |
| 1167 node->condition()->id(), |
| 1168 node->condition()->token_index()); |
1129 node->condition()->Visit(&for_test); | 1169 node->condition()->Visit(&for_test); |
1130 ASSERT(is_open()); | 1170 ASSERT(is_open()); |
1131 | 1171 |
1132 if (FLAG_enable_type_checks) { | |
1133 Bailout("GenerateConditionTypeCheck in do while"); | |
1134 } | |
1135 | |
1136 // Tie do-while loop (test is after the body). | 1172 // Tie do-while loop (test is after the body). |
1137 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); | 1173 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); |
1138 AddInstruction(body_entry_join); | 1174 AddInstruction(body_entry_join); |
1139 body_entry_join->SetSuccessor(for_body.entry()); | 1175 body_entry_join->SetSuccessor(for_body.entry()); |
1140 Instruction* body_exit = | 1176 Instruction* body_exit = |
1141 for_body.is_empty() ? body_entry_join : for_body.exit(); | 1177 for_body.is_empty() ? body_entry_join : for_body.exit(); |
1142 | 1178 |
1143 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { | 1179 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { |
1144 BlockEntryInstr* test_entry = NULL; | 1180 BlockEntryInstr* test_entry = NULL; |
1145 if (node->label()->join_for_continue() == NULL) { | 1181 if (node->label()->join_for_continue() == NULL) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 // Endless loop, no test. | 1264 // Endless loop, no test. |
1229 Append(for_body); | 1265 Append(for_body); |
1230 if (node->label()->join_for_break() == NULL) { | 1266 if (node->label()->join_for_break() == NULL) { |
1231 CloseFragment(); | 1267 CloseFragment(); |
1232 } else { | 1268 } else { |
1233 // Control flow of ForLoop continues into join_for_break. | 1269 // Control flow of ForLoop continues into join_for_break. |
1234 exit_ = node->label()->join_for_break(); | 1270 exit_ = node->label()->join_for_break(); |
1235 } | 1271 } |
1236 } else { | 1272 } else { |
1237 TargetEntryInstr* loop_exit = new TargetEntryInstr(); | 1273 TargetEntryInstr* loop_exit = new TargetEntryInstr(); |
1238 TestGraphVisitor for_test(owner(), temp_index()); | 1274 TestGraphVisitor for_test(owner(), |
| 1275 temp_index(), |
| 1276 node->condition()->id(), |
| 1277 node->condition()->token_index()); |
1239 node->condition()->Visit(&for_test); | 1278 node->condition()->Visit(&for_test); |
1240 Append(for_test); | 1279 Append(for_test); |
1241 if (FLAG_enable_type_checks) { | |
1242 Bailout("GenerateConditionTypeCheck in for"); | |
1243 } | |
1244 *for_test.true_successor_address() = body_entry; | 1280 *for_test.true_successor_address() = body_entry; |
1245 *for_test.false_successor_address() = loop_exit; | 1281 *for_test.false_successor_address() = loop_exit; |
1246 if (node->label()->join_for_break() == NULL) { | 1282 if (node->label()->join_for_break() == NULL) { |
1247 exit_ = loop_exit; | 1283 exit_ = loop_exit; |
1248 } else { | 1284 } else { |
1249 loop_exit->SetSuccessor(node->label()->join_for_break()); | 1285 loop_exit->SetSuccessor(node->label()->join_for_break()); |
1250 exit_ = node->label()->join_for_break(); | 1286 exit_ = node->label()->join_for_break(); |
1251 } | 1287 } |
1252 } | 1288 } |
1253 } | 1289 } |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1764 | 1800 |
1765 Value* value = for_value.value(); | 1801 Value* value = for_value.value(); |
1766 if (FLAG_enable_type_checks) { | 1802 if (FLAG_enable_type_checks) { |
1767 Value* type_arguments = NULL; | 1803 Value* type_arguments = NULL; |
1768 if (!node->local().type().IsInstantiated()) { | 1804 if (!node->local().type().IsInstantiated()) { |
1769 type_arguments = BuildInstantiatorTypeArguments( | 1805 type_arguments = BuildInstantiatorTypeArguments( |
1770 node->token_index(), for_value.temp_index()); | 1806 node->token_index(), for_value.temp_index()); |
1771 } | 1807 } |
1772 AssertAssignableComp* assert_assignable = | 1808 AssertAssignableComp* assert_assignable = |
1773 new AssertAssignableComp(node->id(), | 1809 new AssertAssignableComp(node->id(), |
1774 node->local().token_index(), | 1810 node->value()->token_index(), |
1775 owner()->try_index(), | 1811 owner()->try_index(), |
1776 value, | 1812 value, |
1777 type_arguments, | 1813 type_arguments, |
1778 node->local().type(), | 1814 node->local().type(), |
1779 node->local().name()); | 1815 node->local().name()); |
1780 AddInstruction(new BindInstr(temp_index(), assert_assignable)); | 1816 AddInstruction(new BindInstr(temp_index(), assert_assignable)); |
1781 value = new TempVal(temp_index()); | 1817 value = new TempVal(temp_index()); |
1782 } | 1818 } |
1783 | 1819 |
1784 StoreLocalComp* store = | 1820 StoreLocalComp* store = |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1844 Value* store_value = for_value.value(); | 1880 Value* store_value = for_value.value(); |
1845 if (FLAG_enable_type_checks) { | 1881 if (FLAG_enable_type_checks) { |
1846 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1882 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
1847 Value* type_arguments = NULL; | 1883 Value* type_arguments = NULL; |
1848 if (!type.IsInstantiated()) { | 1884 if (!type.IsInstantiated()) { |
1849 type_arguments = BuildInstantiatorTypeArguments( | 1885 type_arguments = BuildInstantiatorTypeArguments( |
1850 node->token_index(), for_value.temp_index()); | 1886 node->token_index(), for_value.temp_index()); |
1851 } | 1887 } |
1852 AssertAssignableComp* assert_assignable = | 1888 AssertAssignableComp* assert_assignable = |
1853 new AssertAssignableComp(node->id(), | 1889 new AssertAssignableComp(node->id(), |
1854 node->field().token_index(), | 1890 node->value()->token_index(), |
1855 owner()->try_index(), | 1891 owner()->try_index(), |
1856 store_value, | 1892 store_value, |
1857 type_arguments, | 1893 type_arguments, |
1858 type, | 1894 type, |
1859 String::ZoneHandle(node->field().name())); | 1895 String::ZoneHandle(node->field().name())); |
1860 AddInstruction(new BindInstr(temp_index(), assert_assignable)); | 1896 AddInstruction(new BindInstr(temp_index(), assert_assignable)); |
1861 store_value = new TempVal(temp_index()); | 1897 store_value = new TempVal(temp_index()); |
1862 } | 1898 } |
1863 StoreStaticFieldComp* store = | 1899 StoreStaticFieldComp* store = |
1864 new StoreStaticFieldComp(node->field(), store_value); | 1900 new StoreStaticFieldComp(node->field(), store_value); |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2261 | 2297 |
2262 void FlowGraphPrinter::VisitConstant(ConstantVal* val) { | 2298 void FlowGraphPrinter::VisitConstant(ConstantVal* val) { |
2263 OS::Print("#%s", val->value().ToCString()); | 2299 OS::Print("#%s", val->value().ToCString()); |
2264 } | 2300 } |
2265 | 2301 |
2266 | 2302 |
2267 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { | 2303 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { |
2268 OS::Print("AssertAssignable("); | 2304 OS::Print("AssertAssignable("); |
2269 comp->value()->Accept(this); | 2305 comp->value()->Accept(this); |
2270 OS::Print(", %s, '%s'", | 2306 OS::Print(", %s, '%s'", |
2271 comp->dst_type().ToCString(), | 2307 String::Handle(comp->dst_type().Name()).ToCString(), |
2272 comp->dst_name().ToCString()); | 2308 comp->dst_name().ToCString()); |
2273 if (comp->type_arguments() != NULL) { | 2309 if (comp->type_arguments() != NULL) { |
2274 OS::Print(" (type-arg:"); | 2310 OS::Print(" (type-arg:"); |
2275 comp->type_arguments()->Accept(this); | 2311 comp->type_arguments()->Accept(this); |
2276 } | 2312 } |
2277 OS::Print(")"); | 2313 OS::Print(")"); |
2278 } | 2314 } |
2279 | 2315 |
2280 | 2316 |
2281 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) { | 2317 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) { |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2734 char* chars = reinterpret_cast<char*>( | 2770 char* chars = reinterpret_cast<char*>( |
2735 Isolate::Current()->current_zone()->Allocate(len)); | 2771 Isolate::Current()->current_zone()->Allocate(len)); |
2736 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2772 OS::SNPrint(chars, len, kFormat, function_name, reason); |
2737 const Error& error = Error::Handle( | 2773 const Error& error = Error::Handle( |
2738 LanguageError::New(String::Handle(String::New(chars)))); | 2774 LanguageError::New(String::Handle(String::New(chars)))); |
2739 Isolate::Current()->long_jump_base()->Jump(1, error); | 2775 Isolate::Current()->long_jump_base()->Jump(1, error); |
2740 } | 2776 } |
2741 | 2777 |
2742 | 2778 |
2743 } // namespace dart | 2779 } // namespace dart |
OLD | NEW |