Chromium Code Reviews| 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/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/debugger.h" | 9 #include "vm/debugger.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 const char* Exceptions::kCastErrorDstName = "type cast"; | 39 const char* Exceptions::kCastErrorDstName = "type cast"; |
| 40 | 40 |
| 41 | 41 |
| 42 class StacktraceBuilder : public ValueObject { | 42 class StacktraceBuilder : public ValueObject { |
| 43 public: | 43 public: |
| 44 StacktraceBuilder() { } | 44 StacktraceBuilder() { } |
| 45 virtual ~StacktraceBuilder() { } | 45 virtual ~StacktraceBuilder() { } |
| 46 | 46 |
| 47 virtual void AddFrame(const Function& func, | 47 virtual void AddFrame(const Function& func, |
| 48 const Code& code, | 48 const Code& code, |
| 49 const Smi& offset) = 0; | 49 const Smi& offset, |
| 50 bool is_catch_frame) = 0; | |
| 51 | |
| 52 virtual bool full_stacktrace() const = 0; | |
|
srdjan
2013/07/25 17:47:08
I think virtuals are typically in CamelCase.
siva
2013/07/25 19:28:42
Done.
| |
| 50 }; | 53 }; |
| 51 | 54 |
| 52 | 55 |
| 53 class RegularStacktraceBuilder : public StacktraceBuilder { | 56 class RegularStacktraceBuilder : public StacktraceBuilder { |
| 54 public: | 57 public: |
| 55 RegularStacktraceBuilder() | 58 explicit RegularStacktraceBuilder(bool full_stacktrace) |
| 56 : func_list_(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 59 : func_list_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 57 code_list_(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 60 code_list_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 58 pc_offset_list_( | 61 pc_offset_list_( |
| 59 GrowableObjectArray::Handle(GrowableObjectArray::New())) { } | 62 GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 63 catch_func_list_( | |
| 64 full_stacktrace ? | |
| 65 GrowableObjectArray::Handle(GrowableObjectArray::New()) : | |
| 66 GrowableObjectArray::Handle()), | |
|
srdjan
2013/07/25 17:47:08
Indent should be another 4 spaces (here and below)
siva
2013/07/25 19:28:42
Done.
| |
| 67 catch_code_list_( | |
| 68 full_stacktrace ? | |
| 69 GrowableObjectArray::Handle(GrowableObjectArray::New()) : | |
| 70 GrowableObjectArray::Handle()), | |
| 71 catch_pc_offset_list_( | |
| 72 full_stacktrace ? | |
| 73 GrowableObjectArray::Handle(GrowableObjectArray::New()) : | |
| 74 GrowableObjectArray::Handle()), | |
| 75 full_stacktrace_(full_stacktrace) { } | |
| 60 ~RegularStacktraceBuilder() { } | 76 ~RegularStacktraceBuilder() { } |
| 61 | 77 |
| 62 const GrowableObjectArray& func_list() const { return func_list_; } | 78 const GrowableObjectArray& func_list() const { return func_list_; } |
| 63 const GrowableObjectArray& code_list() const { return code_list_; } | 79 const GrowableObjectArray& code_list() const { return code_list_; } |
| 64 const GrowableObjectArray& pc_offset_list() const { return pc_offset_list_; } | 80 const GrowableObjectArray& pc_offset_list() const { return pc_offset_list_; } |
| 81 const GrowableObjectArray& catch_func_list() const { | |
| 82 return catch_func_list_; | |
| 83 } | |
| 84 const GrowableObjectArray& catch_code_list() const { | |
| 85 return catch_code_list_; | |
| 86 } | |
| 87 const GrowableObjectArray& catch_pc_offset_list() const { | |
| 88 return catch_pc_offset_list_; | |
| 89 } | |
| 90 virtual bool full_stacktrace() const { return full_stacktrace_; } | |
| 65 | 91 |
| 66 virtual void AddFrame(const Function& func, | 92 virtual void AddFrame(const Function& func, |
| 67 const Code& code, | 93 const Code& code, |
| 68 const Smi& offset) { | 94 const Smi& offset, |
| 69 func_list_.Add(func); | 95 bool is_catch_frame) { |
| 70 code_list_.Add(code); | 96 if (is_catch_frame) { |
| 71 pc_offset_list_.Add(offset); | 97 catch_func_list_.Add(func); |
| 98 catch_code_list_.Add(code); | |
| 99 catch_pc_offset_list_.Add(offset); | |
| 100 } else { | |
| 101 func_list_.Add(func); | |
| 102 code_list_.Add(code); | |
| 103 pc_offset_list_.Add(offset); | |
| 104 } | |
| 72 } | 105 } |
| 73 | 106 |
| 74 private: | 107 private: |
| 75 const GrowableObjectArray& func_list_; | 108 const GrowableObjectArray& func_list_; |
| 76 const GrowableObjectArray& code_list_; | 109 const GrowableObjectArray& code_list_; |
| 77 const GrowableObjectArray& pc_offset_list_; | 110 const GrowableObjectArray& pc_offset_list_; |
| 111 const GrowableObjectArray& catch_func_list_; | |
| 112 const GrowableObjectArray& catch_code_list_; | |
| 113 const GrowableObjectArray& catch_pc_offset_list_; | |
| 114 bool full_stacktrace_; | |
| 78 | 115 |
| 79 DISALLOW_COPY_AND_ASSIGN(RegularStacktraceBuilder); | 116 DISALLOW_COPY_AND_ASSIGN(RegularStacktraceBuilder); |
| 80 }; | 117 }; |
| 81 | 118 |
| 82 | 119 |
| 83 class PreallocatedStacktraceBuilder : public StacktraceBuilder { | 120 class PreallocatedStacktraceBuilder : public StacktraceBuilder { |
| 84 public: | 121 public: |
| 85 explicit PreallocatedStacktraceBuilder(const Stacktrace& stacktrace) | 122 explicit PreallocatedStacktraceBuilder(const Stacktrace& stacktrace) |
| 86 : stacktrace_(stacktrace), | 123 : stacktrace_(stacktrace), |
| 87 cur_index_(0) { | 124 cur_index_(0) { |
| 88 ASSERT(stacktrace_.raw() == | 125 ASSERT(stacktrace_.raw() == |
| 89 Isolate::Current()->object_store()->preallocated_stack_trace()); | 126 Isolate::Current()->object_store()->preallocated_stack_trace()); |
| 90 } | 127 } |
| 91 ~PreallocatedStacktraceBuilder() { } | 128 ~PreallocatedStacktraceBuilder() { } |
| 92 | 129 |
| 93 virtual void AddFrame(const Function& func, | 130 virtual void AddFrame(const Function& func, |
| 94 const Code& code, | 131 const Code& code, |
| 95 const Smi& offset); | 132 const Smi& offset, |
| 133 bool is_catch_frame); | |
| 134 | |
| 135 virtual bool full_stacktrace() const { return false; } | |
| 96 | 136 |
| 97 private: | 137 private: |
| 98 static const int kNumTopframes = 3; | 138 static const int kNumTopframes = 3; |
| 99 | 139 |
| 100 const Stacktrace& stacktrace_; | 140 const Stacktrace& stacktrace_; |
| 101 intptr_t cur_index_; | 141 intptr_t cur_index_; |
| 102 | 142 |
| 103 DISALLOW_COPY_AND_ASSIGN(PreallocatedStacktraceBuilder); | 143 DISALLOW_COPY_AND_ASSIGN(PreallocatedStacktraceBuilder); |
| 104 }; | 144 }; |
| 105 | 145 |
| 106 | 146 |
| 107 void PreallocatedStacktraceBuilder::AddFrame(const Function& func, | 147 void PreallocatedStacktraceBuilder::AddFrame(const Function& func, |
| 108 const Code& code, | 148 const Code& code, |
| 109 const Smi& offset) { | 149 const Smi& offset, |
| 150 bool is_catch_frame) { | |
| 110 if (cur_index_ >= Stacktrace::kPreallocatedStackdepth) { | 151 if (cur_index_ >= Stacktrace::kPreallocatedStackdepth) { |
| 111 // The number of frames is overflowing the preallocated stack trace object. | 152 // The number of frames is overflowing the preallocated stack trace object. |
| 112 Function& frame_func = Function::Handle(); | 153 Function& frame_func = Function::Handle(); |
| 113 Code& frame_code = Code::Handle(); | 154 Code& frame_code = Code::Handle(); |
| 114 Smi& frame_offset = Smi::Handle(); | 155 Smi& frame_offset = Smi::Handle(); |
| 115 intptr_t start = Stacktrace::kPreallocatedStackdepth - (kNumTopframes - 1); | 156 intptr_t start = Stacktrace::kPreallocatedStackdepth - (kNumTopframes - 1); |
| 116 intptr_t null_slot = start - 2; | 157 intptr_t null_slot = start - 2; |
| 117 // Add an empty slot to indicate the overflow so that the toString | 158 // Add an empty slot to indicate the overflow so that the toString |
| 118 // method can account for the overflow. | 159 // method can account for the overflow. |
| 119 if (stacktrace_.FunctionAtFrame(null_slot) != Function::null()) { | 160 if (stacktrace_.FunctionAtFrame(null_slot) != Function::null()) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 static bool FindExceptionHandler(uword* handler_pc, | 194 static bool FindExceptionHandler(uword* handler_pc, |
| 154 uword* handler_sp, | 195 uword* handler_sp, |
| 155 uword* handler_fp, | 196 uword* handler_fp, |
| 156 StacktraceBuilder* builder) { | 197 StacktraceBuilder* builder) { |
| 157 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); | 198 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
| 158 StackFrame* frame = frames.NextFrame(); | 199 StackFrame* frame = frames.NextFrame(); |
| 159 ASSERT(frame != NULL); // We expect to find a dart invocation frame. | 200 ASSERT(frame != NULL); // We expect to find a dart invocation frame. |
| 160 Function& func = Function::Handle(); | 201 Function& func = Function::Handle(); |
| 161 Code& code = Code::Handle(); | 202 Code& code = Code::Handle(); |
| 162 Smi& offset = Smi::Handle(); | 203 Smi& offset = Smi::Handle(); |
| 204 bool handler_found = false; | |
| 163 while (!frame->IsEntryFrame()) { | 205 while (!frame->IsEntryFrame()) { |
| 164 if (frame->IsDartFrame()) { | 206 if (frame->IsDartFrame()) { |
| 165 code = frame->LookupDartCode(); | 207 code = frame->LookupDartCode(); |
| 166 if (code.is_optimized()) { | 208 if (code.is_optimized()) { |
| 167 // For optimized frames, extract all the inlined functions if any | 209 // For optimized frames, extract all the inlined functions if any |
| 168 // into the stack trace. | 210 // into the stack trace. |
| 169 for (InlinedFunctionsIterator it(frame); !it.Done(); it.Advance()) { | 211 for (InlinedFunctionsIterator it(frame); !it.Done(); it.Advance()) { |
| 170 func = it.function(); | 212 func = it.function(); |
| 171 code = it.code(); | 213 code = it.code(); |
| 172 uword pc = it.pc(); | 214 uword pc = it.pc(); |
| 173 ASSERT(pc != 0); | 215 ASSERT(pc != 0); |
| 174 ASSERT(code.EntryPoint() <= pc); | 216 ASSERT(code.EntryPoint() <= pc); |
| 175 ASSERT(pc < (code.EntryPoint() + code.Size())); | 217 ASSERT(pc < (code.EntryPoint() + code.Size())); |
| 176 if (ShouldShowFunction(func)) { | 218 if (ShouldShowFunction(func)) { |
| 177 offset = Smi::New(pc - code.EntryPoint()); | 219 offset = Smi::New(pc - code.EntryPoint()); |
| 178 builder->AddFrame(func, code, offset); | 220 builder->AddFrame(func, code, offset, handler_found); |
| 179 } | 221 } |
| 180 } | 222 } |
| 181 } else { | 223 } else { |
| 182 offset = Smi::New(frame->pc() - code.EntryPoint()); | 224 offset = Smi::New(frame->pc() - code.EntryPoint()); |
| 183 func = code.function(); | 225 func = code.function(); |
| 184 if (ShouldShowFunction(func)) { | 226 if (ShouldShowFunction(func)) { |
| 185 builder->AddFrame(func, code, offset); | 227 builder->AddFrame(func, code, offset, handler_found); |
| 186 } | 228 } |
| 187 } | 229 } |
| 188 if (frame->FindExceptionHandler(handler_pc)) { | 230 if (!handler_found && frame->FindExceptionHandler(handler_pc)) { |
| 189 *handler_sp = frame->sp(); | 231 *handler_sp = frame->sp(); |
| 190 *handler_fp = frame->fp(); | 232 *handler_fp = frame->fp(); |
| 191 return true; | 233 handler_found = true; |
| 234 if (!builder->full_stacktrace()) { | |
| 235 return handler_found; | |
| 236 } | |
| 192 } | 237 } |
| 193 } | 238 } |
| 194 frame = frames.NextFrame(); | 239 frame = frames.NextFrame(); |
| 195 ASSERT(frame != NULL); | 240 ASSERT(frame != NULL); |
| 196 } | 241 } |
| 197 ASSERT(frame->IsEntryFrame()); | 242 ASSERT(frame->IsEntryFrame()); |
| 198 *handler_pc = frame->pc(); | 243 if (!handler_found) { |
| 199 *handler_sp = frame->sp(); | 244 *handler_pc = frame->pc(); |
| 200 *handler_fp = frame->fp(); | 245 *handler_sp = frame->sp(); |
| 201 return false; | 246 *handler_fp = frame->fp(); |
| 247 } | |
| 248 return handler_found; | |
| 202 } | 249 } |
| 203 | 250 |
| 204 | 251 |
| 205 static void FindErrorHandler(uword* handler_pc, | 252 static void FindErrorHandler(uword* handler_pc, |
| 206 uword* handler_sp, | 253 uword* handler_sp, |
| 207 uword* handler_fp) { | 254 uword* handler_fp) { |
| 208 // TODO(turnidge): Is there a faster way to get the next entry frame? | 255 // TODO(turnidge): Is there a faster way to get the next entry frame? |
| 209 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); | 256 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
| 210 StackFrame* frame = frames.NextFrame(); | 257 StackFrame* frame = frames.NextFrame(); |
| 211 ASSERT(frame != NULL); | 258 ASSERT(frame != NULL); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 uword current_sp = reinterpret_cast<uword>(&program_counter) - 1024; | 308 uword current_sp = reinterpret_cast<uword>(&program_counter) - 1024; |
| 262 __asan_unpoison_memory_region(reinterpret_cast<void*>(current_sp), | 309 __asan_unpoison_memory_region(reinterpret_cast<void*>(current_sp), |
| 263 stack_pointer - current_sp); | 310 stack_pointer - current_sp); |
| 264 func(program_counter, stack_pointer, frame_pointer, | 311 func(program_counter, stack_pointer, frame_pointer, |
| 265 raw_exception, raw_stacktrace); | 312 raw_exception, raw_stacktrace); |
| 266 #endif | 313 #endif |
| 267 UNREACHABLE(); | 314 UNREACHABLE(); |
| 268 } | 315 } |
| 269 | 316 |
| 270 | 317 |
| 318 static RawField* LookupStacktraceField(const Instance& instance) { | |
| 319 Isolate* isolate = Isolate::Current(); | |
| 320 Class& error_class = Class::Handle(isolate, | |
| 321 isolate->object_store()->error_class()); | |
| 322 if (error_class.IsNull()) { | |
| 323 const Library& core_lib = Library::Handle(isolate, Library::CoreLibrary()); | |
| 324 error_class = core_lib.LookupClass(Symbols::Error(), NULL); | |
| 325 ASSERT(!error_class.IsNull()); | |
| 326 isolate->object_store()->set_error_class(error_class); | |
| 327 } | |
| 328 const Class& instance_class = Class::Handle(isolate, instance.clazz()); | |
| 329 Error& malformed_type_error = Error::Handle(isolate); | |
| 330 if (instance_class.IsSubtypeOf(Object::null_abstract_type_arguments(), | |
| 331 error_class, | |
| 332 Object::null_abstract_type_arguments(), | |
| 333 &malformed_type_error)) { | |
| 334 ASSERT(malformed_type_error.IsNull()); | |
| 335 return error_class.LookupInstanceField(Symbols::_stackTrace()); | |
| 336 } | |
| 337 return Field::null(); | |
| 338 } | |
| 339 | |
| 340 | |
| 271 static void ThrowExceptionHelper(const Instance& incoming_exception, | 341 static void ThrowExceptionHelper(const Instance& incoming_exception, |
| 272 const Instance& existing_stacktrace) { | 342 const Instance& existing_stacktrace) { |
| 273 bool use_preallocated_stacktrace = false; | 343 bool use_preallocated_stacktrace = false; |
| 274 Isolate* isolate = Isolate::Current(); | 344 Isolate* isolate = Isolate::Current(); |
| 275 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); | 345 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); |
| 276 if (exception.IsNull()) { | 346 if (exception.IsNull()) { |
| 277 exception ^= Exceptions::Create(Exceptions::kNullThrown, | 347 exception ^= Exceptions::Create(Exceptions::kNullThrown, |
| 278 Object::empty_array()); | 348 Object::empty_array()); |
| 279 } else if (exception.raw() == isolate->object_store()->out_of_memory() || | 349 } else if (exception.raw() == isolate->object_store()->out_of_memory() || |
| 280 exception.raw() == isolate->object_store()->stack_overflow()) { | 350 exception.raw() == isolate->object_store()->stack_overflow()) { |
| 281 use_preallocated_stacktrace = true; | 351 use_preallocated_stacktrace = true; |
| 282 } | 352 } |
| 283 uword handler_pc = 0; | 353 uword handler_pc = 0; |
| 284 uword handler_sp = 0; | 354 uword handler_sp = 0; |
| 285 uword handler_fp = 0; | 355 uword handler_fp = 0; |
| 286 Stacktrace& stacktrace = Stacktrace::Handle(isolate); | 356 Stacktrace& stacktrace = Stacktrace::Handle(isolate); |
| 287 bool handler_exists = false; | 357 bool handler_exists = false; |
| 288 if (use_preallocated_stacktrace) { | 358 if (use_preallocated_stacktrace) { |
| 289 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); | 359 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); |
| 290 PreallocatedStacktraceBuilder frame_builder(stacktrace); | 360 PreallocatedStacktraceBuilder frame_builder(stacktrace); |
| 291 handler_exists = FindExceptionHandler(&handler_pc, | 361 handler_exists = FindExceptionHandler(&handler_pc, |
| 292 &handler_sp, | 362 &handler_sp, |
| 293 &handler_fp, | 363 &handler_fp, |
| 294 &frame_builder); | 364 &frame_builder); |
| 295 } else { | 365 } else { |
| 296 RegularStacktraceBuilder frame_builder; | 366 const Field& stacktrace_field = |
| 367 Field::Handle(LookupStacktraceField(incoming_exception)); | |
| 368 bool full_stacktrace = !stacktrace_field.IsNull(); | |
| 369 RegularStacktraceBuilder frame_builder(full_stacktrace); | |
| 297 handler_exists = FindExceptionHandler(&handler_pc, | 370 handler_exists = FindExceptionHandler(&handler_pc, |
| 298 &handler_sp, | 371 &handler_sp, |
| 299 &handler_fp, | 372 &handler_fp, |
| 300 &frame_builder); | 373 &frame_builder); |
| 374 // Create arrays for function, code and pc_offset triplet of each frame. | |
| 375 const Array& func_array = | |
| 376 Array::Handle(isolate, Array::MakeArray(frame_builder.func_list())); | |
| 377 const Array& code_array = | |
| 378 Array::Handle(isolate, Array::MakeArray(frame_builder.code_list())); | |
| 379 const Array& pc_offset_array = | |
| 380 Array::Handle(isolate, | |
| 381 Array::MakeArray(frame_builder.pc_offset_list())); | |
| 382 if (!stacktrace_field.IsNull()) { | |
| 383 // This is an error object and we need to capture the full stack trace | |
| 384 // here implicitly, so we set up the stack trace. The stack trace field | |
| 385 // is set only once, it is not overriden. | |
| 386 const Array& catch_func_array = | |
| 387 Array::Handle(isolate, | |
| 388 Array::MakeArray(frame_builder.catch_func_list())); | |
| 389 const Array& catch_code_array = | |
| 390 Array::Handle(isolate, | |
| 391 Array::MakeArray(frame_builder.catch_code_list())); | |
| 392 const Array& catch_pc_offset_array = | |
| 393 Array::Handle(isolate, | |
| 394 Array::MakeArray(frame_builder.catch_pc_offset_list())); | |
| 395 stacktrace = Stacktrace::New(func_array, code_array, pc_offset_array); | |
| 396 stacktrace.SetCatchStacktrace(catch_func_array, | |
| 397 catch_code_array, | |
| 398 catch_pc_offset_array); | |
| 399 if (incoming_exception.GetField(stacktrace_field) == Object::null()) { | |
| 400 incoming_exception.SetField(stacktrace_field, stacktrace); | |
| 401 } | |
| 402 } | |
| 301 // TODO(5411263): At some point we can optimize by figuring out if a | 403 // TODO(5411263): At some point we can optimize by figuring out if a |
| 302 // stack trace is needed based on whether the catch code specifies a | 404 // stack trace is needed based on whether the catch code specifies a |
| 303 // stack trace object or there is a rethrow in the catch clause. | 405 // stack trace object or there is a rethrow in the catch clause. |
| 304 if (frame_builder.pc_offset_list().Length() != 0) { | 406 if (pc_offset_array.Length() != 0) { |
| 305 // Create arrays for function, code and pc_offset triplet for each frame. | |
| 306 const Array& func_array = | |
| 307 Array::Handle(isolate, Array::MakeArray(frame_builder.func_list())); | |
| 308 const Array& code_array = | |
| 309 Array::Handle(isolate, Array::MakeArray(frame_builder.code_list())); | |
| 310 const Array& pc_offset_array = | |
| 311 Array::Handle(isolate, | |
| 312 Array::MakeArray(frame_builder.pc_offset_list())); | |
| 313 if (existing_stacktrace.IsNull()) { | 407 if (existing_stacktrace.IsNull()) { |
| 314 stacktrace = Stacktrace::New(func_array, code_array, pc_offset_array); | 408 stacktrace = Stacktrace::New(func_array, code_array, pc_offset_array); |
| 315 } else { | 409 } else { |
| 316 stacktrace ^= existing_stacktrace.raw(); | 410 stacktrace ^= existing_stacktrace.raw(); |
| 317 stacktrace.Append(func_array, code_array, pc_offset_array); | 411 stacktrace.Append(func_array, code_array, pc_offset_array); |
| 318 // Since we are re throwing and appending to the existing stack trace | 412 // Since we are re throwing and appending to the existing stack trace |
| 319 // we clear out the catch trace collected in the existing stack trace | 413 // we clear out the catch trace collected in the existing stack trace |
| 320 // as that trace will not be valid anymore. | 414 // as that trace will not be valid anymore. |
| 321 stacktrace.SetCatchStacktrace(Object::empty_array(), | 415 stacktrace.SetCatchStacktrace(Object::empty_array(), |
| 322 Object::empty_array(), | 416 Object::empty_array(), |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 const String& cls_name = String::Handle(Symbols::New(class_name)); | 489 const String& cls_name = String::Handle(Symbols::New(class_name)); |
| 396 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 490 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 397 // No ambiguity error expected: passing NULL. | 491 // No ambiguity error expected: passing NULL. |
| 398 Class& cls = Class::Handle(core_lib.LookupClass(cls_name, NULL)); | 492 Class& cls = Class::Handle(core_lib.LookupClass(cls_name, NULL)); |
| 399 ASSERT(!cls.IsNull()); | 493 ASSERT(!cls.IsNull()); |
| 400 // There are no parameterized error types, so no need to set type arguments. | 494 // There are no parameterized error types, so no need to set type arguments. |
| 401 return Instance::New(cls); | 495 return Instance::New(cls); |
| 402 } | 496 } |
| 403 | 497 |
| 404 | 498 |
| 405 // Assign the value to the field given by its name in the given instance. | |
| 406 void Exceptions::SetField(const Instance& instance, | |
| 407 const Class& cls, | |
| 408 const char* field_name, | |
| 409 const Object& value) { | |
| 410 const Field& field = Field::Handle(cls.LookupInstanceField( | |
| 411 String::Handle(Symbols::New(field_name)))); | |
| 412 ASSERT(!field.IsNull()); | |
| 413 instance.SetField(field, value); | |
| 414 } | |
| 415 | |
| 416 | |
| 417 // Allocate, initialize, and throw a TypeError. | 499 // Allocate, initialize, and throw a TypeError. |
| 418 void Exceptions::CreateAndThrowTypeError(intptr_t location, | 500 void Exceptions::CreateAndThrowTypeError(intptr_t location, |
| 419 const String& src_type_name, | 501 const String& src_type_name, |
| 420 const String& dst_type_name, | 502 const String& dst_type_name, |
| 421 const String& dst_name, | 503 const String& dst_name, |
| 422 const String& malformed_error) { | 504 const String& malformed_error) { |
| 423 const Array& args = Array::Handle(Array::New(8)); | 505 const Array& args = Array::Handle(Array::New(8)); |
| 424 | 506 |
| 425 ExceptionType exception_type = | 507 ExceptionType exception_type = |
| 426 dst_name.Equals(kCastErrorDstName) ? kCast : kType; | 508 dst_name.Equals(kCastErrorDstName) ? kCast : kType; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 Throw(stack_overflow); | 623 Throw(stack_overflow); |
| 542 } | 624 } |
| 543 | 625 |
| 544 | 626 |
| 545 RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) { | 627 RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) { |
| 546 Library& library = Library::Handle(); | 628 Library& library = Library::Handle(); |
| 547 const String* class_name = NULL; | 629 const String* class_name = NULL; |
| 548 const String* constructor_name = &Symbols::Dot(); | 630 const String* constructor_name = &Symbols::Dot(); |
| 549 switch (type) { | 631 switch (type) { |
| 550 case kNone: | 632 case kNone: |
| 633 case kStackOverflow: | |
| 634 case kOutOfMemory: | |
| 551 UNREACHABLE(); | 635 UNREACHABLE(); |
| 552 break; | 636 break; |
| 553 case kRange: | 637 case kRange: |
| 554 library = Library::CoreLibrary(); | 638 library = Library::CoreLibrary(); |
| 555 class_name = &Symbols::RangeError(); | 639 class_name = &Symbols::RangeError(); |
| 556 break; | 640 break; |
| 557 case kArgument: | 641 case kArgument: |
| 558 library = Library::CoreLibrary(); | 642 library = Library::CoreLibrary(); |
| 559 class_name = &Symbols::ArgumentError(); | 643 class_name = &Symbols::ArgumentError(); |
| 560 break; | 644 break; |
| 561 case kNoSuchMethod: | 645 case kNoSuchMethod: |
| 562 library = Library::CoreLibrary(); | 646 library = Library::CoreLibrary(); |
| 563 class_name = &Symbols::NoSuchMethodError(); | 647 class_name = &Symbols::NoSuchMethodError(); |
| 564 constructor_name = &String::Handle(Symbols::New("._withType")); | 648 constructor_name = &String::Handle(Symbols::New("._withType")); |
| 565 break; | 649 break; |
| 566 case kFormat: | 650 case kFormat: |
| 567 library = Library::CoreLibrary(); | 651 library = Library::CoreLibrary(); |
| 568 class_name = &Symbols::FormatException(); | 652 class_name = &Symbols::FormatException(); |
| 569 break; | 653 break; |
| 570 case kUnsupported: | 654 case kUnsupported: |
| 571 library = Library::CoreLibrary(); | 655 library = Library::CoreLibrary(); |
| 572 class_name = &Symbols::UnsupportedError(); | 656 class_name = &Symbols::UnsupportedError(); |
| 573 break; | 657 break; |
| 574 case kStackOverflow: | |
| 575 library = Library::CoreLibrary(); | |
| 576 class_name = &Symbols::StackOverflowError(); | |
| 577 break; | |
| 578 case kOutOfMemory: | |
| 579 library = Library::CoreLibrary(); | |
| 580 class_name = &Symbols::OutOfMemoryError(); | |
| 581 break; | |
| 582 case kInternalError: | 658 case kInternalError: |
| 583 library = Library::CoreLibrary(); | 659 library = Library::CoreLibrary(); |
| 584 class_name = &Symbols::InternalError(); | 660 class_name = &Symbols::InternalError(); |
| 585 break; | 661 break; |
| 586 case kNullThrown: | 662 case kNullThrown: |
| 587 library = Library::CoreLibrary(); | 663 library = Library::CoreLibrary(); |
| 588 class_name = &Symbols::NullThrownError(); | 664 class_name = &Symbols::NullThrownError(); |
| 589 break; | 665 break; |
| 590 case kIsolateSpawn: | 666 case kIsolateSpawn: |
| 591 library = Library::IsolateLibrary(); | 667 library = Library::IsolateLibrary(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 629 break; | 705 break; |
| 630 } | 706 } |
| 631 | 707 |
| 632 return DartLibraryCalls::InstanceCreate(library, | 708 return DartLibraryCalls::InstanceCreate(library, |
| 633 *class_name, | 709 *class_name, |
| 634 *constructor_name, | 710 *constructor_name, |
| 635 arguments); | 711 arguments); |
| 636 } | 712 } |
| 637 | 713 |
| 638 } // namespace dart | 714 } // namespace dart |
| OLD | NEW |