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