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 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 | 357 |
358 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { | 358 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { |
359 return CreateSuccessorFor(false_successor_addresses_); | 359 return CreateSuccessorFor(false_successor_addresses_); |
360 } | 360 } |
361 | 361 |
362 | 362 |
363 void TestGraphVisitor::ReturnValue(Value* value) { | 363 void TestGraphVisitor::ReturnValue(Value* value) { |
364 if (FLAG_enable_type_checks) { | 364 if (FLAG_enable_type_checks) { |
365 value = Bind(new AssertBooleanInstr(condition_token_pos(), value)); | 365 value = Bind(new AssertBooleanInstr(condition_token_pos(), value)); |
366 } | 366 } |
367 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 367 Value* constant_true = Bind(new ConstantInstr(Bool::True())); |
368 Value* constant_true = Bind(new ConstantInstr(bool_true)); | |
369 StrictCompareInstr* comp = | 368 StrictCompareInstr* comp = |
370 new StrictCompareInstr(Token::kEQ_STRICT, value, constant_true); | 369 new StrictCompareInstr(Token::kEQ_STRICT, value, constant_true); |
371 BranchInstr* branch = new BranchInstr(comp); | 370 BranchInstr* branch = new BranchInstr(comp); |
372 AddInstruction(branch); | 371 AddInstruction(branch); |
373 CloseFragment(); | 372 CloseFragment(); |
374 | 373 |
375 true_successor_addresses_.Add(branch->true_successor_address()); | 374 true_successor_addresses_.Add(branch->true_successor_address()); |
376 false_successor_addresses_.Add(branch->false_successor_address()); | 375 false_successor_addresses_.Add(branch->false_successor_address()); |
377 } | 376 } |
378 | 377 |
(...skipping 16 matching lines...) Expand all Loading... |
395 } | 394 } |
396 AddInstruction(branch); | 395 AddInstruction(branch); |
397 CloseFragment(); | 396 CloseFragment(); |
398 true_successor_addresses_.Add(branch->true_successor_address()); | 397 true_successor_addresses_.Add(branch->true_successor_address()); |
399 false_successor_addresses_.Add(branch->false_successor_address()); | 398 false_successor_addresses_.Add(branch->false_successor_address()); |
400 } | 399 } |
401 | 400 |
402 | 401 |
403 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { | 402 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { |
404 ASSERT(!FLAG_enable_type_checks); | 403 ASSERT(!FLAG_enable_type_checks); |
405 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 404 Value* constant_true = Bind(new ConstantInstr(Bool::True())); |
406 Value* constant_true = Bind(new ConstantInstr(bool_true)); | |
407 BranchInstr* branch = new BranchInstr( | 405 BranchInstr* branch = new BranchInstr( |
408 new StrictCompareInstr(Token::kNE_STRICT, neg->value(), constant_true)); | 406 new StrictCompareInstr(Token::kNE_STRICT, neg->value(), constant_true)); |
409 AddInstruction(branch); | 407 AddInstruction(branch); |
410 CloseFragment(); | 408 CloseFragment(); |
411 true_successor_addresses_.Add(branch->true_successor_address()); | 409 true_successor_addresses_.Add(branch->true_successor_address()); |
412 false_successor_addresses_.Add(branch->false_successor_address()); | 410 false_successor_addresses_.Add(branch->false_successor_address()); |
413 } | 411 } |
414 | 412 |
415 | 413 |
416 void TestGraphVisitor::ReturnDefinition(Definition* definition) { | 414 void TestGraphVisitor::ReturnDefinition(Definition* definition) { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 | 692 |
695 // Special handling for AND/OR. | 693 // Special handling for AND/OR. |
696 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 694 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
697 // Operators "&&" and "||" cannot be overloaded therefore do not call | 695 // Operators "&&" and "||" cannot be overloaded therefore do not call |
698 // operator. | 696 // operator. |
699 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 697 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
700 // Implement short-circuit logic: do not evaluate right if evaluation | 698 // Implement short-circuit logic: do not evaluate right if evaluation |
701 // of left is sufficient. | 699 // of left is sufficient. |
702 // AND: left ? right === true : false; | 700 // AND: left ? right === true : false; |
703 // OR: left ? true : right === true; | 701 // OR: left ? true : right === true; |
704 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
705 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
706 | 702 |
707 TestGraphVisitor for_test(owner(), | 703 TestGraphVisitor for_test(owner(), |
708 temp_index(), | 704 temp_index(), |
709 loop_depth(), | 705 loop_depth(), |
710 node->left()->token_pos()); | 706 node->left()->token_pos()); |
711 node->left()->Visit(&for_test); | 707 node->left()->Visit(&for_test); |
712 | 708 |
713 ValueGraphVisitor for_right(owner(), temp_index(), loop_depth()); | 709 ValueGraphVisitor for_right(owner(), temp_index(), loop_depth()); |
714 node->right()->Visit(&for_right); | 710 node->right()->Visit(&for_right); |
715 Value* right_value = for_right.value(); | 711 Value* right_value = for_right.value(); |
716 if (FLAG_enable_type_checks) { | 712 if (FLAG_enable_type_checks) { |
717 right_value = | 713 right_value = |
718 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), | 714 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), |
719 right_value)); | 715 right_value)); |
720 } | 716 } |
721 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); | 717 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True())); |
722 Value* compare = | 718 Value* compare = |
723 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, | 719 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, |
724 right_value, | 720 right_value, |
725 constant_true)); | 721 constant_true)); |
726 for_right.Do(BuildStoreExprTemp(compare)); | 722 for_right.Do(BuildStoreExprTemp(compare)); |
727 | 723 |
728 if (node->kind() == Token::kAND) { | 724 if (node->kind() == Token::kAND) { |
729 ValueGraphVisitor for_false(owner(), temp_index(), loop_depth()); | 725 ValueGraphVisitor for_false(owner(), temp_index(), loop_depth()); |
730 Value* constant_false = for_false.Bind(new ConstantInstr(bool_false)); | 726 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False())); |
731 for_false.Do(BuildStoreExprTemp(constant_false)); | 727 for_false.Do(BuildStoreExprTemp(constant_false)); |
732 Join(for_test, for_right, for_false); | 728 Join(for_test, for_right, for_false); |
733 } else { | 729 } else { |
734 ASSERT(node->kind() == Token::kOR); | 730 ASSERT(node->kind() == Token::kOR); |
735 ValueGraphVisitor for_true(owner(), temp_index(), loop_depth()); | 731 ValueGraphVisitor for_true(owner(), temp_index(), loop_depth()); |
736 Value* constant_true = for_true.Bind(new ConstantInstr(bool_true)); | 732 Value* constant_true = for_true.Bind(new ConstantInstr(Bool::True())); |
737 for_true.Do(BuildStoreExprTemp(constant_true)); | 733 for_true.Do(BuildStoreExprTemp(constant_true)); |
738 Join(for_test, for_true, for_right); | 734 Join(for_test, for_true, for_right); |
739 } | 735 } |
740 ReturnDefinition(BuildLoadExprTemp()); | 736 ReturnDefinition(BuildLoadExprTemp()); |
741 return; | 737 return; |
742 } | 738 } |
743 EffectGraphVisitor::VisitBinaryOpNode(node); | 739 EffectGraphVisitor::VisitBinaryOpNode(node); |
744 } | 740 } |
745 | 741 |
746 | 742 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | 858 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |
863 Append(for_value); | 859 Append(for_value); |
864 Do(BuildAssertAssignable( | 860 Do(BuildAssertAssignable( |
865 node->token_pos(), for_value.value(), type, dst_name)); | 861 node->token_pos(), for_value.value(), type, dst_name)); |
866 } | 862 } |
867 } | 863 } |
868 | 864 |
869 | 865 |
870 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 866 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
871 ASSERT(Token::IsTypeTestOperator(node->kind())); | 867 ASSERT(Token::IsTypeTestOperator(node->kind())); |
872 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
873 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
874 const AbstractType& type = node->right()->AsTypeNode()->type(); | 868 const AbstractType& type = node->right()->AsTypeNode()->type(); |
875 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 869 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
876 const bool negate_result = (node->kind() == Token::kISNOT); | 870 const bool negate_result = (node->kind() == Token::kISNOT); |
877 // All objects are instances of type T if Object type is a subtype of type T. | 871 // All objects are instances of type T if Object type is a subtype of type T. |
878 const Type& object_type = Type::Handle(Type::ObjectType()); | 872 const Type& object_type = Type::Handle(Type::ObjectType()); |
879 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 873 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
880 // Must evaluate left side. | 874 // Must evaluate left side. |
881 EffectGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 875 EffectGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
882 node->left()->Visit(&for_left_value); | 876 node->left()->Visit(&for_left_value); |
883 Append(for_left_value); | 877 Append(for_left_value); |
884 ReturnDefinition(new ConstantInstr(negate_result ? bool_false : bool_true)); | 878 ReturnDefinition(new ConstantInstr(negate_result ? |
| 879 Bool::False() : Bool::True())); |
885 return; | 880 return; |
886 } | 881 } |
887 | 882 |
888 // Eliminate the test if it can be performed successfully at compile time. | 883 // Eliminate the test if it can be performed successfully at compile time. |
889 if ((node->left() != NULL) && | 884 if ((node->left() != NULL) && |
890 node->left()->IsLiteralNode() && | 885 node->left()->IsLiteralNode() && |
891 type.IsInstantiated()) { | 886 type.IsInstantiated()) { |
892 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); | 887 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); |
893 const Class& cls = Class::Handle(literal_value.clazz()); | 888 const Class& cls = Class::Handle(literal_value.clazz()); |
894 ConstantInstr* result = NULL; | 889 ConstantInstr* result = NULL; |
895 if (cls.IsNullClass()) { | 890 if (cls.IsNullClass()) { |
896 // A null object is only an instance of Object and dynamic, which has | 891 // A null object is only an instance of Object and dynamic, which has |
897 // already been checked above (if the type is instantiated). So we can | 892 // already been checked above (if the type is instantiated). So we can |
898 // return false here if the instance is null (and if the type is | 893 // return false here if the instance is null (and if the type is |
899 // instantiated). | 894 // instantiated). |
900 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 895 result = new ConstantInstr(negate_result ? Bool::True() : Bool::False()); |
901 } else { | 896 } else { |
902 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { | 897 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { |
903 result = new ConstantInstr(negate_result ? bool_false : bool_true); | 898 result = new ConstantInstr(negate_result ? |
| 899 Bool::False() : Bool::True()); |
904 } else { | 900 } else { |
905 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 901 result = new ConstantInstr(negate_result ? |
| 902 Bool::True() : Bool::False()); |
906 } | 903 } |
907 } | 904 } |
908 ReturnDefinition(result); | 905 ReturnDefinition(result); |
909 return; | 906 return; |
910 } | 907 } |
911 | 908 |
912 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 909 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
913 node->left()->Visit(&for_left_value); | 910 node->left()->Visit(&for_left_value); |
914 Append(for_left_value); | 911 Append(for_left_value); |
915 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 912 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
(...skipping 10 matching lines...) Expand all Loading... |
926 const String& name = String::ZoneHandle(Symbols::New("_instanceOf")); | 923 const String& name = String::ZoneHandle(Symbols::New("_instanceOf")); |
927 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 924 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
928 new ZoneGrowableArray<PushArgumentInstr*>(5); | 925 new ZoneGrowableArray<PushArgumentInstr*>(5); |
929 arguments->Add(push_left); | 926 arguments->Add(push_left); |
930 arguments->Add(push_instantiator); | 927 arguments->Add(push_instantiator); |
931 arguments->Add(push_type_args); | 928 arguments->Add(push_type_args); |
932 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); | 929 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); |
933 Value* type_arg = Bind( | 930 Value* type_arg = Bind( |
934 new ConstantInstr(node->right()->AsTypeNode()->type())); | 931 new ConstantInstr(node->right()->AsTypeNode()->type())); |
935 arguments->Add(PushArgument(type_arg)); | 932 arguments->Add(PushArgument(type_arg)); |
936 const Bool& negate = Bool::ZoneHandle(node->kind() == Token::kISNOT ? | 933 const Bool& negate = (node->kind() == Token::kISNOT) ? Bool::True() : |
937 Bool::True() : Bool::False()); | 934 Bool::False(); |
938 Value* negate_arg = Bind(new ConstantInstr(negate)); | 935 Value* negate_arg = Bind(new ConstantInstr(negate)); |
939 arguments->Add(PushArgument(negate_arg)); | 936 arguments->Add(PushArgument(negate_arg)); |
940 const intptr_t kNumArgsChecked = 1; | 937 const intptr_t kNumArgsChecked = 1; |
941 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 938 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
942 name, | 939 name, |
943 node->kind(), | 940 node->kind(), |
944 arguments, | 941 arguments, |
945 Array::ZoneHandle(), | 942 Array::ZoneHandle(), |
946 kNumArgsChecked); | 943 kNumArgsChecked); |
947 ReturnDefinition(call); | 944 ReturnDefinition(call); |
(...skipping 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3074 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3071 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
3075 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3072 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
3076 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3073 OS::SNPrint(chars, len, kFormat, function_name, reason); |
3077 const Error& error = Error::Handle( | 3074 const Error& error = Error::Handle( |
3078 LanguageError::New(String::Handle(String::New(chars)))); | 3075 LanguageError::New(String::Handle(String::New(chars)))); |
3079 Isolate::Current()->long_jump_base()->Jump(1, error); | 3076 Isolate::Current()->long_jump_base()->Jump(1, error); |
3080 } | 3077 } |
3081 | 3078 |
3082 | 3079 |
3083 } // namespace dart | 3080 } // namespace dart |
OLD | NEW |