| 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 |