Chromium Code Reviews| 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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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. | |
|
srdjan
2012/05/01 23:30:51
Can you measure if there is any performance impact
regis
2012/05/02 01:34:16
Yes, I will measure (I'll check with you for the p
| |
| 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 Loading... | |
| 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 |
| OLD | NEW |