| 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/code_patcher.h" | 7 #include "vm/code_patcher.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 return String::NewSymbol("int"); | 404 return String::NewSymbol("int"); |
| 405 } else { | 405 } else { |
| 406 return Type::Handle(value.GetType()).Name(); | 406 return Type::Handle(value.GetType()).Name(); |
| 407 } | 407 } |
| 408 } | 408 } |
| 409 | 409 |
| 410 | 410 |
| 411 // Check that the type of the given instance is a subtype of the given type and | 411 // Check that the type of the given instance is a subtype of the given type and |
| 412 // can therefore be assigned. | 412 // can therefore be assigned. |
| 413 // Arg0: index of the token of the assignment (source location). | 413 // Arg0: index of the token of the assignment (source location). |
| 414 // Arg1: node-id of the assignemnt. |
| 414 // Arg1: instance being assigned. | 415 // Arg1: instance being assigned. |
| 415 // Arg2: type being assigned to. | 416 // Arg2: type being assigned to. |
| 416 // Arg3: type arguments of the instantiator of the type being assigned to. | 417 // Arg3: type arguments of the instantiator of the type being assigned to. |
| 417 // Arg4: name of variable being assigned to. | 418 // Arg4: name of variable being assigned to. |
| 418 // Return value: instance if a subtype, otherwise throw a TypeError. | 419 // Return value: instance if a subtype, otherwise throw a TypeError. |
| 419 DEFINE_RUNTIME_ENTRY(TypeCheck, 5) { | 420 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) { |
| 420 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); | 421 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); |
| 421 // TODO(regis): Get the token index from the PcDesc (via DartFrame). | 422 // TODO(regis): Get the token index from the PcDesc (via DartFrame). |
| 422 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); | 423 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); |
| 423 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); | 424 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value(); |
| 424 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(2)); | 425 const Instance& src_instance = Instance::CheckedHandle(arguments.At(2)); |
| 426 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(3)); |
| 425 const AbstractTypeArguments& dst_type_instantiator = | 427 const AbstractTypeArguments& dst_type_instantiator = |
| 426 AbstractTypeArguments::CheckedHandle(arguments.At(3)); | 428 AbstractTypeArguments::CheckedHandle(arguments.At(4)); |
| 427 const String& dst_name = String::CheckedHandle(arguments.At(4)); | 429 const String& dst_name = String::CheckedHandle(arguments.At(5)); |
| 428 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. | 430 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. |
| 429 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. | 431 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. |
| 430 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. | 432 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. |
| 431 | 433 |
| 432 Error& malformed_error = Error::Handle(); | 434 Error& malformed_error = Error::Handle(); |
| 433 const bool is_instance_of = src_instance.IsInstanceOf( | 435 const bool is_instance_of = src_instance.IsInstanceOf( |
| 434 dst_type, dst_type_instantiator, &malformed_error); | 436 dst_type, dst_type_instantiator, &malformed_error); |
| 435 | 437 |
| 436 if (FLAG_trace_type_checks) { | 438 if (FLAG_trace_type_checks) { |
| 437 const Type& src_type = Type::Handle(src_instance.GetType()); | 439 const Type& src_type = Type::Handle(src_instance.GetType()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 } | 476 } |
| 475 String& malformed_error_message = String::Handle(); | 477 String& malformed_error_message = String::Handle(); |
| 476 if (!malformed_error.IsNull()) { | 478 if (!malformed_error.IsNull()) { |
| 477 ASSERT(FLAG_enable_type_checks); | 479 ASSERT(FLAG_enable_type_checks); |
| 478 malformed_error_message = String::New(malformed_error.ToErrorCString()); | 480 malformed_error_message = String::New(malformed_error.ToErrorCString()); |
| 479 } | 481 } |
| 480 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, | 482 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, |
| 481 dst_name, malformed_error_message); | 483 dst_name, malformed_error_message); |
| 482 UNREACHABLE(); | 484 UNREACHABLE(); |
| 483 } | 485 } |
| 486 // Update cache: add class of instance and result. |
| 487 if (dst_type.IsInstantiated() && |
| 488 !Class::Handle(dst_type.type_class()).HasTypeArguments()) { |
| 489 DartFrameIterator iterator; |
| 490 DartFrame* caller_frame = iterator.NextFrame(); |
| 491 ASSERT(caller_frame != NULL); |
| 492 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 493 ASSERT(!code.IsNull()); |
| 494 uword loc = code.GetTypeTestAtNodeId(node_id); |
| 495 if (loc != 0) { |
| 496 // Found type test cache. |
| 497 Array& value = Array::Handle(CodePatcher::GetTypeTestArray(loc)); |
| 498 const Class& src_instance_class = Class::Handle(src_instance.clazz()); |
| 499 |
| 500 #if defined(DEBUG) |
| 501 // Check for duplicate entries. |
| 502 Class& last_checked = Class::Handle(); |
| 503 for (intptr_t i = 0; i < value.Length(); i += 2) { |
| 504 last_checked ^= value.At(i); |
| 505 ASSERT(last_checked.raw() != src_instance_class.raw()); |
| 506 } |
| 507 // Array must be null terminated. |
| 508 ASSERT(last_checked.IsNull()); |
| 509 #endif |
| 510 |
| 511 ASSERT(!value.IsNull()); |
| 512 intptr_t old_len = value.Length(); |
| 513 value = value.Grow(value, old_len + 2); |
| 514 value.SetAt(old_len - 2, src_instance_class); |
| 515 value.SetAt(old_len - 1, Bool::ZoneHandle(Bool::True())); |
| 516 CodePatcher::SetTypeTestArray(loc, value); |
| 517 } |
| 518 } |
| 484 arguments.SetReturn(src_instance); | 519 arguments.SetReturn(src_instance); |
| 485 } | 520 } |
| 486 | 521 |
| 487 | 522 |
| 488 // Report that the type of the given object is not bool in conditional context. | 523 // Report that the type of the given object is not bool in conditional context. |
| 489 // Arg0: index of the token of the assignment (source location). | 524 // Arg0: index of the token of the assignment (source location). |
| 490 // Arg1: bad object. | 525 // Arg1: bad object. |
| 491 // Return value: none, throws a TypeError. | 526 // Return value: none, throws a TypeError. |
| 492 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { | 527 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { |
| 493 ASSERT(arguments.Count() == | 528 ASSERT(arguments.Count() == |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 } | 1429 } |
| 1395 } | 1430 } |
| 1396 } | 1431 } |
| 1397 // The cache is null terminated, therefore the loop above should never | 1432 // The cache is null terminated, therefore the loop above should never |
| 1398 // terminate by itself. | 1433 // terminate by itself. |
| 1399 UNREACHABLE(); | 1434 UNREACHABLE(); |
| 1400 return Code::null(); | 1435 return Code::null(); |
| 1401 } | 1436 } |
| 1402 | 1437 |
| 1403 } // namespace dart | 1438 } // namespace dart |
| OLD | NEW |