| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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_index_table.h" | 7 #include "vm/code_index_table.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 // Allocation of a fixed length array of given element type. | 103 // Allocation of a fixed length array of given element type. |
| 104 // Arg0: array length. | 104 // Arg0: array length. |
| 105 // Arg1: array element type. | 105 // Arg1: array element type. |
| 106 // Arg2: type arguments of the instantiator. | 106 // Arg2: type arguments of the instantiator. |
| 107 // Return value: newly allocated array of length arg0. | 107 // Return value: newly allocated array of length arg0. |
| 108 DEFINE_RUNTIME_ENTRY(AllocateArray, 3) { | 108 DEFINE_RUNTIME_ENTRY(AllocateArray, 3) { |
| 109 ASSERT(arguments.Count() == kAllocateArrayRuntimeEntry.argument_count()); | 109 ASSERT(arguments.Count() == kAllocateArrayRuntimeEntry.argument_count()); |
| 110 const Smi& length = Smi::CheckedHandle(arguments.At(0)); | 110 const Smi& length = Smi::CheckedHandle(arguments.At(0)); |
| 111 const Array& array = Array::Handle(Array::New(length.Value())); | 111 const Array& array = Array::Handle(Array::New(length.Value())); |
| 112 arguments.SetReturn(array); | 112 arguments.SetReturn(array); |
| 113 TypeArguments& element_type = TypeArguments::CheckedHandle(arguments.At(1)); | 113 AbstractTypeArguments& element_type = |
| 114 AbstractTypeArguments::CheckedHandle(arguments.At(1)); |
| 114 if (element_type.IsNull()) { | 115 if (element_type.IsNull()) { |
| 115 // No instantiator required for a raw type. | 116 // No instantiator required for a raw type. |
| 116 ASSERT(TypeArguments::CheckedHandle(arguments.At(2)).IsNull()); | 117 ASSERT(AbstractTypeArguments::CheckedHandle(arguments.At(2)).IsNull()); |
| 117 return; | 118 return; |
| 118 } | 119 } |
| 119 // An Array takes only one type argument. | 120 // An Array takes only one type argument. |
| 120 ASSERT(element_type.Length() == 1); | 121 ASSERT(element_type.Length() == 1); |
| 121 const TypeArguments& instantiator = | 122 const AbstractTypeArguments& instantiator = |
| 122 TypeArguments::CheckedHandle(arguments.At(2)); | 123 AbstractTypeArguments::CheckedHandle(arguments.At(2)); |
| 123 if (instantiator.IsNull()) { | 124 if (instantiator.IsNull()) { |
| 124 // Either the type element is instantiated (use it), or the instantiator is | 125 // Either the type element is instantiated (use it), or the instantiator is |
| 125 // of a raw type and we cannot instantiate the element type (leave as null). | 126 // of a raw type and we cannot instantiate the element type (leave as null). |
| 126 if (element_type.IsInstantiated()) { | 127 if (element_type.IsInstantiated()) { |
| 127 array.SetTypeArguments(element_type); | 128 array.SetTypeArguments(element_type); |
| 128 } | 129 } |
| 129 return; | 130 return; |
| 130 } | 131 } |
| 131 ASSERT(!element_type.IsInstantiated()); | 132 ASSERT(!element_type.IsInstantiated()); |
| 132 // If possible, use the instantiator as the type argument vector. | 133 // If possible, use the instantiator as the type argument vector. |
| 133 if (element_type.IsUninstantiatedIdentity() && (instantiator.Length() == 1)) { | 134 if (element_type.IsUninstantiatedIdentity() && (instantiator.Length() == 1)) { |
| 134 // No need to check that the instantiator is a TypeArray, since the virtual | 135 // No need to check that the instantiator is a TypeArguments, since the |
| 135 // call to Length() handles other cases that are harder to inline. | 136 // virtual call to Length() handles other cases that are harder to inline. |
| 136 element_type = instantiator.raw(); | 137 element_type = instantiator.raw(); |
| 137 } else { | 138 } else { |
| 138 element_type = TypeArguments::NewInstantiatedTypeArguments(element_type, | 139 element_type = |
| 139 instantiator); | 140 AbstractTypeArguments::NewInstantiatedTypeArguments(element_type, |
| 141 instantiator); |
| 140 } | 142 } |
| 141 array.SetTypeArguments(element_type); | 143 array.SetTypeArguments(element_type); |
| 142 } | 144 } |
| 143 | 145 |
| 144 | 146 |
| 145 // Allocate a new object. | 147 // Allocate a new object. |
| 146 // Arg0: class of the object that needs to be allocated. | 148 // Arg0: class of the object that needs to be allocated. |
| 147 // Arg1: type arguments of the object that needs to be allocated. | 149 // Arg1: type arguments of the object that needs to be allocated. |
| 148 // Arg2: type arguments of the instantiator. | 150 // Arg2: type arguments of the instantiator. |
| 149 // Return value: newly allocated object. | 151 // Return value: newly allocated object. |
| 150 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { | 152 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { |
| 151 ASSERT(arguments.Count() == kAllocateObjectRuntimeEntry.argument_count()); | 153 ASSERT(arguments.Count() == kAllocateObjectRuntimeEntry.argument_count()); |
| 152 const Class& cls = Class::CheckedHandle(arguments.At(0)); | 154 const Class& cls = Class::CheckedHandle(arguments.At(0)); |
| 153 const Instance& instance = Instance::Handle(Instance::New(cls)); | 155 const Instance& instance = Instance::Handle(Instance::New(cls)); |
| 154 arguments.SetReturn(instance); | 156 arguments.SetReturn(instance); |
| 155 if (!cls.HasTypeArguments()) { | 157 if (!cls.HasTypeArguments()) { |
| 156 // No type arguments required for a non-parameterized type. | 158 // No type arguments required for a non-parameterized type. |
| 157 ASSERT(Instance::CheckedHandle(arguments.At(1)).IsNull()); | 159 ASSERT(Instance::CheckedHandle(arguments.At(1)).IsNull()); |
| 158 return; | 160 return; |
| 159 } | 161 } |
| 160 TypeArguments& type_arguments = TypeArguments::CheckedHandle(arguments.At(1)); | 162 AbstractTypeArguments& type_arguments = |
| 163 AbstractTypeArguments::CheckedHandle(arguments.At(1)); |
| 161 if (type_arguments.IsNull()) { | 164 if (type_arguments.IsNull()) { |
| 162 // No instantiator is required for a raw type. | 165 // No instantiator is required for a raw type. |
| 163 ASSERT(Instance::CheckedHandle(arguments.At(2)).IsNull()); | 166 ASSERT(Instance::CheckedHandle(arguments.At(2)).IsNull()); |
| 164 return; | 167 return; |
| 165 } | 168 } |
| 166 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); | 169 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); |
| 167 const TypeArguments& instantiator = | 170 const AbstractTypeArguments& instantiator = |
| 168 TypeArguments::CheckedHandle(arguments.At(2)); | 171 AbstractTypeArguments::CheckedHandle(arguments.At(2)); |
| 169 if (instantiator.IsNull()) { | 172 if (instantiator.IsNull()) { |
| 170 // Either the type argument vector is instantiated (use it), or the | 173 // Either the type argument vector is instantiated (use it), or the |
| 171 // instantiator is of a raw type and we cannot instantiate the type argument | 174 // instantiator is of a raw type and we cannot instantiate the type argument |
| 172 // vector (leave it as null). | 175 // vector (leave it as null). |
| 173 if (type_arguments.IsInstantiated()) { | 176 if (type_arguments.IsInstantiated()) { |
| 174 instance.SetTypeArguments(type_arguments); | 177 instance.SetTypeArguments(type_arguments); |
| 175 } | 178 } |
| 176 return; | 179 return; |
| 177 } | 180 } |
| 178 ASSERT(!type_arguments.IsInstantiated()); | 181 ASSERT(!type_arguments.IsInstantiated()); |
| 179 // If possible, use the instantiator as the type argument vector. | 182 // If possible, use the instantiator as the type argument vector. |
| 180 if (instantiator.IsTypeArray()) { | 183 if (instantiator.IsTypeArguments()) { |
| 181 // Code inlined in the caller should have optimized the case where the | 184 // Code inlined in the caller should have optimized the case where the |
| 182 // instantiator is a TypeArray and can be used as type argument vector. | 185 // instantiator is a TypeArguments and can be used as type argument vector. |
| 183 ASSERT(!type_arguments.IsUninstantiatedIdentity() || | 186 ASSERT(!type_arguments.IsUninstantiatedIdentity() || |
| 184 (instantiator.Length() != type_arguments.Length())); | 187 (instantiator.Length() != type_arguments.Length())); |
| 185 type_arguments = TypeArguments::NewInstantiatedTypeArguments(type_arguments, | 188 type_arguments = |
| 186 instantiator); | 189 AbstractTypeArguments::NewInstantiatedTypeArguments(type_arguments, |
| 190 instantiator); |
| 187 } else { | 191 } else { |
| 188 if (type_arguments.IsUninstantiatedIdentity() && | 192 if (type_arguments.IsUninstantiatedIdentity() && |
| 189 (instantiator.Length() == type_arguments.Length())) { | 193 (instantiator.Length() == type_arguments.Length())) { |
| 190 type_arguments = instantiator.raw(); | 194 type_arguments = instantiator.raw(); |
| 191 } else { | 195 } else { |
| 192 type_arguments = | 196 type_arguments = |
| 193 TypeArguments::NewInstantiatedTypeArguments(type_arguments, | 197 AbstractTypeArguments::NewInstantiatedTypeArguments(type_arguments, |
| 194 instantiator); | 198 instantiator); |
| 195 } | 199 } |
| 196 } | 200 } |
| 197 instance.SetTypeArguments(type_arguments); | 201 instance.SetTypeArguments(type_arguments); |
| 198 } | 202 } |
| 199 | 203 |
| 200 | 204 |
| 201 // Instantiate type arguments. | 205 // Instantiate type arguments. |
| 202 // Arg0: uninstantiated type arguments. | 206 // Arg0: uninstantiated type arguments. |
| 203 // Arg1: instantiator type arguments. | 207 // Arg1: instantiator type arguments. |
| 204 // Return value: instantiated type arguments. | 208 // Return value: instantiated type arguments. |
| 205 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { | 209 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { |
| 206 ASSERT(arguments.Count() == | 210 ASSERT(arguments.Count() == |
| 207 kInstantiateTypeArgumentsRuntimeEntry.argument_count()); | 211 kInstantiateTypeArgumentsRuntimeEntry.argument_count()); |
| 208 TypeArguments& type_arguments = TypeArguments::CheckedHandle(arguments.At(0)); | 212 AbstractTypeArguments& type_arguments = |
| 209 const TypeArguments& instantiator = | 213 AbstractTypeArguments::CheckedHandle(arguments.At(0)); |
| 210 TypeArguments::CheckedHandle(arguments.At(1)); | 214 const AbstractTypeArguments& instantiator = |
| 215 AbstractTypeArguments::CheckedHandle(arguments.At(1)); |
| 211 ASSERT(!type_arguments.IsNull() && | 216 ASSERT(!type_arguments.IsNull() && |
| 212 !type_arguments.IsInstantiated() && | 217 !type_arguments.IsInstantiated() && |
| 213 !instantiator.IsNull()); | 218 !instantiator.IsNull()); |
| 214 // Code inlined in the caller should have optimized the case where the | 219 // Code inlined in the caller should have optimized the case where the |
| 215 // instantiator can be used as type argument vector. | 220 // instantiator can be used as type argument vector. |
| 216 ASSERT(!type_arguments.IsUninstantiatedIdentity() || | 221 ASSERT(!type_arguments.IsUninstantiatedIdentity() || |
| 217 !instantiator.IsTypeArray() || | 222 !instantiator.IsTypeArguments() || |
| 218 (instantiator.Length() != type_arguments.Length())); | 223 (instantiator.Length() != type_arguments.Length())); |
| 219 type_arguments = TypeArguments::NewInstantiatedTypeArguments(type_arguments, | 224 type_arguments = |
| 220 instantiator); | 225 AbstractTypeArguments::NewInstantiatedTypeArguments(type_arguments, |
| 226 instantiator); |
| 221 arguments.SetReturn(type_arguments); | 227 arguments.SetReturn(type_arguments); |
| 222 } | 228 } |
| 223 | 229 |
| 224 | 230 |
| 225 // Allocate a new closure. | 231 // Allocate a new closure. |
| 226 // Arg0: local function. | 232 // Arg0: local function. |
| 227 // Arg1: type arguments of the closure. | 233 // Arg1: type arguments of the closure. |
| 228 // Return value: newly allocated closure. | 234 // Return value: newly allocated closure. |
| 229 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) { | 235 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) { |
| 230 ASSERT(arguments.Count() == kAllocateClosureRuntimeEntry.argument_count()); | 236 ASSERT(arguments.Count() == kAllocateClosureRuntimeEntry.argument_count()); |
| 231 const Function& function = Function::CheckedHandle(arguments.At(0)); | 237 const Function& function = Function::CheckedHandle(arguments.At(0)); |
| 232 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); | 238 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); |
| 233 const TypeArguments& type_arguments = | 239 const AbstractTypeArguments& type_arguments = |
| 234 TypeArguments::CheckedHandle(arguments.At(1)); | 240 AbstractTypeArguments::CheckedHandle(arguments.At(1)); |
| 235 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); | 241 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); |
| 236 // The current context was saved in the Isolate structure when entering the | 242 // The current context was saved in the Isolate structure when entering the |
| 237 // runtime. | 243 // runtime. |
| 238 const Context& context = Context::Handle(isolate->top_context()); | 244 const Context& context = Context::Handle(isolate->top_context()); |
| 239 ASSERT(!context.IsNull()); | 245 ASSERT(!context.IsNull()); |
| 240 const Closure& closure = Closure::Handle(Closure::New(function, context)); | 246 const Closure& closure = Closure::Handle(Closure::New(function, context)); |
| 241 closure.SetTypeArguments(type_arguments); | 247 closure.SetTypeArguments(type_arguments); |
| 242 arguments.SetReturn(closure); | 248 arguments.SetReturn(closure); |
| 243 } | 249 } |
| 244 | 250 |
| 245 | 251 |
| 246 // Allocate a new implicit static closure. | 252 // Allocate a new implicit static closure. |
| 247 // Arg0: local function. | 253 // Arg0: local function. |
| 248 // Return value: newly allocated closure. | 254 // Return value: newly allocated closure. |
| 249 DEFINE_RUNTIME_ENTRY(AllocateImplicitStaticClosure, 1) { | 255 DEFINE_RUNTIME_ENTRY(AllocateImplicitStaticClosure, 1) { |
| 250 ASSERT(arguments.Count() == | 256 ASSERT(arguments.Count() == |
| 251 kAllocateImplicitStaticClosureRuntimeEntry.argument_count()); | 257 kAllocateImplicitStaticClosureRuntimeEntry.argument_count()); |
| 252 ObjectStore* object_store = isolate->object_store(); | 258 ObjectStore* object_store = isolate->object_store(); |
| 253 ASSERT(object_store != NULL); | 259 ASSERT(object_store != NULL); |
| 254 const Function& function = Function::CheckedHandle(arguments.At(0)); | 260 const Function& function = Function::CheckedHandle(arguments.At(0)); |
| 261 ASSERT(!function.IsNull()); |
| 255 ASSERT(function.IsImplicitStaticClosureFunction()); | 262 ASSERT(function.IsImplicitStaticClosureFunction()); |
| 256 const Context& context = Context::Handle(object_store->empty_context()); | 263 const Context& context = Context::Handle(object_store->empty_context()); |
| 257 arguments.SetReturn(Closure::Handle(Closure::New(function, context))); | 264 arguments.SetReturn(Closure::Handle(Closure::New(function, context))); |
| 258 } | 265 } |
| 259 | 266 |
| 260 | 267 |
| 261 // Allocate a new implicit instance closure. | 268 // Allocate a new implicit instance closure. |
| 262 // Arg0: local function. | 269 // Arg0: local function. |
| 263 // Arg1: receiver object. | 270 // Arg1: receiver object. |
| 264 // Arg2: type arguments of the closure. | 271 // Arg2: type arguments of the closure. |
| 265 // Return value: newly allocated closure. | 272 // Return value: newly allocated closure. |
| 266 DEFINE_RUNTIME_ENTRY(AllocateImplicitInstanceClosure, 3) { | 273 DEFINE_RUNTIME_ENTRY(AllocateImplicitInstanceClosure, 3) { |
| 267 ASSERT(arguments.Count() == | 274 ASSERT(arguments.Count() == |
| 268 kAllocateImplicitInstanceClosureRuntimeEntry.argument_count()); | 275 kAllocateImplicitInstanceClosureRuntimeEntry.argument_count()); |
| 269 const Function& function = Function::CheckedHandle(arguments.At(0)); | 276 const Function& function = Function::CheckedHandle(arguments.At(0)); |
| 270 ASSERT(function.IsImplicitInstanceClosureFunction()); | 277 ASSERT(function.IsImplicitInstanceClosureFunction()); |
| 271 const Instance& receiver = Instance::CheckedHandle(arguments.At(1)); | 278 const Instance& receiver = Instance::CheckedHandle(arguments.At(1)); |
| 272 const TypeArguments& type_arguments = | 279 const AbstractTypeArguments& type_arguments = |
| 273 TypeArguments::CheckedHandle(arguments.At(2)); | 280 AbstractTypeArguments::CheckedHandle(arguments.At(2)); |
| 274 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); | 281 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); |
| 275 Context& context = Context::Handle(); | 282 Context& context = Context::Handle(); |
| 276 context = Context::New(1); | 283 context = Context::New(1); |
| 277 context.SetAt(0, receiver); | 284 context.SetAt(0, receiver); |
| 278 const Closure& closure = Closure::Handle(Closure::New(function, context)); | 285 const Closure& closure = Closure::Handle(Closure::New(function, context)); |
| 279 closure.SetTypeArguments(type_arguments); | 286 closure.SetTypeArguments(type_arguments); |
| 280 arguments.SetReturn(closure); | 287 arguments.SetReturn(closure); |
| 281 } | 288 } |
| 282 | 289 |
| 283 | 290 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 312 // Check that the given instance is an instance of the given type. | 319 // Check that the given instance is an instance of the given type. |
| 313 // Tested instance may not be null, because the null test is inlined. | 320 // Tested instance may not be null, because the null test is inlined. |
| 314 // Arg0: instance being checked. | 321 // Arg0: instance being checked. |
| 315 // Arg1: type. | 322 // Arg1: type. |
| 316 // Arg2: type arguments of the instantiator of the type. | 323 // Arg2: type arguments of the instantiator of the type. |
| 317 // Return value: true or false. | 324 // Return value: true or false. |
| 318 DEFINE_RUNTIME_ENTRY(Instanceof, 3) { | 325 DEFINE_RUNTIME_ENTRY(Instanceof, 3) { |
| 319 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count()); | 326 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count()); |
| 320 const Instance& instance = Instance::CheckedHandle(arguments.At(0)); | 327 const Instance& instance = Instance::CheckedHandle(arguments.At(0)); |
| 321 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(1)); | 328 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(1)); |
| 322 const TypeArguments& type_instantiator = | 329 const AbstractTypeArguments& type_instantiator = |
| 323 TypeArguments::CheckedHandle(arguments.At(2)); | 330 AbstractTypeArguments::CheckedHandle(arguments.At(2)); |
| 324 ASSERT(type.IsFinalized()); | 331 ASSERT(type.IsFinalized()); |
| 325 const Bool& result = Bool::Handle( | 332 const Bool& result = Bool::Handle( |
| 326 instance.IsInstanceOf(type, type_instantiator) ? | 333 instance.IsInstanceOf(type, type_instantiator) ? |
| 327 Bool::True() : Bool::False()); | 334 Bool::True() : Bool::False()); |
| 328 if (FLAG_trace_type_checks) { | 335 if (FLAG_trace_type_checks) { |
| 329 const Type& instance_type = Type::Handle(instance.GetType()); | 336 const Type& instance_type = Type::Handle(instance.GetType()); |
| 330 ASSERT(instance_type.IsInstantiated()); | 337 ASSERT(instance_type.IsInstantiated()); |
| 331 if (type.IsInstantiated()) { | 338 if (type.IsInstantiated()) { |
| 332 OS::Print("InstanceOf: '%s' %s '%s'\n", | 339 OS::Print("InstanceOf: '%s' %s '%s'\n", |
| 333 String::Handle(instance_type.Name()).ToCString(), | 340 String::Handle(instance_type.Name()).ToCString(), |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 arguments.SetReturn(closure); | 610 arguments.SetReturn(closure); |
| 604 return; | 611 return; |
| 605 } | 612 } |
| 606 Function& implicit_closure_function = | 613 Function& implicit_closure_function = |
| 607 Function::Handle(function.ImplicitClosureFunction()); | 614 Function::Handle(function.ImplicitClosureFunction()); |
| 608 // Create a closure object for the implicit closure function. | 615 // Create a closure object for the implicit closure function. |
| 609 const Context& context = Context::Handle(Context::New(1)); | 616 const Context& context = Context::Handle(Context::New(1)); |
| 610 context.SetAt(0, receiver); | 617 context.SetAt(0, receiver); |
| 611 closure = Closure::New(implicit_closure_function, context); | 618 closure = Closure::New(implicit_closure_function, context); |
| 612 if (receiver_class.HasTypeArguments()) { | 619 if (receiver_class.HasTypeArguments()) { |
| 613 const TypeArguments& type_arguments = | 620 const AbstractTypeArguments& type_arguments = |
| 614 TypeArguments::Handle(receiver.GetTypeArguments()); | 621 AbstractTypeArguments::Handle(receiver.GetTypeArguments()); |
| 615 closure.SetTypeArguments(type_arguments); | 622 closure.SetTypeArguments(type_arguments); |
| 616 } | 623 } |
| 617 arguments.SetReturn(closure); | 624 arguments.SetReturn(closure); |
| 618 } | 625 } |
| 619 | 626 |
| 620 | 627 |
| 621 // Resolve an implicit closure by invoking getter and checking if the return | 628 // Resolve an implicit closure by invoking getter and checking if the return |
| 622 // value from getter is a closure. | 629 // value from getter is a closure. |
| 623 // Arg0: receiver object. | 630 // Arg0: receiver object. |
| 624 // Arg1: ic-data array. | 631 // Arg1: ic-data array. |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 } | 1038 } |
| 1032 } | 1039 } |
| 1033 } | 1040 } |
| 1034 // The cache is null terminated, therefore the loop above should never | 1041 // The cache is null terminated, therefore the loop above should never |
| 1035 // terminate by itself. | 1042 // terminate by itself. |
| 1036 UNREACHABLE(); | 1043 UNREACHABLE(); |
| 1037 return Code::null(); | 1044 return Code::null(); |
| 1038 } | 1045 } |
| 1039 | 1046 |
| 1040 } // namespace dart | 1047 } // namespace dart |
| OLD | NEW |