| 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/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 ASSERT(arguments.ArgCount() == | 174 ASSERT(arguments.ArgCount() == |
| 175 kAllocateObjectWithBoundsCheckRuntimeEntry.argument_count()); | 175 kAllocateObjectWithBoundsCheckRuntimeEntry.argument_count()); |
| 176 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); | 176 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); |
| 177 const Instance& instance = Instance::Handle(Instance::New(cls)); | 177 const Instance& instance = Instance::Handle(Instance::New(cls)); |
| 178 arguments.SetReturn(instance); | 178 arguments.SetReturn(instance); |
| 179 ASSERT(cls.HasTypeArguments()); | 179 ASSERT(cls.HasTypeArguments()); |
| 180 AbstractTypeArguments& type_arguments = | 180 AbstractTypeArguments& type_arguments = |
| 181 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); | 181 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 182 ASSERT(type_arguments.IsNull() || | 182 ASSERT(type_arguments.IsNull() || |
| 183 (type_arguments.Length() == cls.NumTypeArguments())); | 183 (type_arguments.Length() == cls.NumTypeArguments())); |
| 184 AbstractTypeArguments& bounds_instantiator = AbstractTypeArguments::Handle(); | |
| 185 if (Object::Handle(arguments.ArgAt(2)).IsSmi()) { | 184 if (Object::Handle(arguments.ArgAt(2)).IsSmi()) { |
| 186 ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() == | 185 ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() == |
| 187 StubCode::kNoInstantiator); | 186 StubCode::kNoInstantiator); |
| 188 } else { | 187 } else { |
| 189 ASSERT(!type_arguments.IsInstantiated()); | 188 ASSERT(!type_arguments.IsInstantiated()); |
| 190 const AbstractTypeArguments& instantiator = | 189 const AbstractTypeArguments& instantiator = |
| 191 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2)); | 190 AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2)); |
| 192 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | 191 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
| 192 Error& malformed_error = Error::Handle(); |
| 193 if (instantiator.IsNull()) { | 193 if (instantiator.IsNull()) { |
| 194 type_arguments = | 194 type_arguments = type_arguments.InstantiateFrom(instantiator, |
| 195 InstantiatedTypeArguments::New(type_arguments, instantiator); | 195 &malformed_error); |
| 196 } else if (instantiator.IsTypeArguments()) { | 196 } else if (instantiator.IsTypeArguments()) { |
| 197 // Code inlined in the caller should have optimized the case where the | 197 // Code inlined in the caller should have optimized the case where the |
| 198 // instantiator is a TypeArguments and can be used as type argument | 198 // instantiator is a TypeArguments and can be used as type argument |
| 199 // vector. | 199 // vector. |
| 200 ASSERT(!type_arguments.IsUninstantiatedIdentity() || | 200 ASSERT(!type_arguments.IsUninstantiatedIdentity() || |
| 201 (instantiator.Length() != type_arguments.Length())); | 201 (instantiator.Length() != type_arguments.Length())); |
| 202 type_arguments = | 202 type_arguments = type_arguments.InstantiateFrom(instantiator, |
| 203 InstantiatedTypeArguments::New(type_arguments, instantiator); | 203 &malformed_error); |
| 204 } else { | 204 } else { |
| 205 // If possible, use the instantiator as the type argument vector. | 205 // If possible, use the instantiator as the type argument vector. |
| 206 if (type_arguments.IsUninstantiatedIdentity() && | 206 if (type_arguments.IsUninstantiatedIdentity() && |
| 207 (instantiator.Length() == type_arguments.Length())) { | 207 (instantiator.Length() == type_arguments.Length())) { |
| 208 type_arguments = instantiator.raw(); | 208 type_arguments = instantiator.raw(); |
| 209 } else { | 209 } else { |
| 210 type_arguments = | 210 type_arguments = type_arguments.InstantiateFrom(instantiator, |
| 211 InstantiatedTypeArguments::New(type_arguments, instantiator); | 211 &malformed_error); |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 bounds_instantiator = instantiator.raw(); | 214 if (!malformed_error.IsNull()) { |
| 215 } | |
| 216 if (!type_arguments.IsNull()) { | |
| 217 ASSERT(type_arguments.IsInstantiated()); | |
| 218 Error& malformed_error = Error::Handle(); | |
| 219 if (!type_arguments.IsWithinBoundsOf(cls, | |
| 220 bounds_instantiator, | |
| 221 &malformed_error)) { | |
| 222 ASSERT(!malformed_error.IsNull()); | |
| 223 // Throw a dynamic type error. | 215 // Throw a dynamic type error. |
| 224 const intptr_t location = GetCallerLocation(); | 216 const intptr_t location = GetCallerLocation(); |
| 225 String& malformed_error_message = String::Handle( | 217 String& malformed_error_message = String::Handle( |
| 226 String::New(malformed_error.ToErrorCString())); | 218 String::New(malformed_error.ToErrorCString())); |
| 227 Exceptions::CreateAndThrowTypeError( | 219 Exceptions::CreateAndThrowTypeError( |
| 228 location, Symbols::Empty(), Symbols::Empty(), | 220 location, Symbols::Empty(), Symbols::Empty(), |
| 229 Symbols::Empty(), malformed_error_message); | 221 Symbols::Empty(), malformed_error_message); |
| 230 UNREACHABLE(); | 222 UNREACHABLE(); |
| 231 } | 223 } |
| 232 } | 224 } |
| 225 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); |
| 233 instance.SetTypeArguments(type_arguments); | 226 instance.SetTypeArguments(type_arguments); |
| 234 } | 227 } |
| 235 | 228 |
| 236 | 229 |
| 237 // Instantiate type arguments. | 230 // Instantiate type arguments. |
| 238 // Arg0: uninstantiated type arguments. | 231 // Arg0: uninstantiated type arguments. |
| 239 // Arg1: instantiator type arguments. | 232 // Arg1: instantiator type arguments. |
| 240 // Return value: instantiated type arguments. | 233 // Return value: instantiated type arguments. |
| 241 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { | 234 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { |
| 242 ASSERT(arguments.ArgCount() == | 235 ASSERT(arguments.ArgCount() == |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 OS::PrintErr("%s: '%s' %"Pd" %s '%s' %"Pd" (pc: %#"Px").\n", | 359 OS::PrintErr("%s: '%s' %"Pd" %s '%s' %"Pd" (pc: %#"Px").\n", |
| 367 message, | 360 message, |
| 368 String::Handle(instance_type.Name()).ToCString(), | 361 String::Handle(instance_type.Name()).ToCString(), |
| 369 Class::Handle(instance_type.type_class()).id(), | 362 Class::Handle(instance_type.type_class()).id(), |
| 370 (result.raw() == Bool::True().raw()) ? "is" : "is !", | 363 (result.raw() == Bool::True().raw()) ? "is" : "is !", |
| 371 String::Handle(type.Name()).ToCString(), | 364 String::Handle(type.Name()).ToCString(), |
| 372 Class::Handle(type.type_class()).id(), | 365 Class::Handle(type.type_class()).id(), |
| 373 caller_frame->pc()); | 366 caller_frame->pc()); |
| 374 } else { | 367 } else { |
| 375 // Instantiate type before printing. | 368 // Instantiate type before printing. |
| 376 const AbstractType& instantiated_type = | 369 Error& malformed_error = Error::Handle(); |
| 377 AbstractType::Handle(type.InstantiateFrom(instantiator_type_arguments)); | 370 const AbstractType& instantiated_type = AbstractType::Handle( |
| 371 type.InstantiateFrom(instantiator_type_arguments, &malformed_error)); |
| 378 OS::PrintErr("%s: '%s' %s '%s' instantiated from '%s' (pc: %#"Px").\n", | 372 OS::PrintErr("%s: '%s' %s '%s' instantiated from '%s' (pc: %#"Px").\n", |
| 379 message, | 373 message, |
| 380 String::Handle(instance_type.Name()).ToCString(), | 374 String::Handle(instance_type.Name()).ToCString(), |
| 381 (result.raw() == Bool::True().raw()) ? "is" : "is !", | 375 (result.raw() == Bool::True().raw()) ? "is" : "is !", |
| 382 String::Handle(instantiated_type.Name()).ToCString(), | 376 String::Handle(instantiated_type.Name()).ToCString(), |
| 383 String::Handle(type.Name()).ToCString(), | 377 String::Handle(type.Name()).ToCString(), |
| 384 caller_frame->pc()); | 378 caller_frame->pc()); |
| 379 if (!malformed_error.IsNull()) { |
| 380 OS::Print(" malformed error: %s\n", malformed_error.ToErrorCString()); |
| 381 } |
| 385 } | 382 } |
| 386 const Function& function = Function::Handle( | 383 const Function& function = Function::Handle( |
| 387 caller_frame->LookupDartFunction()); | 384 caller_frame->LookupDartFunction()); |
| 388 OS::PrintErr(" -> Function %s\n", function.ToFullyQualifiedCString()); | 385 OS::PrintErr(" -> Function %s\n", function.ToFullyQualifiedCString()); |
| 389 } | 386 } |
| 390 | 387 |
| 391 | 388 |
| 392 // Converts InstantiatedTypeArguments to TypeArguments and stores it | 389 // Converts InstantiatedTypeArguments to TypeArguments and stores it |
| 393 // into the instance. The assembly code can handle only type arguments of | 390 // into the instance. The assembly code can handle only type arguments of |
| 394 // class TypeArguments. Because of the overhead, do it only when needed. | 391 // class TypeArguments. Because of the overhead, do it only when needed. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 406 bool replaced = false; | 403 bool replaced = false; |
| 407 if (type_arguments.IsInstantiatedTypeArguments()) { | 404 if (type_arguments.IsInstantiatedTypeArguments()) { |
| 408 AbstractTypeArguments& uninstantiated = AbstractTypeArguments::Handle(); | 405 AbstractTypeArguments& uninstantiated = AbstractTypeArguments::Handle(); |
| 409 AbstractTypeArguments& instantiator = AbstractTypeArguments::Handle(); | 406 AbstractTypeArguments& instantiator = AbstractTypeArguments::Handle(); |
| 410 do { | 407 do { |
| 411 const InstantiatedTypeArguments& instantiated_type_arguments = | 408 const InstantiatedTypeArguments& instantiated_type_arguments = |
| 412 InstantiatedTypeArguments::Cast(type_arguments); | 409 InstantiatedTypeArguments::Cast(type_arguments); |
| 413 uninstantiated = | 410 uninstantiated = |
| 414 instantiated_type_arguments.uninstantiated_type_arguments(); | 411 instantiated_type_arguments.uninstantiated_type_arguments(); |
| 415 instantiator = instantiated_type_arguments.instantiator_type_arguments(); | 412 instantiator = instantiated_type_arguments.instantiator_type_arguments(); |
| 416 type_arguments = uninstantiated.InstantiateFrom(instantiator); | 413 Error& malformed_error = Error::Handle(); |
| 414 type_arguments = uninstantiated.InstantiateFrom(instantiator, |
| 415 &malformed_error); |
| 416 ASSERT(malformed_error.IsNull()); // Malformed types are not optimized. |
| 417 } while (type_arguments.IsInstantiatedTypeArguments()); | 417 } while (type_arguments.IsInstantiatedTypeArguments()); |
| 418 AbstractTypeArguments& new_type_arguments = AbstractTypeArguments::Handle(); | 418 AbstractTypeArguments& new_type_arguments = AbstractTypeArguments::Handle(); |
| 419 new_type_arguments = type_arguments.Canonicalize(); | 419 new_type_arguments = type_arguments.Canonicalize(); |
| 420 instance.SetTypeArguments(new_type_arguments); | 420 instance.SetTypeArguments(new_type_arguments); |
| 421 replaced = true; | 421 replaced = true; |
| 422 } else if (!type_arguments.IsCanonical()) { | 422 } else if (!type_arguments.IsCanonical()) { |
| 423 AbstractTypeArguments& new_type_arguments = AbstractTypeArguments::Handle(); | 423 AbstractTypeArguments& new_type_arguments = AbstractTypeArguments::Handle(); |
| 424 new_type_arguments = type_arguments.Canonicalize(); | 424 new_type_arguments = type_arguments.Canonicalize(); |
| 425 instance.SetTypeArguments(new_type_arguments); | 425 instance.SetTypeArguments(new_type_arguments); |
| 426 replaced = true; | 426 replaced = true; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 } | 509 } |
| 510 if (!instantiator_type_arguments.IsInstantiatedTypeArguments()) { | 510 if (!instantiator_type_arguments.IsInstantiatedTypeArguments()) { |
| 511 new_cache.AddCheck(instance_class.id(), | 511 new_cache.AddCheck(instance_class.id(), |
| 512 instance_type_arguments, | 512 instance_type_arguments, |
| 513 instantiator_type_arguments, | 513 instantiator_type_arguments, |
| 514 result); | 514 result); |
| 515 } | 515 } |
| 516 if (FLAG_trace_type_checks) { | 516 if (FLAG_trace_type_checks) { |
| 517 AbstractType& test_type = AbstractType::Handle(type.raw()); | 517 AbstractType& test_type = AbstractType::Handle(type.raw()); |
| 518 if (!test_type.IsInstantiated()) { | 518 if (!test_type.IsInstantiated()) { |
| 519 test_type = type.InstantiateFrom(instantiator_type_arguments); | 519 Error& malformed_error = Error::Handle(); |
| 520 test_type = type.InstantiateFrom(instantiator_type_arguments, |
| 521 &malformed_error); |
| 522 ASSERT(malformed_error.IsNull()); // Malformed types are not optimized. |
| 520 } | 523 } |
| 521 OS::PrintErr(" Updated test cache %p ix: %"Pd" with (%"Pd", %p, %p, %s)\n" | 524 OS::PrintErr(" Updated test cache %p ix: %"Pd" with (%"Pd", %p, %p, %s)\n" |
| 522 " [%p %s %"Pd", %p %s]\n" | 525 " [%p %s %"Pd", %p %s]\n" |
| 523 " [%p %s %"Pd", %p %s] %s\n", | 526 " [%p %s %"Pd", %p %s] %s\n", |
| 524 new_cache.raw(), | 527 new_cache.raw(), |
| 525 len, | 528 len, |
| 526 instance_class.id(), | 529 instance_class.id(), |
| 527 | 530 |
| 528 instance_type_arguments.raw(), | 531 instance_type_arguments.raw(), |
| 529 instantiator_type_arguments.raw(), | 532 instantiator_type_arguments.raw(), |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 } | 627 } |
| 625 if (!is_instance_of) { | 628 if (!is_instance_of) { |
| 626 // Throw a dynamic type error. | 629 // Throw a dynamic type error. |
| 627 const intptr_t location = GetCallerLocation(); | 630 const intptr_t location = GetCallerLocation(); |
| 628 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); | 631 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); |
| 629 const String& src_type_name = String::Handle(src_type.UserVisibleName()); | 632 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 630 String& dst_type_name = String::Handle(); | 633 String& dst_type_name = String::Handle(); |
| 631 if (!dst_type.IsInstantiated()) { | 634 if (!dst_type.IsInstantiated()) { |
| 632 // Instantiate dst_type before reporting the error. | 635 // Instantiate dst_type before reporting the error. |
| 633 const AbstractType& instantiated_dst_type = AbstractType::Handle( | 636 const AbstractType& instantiated_dst_type = AbstractType::Handle( |
| 634 dst_type.InstantiateFrom(instantiator_type_arguments)); | 637 dst_type.InstantiateFrom(instantiator_type_arguments, NULL)); |
| 638 // Note that instantiated_dst_type may be malformed. |
| 635 dst_type_name = instantiated_dst_type.UserVisibleName(); | 639 dst_type_name = instantiated_dst_type.UserVisibleName(); |
| 636 } else { | 640 } else { |
| 637 dst_type_name = dst_type.UserVisibleName(); | 641 dst_type_name = dst_type.UserVisibleName(); |
| 638 } | 642 } |
| 639 String& malformed_error_message = String::Handle(); | 643 String& malformed_error_message = String::Handle(); |
| 640 if (!malformed_error.IsNull()) { | 644 if (!malformed_error.IsNull()) { |
| 641 ASSERT(FLAG_enable_type_checks); | 645 ASSERT(FLAG_enable_type_checks); |
| 642 malformed_error_message = String::New(malformed_error.ToErrorCString()); | 646 malformed_error_message = String::New(malformed_error.ToErrorCString()); |
| 643 } | 647 } |
| 644 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, | 648 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, |
| (...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1723 if (right < 0) { | 1727 if (right < 0) { |
| 1724 remainder -= right; | 1728 remainder -= right; |
| 1725 } else { | 1729 } else { |
| 1726 remainder += right; | 1730 remainder += right; |
| 1727 } | 1731 } |
| 1728 } | 1732 } |
| 1729 return remainder; | 1733 return remainder; |
| 1730 } | 1734 } |
| 1731 | 1735 |
| 1732 } // namespace dart | 1736 } // namespace dart |
| OLD | NEW |