| 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 "platform/address_sanitizer.h" | 7 #include "platform/address_sanitizer.h" |
| 8 | 8 |
| 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 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 namespace dart { | 22 namespace dart { |
| 23 | 23 |
| 24 DECLARE_FLAG(bool, trace_deoptimization); | 24 DECLARE_FLAG(bool, trace_deoptimization); |
| 25 DEFINE_FLAG(bool, | 25 DEFINE_FLAG(bool, |
| 26 print_stacktrace_at_throw, | 26 print_stacktrace_at_throw, |
| 27 false, | 27 false, |
| 28 "Prints a stack trace everytime a throw occurs."); | 28 "Prints a stack trace everytime a throw occurs."); |
| 29 | 29 |
| 30 | 30 |
| 31 class StacktraceBuilder : public ValueObject { | 31 class StackTraceBuilder : public ValueObject { |
| 32 public: | 32 public: |
| 33 StacktraceBuilder() {} | 33 StackTraceBuilder() {} |
| 34 virtual ~StacktraceBuilder() {} | 34 virtual ~StackTraceBuilder() {} |
| 35 | 35 |
| 36 virtual void AddFrame(const Code& code, const Smi& offset) = 0; | 36 virtual void AddFrame(const Code& code, const Smi& offset) = 0; |
| 37 }; | 37 }; |
| 38 | 38 |
| 39 | 39 |
| 40 class RegularStacktraceBuilder : public StacktraceBuilder { | 40 class RegularStackTraceBuilder : public StackTraceBuilder { |
| 41 public: | 41 public: |
| 42 explicit RegularStacktraceBuilder(Zone* zone) | 42 explicit RegularStackTraceBuilder(Zone* zone) |
| 43 : code_list_( | 43 : code_list_( |
| 44 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())), | 44 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())), |
| 45 pc_offset_list_( | 45 pc_offset_list_( |
| 46 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())) {} | 46 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())) {} |
| 47 ~RegularStacktraceBuilder() {} | 47 ~RegularStackTraceBuilder() {} |
| 48 | 48 |
| 49 const GrowableObjectArray& code_list() const { return code_list_; } | 49 const GrowableObjectArray& code_list() const { return code_list_; } |
| 50 const GrowableObjectArray& pc_offset_list() const { return pc_offset_list_; } | 50 const GrowableObjectArray& pc_offset_list() const { return pc_offset_list_; } |
| 51 | 51 |
| 52 virtual void AddFrame(const Code& code, const Smi& offset) { | 52 virtual void AddFrame(const Code& code, const Smi& offset) { |
| 53 code_list_.Add(code); | 53 code_list_.Add(code); |
| 54 pc_offset_list_.Add(offset); | 54 pc_offset_list_.Add(offset); |
| 55 } | 55 } |
| 56 | 56 |
| 57 private: | 57 private: |
| 58 const GrowableObjectArray& code_list_; | 58 const GrowableObjectArray& code_list_; |
| 59 const GrowableObjectArray& pc_offset_list_; | 59 const GrowableObjectArray& pc_offset_list_; |
| 60 | 60 |
| 61 DISALLOW_COPY_AND_ASSIGN(RegularStacktraceBuilder); | 61 DISALLOW_COPY_AND_ASSIGN(RegularStackTraceBuilder); |
| 62 }; | 62 }; |
| 63 | 63 |
| 64 | 64 |
| 65 class PreallocatedStacktraceBuilder : public StacktraceBuilder { | 65 class PreallocatedStackTraceBuilder : public StackTraceBuilder { |
| 66 public: | 66 public: |
| 67 explicit PreallocatedStacktraceBuilder(const Instance& stacktrace) | 67 explicit PreallocatedStackTraceBuilder(const Instance& stacktrace) |
| 68 : stacktrace_(Stacktrace::Cast(stacktrace)), | 68 : stacktrace_(StackTrace::Cast(stacktrace)), |
| 69 cur_index_(0), | 69 cur_index_(0), |
| 70 dropped_frames_(0) { | 70 dropped_frames_(0) { |
| 71 ASSERT(stacktrace_.raw() == | 71 ASSERT(stacktrace_.raw() == |
| 72 Isolate::Current()->object_store()->preallocated_stack_trace()); | 72 Isolate::Current()->object_store()->preallocated_stack_trace()); |
| 73 } | 73 } |
| 74 ~PreallocatedStacktraceBuilder() {} | 74 ~PreallocatedStackTraceBuilder() {} |
| 75 | 75 |
| 76 virtual void AddFrame(const Code& code, const Smi& offset); | 76 virtual void AddFrame(const Code& code, const Smi& offset); |
| 77 | 77 |
| 78 private: | 78 private: |
| 79 static const int kNumTopframes = Stacktrace::kPreallocatedStackdepth / 2; | 79 static const int kNumTopframes = StackTrace::kPreallocatedStackdepth / 2; |
| 80 | 80 |
| 81 const Stacktrace& stacktrace_; | 81 const StackTrace& stacktrace_; |
| 82 intptr_t cur_index_; | 82 intptr_t cur_index_; |
| 83 intptr_t dropped_frames_; | 83 intptr_t dropped_frames_; |
| 84 | 84 |
| 85 DISALLOW_COPY_AND_ASSIGN(PreallocatedStacktraceBuilder); | 85 DISALLOW_COPY_AND_ASSIGN(PreallocatedStackTraceBuilder); |
| 86 }; | 86 }; |
| 87 | 87 |
| 88 | 88 |
| 89 void PreallocatedStacktraceBuilder::AddFrame(const Code& code, | 89 void PreallocatedStackTraceBuilder::AddFrame(const Code& code, |
| 90 const Smi& offset) { | 90 const Smi& offset) { |
| 91 if (cur_index_ >= Stacktrace::kPreallocatedStackdepth) { | 91 if (cur_index_ >= StackTrace::kPreallocatedStackdepth) { |
| 92 // The number of frames is overflowing the preallocated stack trace object. | 92 // The number of frames is overflowing the preallocated stack trace object. |
| 93 Code& frame_code = Code::Handle(); | 93 Code& frame_code = Code::Handle(); |
| 94 Smi& frame_offset = Smi::Handle(); | 94 Smi& frame_offset = Smi::Handle(); |
| 95 intptr_t start = Stacktrace::kPreallocatedStackdepth - (kNumTopframes - 1); | 95 intptr_t start = StackTrace::kPreallocatedStackdepth - (kNumTopframes - 1); |
| 96 intptr_t null_slot = start - 2; | 96 intptr_t null_slot = start - 2; |
| 97 // We are going to drop one frame. | 97 // We are going to drop one frame. |
| 98 dropped_frames_++; | 98 dropped_frames_++; |
| 99 // Add an empty slot to indicate the overflow so that the toString | 99 // Add an empty slot to indicate the overflow so that the toString |
| 100 // method can account for the overflow. | 100 // method can account for the overflow. |
| 101 if (stacktrace_.FunctionAtFrame(null_slot) != Function::null()) { | 101 if (stacktrace_.FunctionAtFrame(null_slot) != Function::null()) { |
| 102 stacktrace_.SetCodeAtFrame(null_slot, frame_code); | 102 stacktrace_.SetCodeAtFrame(null_slot, frame_code); |
| 103 // We drop an extra frame here too. | 103 // We drop an extra frame here too. |
| 104 dropped_frames_++; | 104 dropped_frames_++; |
| 105 } | 105 } |
| 106 // Encode the number of dropped frames into the pc offset. | 106 // Encode the number of dropped frames into the pc offset. |
| 107 frame_offset ^= Smi::New(dropped_frames_); | 107 frame_offset ^= Smi::New(dropped_frames_); |
| 108 stacktrace_.SetPcOffsetAtFrame(null_slot, frame_offset); | 108 stacktrace_.SetPcOffsetAtFrame(null_slot, frame_offset); |
| 109 // Move frames one slot down so that we can accomodate the new frame. | 109 // Move frames one slot down so that we can accomodate the new frame. |
| 110 for (intptr_t i = start; i < Stacktrace::kPreallocatedStackdepth; i++) { | 110 for (intptr_t i = start; i < StackTrace::kPreallocatedStackdepth; i++) { |
| 111 intptr_t prev = (i - 1); | 111 intptr_t prev = (i - 1); |
| 112 frame_code = stacktrace_.CodeAtFrame(i); | 112 frame_code = stacktrace_.CodeAtFrame(i); |
| 113 frame_offset = stacktrace_.PcOffsetAtFrame(i); | 113 frame_offset = stacktrace_.PcOffsetAtFrame(i); |
| 114 stacktrace_.SetCodeAtFrame(prev, frame_code); | 114 stacktrace_.SetCodeAtFrame(prev, frame_code); |
| 115 stacktrace_.SetPcOffsetAtFrame(prev, frame_offset); | 115 stacktrace_.SetPcOffsetAtFrame(prev, frame_offset); |
| 116 } | 116 } |
| 117 cur_index_ = (Stacktrace::kPreallocatedStackdepth - 1); | 117 cur_index_ = (StackTrace::kPreallocatedStackdepth - 1); |
| 118 } | 118 } |
| 119 stacktrace_.SetCodeAtFrame(cur_index_, code); | 119 stacktrace_.SetCodeAtFrame(cur_index_, code); |
| 120 stacktrace_.SetPcOffsetAtFrame(cur_index_, offset); | 120 stacktrace_.SetPcOffsetAtFrame(cur_index_, offset); |
| 121 cur_index_ += 1; | 121 cur_index_ += 1; |
| 122 } | 122 } |
| 123 | 123 |
| 124 | 124 |
| 125 static void BuildStackTrace(StacktraceBuilder* builder) { | 125 static void BuildStackTrace(StackTraceBuilder* builder) { |
| 126 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); | 126 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
| 127 StackFrame* frame = frames.NextFrame(); | 127 StackFrame* frame = frames.NextFrame(); |
| 128 ASSERT(frame != NULL); // We expect to find a dart invocation frame. | 128 ASSERT(frame != NULL); // We expect to find a dart invocation frame. |
| 129 Code& code = Code::Handle(); | 129 Code& code = Code::Handle(); |
| 130 Smi& offset = Smi::Handle(); | 130 Smi& offset = Smi::Handle(); |
| 131 while (frame != NULL) { | 131 while (frame != NULL) { |
| 132 if (frame->IsDartFrame()) { | 132 if (frame->IsDartFrame()) { |
| 133 code = frame->LookupDartCode(); | 133 code = frame->LookupDartCode(); |
| 134 ASSERT(code.ContainsInstructionAt(frame->pc())); | 134 ASSERT(code.ContainsInstructionAt(frame->pc())); |
| 135 offset = Smi::New(frame->pc() - code.PayloadStart()); | 135 offset = Smi::New(frame->pc() - code.PayloadStart()); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 uword current_sp = Thread::GetCurrentStackPointer() - 1024; | 328 uword current_sp = Thread::GetCurrentStackPointer() - 1024; |
| 329 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp), | 329 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp), |
| 330 stack_pointer - current_sp); | 330 stack_pointer - current_sp); |
| 331 | 331 |
| 332 func(program_counter, stack_pointer, frame_pointer, thread); | 332 func(program_counter, stack_pointer, frame_pointer, thread); |
| 333 #endif | 333 #endif |
| 334 UNREACHABLE(); | 334 UNREACHABLE(); |
| 335 } | 335 } |
| 336 | 336 |
| 337 | 337 |
| 338 static RawField* LookupStacktraceField(const Instance& instance) { | 338 static RawField* LookupStackTraceField(const Instance& instance) { |
| 339 if (instance.GetClassId() < kNumPredefinedCids) { | 339 if (instance.GetClassId() < kNumPredefinedCids) { |
| 340 // 'class Error' is not a predefined class. | 340 // 'class Error' is not a predefined class. |
| 341 return Field::null(); | 341 return Field::null(); |
| 342 } | 342 } |
| 343 Thread* thread = Thread::Current(); | 343 Thread* thread = Thread::Current(); |
| 344 Zone* zone = thread->zone(); | 344 Zone* zone = thread->zone(); |
| 345 Isolate* isolate = thread->isolate(); | 345 Isolate* isolate = thread->isolate(); |
| 346 Class& error_class = | 346 Class& error_class = |
| 347 Class::Handle(zone, isolate->object_store()->error_class()); | 347 Class::Handle(zone, isolate->object_store()->error_class()); |
| 348 if (error_class.IsNull()) { | 348 if (error_class.IsNull()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 361 } | 361 } |
| 362 type = test_class.super_type(); | 362 type = test_class.super_type(); |
| 363 if (type.IsNull()) return Field::null(); | 363 if (type.IsNull()) return Field::null(); |
| 364 test_class = type.type_class(); | 364 test_class = type.type_class(); |
| 365 } | 365 } |
| 366 UNREACHABLE(); | 366 UNREACHABLE(); |
| 367 return Field::null(); | 367 return Field::null(); |
| 368 } | 368 } |
| 369 | 369 |
| 370 | 370 |
| 371 RawStacktrace* Exceptions::CurrentStacktrace() { | 371 RawStackTrace* Exceptions::CurrentStackTrace() { |
| 372 Zone* zone = Thread::Current()->zone(); | 372 Zone* zone = Thread::Current()->zone(); |
| 373 RegularStacktraceBuilder frame_builder(zone); | 373 RegularStackTraceBuilder frame_builder(zone); |
| 374 BuildStackTrace(&frame_builder); | 374 BuildStackTrace(&frame_builder); |
| 375 | 375 |
| 376 // Create arrays for code and pc_offset tuples of each frame. | 376 // Create arrays for code and pc_offset tuples of each frame. |
| 377 const Array& full_code_array = | 377 const Array& full_code_array = |
| 378 Array::Handle(zone, Array::MakeArray(frame_builder.code_list())); | 378 Array::Handle(zone, Array::MakeArray(frame_builder.code_list())); |
| 379 const Array& full_pc_offset_array = | 379 const Array& full_pc_offset_array = |
| 380 Array::Handle(zone, Array::MakeArray(frame_builder.pc_offset_list())); | 380 Array::Handle(zone, Array::MakeArray(frame_builder.pc_offset_list())); |
| 381 const Stacktrace& full_stacktrace = Stacktrace::Handle( | 381 const StackTrace& full_stacktrace = StackTrace::Handle( |
| 382 Stacktrace::New(full_code_array, full_pc_offset_array)); | 382 StackTrace::New(full_code_array, full_pc_offset_array)); |
| 383 return full_stacktrace.raw(); | 383 return full_stacktrace.raw(); |
| 384 } | 384 } |
| 385 | 385 |
| 386 | 386 |
| 387 static void ThrowExceptionHelper(Thread* thread, | 387 static void ThrowExceptionHelper(Thread* thread, |
| 388 const Instance& incoming_exception, | 388 const Instance& incoming_exception, |
| 389 const Instance& existing_stacktrace, | 389 const Instance& existing_stacktrace, |
| 390 const bool is_rethrow) { | 390 const bool is_rethrow) { |
| 391 Zone* zone = thread->zone(); | 391 Zone* zone = thread->zone(); |
| 392 Isolate* isolate = thread->isolate(); | 392 Isolate* isolate = thread->isolate(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 413 if (handler_pc == 0) { | 413 if (handler_pc == 0) { |
| 414 // No Dart frame. | 414 // No Dart frame. |
| 415 ASSERT(incoming_exception.raw() == | 415 ASSERT(incoming_exception.raw() == |
| 416 isolate->object_store()->out_of_memory()); | 416 isolate->object_store()->out_of_memory()); |
| 417 const UnhandledException& error = UnhandledException::Handle( | 417 const UnhandledException& error = UnhandledException::Handle( |
| 418 zone, isolate->object_store()->preallocated_unhandled_exception()); | 418 zone, isolate->object_store()->preallocated_unhandled_exception()); |
| 419 thread->long_jump_base()->Jump(1, error); | 419 thread->long_jump_base()->Jump(1, error); |
| 420 UNREACHABLE(); | 420 UNREACHABLE(); |
| 421 } | 421 } |
| 422 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); | 422 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); |
| 423 PreallocatedStacktraceBuilder frame_builder(stacktrace); | 423 PreallocatedStackTraceBuilder frame_builder(stacktrace); |
| 424 if (handler_needs_stacktrace) { | 424 if (handler_needs_stacktrace) { |
| 425 BuildStackTrace(&frame_builder); | 425 BuildStackTrace(&frame_builder); |
| 426 } | 426 } |
| 427 } else { | 427 } else { |
| 428 if (!existing_stacktrace.IsNull()) { | 428 if (!existing_stacktrace.IsNull()) { |
| 429 // If we have an existing stack trace then this better be a rethrow. The | 429 // If we have an existing stack trace then this better be a rethrow. The |
| 430 // reverse is not necessarily true (e.g. Dart_PropagateError can cause | 430 // reverse is not necessarily true (e.g. Dart_PropagateError can cause |
| 431 // a rethrow being called without an existing stacktrace.) | 431 // a rethrow being called without an existing stacktrace.) |
| 432 ASSERT(is_rethrow); | 432 ASSERT(is_rethrow); |
| 433 stacktrace = existing_stacktrace.raw(); | 433 stacktrace = existing_stacktrace.raw(); |
| 434 } else { | 434 } else { |
| 435 // Get stacktrace field of class Error to determine whether we have a | 435 // Get stacktrace field of class Error to determine whether we have a |
| 436 // subclass of Error which carries around its stack trace. | 436 // subclass of Error which carries around its stack trace. |
| 437 const Field& stacktrace_field = | 437 const Field& stacktrace_field = |
| 438 Field::Handle(zone, LookupStacktraceField(exception)); | 438 Field::Handle(zone, LookupStackTraceField(exception)); |
| 439 if (!stacktrace_field.IsNull() || handler_needs_stacktrace) { | 439 if (!stacktrace_field.IsNull() || handler_needs_stacktrace) { |
| 440 // Collect the stacktrace if needed. | 440 // Collect the stacktrace if needed. |
| 441 ASSERT(existing_stacktrace.IsNull()); | 441 ASSERT(existing_stacktrace.IsNull()); |
| 442 stacktrace = Exceptions::CurrentStacktrace(); | 442 stacktrace = Exceptions::CurrentStackTrace(); |
| 443 // If we have an Error object, then set its stackTrace field only if it | 443 // If we have an Error object, then set its stackTrace field only if it |
| 444 // not yet initialized. | 444 // not yet initialized. |
| 445 if (!stacktrace_field.IsNull() && | 445 if (!stacktrace_field.IsNull() && |
| 446 (exception.GetField(stacktrace_field) == Object::null())) { | 446 (exception.GetField(stacktrace_field) == Object::null())) { |
| 447 exception.SetField(stacktrace_field, stacktrace); | 447 exception.SetField(stacktrace_field, stacktrace); |
| 448 } | 448 } |
| 449 } | 449 } |
| 450 } | 450 } |
| 451 } | 451 } |
| 452 // We expect to find a handler_pc, if the exception is unhandled | 452 // We expect to find a handler_pc, if the exception is unhandled |
| (...skipping 13 matching lines...) Expand all Loading... |
| 466 } else { | 466 } else { |
| 467 // No dart exception handler found in this invocation sequence, | 467 // No dart exception handler found in this invocation sequence, |
| 468 // so we create an unhandled exception object and return to the | 468 // so we create an unhandled exception object and return to the |
| 469 // invocation stub so that it returns this unhandled exception | 469 // invocation stub so that it returns this unhandled exception |
| 470 // object. The C++ code which invoked this dart sequence can check | 470 // object. The C++ code which invoked this dart sequence can check |
| 471 // and do the appropriate thing (rethrow the exception to the | 471 // and do the appropriate thing (rethrow the exception to the |
| 472 // dart invocation sequence above it, print diagnostics and terminate | 472 // dart invocation sequence above it, print diagnostics and terminate |
| 473 // the isolate etc.). | 473 // the isolate etc.). |
| 474 const UnhandledException& unhandled_exception = UnhandledException::Handle( | 474 const UnhandledException& unhandled_exception = UnhandledException::Handle( |
| 475 zone, UnhandledException::New(exception, stacktrace)); | 475 zone, UnhandledException::New(exception, stacktrace)); |
| 476 stacktrace = Stacktrace::null(); | 476 stacktrace = StackTrace::null(); |
| 477 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, | 477 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, |
| 478 unhandled_exception, stacktrace); | 478 unhandled_exception, stacktrace); |
| 479 } | 479 } |
| 480 UNREACHABLE(); | 480 UNREACHABLE(); |
| 481 } | 481 } |
| 482 | 482 |
| 483 | 483 |
| 484 // Static helpers for allocating, initializing, and throwing an error instance. | 484 // Static helpers for allocating, initializing, and throwing an error instance. |
| 485 | 485 |
| 486 // Return the script of the Dart function that called the native entry or the | 486 // Return the script of the Dart function that called the native entry or the |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 // The VM would crash when the debugger calls back into the VM to | 625 // The VM would crash when the debugger calls back into the VM to |
| 626 // get values of variables. | 626 // get values of variables. |
| 627 if (FLAG_support_debugger) { | 627 if (FLAG_support_debugger) { |
| 628 Isolate* isolate = thread->isolate(); | 628 Isolate* isolate = thread->isolate(); |
| 629 if (exception.raw() != isolate->object_store()->out_of_memory() && | 629 if (exception.raw() != isolate->object_store()->out_of_memory() && |
| 630 exception.raw() != isolate->object_store()->stack_overflow()) { | 630 exception.raw() != isolate->object_store()->stack_overflow()) { |
| 631 isolate->debugger()->PauseException(exception); | 631 isolate->debugger()->PauseException(exception); |
| 632 } | 632 } |
| 633 } | 633 } |
| 634 // Null object is a valid exception object. | 634 // Null object is a valid exception object. |
| 635 ThrowExceptionHelper(thread, exception, Stacktrace::Handle(thread->zone()), | 635 ThrowExceptionHelper(thread, exception, StackTrace::Handle(thread->zone()), |
| 636 false); | 636 false); |
| 637 } | 637 } |
| 638 | 638 |
| 639 | 639 |
| 640 void Exceptions::ReThrow(Thread* thread, | 640 void Exceptions::ReThrow(Thread* thread, |
| 641 const Instance& exception, | 641 const Instance& exception, |
| 642 const Instance& stacktrace) { | 642 const Instance& stacktrace) { |
| 643 // Null object is a valid exception object. | 643 // Null object is a valid exception object. |
| 644 ThrowExceptionHelper(thread, exception, stacktrace, true); | 644 ThrowExceptionHelper(thread, exception, stacktrace, true); |
| 645 } | 645 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 658 Exceptions::ReThrow(thread, exc, stk); | 658 Exceptions::ReThrow(thread, exc, stk); |
| 659 } else { | 659 } else { |
| 660 // Return to the invocation stub and return this error object. The | 660 // Return to the invocation stub and return this error object. The |
| 661 // C++ code which invoked this dart sequence can check and do the | 661 // C++ code which invoked this dart sequence can check and do the |
| 662 // appropriate thing. | 662 // appropriate thing. |
| 663 uword handler_pc = 0; | 663 uword handler_pc = 0; |
| 664 uword handler_sp = 0; | 664 uword handler_sp = 0; |
| 665 uword handler_fp = 0; | 665 uword handler_fp = 0; |
| 666 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); | 666 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); |
| 667 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error, | 667 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error, |
| 668 Stacktrace::Handle(zone)); // Null stacktrace. | 668 StackTrace::Handle(zone)); // Null stacktrace. |
| 669 } | 669 } |
| 670 UNREACHABLE(); | 670 UNREACHABLE(); |
| 671 } | 671 } |
| 672 | 672 |
| 673 | 673 |
| 674 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) { | 674 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) { |
| 675 Thread* thread = Thread::Current(); | 675 Thread* thread = Thread::Current(); |
| 676 const Object& result = | 676 const Object& result = |
| 677 Object::Handle(thread->zone(), Create(type, arguments)); | 677 Object::Handle(thread->zone(), Create(type, arguments)); |
| 678 if (result.IsError()) { | 678 if (result.IsError()) { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 class_name = &Symbols::_CompileTimeError(); | 810 class_name = &Symbols::_CompileTimeError(); |
| 811 break; | 811 break; |
| 812 } | 812 } |
| 813 | 813 |
| 814 return DartLibraryCalls::InstanceCreate(library, *class_name, | 814 return DartLibraryCalls::InstanceCreate(library, *class_name, |
| 815 *constructor_name, arguments); | 815 *constructor_name, arguments); |
| 816 } | 816 } |
| 817 | 817 |
| 818 | 818 |
| 819 } // namespace dart | 819 } // namespace dart |
| OLD | NEW |