| 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. | |
| 416 // Arg1: instance being assigned. | 415 // Arg1: instance being assigned. |
| 417 // Arg2: type being assigned to. | 416 // Arg2: type being assigned to. |
| 418 // 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. |
| 419 // Arg4: name of variable being assigned to. | 418 // Arg4: name of variable being assigned to. |
| 420 // Return value: instance if a subtype, otherwise throw a TypeError. | 419 // Return value: instance if a subtype, otherwise throw a TypeError. |
| 421 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) { | 420 DEFINE_RUNTIME_ENTRY(TypeCheck, 5) { |
| 422 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); | 421 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); |
| 423 // TODO(regis): Get the token index from the PcDesc (via DartFrame). | 422 // TODO(regis): Get the token index from the PcDesc (via DartFrame). |
| 424 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); | 423 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); |
| 425 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value(); | 424 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); |
| 426 const Instance& src_instance = Instance::CheckedHandle(arguments.At(2)); | 425 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(2)); |
| 427 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(3)); | |
| 428 const AbstractTypeArguments& dst_type_instantiator = | 426 const AbstractTypeArguments& dst_type_instantiator = |
| 429 AbstractTypeArguments::CheckedHandle(arguments.At(4)); | 427 AbstractTypeArguments::CheckedHandle(arguments.At(3)); |
| 430 const String& dst_name = String::CheckedHandle(arguments.At(5)); | 428 const String& dst_name = String::CheckedHandle(arguments.At(4)); |
| 431 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. | 429 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. |
| 432 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. | 430 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. |
| 433 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. | 431 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. |
| 434 | 432 |
| 435 Error& malformed_error = Error::Handle(); | 433 Error& malformed_error = Error::Handle(); |
| 436 const bool is_instance_of = src_instance.IsInstanceOf( | 434 const bool is_instance_of = src_instance.IsInstanceOf( |
| 437 dst_type, dst_type_instantiator, &malformed_error); | 435 dst_type, dst_type_instantiator, &malformed_error); |
| 438 | 436 |
| 439 if (FLAG_trace_type_checks) { | 437 if (FLAG_trace_type_checks) { |
| 440 const Type& src_type = Type::Handle(src_instance.GetType()); | 438 const Type& src_type = Type::Handle(src_instance.GetType()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 } | 475 } |
| 478 String& malformed_error_message = String::Handle(); | 476 String& malformed_error_message = String::Handle(); |
| 479 if (!malformed_error.IsNull()) { | 477 if (!malformed_error.IsNull()) { |
| 480 ASSERT(FLAG_enable_type_checks); | 478 ASSERT(FLAG_enable_type_checks); |
| 481 malformed_error_message = String::New(malformed_error.ToErrorCString()); | 479 malformed_error_message = String::New(malformed_error.ToErrorCString()); |
| 482 } | 480 } |
| 483 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, | 481 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, |
| 484 dst_name, malformed_error_message); | 482 dst_name, malformed_error_message); |
| 485 UNREACHABLE(); | 483 UNREACHABLE(); |
| 486 } | 484 } |
| 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 } | |
| 520 arguments.SetReturn(src_instance); | 485 arguments.SetReturn(src_instance); |
| 521 } | 486 } |
| 522 | 487 |
| 523 | 488 |
| 524 // Report that the type of the given object is not bool in conditional context. | 489 // Report that the type of the given object is not bool in conditional context. |
| 525 // Arg0: index of the token of the assignment (source location). | 490 // Arg0: index of the token of the assignment (source location). |
| 526 // Arg1: bad object. | 491 // Arg1: bad object. |
| 527 // Return value: none, throws a TypeError. | 492 // Return value: none, throws a TypeError. |
| 528 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { | 493 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { |
| 529 ASSERT(arguments.Count() == | 494 ASSERT(arguments.Count() == |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1430 } | 1395 } |
| 1431 } | 1396 } |
| 1432 } | 1397 } |
| 1433 // The cache is null terminated, therefore the loop above should never | 1398 // The cache is null terminated, therefore the loop above should never |
| 1434 // terminate by itself. | 1399 // terminate by itself. |
| 1435 UNREACHABLE(); | 1400 UNREACHABLE(); |
| 1436 return Code::null(); | 1401 return Code::null(); |
| 1437 } | 1402 } |
| 1438 | 1403 |
| 1439 } // namespace dart | 1404 } // namespace dart |
| OLD | NEW |