| OLD | NEW |
| 1 // Copyright (c) 2011, 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 "lib/error.h" | 5 #include "lib/error.h" |
| 6 | 6 |
| 7 #include "vm/bootstrap_natives.h" | 7 #include "vm/bootstrap_natives.h" |
| 8 #include "vm/exceptions.h" | 8 #include "vm/exceptions.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 #include "vm/runtime_entry.h" | 10 #include "vm/runtime_entry.h" |
| 11 #include "vm/stack_frame.h" | 11 #include "vm/stack_frame.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 // Throw AssertionError instance. | 99 // Throw AssertionError instance. |
| 100 Exceptions::Throw(assertion_error); | 100 Exceptions::Throw(assertion_error); |
| 101 UNREACHABLE(); | 101 UNREACHABLE(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 | 104 |
| 105 // Allocate, initialize, and throw a TypeError. | 105 // Allocate, initialize, and throw a TypeError. |
| 106 static void ThrowTypeError(intptr_t location, | 106 static void ThrowTypeError(intptr_t location, |
| 107 const String& src_type_name, | 107 const String& src_type_name, |
| 108 const String& dst_type_name, | 108 const String& dst_type_name, |
| 109 const String& dst_name) { | 109 const String& dst_name, |
| 110 const String& malformed_error) { |
| 110 // Allocate a new instance of TypeError. | 111 // Allocate a new instance of TypeError. |
| 111 const Instance& type_error = Instance::Handle(NewInstance("TypeError")); | 112 const Instance& type_error = Instance::Handle(NewInstance("TypeError")); |
| 112 | 113 |
| 113 // Initialize 'url', 'line', and 'column' fields. | 114 // Initialize 'url', 'line', and 'column' fields. |
| 114 DartFrameIterator iterator; | 115 DartFrameIterator iterator; |
| 115 const Script& script = Script::Handle(GetCallerScript(&iterator)); | 116 const Script& script = Script::Handle(GetCallerScript(&iterator)); |
| 116 const Class& cls = Class::Handle(type_error.clazz()); | 117 const Class& cls = Class::Handle(type_error.clazz()); |
| 117 // Location fields are defined in AssertionError, the superclass of TypeError. | 118 // Location fields are defined in AssertionError, the superclass of TypeError. |
| 118 const Class& assertion_error_class = Class::Handle(cls.SuperClass()); | 119 const Class& assertion_error_class = Class::Handle(cls.SuperClass()); |
| 119 SetLocationFields(type_error, assertion_error_class, script, location); | 120 SetLocationFields(type_error, assertion_error_class, script, location); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 132 | 133 |
| 133 // Initialize field 'srcType'. | 134 // Initialize field 'srcType'. |
| 134 SetField(type_error, cls, "srcType", src_type_name); | 135 SetField(type_error, cls, "srcType", src_type_name); |
| 135 | 136 |
| 136 // Initialize field 'dstType'. | 137 // Initialize field 'dstType'. |
| 137 SetField(type_error, cls, "dstType", dst_type_name); | 138 SetField(type_error, cls, "dstType", dst_type_name); |
| 138 | 139 |
| 139 // Initialize field 'dstName'. | 140 // Initialize field 'dstName'. |
| 140 SetField(type_error, cls, "dstName", dst_name); | 141 SetField(type_error, cls, "dstName", dst_name); |
| 141 | 142 |
| 143 // Initialize field 'malformedError'. |
| 144 SetField(type_error, cls, "malformedError", malformed_error); |
| 145 |
| 142 // Type errors in the core library may be difficult to diagnose. | 146 // Type errors in the core library may be difficult to diagnose. |
| 143 // Print type error information before throwing the error when debugging. | 147 // Print type error information before throwing the error when debugging. |
| 144 if (FLAG_print_stack_trace_at_throw) { | 148 if (FLAG_print_stack_trace_at_throw) { |
| 145 intptr_t line, column; | 149 if (!malformed_error.IsNull()) { |
| 146 script.GetTokenLocation(location, &line, &column); | 150 OS::Print("%s", malformed_error.ToCString()); |
| 147 OS::Print("'%s': Failed type check: line %d pos %d: " | 151 } else { |
| 148 "type '%s' is not assignable to type '%s' of '%s'.\n", | 152 intptr_t line, column; |
| 149 String::Handle(script.url()).ToCString(), | 153 script.GetTokenLocation(location, &line, &column); |
| 150 line, column, | 154 OS::Print("'%s': Failed type check: line %d pos %d: " |
| 151 src_type_name.ToCString(), | 155 "type '%s' is not assignable to type '%s' of '%s'.\n", |
| 152 dst_type_name.ToCString(), | 156 String::Handle(script.url()).ToCString(), |
| 153 dst_name.ToCString()); | 157 line, column, |
| 158 src_type_name.ToCString(), |
| 159 dst_type_name.ToCString(), |
| 160 dst_name.ToCString()); |
| 161 } |
| 154 } | 162 } |
| 155 // Throw TypeError instance. | 163 // Throw TypeError instance. |
| 156 Exceptions::Throw(type_error); | 164 Exceptions::Throw(type_error); |
| 157 UNREACHABLE(); | 165 UNREACHABLE(); |
| 158 } | 166 } |
| 159 | 167 |
| 160 | 168 |
| 161 // Allocate and throw a new TypeError. | 169 // Allocate and throw a new TypeError. |
| 162 // Arg0: index of the token of the failed type check. | 170 // Arg0: index of the token of the failed type check. |
| 163 // Arg1: src value. | 171 // Arg1: src value. |
| 164 // Arg2: dst type name. | 172 // Arg2: dst type name. |
| 165 // Arg3: dst name. | 173 // Arg3: dst name. |
| 174 // Arg4: malformed type error message. |
| 166 // Return value: none, throws an exception. | 175 // Return value: none, throws an exception. |
| 167 DEFINE_NATIVE_ENTRY(TypeError_throwNew, 4) { | 176 DEFINE_NATIVE_ENTRY(TypeError_throwNew, 5) { |
| 168 intptr_t location = Smi::CheckedHandle(arguments->At(0)).Value(); | 177 intptr_t location = Smi::CheckedHandle(arguments->At(0)).Value(); |
| 169 const Instance& src_value = Instance::CheckedHandle(arguments->At(1)); | 178 const Instance& src_value = Instance::CheckedHandle(arguments->At(1)); |
| 170 const String& dst_type_name = String::CheckedHandle(arguments->At(2)); | 179 const String& dst_type_name = String::CheckedHandle(arguments->At(2)); |
| 171 const String& dst_name = String::CheckedHandle(arguments->At(3)); | 180 const String& dst_name = String::CheckedHandle(arguments->At(3)); |
| 181 const String& malformed_error = String::CheckedHandle(arguments->At(4)); |
| 172 const String& src_type_name = | 182 const String& src_type_name = |
| 173 String::Handle(Type::Handle(src_value.GetType()).Name()); | 183 String::Handle(Type::Handle(src_value.GetType()).Name()); |
| 174 ThrowTypeError(location, src_type_name, dst_type_name, dst_name); | 184 ThrowTypeError(location, src_type_name, |
| 185 dst_type_name, dst_name, malformed_error); |
| 175 } | 186 } |
| 176 | 187 |
| 177 | 188 |
| 178 // Allocate and throw a new FallThroughError. | 189 // Allocate and throw a new FallThroughError. |
| 179 // Arg0: index of the case clause token into which we fall through. | 190 // Arg0: index of the case clause token into which we fall through. |
| 180 // Return value: none, throws an exception. | 191 // Return value: none, throws an exception. |
| 181 DEFINE_NATIVE_ENTRY(FallThroughError_throwNew, 1) { | 192 DEFINE_NATIVE_ENTRY(FallThroughError_throwNew, 1) { |
| 182 GET_NATIVE_ARGUMENT(Smi, smi_pos, arguments->At(0)); | 193 GET_NATIVE_ARGUMENT(Smi, smi_pos, arguments->At(0)); |
| 183 intptr_t fallthrough_pos = smi_pos.Value(); | 194 intptr_t fallthrough_pos = smi_pos.Value(); |
| 184 | 195 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 const String& src_type_name = String::Handle(src_type.Name()); | 295 const String& src_type_name = String::Handle(src_type.Name()); |
| 285 String& dst_type_name = String::Handle(); | 296 String& dst_type_name = String::Handle(); |
| 286 if (!dst_type.IsInstantiated()) { | 297 if (!dst_type.IsInstantiated()) { |
| 287 // Instantiate dst_type before reporting the error. | 298 // Instantiate dst_type before reporting the error. |
| 288 const AbstractType& instantiated_dst_type = AbstractType::Handle( | 299 const AbstractType& instantiated_dst_type = AbstractType::Handle( |
| 289 dst_type.InstantiateFrom(dst_type_instantiator)); | 300 dst_type.InstantiateFrom(dst_type_instantiator)); |
| 290 dst_type_name = instantiated_dst_type.Name(); | 301 dst_type_name = instantiated_dst_type.Name(); |
| 291 } else { | 302 } else { |
| 292 dst_type_name = dst_type.Name(); | 303 dst_type_name = dst_type.Name(); |
| 293 } | 304 } |
| 294 ThrowTypeError(location, src_type_name, dst_type_name, dst_name); | 305 const String& no_malformed_type_error = String::Handle(); |
| 306 ThrowTypeError(location, src_type_name, dst_type_name, dst_name, |
| 307 no_malformed_type_error); |
| 295 UNREACHABLE(); | 308 UNREACHABLE(); |
| 296 } | 309 } |
| 297 arguments.SetReturn(src_instance); | 310 arguments.SetReturn(src_instance); |
| 298 } | 311 } |
| 299 | 312 |
| 300 | 313 |
| 301 // Report that the type of the given object is not bool in conditional context. | 314 // Report that the type of the given object is not bool in conditional context. |
| 302 // Arg0: index of the token of the assignment (source location). | 315 // Arg0: index of the token of the assignment (source location). |
| 303 // Arg1: bad object. | 316 // Arg1: bad object. |
| 304 // Return value: none, throws a TypeError. | 317 // Return value: none, throws a TypeError. |
| 305 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { | 318 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { |
| 306 ASSERT(arguments.Count() == | 319 ASSERT(arguments.Count() == |
| 307 kConditionTypeErrorRuntimeEntry.argument_count()); | 320 kConditionTypeErrorRuntimeEntry.argument_count()); |
| 308 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); | 321 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); |
| 309 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); | 322 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); |
| 310 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); | 323 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); |
| 311 const char* msg = "boolean expression"; | |
| 312 const Type& bool_interface = Type::Handle(Type::BoolInterface()); | 324 const Type& bool_interface = Type::Handle(Type::BoolInterface()); |
| 313 const Type& src_type = Type::Handle(src_instance.GetType()); | 325 const Type& src_type = Type::Handle(src_instance.GetType()); |
| 314 const String& src_type_name = String::Handle(src_type.Name()); | 326 const String& src_type_name = String::Handle(src_type.Name()); |
| 315 const String& bool_type_name = String::Handle(bool_interface.Name()); | 327 const String& bool_type_name = String::Handle(bool_interface.Name()); |
| 316 ThrowTypeError(location, src_type_name, bool_type_name, | 328 const String& expr = String::Handle(String::NewSymbol("boolean expression")); |
| 317 String::Handle(String::NewSymbol(msg))); | 329 const String& no_malformed_type_error = String::Handle(); |
| 330 ThrowTypeError(location, src_type_name, bool_type_name, expr, |
| 331 no_malformed_type_error); |
| 332 UNREACHABLE(); |
| 333 } |
| 334 |
| 335 |
| 336 // Report that the type of the type check is malformed. |
| 337 // Arg0: index of the token of the failed type check. |
| 338 // Arg1: src value. |
| 339 // Arg2: malformed type error message. |
| 340 // Return value: none, throws an exception. |
| 341 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { |
| 342 ASSERT(arguments.Count() == |
| 343 kMalformedTypeErrorRuntimeEntry.argument_count()); |
| 344 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); |
| 345 const Instance& src_value = Instance::CheckedHandle(arguments.At(1)); |
| 346 const String& malformed_error = String::CheckedHandle(arguments.At(2)); |
| 347 const String& dst_type_name = |
| 348 String::Handle(String::NewSymbol("malformed type")); |
| 349 const String& dst_name = String::Handle(String::NewSymbol("")); |
| 350 const String& src_type_name = |
| 351 String::Handle(Type::Handle(src_value.GetType()).Name()); |
| 352 ThrowTypeError(location, src_type_name, |
| 353 dst_type_name, dst_name, malformed_error); |
| 318 UNREACHABLE(); | 354 UNREACHABLE(); |
| 319 } | 355 } |
| 320 | 356 |
| 321 | 357 |
| 322 // Check that the type of each element of the given array is assignable to the | 358 // Check that the type of each element of the given array is assignable to the |
| 323 // given type. | 359 // given type. |
| 324 // Arg0: index of the token of the rest argument declaration (source location). | 360 // Arg0: index of the token of the rest argument declaration (source location). |
| 325 // Arg1: rest argument array. | 361 // Arg1: rest argument array. |
| 326 // Arg2: element declaration type. | 362 // Arg2: element declaration type. |
| 327 // Arg3: type arguments of the instantiator of the element declaration type. | 363 // Arg3: type arguments of the instantiator of the element declaration type. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 354 String& dst_type_name = String::Handle(); | 390 String& dst_type_name = String::Handle(); |
| 355 if (!element_type.IsInstantiated()) { | 391 if (!element_type.IsInstantiated()) { |
| 356 // Instantiate element_type before reporting the error. | 392 // Instantiate element_type before reporting the error. |
| 357 const AbstractType& instantiated_element_type = AbstractType::Handle( | 393 const AbstractType& instantiated_element_type = AbstractType::Handle( |
| 358 element_type.InstantiateFrom(element_type_instantiator)); | 394 element_type.InstantiateFrom(element_type_instantiator)); |
| 359 dst_type_name = instantiated_element_type.Name(); | 395 dst_type_name = instantiated_element_type.Name(); |
| 360 } else { | 396 } else { |
| 361 dst_type_name = element_type.Name(); | 397 dst_type_name = element_type.Name(); |
| 362 } | 398 } |
| 363 const String& dst_name = String::Handle(String::New(buf)); | 399 const String& dst_name = String::Handle(String::New(buf)); |
| 364 ThrowTypeError(location, src_type_name, dst_type_name, dst_name); | 400 const String& no_malformed_type_error = String::Handle(); |
| 401 ThrowTypeError(location, src_type_name, dst_type_name, dst_name, |
| 402 no_malformed_type_error); |
| 365 UNREACHABLE(); | 403 UNREACHABLE(); |
| 366 } | 404 } |
| 367 } | 405 } |
| 368 } | 406 } |
| 369 | 407 |
| 370 } // namespace dart | 408 } // namespace dart |
| OLD | NEW |