Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1241)

Unified Diff: runtime/vm/code_generator.cc

Issue 10280007: Check upper bounds of type arguments when allocating objects of a generic type (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/code_generator_ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/code_generator.cc
===================================================================
--- runtime/vm/code_generator.cc (revision 7210)
+++ runtime/vm/code_generator.cc (working copy)
@@ -188,6 +188,78 @@
}
+// Allocate a new object of a generic type and check that the instantiated type
+// arguments are within the declared bounds or throw a dynamic type error.
+// Arg0: index of the token of the instance creation (source location).
+// Arg1: class of the object that needs to be allocated.
+// Arg2: type arguments of the object that needs to be allocated.
+// Arg3: type arguments of the instantiator or kNoInstantiator.
+// Return value: newly allocated object.
+DEFINE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck, 4) {
+ ASSERT(FLAG_enable_type_checks);
+ ASSERT(arguments.Count() ==
+ kAllocateObjectWithBoundsCheckRuntimeEntry.argument_count());
+ const Class& cls = Class::CheckedHandle(arguments.At(1));
+ const Instance& instance = Instance::Handle(Instance::New(cls));
+ arguments.SetReturn(instance);
+ ASSERT(cls.HasTypeArguments());
+ AbstractTypeArguments& type_arguments =
+ AbstractTypeArguments::CheckedHandle(arguments.At(2));
+ ASSERT(type_arguments.IsNull() ||
+ (type_arguments.Length() == cls.NumTypeArguments()));
+ AbstractTypeArguments& bounds_instantiator = AbstractTypeArguments::Handle();
+ if (Object::Handle(arguments.At(3)).IsSmi()) {
+ ASSERT(Smi::CheckedHandle(arguments.At(3)).Value() ==
+ StubCode::kNoInstantiator);
+ } else {
+ ASSERT(!type_arguments.IsInstantiated());
+ const AbstractTypeArguments& instantiator =
+ AbstractTypeArguments::CheckedHandle(arguments.At(3));
+ ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
+ if (instantiator.IsNull()) {
+ type_arguments =
+ InstantiatedTypeArguments::New(type_arguments, instantiator);
+ } else if (instantiator.IsTypeArguments()) {
+ // Code inlined in the caller should have optimized the case where the
+ // instantiator is a TypeArguments and can be used as type argument
+ // vector.
+ ASSERT(!type_arguments.IsUninstantiatedIdentity() ||
+ (instantiator.Length() != type_arguments.Length()));
+ type_arguments =
+ InstantiatedTypeArguments::New(type_arguments, instantiator);
+ } else {
+ // If possible, use the instantiator as the type argument vector.
+ if (type_arguments.IsUninstantiatedIdentity() &&
+ (instantiator.Length() == type_arguments.Length())) {
+ type_arguments = instantiator.raw();
+ } else {
+ type_arguments =
+ InstantiatedTypeArguments::New(type_arguments, instantiator);
+ }
+ }
+ bounds_instantiator = instantiator.raw();
+ }
+ if (!type_arguments.IsNull()) {
+ ASSERT(type_arguments.IsInstantiated());
+ Error& malformed_error = Error::Handle();
+ if (!type_arguments.IsWithinBoundsOf(cls,
+ bounds_instantiator,
+ &malformed_error)) {
+ ASSERT(!malformed_error.IsNull());
+ // Throw a dynamic type error.
+ intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
+ String& malformed_error_message = String::Handle(
+ String::New(malformed_error.ToErrorCString()));
+ const String& no_name = String::Handle(String::NewSymbol(""));
+ Exceptions::CreateAndThrowTypeError(
+ location, no_name, no_name, no_name, malformed_error_message);
+ UNREACHABLE();
+ }
+ }
+ instance.SetTypeArguments(type_arguments);
+}
+
+
// Instantiate type arguments.
// Arg0: uninstantiated type arguments.
// Arg1: instantiator type arguments.
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/code_generator_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698