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

Side by Side 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, 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/code_generator_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 } else { 181 } else {
182 type_arguments = 182 type_arguments =
183 InstantiatedTypeArguments::New(type_arguments, instantiator); 183 InstantiatedTypeArguments::New(type_arguments, instantiator);
184 } 184 }
185 } 185 }
186 ASSERT(type_arguments.IsInstantiated()); 186 ASSERT(type_arguments.IsInstantiated());
187 instance.SetTypeArguments(type_arguments); 187 instance.SetTypeArguments(type_arguments);
188 } 188 }
189 189
190 190
191 // Allocate a new object of a generic type and check that the instantiated type
192 // arguments are within the declared bounds or throw a dynamic type error.
193 // Arg0: index of the token of the instance creation (source location).
194 // Arg1: class of the object that needs to be allocated.
195 // Arg2: type arguments of the object that needs to be allocated.
196 // Arg3: type arguments of the instantiator or kNoInstantiator.
197 // Return value: newly allocated object.
198 DEFINE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck, 4) {
199 ASSERT(FLAG_enable_type_checks);
200 ASSERT(arguments.Count() ==
201 kAllocateObjectWithBoundsCheckRuntimeEntry.argument_count());
202 const Class& cls = Class::CheckedHandle(arguments.At(1));
203 const Instance& instance = Instance::Handle(Instance::New(cls));
204 arguments.SetReturn(instance);
205 ASSERT(cls.HasTypeArguments());
206 AbstractTypeArguments& type_arguments =
207 AbstractTypeArguments::CheckedHandle(arguments.At(2));
208 ASSERT(type_arguments.IsNull() ||
209 (type_arguments.Length() == cls.NumTypeArguments()));
210 AbstractTypeArguments& bounds_instantiator = AbstractTypeArguments::Handle();
211 if (Object::Handle(arguments.At(3)).IsSmi()) {
212 ASSERT(Smi::CheckedHandle(arguments.At(3)).Value() ==
213 StubCode::kNoInstantiator);
214 } else {
215 ASSERT(!type_arguments.IsInstantiated());
216 const AbstractTypeArguments& instantiator =
217 AbstractTypeArguments::CheckedHandle(arguments.At(3));
218 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
219 if (instantiator.IsNull()) {
220 type_arguments =
221 InstantiatedTypeArguments::New(type_arguments, instantiator);
222 } else if (instantiator.IsTypeArguments()) {
223 // Code inlined in the caller should have optimized the case where the
224 // instantiator is a TypeArguments and can be used as type argument
225 // vector.
226 ASSERT(!type_arguments.IsUninstantiatedIdentity() ||
227 (instantiator.Length() != type_arguments.Length()));
228 type_arguments =
229 InstantiatedTypeArguments::New(type_arguments, instantiator);
230 } else {
231 // If possible, use the instantiator as the type argument vector.
232 if (type_arguments.IsUninstantiatedIdentity() &&
233 (instantiator.Length() == type_arguments.Length())) {
234 type_arguments = instantiator.raw();
235 } else {
236 type_arguments =
237 InstantiatedTypeArguments::New(type_arguments, instantiator);
238 }
239 }
240 bounds_instantiator = instantiator.raw();
241 }
242 if (!type_arguments.IsNull()) {
243 ASSERT(type_arguments.IsInstantiated());
244 Error& malformed_error = Error::Handle();
245 if (!type_arguments.IsWithinBoundsOf(cls,
246 bounds_instantiator,
247 &malformed_error)) {
248 ASSERT(!malformed_error.IsNull());
249 // Throw a dynamic type error.
250 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
251 String& malformed_error_message = String::Handle(
252 String::New(malformed_error.ToErrorCString()));
253 const String& no_name = String::Handle(String::NewSymbol(""));
254 Exceptions::CreateAndThrowTypeError(
255 location, no_name, no_name, no_name, malformed_error_message);
256 UNREACHABLE();
257 }
258 }
259 instance.SetTypeArguments(type_arguments);
260 }
261
262
191 // Instantiate type arguments. 263 // Instantiate type arguments.
192 // Arg0: uninstantiated type arguments. 264 // Arg0: uninstantiated type arguments.
193 // Arg1: instantiator type arguments. 265 // Arg1: instantiator type arguments.
194 // Return value: instantiated type arguments. 266 // Return value: instantiated type arguments.
195 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { 267 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) {
196 ASSERT(arguments.Count() == 268 ASSERT(arguments.Count() ==
197 kInstantiateTypeArgumentsRuntimeEntry.argument_count()); 269 kInstantiateTypeArgumentsRuntimeEntry.argument_count());
198 AbstractTypeArguments& type_arguments = 270 AbstractTypeArguments& type_arguments =
199 AbstractTypeArguments::CheckedHandle(arguments.At(0)); 271 AbstractTypeArguments::CheckedHandle(arguments.At(0));
200 const AbstractTypeArguments& instantiator = 272 const AbstractTypeArguments& instantiator =
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1492 } 1564 }
1493 } 1565 }
1494 } 1566 }
1495 // The cache is null terminated, therefore the loop above should never 1567 // The cache is null terminated, therefore the loop above should never
1496 // terminate by itself. 1568 // terminate by itself.
1497 UNREACHABLE(); 1569 UNREACHABLE();
1498 return Code::null(); 1570 return Code::null();
1499 } 1571 }
1500 1572
1501 } // namespace dart 1573 } // namespace dart
OLDNEW
« 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