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

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

Issue 10659005: Implement type cast in the VM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 304
305 // Type nodes only occur as the right-hand side of instanceof comparisons, 305 // Type nodes only occur as the right-hand side of instanceof comparisons,
306 // and they are handled specially in that context. 306 // and they are handled specially in that context.
307 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } 307 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
308 308
309 309
310 // Returns true if the type check can be skipped, for example, if the 310 // Returns true if the type check can be skipped, for example, if the
311 // destination type is Dynamic or if the static type of the value is a subtype 311 // destination type is Dynamic or if the static type of the value is a subtype
312 // of the destination type. 312 // of the destination type.
313 static bool CanSkipTypeCheck(Value* value, const AbstractType& dst_type) { 313 static bool CanSkipTypeCheck(Value* value, const AbstractType& dst_type) {
314 ASSERT(FLAG_enable_type_checks);
315 ASSERT(!dst_type.IsNull()); 314 ASSERT(!dst_type.IsNull());
316 ASSERT(dst_type.IsFinalized()); 315 ASSERT(dst_type.IsFinalized());
317 if (!FLAG_eliminate_type_checks) { 316 if (!FLAG_eliminate_type_checks) {
318 return false; 317 return false;
319 } 318 }
320 319
321 // Any expression is assignable to the Dynamic type and to the Object type. 320 // Any expression is assignable to the Dynamic type and to the Object type.
322 // Skip the test. 321 // Skip the test.
323 if (!dst_type.IsMalformed() && 322 if (!dst_type.IsMalformed() &&
324 (dst_type.IsDynamicType() || dst_type.IsObjectType())) { 323 (dst_type.IsDynamicType() || dst_type.IsObjectType())) {
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 return new AssertAssignableComp(token_pos, 649 return new AssertAssignableComp(token_pos,
651 owner()->try_index(), 650 owner()->try_index(),
652 value, 651 value,
653 instantiator, 652 instantiator,
654 instantiator_type_arguments, 653 instantiator_type_arguments,
655 dst_type, 654 dst_type,
656 dst_name); 655 dst_name);
657 } 656 }
658 657
659 658
660 // Used to to test assignments. 659 // Used for type casts and to test assignments.
661 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, 660 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos,
662 Value* value, 661 Value* value,
663 const AbstractType& dst_type, 662 const AbstractType& dst_type,
664 const String& dst_name) { 663 const String& dst_name) {
665 if (CanSkipTypeCheck(value, dst_type)) { 664 if (CanSkipTypeCheck(value, dst_type)) {
666 return value; 665 return value;
667 } 666 }
668 AssertAssignableComp* comp = BuildAssertAssignable(token_pos, 667 AssertAssignableComp* comp = BuildAssertAssignable(token_pos,
669 value, 668 value,
670 dst_type, 669 dst_type,
671 dst_name); 670 dst_name);
672 BindInstr* assert_assignable = new BindInstr(comp); 671 BindInstr* assert_assignable = new BindInstr(comp);
673 AddInstruction(assert_assignable); 672 AddInstruction(assert_assignable);
674 return new UseVal(assert_assignable); 673 return new UseVal(assert_assignable);
675 } 674 }
676 675
677 676
678 void EffectGraphVisitor::BuildInstanceOf(ComparisonNode* node) { 677 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
679 ASSERT(Token::IsInstanceofOperator(node->kind())); 678 ASSERT(Token::IsTypeTestOperator(node->kind()));
680 EffectGraphVisitor for_left_value(owner(), temp_index()); 679 EffectGraphVisitor for_left_value(owner(), temp_index());
681 node->left()->Visit(&for_left_value); 680 node->left()->Visit(&for_left_value);
682 Append(for_left_value); 681 Append(for_left_value);
683 } 682 }
684 683
685 684
686 void ValueGraphVisitor::BuildInstanceOf(ComparisonNode* node) { 685 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
687 ASSERT(Token::IsInstanceofOperator(node->kind())); 686 ASSERT(Token::IsTypeCastOperator(node->kind()));
687 const AbstractType& type = node->right()->AsTypeNode()->type();
688 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed.
689 ValueGraphVisitor for_value(owner(), temp_index());
690 node->left()->Visit(&for_value);
691 Append(for_value);
692 const String& dst_name = String::ZoneHandle(
693 String::NewSymbol(Exceptions::kCastExceptionDstName));
694 if (!CanSkipTypeCheck(for_value.value(), type)) {
695 AssertAssignableComp* assert_assignable =
696 BuildAssertAssignable(node->token_pos(),
697 for_value.value(),
698 type,
699 dst_name);
700 AddInstruction(new DoInstr(assert_assignable));
701 }
702 }
703
704
705 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) {
706 ASSERT(Token::IsTypeTestOperator(node->kind()));
688 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 707 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
689 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 708 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
690 const AbstractType& type = node->right()->AsTypeNode()->type(); 709 const AbstractType& type = node->right()->AsTypeNode()->type();
691 ASSERT(type.IsFinalized() && !type.IsMalformed()); 710 ASSERT(type.IsFinalized() && !type.IsMalformed());
692 const bool negate_result = (node->kind() == Token::kISNOT); 711 const bool negate_result = (node->kind() == Token::kISNOT);
693 // All objects are instances of type T if Object type is a subtype of type T. 712 // All objects are instances of type T if Object type is a subtype of type T.
694 const Type& object_type = 713 const Type& object_type = Type::Handle(Type::ObjectType());
695 Type::Handle(Isolate::Current()->object_store()->object_type());
696 Error& malformed_error = Error::Handle(); 714 Error& malformed_error = Error::Handle();
697 if (type.IsInstantiated() && 715 if (type.IsInstantiated() &&
698 object_type.IsSubtypeOf(type, &malformed_error)) { 716 object_type.IsSubtypeOf(type, &malformed_error)) {
699 // Must evaluate left side. 717 // Must evaluate left side.
700 EffectGraphVisitor for_left_value(owner(), temp_index()); 718 EffectGraphVisitor for_left_value(owner(), temp_index());
701 node->left()->Visit(&for_left_value); 719 node->left()->Visit(&for_left_value);
702 Append(for_left_value); 720 Append(for_left_value);
703 ReturnComputation(new ConstantVal(negate_result ? bool_false : bool_true)); 721 ReturnComputation(new ConstantVal(negate_result ? bool_false : bool_true));
704 return; 722 return;
705 } 723 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 owner()->try_index(), 768 owner()->try_index(),
751 for_left_value.value(), 769 for_left_value.value(),
752 instantiator, 770 instantiator,
753 instantiator_type_arguments, 771 instantiator_type_arguments,
754 node->right()->AsTypeNode()->type(), 772 node->right()->AsTypeNode()->type(),
755 (node->kind() == Token::kISNOT)); 773 (node->kind() == Token::kISNOT));
756 ReturnComputation(instance_of); 774 ReturnComputation(instance_of);
757 } 775 }
758 776
759 777
778 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) {
779 ASSERT(Token::IsTypeCastOperator(node->kind()));
780 const AbstractType& type = node->right()->AsTypeNode()->type();
781 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed.
782 ValueGraphVisitor for_value(owner(), temp_index());
783 node->left()->Visit(&for_value);
784 Append(for_value);
785 const String& dst_name = String::ZoneHandle(
786 String::NewSymbol(Exceptions::kCastExceptionDstName));
787 ReturnValue(BuildAssignableValue(node->token_pos(),
788 for_value.value(),
789 type,
790 dst_name));
791 }
792
793
760 // <Expression> :: Comparison { kind: Token::Kind 794 // <Expression> :: Comparison { kind: Token::Kind
761 // left: <Expression> 795 // left: <Expression>
762 // right: <Expression> } 796 // right: <Expression> }
763 // TODO(srdjan): Implement new equality. 797 // TODO(srdjan): Implement new equality.
764 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { 798 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
765 if (Token::IsInstanceofOperator(node->kind())) { 799 if (Token::IsTypeTestOperator(node->kind())) {
766 BuildInstanceOf(node); 800 BuildTypeTest(node);
801 return;
802 }
803 if (Token::IsTypeCastOperator(node->kind())) {
804 BuildTypeCast(node);
767 return; 805 return;
768 } 806 }
769 if ((node->kind() == Token::kEQ_STRICT) || 807 if ((node->kind() == Token::kEQ_STRICT) ||
770 (node->kind() == Token::kNE_STRICT)) { 808 (node->kind() == Token::kNE_STRICT)) {
771 ValueGraphVisitor for_left_value(owner(), temp_index()); 809 ValueGraphVisitor for_left_value(owner(), temp_index());
772 node->left()->Visit(&for_left_value); 810 node->left()->Visit(&for_left_value);
773 Append(for_left_value); 811 Append(for_left_value);
774 ValueGraphVisitor for_right_value(owner(), temp_index()); 812 ValueGraphVisitor for_right_value(owner(), temp_index());
775 node->right()->Visit(&for_right_value); 813 node->right()->Visit(&for_right_value);
776 Append(for_right_value); 814 Append(for_right_value);
(...skipping 1952 matching lines...) Expand 10 before | Expand all | Expand 10 after
2729 char* chars = reinterpret_cast<char*>( 2767 char* chars = reinterpret_cast<char*>(
2730 Isolate::Current()->current_zone()->Allocate(len)); 2768 Isolate::Current()->current_zone()->Allocate(len));
2731 OS::SNPrint(chars, len, kFormat, function_name, reason); 2769 OS::SNPrint(chars, len, kFormat, function_name, reason);
2732 const Error& error = Error::Handle( 2770 const Error& error = Error::Handle(
2733 LanguageError::New(String::Handle(String::New(chars)))); 2771 LanguageError::New(String::Handle(String::New(chars))));
2734 Isolate::Current()->long_jump_base()->Jump(1, error); 2772 Isolate::Current()->long_jump_base()->Jump(1, error);
2735 } 2773 }
2736 2774
2737 2775
2738 } // namespace dart 2776 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698