Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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.h" | 7 #include "vm/assembler.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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 // Check that the type of the given instance is a subtype of the given type and | 487 // Check that the type of the given instance is a subtype of the given type and |
| 488 // can therefore be assigned. | 488 // can therefore be assigned. |
| 489 // Arg0: instance being assigned. | 489 // Arg0: instance being assigned. |
| 490 // Arg1: type being assigned to. | 490 // Arg1: type being assigned to. |
| 491 // Arg2: type arguments of the instantiator of the type being assigned to. | 491 // Arg2: type arguments of the instantiator of the type being assigned to. |
| 492 // Arg3: name of variable being assigned to. | 492 // Arg3: name of variable being assigned to. |
| 493 // Arg4: SubtypeTestCache. | 493 // Arg4: SubtypeTestCache. |
| 494 // Return value: instance if a subtype, otherwise throw a TypeError. | 494 // Return value: instance if a subtype, otherwise throw a TypeError. |
| 495 DEFINE_RUNTIME_ENTRY(TypeCheck, 5) { | 495 DEFINE_RUNTIME_ENTRY(TypeCheck, 5) { |
| 496 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); | 496 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 497 const AbstractType& dst_type = | 497 AbstractType& dst_type = AbstractType::CheckedHandle(arguments.ArgAt(1)); |
| 498 AbstractType::CheckedHandle(arguments.ArgAt(1)); | |
| 499 const TypeArguments& instantiator_type_arguments = | 498 const TypeArguments& instantiator_type_arguments = |
| 500 TypeArguments::CheckedHandle(arguments.ArgAt(2)); | 499 TypeArguments::CheckedHandle(arguments.ArgAt(2)); |
| 501 const String& dst_name = String::CheckedHandle(arguments.ArgAt(3)); | 500 const String& dst_name = String::CheckedHandle(arguments.ArgAt(3)); |
| 502 const SubtypeTestCache& cache = | 501 const SubtypeTestCache& cache = |
| 503 SubtypeTestCache::CheckedHandle(arguments.ArgAt(4)); | 502 SubtypeTestCache::CheckedHandle(arguments.ArgAt(4)); |
| 504 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. | 503 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. |
| 505 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. | 504 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. |
| 506 ASSERT(!dst_type.IsMalbounded()); // Already checked in code generator. | 505 ASSERT(!dst_type.IsMalbounded()); // Already checked in code generator. |
| 507 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. | 506 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. |
| 508 | 507 |
| 509 Error& bound_error = Error::Handle(); | 508 Error& bound_error = Error::Handle(); |
| 510 const bool is_instance_of = src_instance.IsInstanceOf( | 509 const bool is_instance_of = src_instance.IsInstanceOf( |
| 511 dst_type, instantiator_type_arguments, &bound_error); | 510 dst_type, instantiator_type_arguments, &bound_error); |
| 512 | 511 |
| 513 if (FLAG_trace_type_checks) { | 512 if (FLAG_trace_type_checks) { |
| 514 PrintTypeCheck("TypeCheck", | 513 PrintTypeCheck("TypeCheck", |
| 515 src_instance, dst_type, instantiator_type_arguments, | 514 src_instance, dst_type, instantiator_type_arguments, |
| 516 Bool::Get(is_instance_of)); | 515 Bool::Get(is_instance_of)); |
| 517 } | 516 } |
| 518 if (!is_instance_of) { | 517 if (!is_instance_of) { |
| 519 // Throw a dynamic type error. | 518 // Throw a dynamic type error. |
| 520 const TokenPosition location = GetCallerLocation(); | 519 const TokenPosition location = GetCallerLocation(); |
| 521 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); | 520 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); |
| 522 String& src_type_name = String::Handle(src_type.UserVisibleName()); | 521 String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 523 String& dst_type_name = String::Handle(); | |
| 524 Library& dst_type_lib = Library::Handle(); | |
| 525 if (!dst_type.IsInstantiated()) { | 522 if (!dst_type.IsInstantiated()) { |
| 526 // Instantiate dst_type before reporting the error. | 523 // Instantiate dst_type before reporting the error. |
| 527 const AbstractType& instantiated_dst_type = AbstractType::Handle( | 524 dst_type = dst_type.InstantiateFrom(instantiator_type_arguments, NULL, |
| 528 dst_type.InstantiateFrom(instantiator_type_arguments, NULL, | 525 NULL, NULL, Heap::kNew); |
| 529 NULL, NULL, Heap::kNew)); | 526 // Note that instantiated dst_type may be malbounded. |
| 530 // Note that instantiated_dst_type may be malbounded. | |
| 531 dst_type_name = instantiated_dst_type.UserVisibleName(); | |
| 532 dst_type_lib = | |
| 533 Class::Handle(instantiated_dst_type.type_class()).library(); | |
| 534 } else { | |
| 535 dst_type_name = dst_type.UserVisibleName(); | |
| 536 dst_type_lib = Class::Handle(dst_type.type_class()).library(); | |
| 537 } | 527 } |
| 528 String& dst_type_name = String::Handle(dst_type.UserVisibleName()); | |
|
srdjan
2016/02/26 17:54:16
const String
| |
| 538 String& bound_error_message = String::Handle(); | 529 String& bound_error_message = String::Handle(); |
| 539 if (!bound_error.IsNull()) { | 530 if (!bound_error.IsNull()) { |
| 540 ASSERT(isolate->type_checks()); | 531 ASSERT(isolate->type_checks()); |
| 541 bound_error_message = String::New(bound_error.ToErrorCString()); | 532 bound_error_message = String::New(bound_error.ToErrorCString()); |
| 542 } | 533 } |
|
srdjan
2016/02/26 17:54:15
I would still report something special when both s
| |
| 543 if (src_type_name.Equals(dst_type_name)) { | |
| 544 // Qualify the names with their libraries. | |
| 545 String& lib_name = String::Handle(); | |
| 546 lib_name = Library::Handle( | |
| 547 Class::Handle(src_type.type_class()).library()).name(); | |
| 548 if (lib_name.Length() != 0) { | |
| 549 lib_name = String::Concat(lib_name, Symbols::Dot()); | |
| 550 src_type_name = String::Concat(lib_name, src_type_name); | |
| 551 } | |
| 552 lib_name = dst_type_lib.name(); | |
| 553 if (lib_name.Length() != 0) { | |
| 554 lib_name = String::Concat(lib_name, Symbols::Dot()); | |
| 555 dst_type_name = String::Concat(lib_name, dst_type_name); | |
| 556 } | |
| 557 } | |
| 558 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, | 534 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, |
| 559 dst_name, bound_error_message); | 535 dst_name, bound_error_message); |
| 560 UNREACHABLE(); | 536 UNREACHABLE(); |
| 561 } | 537 } |
| 562 UpdateTypeTestCache( | 538 UpdateTypeTestCache( |
| 563 src_instance, dst_type, instantiator_type_arguments, Bool::True(), cache); | 539 src_instance, dst_type, instantiator_type_arguments, Bool::True(), cache); |
| 564 arguments.SetReturn(src_instance); | 540 arguments.SetReturn(src_instance); |
| 565 } | 541 } |
| 566 | 542 |
| 567 | 543 |
| (...skipping 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1894 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 1870 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
| 1895 const TypedData& new_data = | 1871 const TypedData& new_data = |
| 1896 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 1872 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
| 1897 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 1873 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
| 1898 typed_data_cell.SetAt(0, new_data); | 1874 typed_data_cell.SetAt(0, new_data); |
| 1899 arguments.SetReturn(new_data); | 1875 arguments.SetReturn(new_data); |
| 1900 } | 1876 } |
| 1901 | 1877 |
| 1902 | 1878 |
| 1903 } // namespace dart | 1879 } // namespace dart |
| OLD | NEW |