| 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/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.h" |
| 8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
| 9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 } else { | 126 } else { |
| 127 type_arguments = | 127 type_arguments = |
| 128 InstantiatedTypeArguments::New(type_arguments, instantiator); | 128 InstantiatedTypeArguments::New(type_arguments, instantiator); |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 ASSERT(type_arguments.IsInstantiated()); | 131 ASSERT(type_arguments.IsInstantiated()); |
| 132 instance.SetTypeArguments(type_arguments); | 132 instance.SetTypeArguments(type_arguments); |
| 133 } | 133 } |
| 134 | 134 |
| 135 | 135 |
| 136 // Helper returning the token position of the Dart caller. |
| 137 static intptr_t GetCallerLocation() { |
| 138 DartFrameIterator iterator; |
| 139 StackFrame* caller_frame = iterator.NextFrame(); |
| 140 ASSERT(caller_frame != NULL); |
| 141 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 142 const PcDescriptors& descriptors = |
| 143 PcDescriptors::Handle(code.pc_descriptors()); |
| 144 ASSERT(!descriptors.IsNull()); |
| 145 for (int i = 0; i < descriptors.Length(); i++) { |
| 146 if (static_cast<uword>(descriptors.PC(i)) == caller_frame->pc()) { |
| 147 return descriptors.TokenIndex(i); |
| 148 } |
| 149 } |
| 150 return -1; |
| 151 } |
| 152 |
| 153 |
| 136 // Allocate a new object of a generic type and check that the instantiated type | 154 // Allocate a new object of a generic type and check that the instantiated type |
| 137 // arguments are within the declared bounds or throw a dynamic type error. | 155 // arguments are within the declared bounds or throw a dynamic type error. |
| 138 // Arg0: index of the token of the instance creation (source location). | 156 // Arg0: class of the object that needs to be allocated. |
| 139 // Arg1: class of the object that needs to be allocated. | 157 // Arg1: type arguments of the object that needs to be allocated. |
| 140 // Arg2: type arguments of the object that needs to be allocated. | 158 // Arg2: type arguments of the instantiator or kNoInstantiator. |
| 141 // Arg3: type arguments of the instantiator or kNoInstantiator. | |
| 142 // Return value: newly allocated object. | 159 // Return value: newly allocated object. |
| 143 DEFINE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck, 4) { | 160 DEFINE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck, 3) { |
| 144 ASSERT(FLAG_enable_type_checks); | 161 ASSERT(FLAG_enable_type_checks); |
| 145 ASSERT(arguments.Count() == | 162 ASSERT(arguments.Count() == |
| 146 kAllocateObjectWithBoundsCheckRuntimeEntry.argument_count()); | 163 kAllocateObjectWithBoundsCheckRuntimeEntry.argument_count()); |
| 147 const Class& cls = Class::CheckedHandle(arguments.At(1)); | 164 const Class& cls = Class::CheckedHandle(arguments.At(0)); |
| 148 const Instance& instance = Instance::Handle(Instance::New(cls)); | 165 const Instance& instance = Instance::Handle(Instance::New(cls)); |
| 149 arguments.SetReturn(instance); | 166 arguments.SetReturn(instance); |
| 150 ASSERT(cls.HasTypeArguments()); | 167 ASSERT(cls.HasTypeArguments()); |
| 151 AbstractTypeArguments& type_arguments = | 168 AbstractTypeArguments& type_arguments = |
| 152 AbstractTypeArguments::CheckedHandle(arguments.At(2)); | 169 AbstractTypeArguments::CheckedHandle(arguments.At(1)); |
| 153 ASSERT(type_arguments.IsNull() || | 170 ASSERT(type_arguments.IsNull() || |
| 154 (type_arguments.Length() == cls.NumTypeArguments())); | 171 (type_arguments.Length() == cls.NumTypeArguments())); |
| 155 AbstractTypeArguments& bounds_instantiator = AbstractTypeArguments::Handle(); | 172 AbstractTypeArguments& bounds_instantiator = AbstractTypeArguments::Handle(); |
| 156 if (Object::Handle(arguments.At(3)).IsSmi()) { | 173 if (Object::Handle(arguments.At(2)).IsSmi()) { |
| 157 ASSERT(Smi::CheckedHandle(arguments.At(3)).Value() == | 174 ASSERT(Smi::CheckedHandle(arguments.At(2)).Value() == |
| 158 StubCode::kNoInstantiator); | 175 StubCode::kNoInstantiator); |
| 159 } else { | 176 } else { |
| 160 ASSERT(!type_arguments.IsInstantiated()); | 177 ASSERT(!type_arguments.IsInstantiated()); |
| 161 const AbstractTypeArguments& instantiator = | 178 const AbstractTypeArguments& instantiator = |
| 162 AbstractTypeArguments::CheckedHandle(arguments.At(3)); | 179 AbstractTypeArguments::CheckedHandle(arguments.At(2)); |
| 163 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | 180 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
| 164 if (instantiator.IsNull()) { | 181 if (instantiator.IsNull()) { |
| 165 type_arguments = | 182 type_arguments = |
| 166 InstantiatedTypeArguments::New(type_arguments, instantiator); | 183 InstantiatedTypeArguments::New(type_arguments, instantiator); |
| 167 } else if (instantiator.IsTypeArguments()) { | 184 } else if (instantiator.IsTypeArguments()) { |
| 168 // Code inlined in the caller should have optimized the case where the | 185 // Code inlined in the caller should have optimized the case where the |
| 169 // instantiator is a TypeArguments and can be used as type argument | 186 // instantiator is a TypeArguments and can be used as type argument |
| 170 // vector. | 187 // vector. |
| 171 ASSERT(!type_arguments.IsUninstantiatedIdentity() || | 188 ASSERT(!type_arguments.IsUninstantiatedIdentity() || |
| 172 (instantiator.Length() != type_arguments.Length())); | 189 (instantiator.Length() != type_arguments.Length())); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 185 bounds_instantiator = instantiator.raw(); | 202 bounds_instantiator = instantiator.raw(); |
| 186 } | 203 } |
| 187 if (!type_arguments.IsNull()) { | 204 if (!type_arguments.IsNull()) { |
| 188 ASSERT(type_arguments.IsInstantiated()); | 205 ASSERT(type_arguments.IsInstantiated()); |
| 189 Error& malformed_error = Error::Handle(); | 206 Error& malformed_error = Error::Handle(); |
| 190 if (!type_arguments.IsWithinBoundsOf(cls, | 207 if (!type_arguments.IsWithinBoundsOf(cls, |
| 191 bounds_instantiator, | 208 bounds_instantiator, |
| 192 &malformed_error)) { | 209 &malformed_error)) { |
| 193 ASSERT(!malformed_error.IsNull()); | 210 ASSERT(!malformed_error.IsNull()); |
| 194 // Throw a dynamic type error. | 211 // Throw a dynamic type error. |
| 195 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); | 212 const intptr_t location = GetCallerLocation(); |
| 196 String& malformed_error_message = String::Handle( | 213 String& malformed_error_message = String::Handle( |
| 197 String::New(malformed_error.ToErrorCString())); | 214 String::New(malformed_error.ToErrorCString())); |
| 198 const String& no_name = String::Handle(String::NewSymbol("")); | 215 const String& no_name = String::Handle(String::NewSymbol("")); |
| 199 Exceptions::CreateAndThrowTypeError( | 216 Exceptions::CreateAndThrowTypeError( |
| 200 location, no_name, no_name, no_name, malformed_error_message); | 217 location, no_name, no_name, no_name, malformed_error_message); |
| 201 UNREACHABLE(); | 218 UNREACHABLE(); |
| 202 } | 219 } |
| 203 } | 220 } |
| 204 instance.SetTypeArguments(type_arguments); | 221 instance.SetTypeArguments(type_arguments); |
| 205 } | 222 } |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 Class::Handle(test_type.type_class()).ToCString(), | 531 Class::Handle(test_type.type_class()).ToCString(), |
| 515 instantiator_type_arguments.raw(), | 532 instantiator_type_arguments.raw(), |
| 516 instantiator_type_arguments.ToCString(), | 533 instantiator_type_arguments.ToCString(), |
| 517 result.ToCString()); | 534 result.ToCString()); |
| 518 } | 535 } |
| 519 } | 536 } |
| 520 | 537 |
| 521 | 538 |
| 522 // Check that the given instance is an instance of the given type. | 539 // Check that the given instance is an instance of the given type. |
| 523 // Tested instance may not be null, because the null test is inlined. | 540 // Tested instance may not be null, because the null test is inlined. |
| 524 // Arg0: index of the token of the instanceof test (source location). | 541 // Arg0: node id of the instanceof node. |
| 525 // Arg1: node id of the instanceof node. | 542 // Arg1: instance being checked. |
| 526 // Arg2: instance being checked. | 543 // Arg2: type. |
| 527 // Arg3: type. | 544 // Arg3: instantiator (or null). |
| 528 // Arg4: instantiator (or null). | 545 // Arg4: type arguments of the instantiator of the type. |
| 529 // Arg5: type arguments of the instantiator of the type. | 546 // Arg5: SubtypeTestCache. |
| 530 // Arg6: SubtypeTestCache. | |
| 531 // Return value: true or false, or may throw a type error in checked mode. | 547 // Return value: true or false, or may throw a type error in checked mode. |
| 532 DEFINE_RUNTIME_ENTRY(Instanceof, 7) { | 548 DEFINE_RUNTIME_ENTRY(Instanceof, 6) { |
| 533 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count()); | 549 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count()); |
| 534 // TODO(regis): Get the token index from the PcDesc (via DartFrame). | 550 intptr_t node_id = Smi::CheckedHandle(arguments.At(0)).Value(); |
| 535 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); | 551 const Instance& instance = Instance::CheckedHandle(arguments.At(1)); |
| 536 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value(); | 552 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(2)); |
| 537 const Instance& instance = Instance::CheckedHandle(arguments.At(2)); | 553 const Instance& instantiator = Instance::CheckedHandle(arguments.At(3)); |
| 538 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(3)); | |
| 539 const Instance& instantiator = Instance::CheckedHandle(arguments.At(4)); | |
| 540 const AbstractTypeArguments& instantiator_type_arguments = | 554 const AbstractTypeArguments& instantiator_type_arguments = |
| 541 AbstractTypeArguments::CheckedHandle(arguments.At(5)); | 555 AbstractTypeArguments::CheckedHandle(arguments.At(4)); |
| 542 const SubtypeTestCache& cache = | 556 const SubtypeTestCache& cache = |
| 543 SubtypeTestCache::CheckedHandle(arguments.At(6)); | 557 SubtypeTestCache::CheckedHandle(arguments.At(5)); |
| 544 ASSERT(type.IsFinalized()); | 558 ASSERT(type.IsFinalized()); |
| 545 Error& malformed_error = Error::Handle(); | 559 Error& malformed_error = Error::Handle(); |
| 546 const Bool& result = Bool::Handle( | 560 const Bool& result = Bool::Handle( |
| 547 instance.IsInstanceOf(type, | 561 instance.IsInstanceOf(type, |
| 548 instantiator_type_arguments, | 562 instantiator_type_arguments, |
| 549 &malformed_error) ? | 563 &malformed_error) ? |
| 550 Bool::True() : Bool::False()); | 564 Bool::True() : Bool::False()); |
| 551 if (FLAG_trace_type_checks) { | 565 if (FLAG_trace_type_checks) { |
| 552 PrintTypeCheck("InstanceOf", | 566 PrintTypeCheck("InstanceOf", |
| 553 instance, type, instantiator_type_arguments, result); | 567 instance, type, instantiator_type_arguments, result); |
| 554 } | 568 } |
| 555 if (!result.value() && !malformed_error.IsNull()) { | 569 if (!result.value() && !malformed_error.IsNull()) { |
| 556 // Throw a dynamic type error only if the instanceof test fails. | 570 // Throw a dynamic type error only if the instanceof test fails. |
| 571 const intptr_t location = GetCallerLocation(); |
| 557 String& malformed_error_message = String::Handle( | 572 String& malformed_error_message = String::Handle( |
| 558 String::New(malformed_error.ToErrorCString())); | 573 String::New(malformed_error.ToErrorCString())); |
| 559 const String& no_name = String::Handle(String::NewSymbol("")); | 574 const String& no_name = String::Handle(String::NewSymbol("")); |
| 560 Exceptions::CreateAndThrowTypeError( | 575 Exceptions::CreateAndThrowTypeError( |
| 561 location, no_name, no_name, no_name, malformed_error_message); | 576 location, no_name, no_name, no_name, malformed_error_message); |
| 562 UNREACHABLE(); | 577 UNREACHABLE(); |
| 563 } | 578 } |
| 564 UpdateTypeTestCache(node_id, instance, type, instantiator, | 579 UpdateTypeTestCache(node_id, instance, type, instantiator, |
| 565 instantiator_type_arguments, result, cache); | 580 instantiator_type_arguments, result, cache); |
| 566 arguments.SetReturn(result); | 581 arguments.SetReturn(result); |
| 567 } | 582 } |
| 568 | 583 |
| 569 | 584 |
| 570 // For error reporting simplify type name, e.g, all integer types (Smi, Mint, | 585 // For error reporting simplify type name, e.g, all integer types (Smi, Mint, |
| 571 // Bigint) a re reported as 'int'. | 586 // Bigint) a re reported as 'int'. |
| 572 static RawString* GetSimpleTypeName(const Instance& value) { | 587 static RawString* GetSimpleTypeName(const Instance& value) { |
| 573 if (value.IsInteger()) { | 588 if (value.IsInteger()) { |
| 574 return String::NewSymbol("int"); | 589 return String::NewSymbol("int"); |
| 575 } else { | 590 } else { |
| 576 return Type::Handle(value.GetType()).Name(); | 591 return Type::Handle(value.GetType()).Name(); |
| 577 } | 592 } |
| 578 } | 593 } |
| 579 | 594 |
| 580 | 595 |
| 581 // Check that the type of the given instance is a subtype of the given type and | 596 // Check that the type of the given instance is a subtype of the given type and |
| 582 // can therefore be assigned. | 597 // can therefore be assigned. |
| 583 // Arg0: index of the token of the assignment (source location). | 598 // Arg0: node-id of the assignment. |
| 584 // Arg1: node-id of the assignment. | 599 // Arg1: instance being assigned. |
| 585 // Arg2: instance being assigned. | 600 // Arg2: type being assigned to. |
| 586 // Arg3: type being assigned to. | 601 // Arg3: instantiator (or null). |
| 587 // Arg4: instantiator (or null). | 602 // Arg4: type arguments of the instantiator of the type being assigned to. |
| 588 // Arg5: type arguments of the instantiator of the type being assigned to. | 603 // Arg5: name of variable being assigned to. |
| 589 // Arg6: name of variable being assigned to. | 604 // Arg6: SubtypeTestCache. |
| 590 // Arg7: SubtypeTestCache. | |
| 591 // Return value: instance if a subtype, otherwise throw a TypeError. | 605 // Return value: instance if a subtype, otherwise throw a TypeError. |
| 592 DEFINE_RUNTIME_ENTRY(TypeCheck, 8) { | 606 DEFINE_RUNTIME_ENTRY(TypeCheck, 7) { |
| 593 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); | 607 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); |
| 594 // TODO(regis): Get the token index from the PcDesc (via DartFrame). | 608 intptr_t node_id = Smi::CheckedHandle(arguments.At(0)).Value(); |
| 595 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); | 609 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); |
| 596 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value(); | 610 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(2)); |
| 597 const Instance& src_instance = Instance::CheckedHandle(arguments.At(2)); | 611 const Instance& dst_instantiator = Instance::CheckedHandle(arguments.At(3)); |
| 598 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(3)); | |
| 599 const Instance& dst_instantiator = Instance::CheckedHandle(arguments.At(4)); | |
| 600 const AbstractTypeArguments& instantiator_type_arguments = | 612 const AbstractTypeArguments& instantiator_type_arguments = |
| 601 AbstractTypeArguments::CheckedHandle(arguments.At(5)); | 613 AbstractTypeArguments::CheckedHandle(arguments.At(4)); |
| 602 const String& dst_name = String::CheckedHandle(arguments.At(6)); | 614 const String& dst_name = String::CheckedHandle(arguments.At(5)); |
| 603 const SubtypeTestCache& cache = | 615 const SubtypeTestCache& cache = |
| 604 SubtypeTestCache::CheckedHandle(arguments.At(7)); | 616 SubtypeTestCache::CheckedHandle(arguments.At(6)); |
| 605 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. | 617 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. |
| 606 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. | 618 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. |
| 607 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. | 619 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. |
| 608 | 620 |
| 609 Error& malformed_error = Error::Handle(); | 621 Error& malformed_error = Error::Handle(); |
| 610 const bool is_instance_of = src_instance.IsInstanceOf( | 622 const bool is_instance_of = src_instance.IsInstanceOf( |
| 611 dst_type, instantiator_type_arguments, &malformed_error); | 623 dst_type, instantiator_type_arguments, &malformed_error); |
| 612 | 624 |
| 613 if (FLAG_trace_type_checks) { | 625 if (FLAG_trace_type_checks) { |
| 614 PrintTypeCheck("TypeCheck", | 626 PrintTypeCheck("TypeCheck", |
| 615 src_instance, dst_type, instantiator_type_arguments, | 627 src_instance, dst_type, instantiator_type_arguments, |
| 616 Bool::Handle(is_instance_of ? Bool::True() : Bool::False())); | 628 Bool::Handle(is_instance_of ? Bool::True() : Bool::False())); |
| 617 } | 629 } |
| 618 if (!is_instance_of) { | 630 if (!is_instance_of) { |
| 631 // Throw a dynamic type error. |
| 632 const intptr_t location = GetCallerLocation(); |
| 619 String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); | 633 String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); |
| 620 String& dst_type_name = String::Handle(); | 634 String& dst_type_name = String::Handle(); |
| 621 if (!dst_type.IsInstantiated()) { | 635 if (!dst_type.IsInstantiated()) { |
| 622 // Instantiate dst_type before reporting the error. | 636 // Instantiate dst_type before reporting the error. |
| 623 const AbstractType& instantiated_dst_type = AbstractType::Handle( | 637 const AbstractType& instantiated_dst_type = AbstractType::Handle( |
| 624 dst_type.InstantiateFrom(instantiator_type_arguments)); | 638 dst_type.InstantiateFrom(instantiator_type_arguments)); |
| 625 dst_type_name = instantiated_dst_type.Name(); | 639 dst_type_name = instantiated_dst_type.Name(); |
| 626 } else { | 640 } else { |
| 627 dst_type_name = dst_type.Name(); | 641 dst_type_name = dst_type.Name(); |
| 628 } | 642 } |
| 629 String& malformed_error_message = String::Handle(); | 643 String& malformed_error_message = String::Handle(); |
| 630 if (!malformed_error.IsNull()) { | 644 if (!malformed_error.IsNull()) { |
| 631 ASSERT(FLAG_enable_type_checks); | 645 ASSERT(FLAG_enable_type_checks); |
| 632 malformed_error_message = String::New(malformed_error.ToErrorCString()); | 646 malformed_error_message = String::New(malformed_error.ToErrorCString()); |
| 633 } | 647 } |
| 634 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, | 648 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, |
| 635 dst_name, malformed_error_message); | 649 dst_name, malformed_error_message); |
| 636 UNREACHABLE(); | 650 UNREACHABLE(); |
| 637 } | 651 } |
| 638 UpdateTypeTestCache(node_id, src_instance, dst_type, | 652 UpdateTypeTestCache(node_id, src_instance, dst_type, |
| 639 dst_instantiator, instantiator_type_arguments, | 653 dst_instantiator, instantiator_type_arguments, |
| 640 Bool::ZoneHandle(Bool::True()), cache); | 654 Bool::ZoneHandle(Bool::True()), cache); |
| 641 arguments.SetReturn(src_instance); | 655 arguments.SetReturn(src_instance); |
| 642 } | 656 } |
| 643 | 657 |
| 644 | 658 |
| 645 // Report that the type of the given object is not bool in conditional context. | 659 // Report that the type of the given object is not bool in conditional context. |
| 646 // Arg0: index of the token of the assignment (source location). | 660 // Arg0: bad object. |
| 647 // Arg1: bad object. | |
| 648 // Return value: none, throws a TypeError. | 661 // Return value: none, throws a TypeError. |
| 649 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { | 662 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { |
| 650 ASSERT(arguments.Count() == | 663 ASSERT(arguments.Count() == |
| 651 kConditionTypeErrorRuntimeEntry.argument_count()); | 664 kConditionTypeErrorRuntimeEntry.argument_count()); |
| 652 // TODO(regis): Get the token index from the PcDesc (via DartFrame). | 665 const intptr_t location = GetCallerLocation(); |
| 653 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); | 666 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0)); |
| 654 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); | |
| 655 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); | 667 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); |
| 656 const Type& bool_interface = Type::Handle(Type::BoolInterface()); | 668 const Type& bool_interface = Type::Handle(Type::BoolInterface()); |
| 657 const String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); | 669 const String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); |
| 658 const String& bool_type_name = String::Handle(bool_interface.Name()); | 670 const String& bool_type_name = String::Handle(bool_interface.Name()); |
| 659 const String& expr = String::Handle(String::NewSymbol("boolean expression")); | 671 const String& expr = String::Handle(String::NewSymbol("boolean expression")); |
| 660 const String& no_malformed_type_error = String::Handle(); | 672 const String& no_malformed_type_error = String::Handle(); |
| 661 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, | 673 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, |
| 662 expr, no_malformed_type_error); | 674 expr, no_malformed_type_error); |
| 663 UNREACHABLE(); | 675 UNREACHABLE(); |
| 664 } | 676 } |
| 665 | 677 |
| 666 | 678 |
| 667 // Report that the type of the type check is malformed. | 679 // Report that the type of the type check is malformed. |
| 668 // Arg0: index of the token of the failed type check. | 680 // Arg0: src value. |
| 669 // Arg1: src value. | 681 // Arg1: name of instance being assigned to. |
| 670 // Arg2: name of instance being assigned to. | 682 // Arg2: malformed type error message. |
| 671 // Arg3: malformed type error message. | |
| 672 // Return value: none, throws an exception. | 683 // Return value: none, throws an exception. |
| 673 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 4) { | 684 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { |
| 674 ASSERT(arguments.Count() == | 685 ASSERT(arguments.Count() == |
| 675 kMalformedTypeErrorRuntimeEntry.argument_count()); | 686 kMalformedTypeErrorRuntimeEntry.argument_count()); |
| 676 // TODO(regis): Get the token index from the PcDesc (via DartFrame). | 687 const intptr_t location = GetCallerLocation(); |
| 677 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); | 688 const Instance& src_value = Instance::CheckedHandle(arguments.At(0)); |
| 678 const Instance& src_value = Instance::CheckedHandle(arguments.At(1)); | 689 const String& dst_name = String::CheckedHandle(arguments.At(1)); |
| 679 const String& dst_name = String::CheckedHandle(arguments.At(2)); | 690 const String& malformed_error = String::CheckedHandle(arguments.At(2)); |
| 680 const String& malformed_error = String::CheckedHandle(arguments.At(3)); | |
| 681 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); | 691 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); |
| 682 const String& src_type_name = String::Handle(GetSimpleTypeName(src_value)); | 692 const String& src_type_name = String::Handle(GetSimpleTypeName(src_value)); |
| 683 Exceptions::CreateAndThrowTypeError(location, src_type_name, | 693 Exceptions::CreateAndThrowTypeError(location, src_type_name, |
| 684 dst_type_name, dst_name, malformed_error); | 694 dst_type_name, dst_name, malformed_error); |
| 685 UNREACHABLE(); | 695 UNREACHABLE(); |
| 686 } | 696 } |
| 687 | 697 |
| 688 | 698 |
| 689 DEFINE_RUNTIME_ENTRY(Throw, 1) { | 699 DEFINE_RUNTIME_ENTRY(Throw, 1) { |
| 690 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); | 700 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); |
| (...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1522 } | 1532 } |
| 1523 } | 1533 } |
| 1524 } | 1534 } |
| 1525 // The cache is null terminated, therefore the loop above should never | 1535 // The cache is null terminated, therefore the loop above should never |
| 1526 // terminate by itself. | 1536 // terminate by itself. |
| 1527 UNREACHABLE(); | 1537 UNREACHABLE(); |
| 1528 return Code::null(); | 1538 return Code::null(); |
| 1529 } | 1539 } |
| 1530 | 1540 |
| 1531 } // namespace dart | 1541 } // namespace dart |
| OLD | NEW |