| 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/exceptions.h" | 5 #include "vm/exceptions.h" |
| 6 | 6 |
| 7 #include "vm/cpu.h" | 7 #include "vm/cpu.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 UnhandledException::New(exception, stacktrace)); | 111 UnhandledException::New(exception, stacktrace)); |
| 112 CPU::JumpToErrorHandler(handler_pc, | 112 CPU::JumpToErrorHandler(handler_pc, |
| 113 handler_sp, | 113 handler_sp, |
| 114 handler_fp, | 114 handler_fp, |
| 115 unhandled_exception); | 115 unhandled_exception); |
| 116 } | 116 } |
| 117 UNREACHABLE(); | 117 UNREACHABLE(); |
| 118 } | 118 } |
| 119 | 119 |
| 120 | 120 |
| 121 // Static helpers for allocating, initializing, and throwing an error instance. |
| 122 |
| 123 // Return the script of the Dart function that called the native entry or the |
| 124 // runtime entry. The frame iterator points to the callee. |
| 125 RawScript* Exceptions::GetCallerScript(DartFrameIterator* iterator) { |
| 126 DartFrame* caller_frame = iterator->NextFrame(); |
| 127 ASSERT(caller_frame != NULL); |
| 128 const Function& caller = Function::Handle(caller_frame->LookupDartFunction()); |
| 129 ASSERT(!caller.IsNull()); |
| 130 const Class& caller_class = Class::Handle(caller.owner()); |
| 131 return caller_class.script(); |
| 132 } |
| 133 |
| 134 |
| 135 // Allocate a new instance of the given class name. |
| 136 // TODO(hausner): Rename this NewCoreInstance to call out the fact that |
| 137 // the class name is resolved in the core library implicitly? |
| 138 RawInstance* Exceptions::NewInstance(const char* class_name) { |
| 139 const String& cls_name = String::Handle(String::NewSymbol(class_name)); |
| 140 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 141 Class& cls = Class::Handle(core_lib.LookupClass(cls_name)); |
| 142 ASSERT(!cls.IsNull()); |
| 143 // There are no parameterized error types, so no need to set type arguments. |
| 144 return Instance::New(cls); |
| 145 } |
| 146 |
| 147 |
| 148 // Assign the value to the field given by its name in the given instance. |
| 149 void Exceptions::SetField(const Instance& instance, |
| 150 const Class& cls, |
| 151 const char* field_name, |
| 152 const Object& value) { |
| 153 const Field& field = Field::Handle(cls.LookupInstanceField( |
| 154 String::Handle(String::NewSymbol(field_name)))); |
| 155 ASSERT(!field.IsNull()); |
| 156 instance.SetField(field, value); |
| 157 } |
| 158 |
| 159 |
| 160 // Initialize the fields 'url', 'line', and 'column' in the given instance |
| 161 // according to the given token location in the given script. |
| 162 void Exceptions::SetLocationFields(const Instance& instance, |
| 163 const Class& cls, |
| 164 const Script& script, |
| 165 intptr_t location) { |
| 166 SetField(instance, cls, "url", String::Handle(script.url())); |
| 167 intptr_t line, column; |
| 168 script.GetTokenLocation(location, &line, &column); |
| 169 SetField(instance, cls, "line", Smi::Handle(Smi::New(line))); |
| 170 SetField(instance, cls, "column", Smi::Handle(Smi::New(column))); |
| 171 } |
| 172 |
| 173 |
| 174 // Allocate, initialize, and throw a TypeError. |
| 175 void Exceptions::CreateAndThrowTypeError(intptr_t location, |
| 176 const String& src_type_name, |
| 177 const String& dst_type_name, |
| 178 const String& dst_name, |
| 179 const String& malformed_error) { |
| 180 // Allocate a new instance of TypeError. |
| 181 const Instance& type_error = Instance::Handle(NewInstance("TypeError")); |
| 182 |
| 183 // Initialize 'url', 'line', and 'column' fields. |
| 184 DartFrameIterator iterator; |
| 185 const Script& script = Script::Handle(GetCallerScript(&iterator)); |
| 186 const Class& cls = Class::Handle(type_error.clazz()); |
| 187 // Location fields are defined in AssertionError, the superclass of TypeError. |
| 188 const Class& assertion_error_class = Class::Handle(cls.SuperClass()); |
| 189 SetLocationFields(type_error, assertion_error_class, script, location); |
| 190 |
| 191 // Initialize field 'failedAssertion' in AssertionError superclass. |
| 192 // Printing the src_obj value would be possible, but ToString() is expensive |
| 193 // and not meaningful for all classes, so we just print '$expr instanceof...'. |
| 194 // Users should look at TypeError.ToString(), which contains more useful |
| 195 // information than AssertionError.failedAssertion. |
| 196 String& failed_assertion = String::Handle(String::New("$expr instanceof ")); |
| 197 failed_assertion = String::Concat(failed_assertion, dst_type_name); |
| 198 SetField(type_error, |
| 199 assertion_error_class, |
| 200 "failedAssertion", |
| 201 failed_assertion); |
| 202 |
| 203 // Initialize field 'srcType'. |
| 204 SetField(type_error, cls, "srcType", src_type_name); |
| 205 |
| 206 // Initialize field 'dstType'. |
| 207 SetField(type_error, cls, "dstType", dst_type_name); |
| 208 |
| 209 // Initialize field 'dstName'. |
| 210 SetField(type_error, cls, "dstName", dst_name); |
| 211 |
| 212 // Initialize field 'malformedError'. |
| 213 SetField(type_error, cls, "malformedError", malformed_error); |
| 214 |
| 215 // Type errors in the core library may be difficult to diagnose. |
| 216 // Print type error information before throwing the error when debugging. |
| 217 if (FLAG_print_stack_trace_at_throw) { |
| 218 if (!malformed_error.IsNull()) { |
| 219 OS::Print("%s\n", malformed_error.ToCString()); |
| 220 } |
| 221 intptr_t line, column; |
| 222 script.GetTokenLocation(location, &line, &column); |
| 223 OS::Print("'%s': Failed type check: line %d pos %d: ", |
| 224 String::Handle(script.url()).ToCString(), line, column); |
| 225 if (!dst_name.IsNull() && (dst_name.Length() > 0)) { |
| 226 OS::Print("type '%s' is not assignable to type '%s' of '%s'.\n", |
| 227 src_type_name.ToCString(), |
| 228 dst_type_name.ToCString(), |
| 229 dst_name.ToCString()); |
| 230 } else { |
| 231 OS::Print("malformed type used in type test.\n", |
| 232 String::Handle(script.url()).ToCString(), |
| 233 line, column); |
| 234 } |
| 235 } |
| 236 // Throw TypeError instance. |
| 237 Exceptions::Throw(type_error); |
| 238 UNREACHABLE(); |
| 239 } |
| 240 |
| 241 |
| 121 void Exceptions::Throw(const Instance& exception) { | 242 void Exceptions::Throw(const Instance& exception) { |
| 122 // Null object is a valid exception object. | 243 // Null object is a valid exception object. |
| 123 ThrowExceptionHelper(exception, Instance::Handle()); | 244 ThrowExceptionHelper(exception, Instance::Handle()); |
| 124 } | 245 } |
| 125 | 246 |
| 126 | 247 |
| 127 void Exceptions::ReThrow(const Instance& exception, | 248 void Exceptions::ReThrow(const Instance& exception, |
| 128 const Instance& stacktrace) { | 249 const Instance& stacktrace) { |
| 129 // Null object is a valid exception object. | 250 // Null object is a valid exception object. |
| 130 ThrowExceptionHelper(exception, stacktrace); | 251 ThrowExceptionHelper(exception, stacktrace); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 break; | 335 break; |
| 215 case kIllegalJSRegExp: | 336 case kIllegalJSRegExp: |
| 216 class_name = String::NewSymbol("IllegalJSRegExpException"); | 337 class_name = String::NewSymbol("IllegalJSRegExpException"); |
| 217 break; | 338 break; |
| 218 } | 339 } |
| 219 | 340 |
| 220 return DartLibraryCalls::ExceptionCreate(class_name, arguments); | 341 return DartLibraryCalls::ExceptionCreate(class_name, arguments); |
| 221 } | 342 } |
| 222 | 343 |
| 223 } // namespace dart | 344 } // namespace dart |
| OLD | NEW |