Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: runtime/vm/exceptions.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/exceptions.h ('k') | runtime/vm/exceptions_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "lib/stacktrace.h" 9 #include "lib/stacktrace.h"
10 10
11 #include "vm/dart_api_impl.h" 11 #include "vm/dart_api_impl.h"
12 #include "vm/dart_entry.h" 12 #include "vm/dart_entry.h"
13 #include "vm/datastream.h" 13 #include "vm/datastream.h"
14 #include "vm/debugger.h" 14 #include "vm/debugger.h"
15 #include "vm/deopt_instructions.h" 15 #include "vm/deopt_instructions.h"
16 #include "vm/flags.h" 16 #include "vm/flags.h"
17 #include "vm/log.h" 17 #include "vm/log.h"
18 #include "vm/longjump.h" 18 #include "vm/longjump.h"
19 #include "vm/object.h" 19 #include "vm/object.h"
20 #include "vm/object_store.h" 20 #include "vm/object_store.h"
21 #include "vm/stack_frame.h" 21 #include "vm/stack_frame.h"
22 #include "vm/stub_code.h" 22 #include "vm/stub_code.h"
23 #include "vm/symbols.h" 23 #include "vm/symbols.h"
24 #include "vm/tags.h" 24 #include "vm/tags.h"
25 25
26
27 namespace dart { 26 namespace dart {
28 27
29 DECLARE_FLAG(bool, trace_deoptimization); 28 DECLARE_FLAG(bool, trace_deoptimization);
30 DEFINE_FLAG(bool, 29 DEFINE_FLAG(bool,
31 print_stacktrace_at_throw, 30 print_stacktrace_at_throw,
32 false, 31 false,
33 "Prints a stack trace everytime a throw occurs."); 32 "Prints a stack trace everytime a throw occurs.");
34 33
35
36 class StackTraceBuilder : public ValueObject { 34 class StackTraceBuilder : public ValueObject {
37 public: 35 public:
38 StackTraceBuilder() {} 36 StackTraceBuilder() {}
39 virtual ~StackTraceBuilder() {} 37 virtual ~StackTraceBuilder() {}
40 38
41 virtual void AddFrame(const Code& code, const Smi& offset) = 0; 39 virtual void AddFrame(const Code& code, const Smi& offset) = 0;
42 }; 40 };
43 41
44
45 class RegularStackTraceBuilder : public StackTraceBuilder { 42 class RegularStackTraceBuilder : public StackTraceBuilder {
46 public: 43 public:
47 explicit RegularStackTraceBuilder(Zone* zone) 44 explicit RegularStackTraceBuilder(Zone* zone)
48 : code_list_( 45 : code_list_(
49 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())), 46 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())),
50 pc_offset_list_( 47 pc_offset_list_(
51 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())) {} 48 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())) {}
52 ~RegularStackTraceBuilder() {} 49 ~RegularStackTraceBuilder() {}
53 50
54 const GrowableObjectArray& code_list() const { return code_list_; } 51 const GrowableObjectArray& code_list() const { return code_list_; }
55 const GrowableObjectArray& pc_offset_list() const { return pc_offset_list_; } 52 const GrowableObjectArray& pc_offset_list() const { return pc_offset_list_; }
56 53
57 virtual void AddFrame(const Code& code, const Smi& offset) { 54 virtual void AddFrame(const Code& code, const Smi& offset) {
58 code_list_.Add(code); 55 code_list_.Add(code);
59 pc_offset_list_.Add(offset); 56 pc_offset_list_.Add(offset);
60 } 57 }
61 58
62 private: 59 private:
63 const GrowableObjectArray& code_list_; 60 const GrowableObjectArray& code_list_;
64 const GrowableObjectArray& pc_offset_list_; 61 const GrowableObjectArray& pc_offset_list_;
65 62
66 DISALLOW_COPY_AND_ASSIGN(RegularStackTraceBuilder); 63 DISALLOW_COPY_AND_ASSIGN(RegularStackTraceBuilder);
67 }; 64 };
68 65
69
70 class PreallocatedStackTraceBuilder : public StackTraceBuilder { 66 class PreallocatedStackTraceBuilder : public StackTraceBuilder {
71 public: 67 public:
72 explicit PreallocatedStackTraceBuilder(const Instance& stacktrace) 68 explicit PreallocatedStackTraceBuilder(const Instance& stacktrace)
73 : stacktrace_(StackTrace::Cast(stacktrace)), 69 : stacktrace_(StackTrace::Cast(stacktrace)),
74 cur_index_(0), 70 cur_index_(0),
75 dropped_frames_(0) { 71 dropped_frames_(0) {
76 ASSERT(stacktrace_.raw() == 72 ASSERT(stacktrace_.raw() ==
77 Isolate::Current()->object_store()->preallocated_stack_trace()); 73 Isolate::Current()->object_store()->preallocated_stack_trace());
78 } 74 }
79 ~PreallocatedStackTraceBuilder() {} 75 ~PreallocatedStackTraceBuilder() {}
80 76
81 virtual void AddFrame(const Code& code, const Smi& offset); 77 virtual void AddFrame(const Code& code, const Smi& offset);
82 78
83 private: 79 private:
84 static const int kNumTopframes = StackTrace::kPreallocatedStackdepth / 2; 80 static const int kNumTopframes = StackTrace::kPreallocatedStackdepth / 2;
85 81
86 const StackTrace& stacktrace_; 82 const StackTrace& stacktrace_;
87 intptr_t cur_index_; 83 intptr_t cur_index_;
88 intptr_t dropped_frames_; 84 intptr_t dropped_frames_;
89 85
90 DISALLOW_COPY_AND_ASSIGN(PreallocatedStackTraceBuilder); 86 DISALLOW_COPY_AND_ASSIGN(PreallocatedStackTraceBuilder);
91 }; 87 };
92 88
93
94 void PreallocatedStackTraceBuilder::AddFrame(const Code& code, 89 void PreallocatedStackTraceBuilder::AddFrame(const Code& code,
95 const Smi& offset) { 90 const Smi& offset) {
96 if (cur_index_ >= StackTrace::kPreallocatedStackdepth) { 91 if (cur_index_ >= StackTrace::kPreallocatedStackdepth) {
97 // The number of frames is overflowing the preallocated stack trace object. 92 // The number of frames is overflowing the preallocated stack trace object.
98 Code& frame_code = Code::Handle(); 93 Code& frame_code = Code::Handle();
99 Smi& frame_offset = Smi::Handle(); 94 Smi& frame_offset = Smi::Handle();
100 intptr_t start = StackTrace::kPreallocatedStackdepth - (kNumTopframes - 1); 95 intptr_t start = StackTrace::kPreallocatedStackdepth - (kNumTopframes - 1);
101 intptr_t null_slot = start - 2; 96 intptr_t null_slot = start - 2;
102 // We are going to drop one frame. 97 // We are going to drop one frame.
103 dropped_frames_++; 98 dropped_frames_++;
(...skipping 15 matching lines...) Expand all
119 stacktrace_.SetCodeAtFrame(prev, frame_code); 114 stacktrace_.SetCodeAtFrame(prev, frame_code);
120 stacktrace_.SetPcOffsetAtFrame(prev, frame_offset); 115 stacktrace_.SetPcOffsetAtFrame(prev, frame_offset);
121 } 116 }
122 cur_index_ = (StackTrace::kPreallocatedStackdepth - 1); 117 cur_index_ = (StackTrace::kPreallocatedStackdepth - 1);
123 } 118 }
124 stacktrace_.SetCodeAtFrame(cur_index_, code); 119 stacktrace_.SetCodeAtFrame(cur_index_, code);
125 stacktrace_.SetPcOffsetAtFrame(cur_index_, offset); 120 stacktrace_.SetPcOffsetAtFrame(cur_index_, offset);
126 cur_index_ += 1; 121 cur_index_ += 1;
127 } 122 }
128 123
129
130 static void BuildStackTrace(StackTraceBuilder* builder) { 124 static void BuildStackTrace(StackTraceBuilder* builder) {
131 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames, 125 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames,
132 Thread::Current(), 126 Thread::Current(),
133 StackFrameIterator::kNoCrossThreadIteration); 127 StackFrameIterator::kNoCrossThreadIteration);
134 StackFrame* frame = frames.NextFrame(); 128 StackFrame* frame = frames.NextFrame();
135 ASSERT(frame != NULL); // We expect to find a dart invocation frame. 129 ASSERT(frame != NULL); // We expect to find a dart invocation frame.
136 Code& code = Code::Handle(); 130 Code& code = Code::Handle();
137 Smi& offset = Smi::Handle(); 131 Smi& offset = Smi::Handle();
138 while (frame != NULL) { 132 while (frame != NULL) {
139 if (frame->IsDartFrame()) { 133 if (frame->IsDartFrame()) {
140 code = frame->LookupDartCode(); 134 code = frame->LookupDartCode();
141 ASSERT(code.ContainsInstructionAt(frame->pc())); 135 ASSERT(code.ContainsInstructionAt(frame->pc()));
142 offset = Smi::New(frame->pc() - code.PayloadStart()); 136 offset = Smi::New(frame->pc() - code.PayloadStart());
143 builder->AddFrame(code, offset); 137 builder->AddFrame(code, offset);
144 } 138 }
145 frame = frames.NextFrame(); 139 frame = frames.NextFrame();
146 } 140 }
147 } 141 }
148 142
149
150 static RawObject** VariableAt(uword fp, int stack_slot) { 143 static RawObject** VariableAt(uword fp, int stack_slot) {
151 #if defined(TARGET_ARCH_DBC) 144 #if defined(TARGET_ARCH_DBC)
152 return reinterpret_cast<RawObject**>(fp + stack_slot * kWordSize); 145 return reinterpret_cast<RawObject**>(fp + stack_slot * kWordSize);
153 #else 146 #else
154 if (stack_slot < 0) { 147 if (stack_slot < 0) {
155 return reinterpret_cast<RawObject**>(ParamAddress(fp, -stack_slot)); 148 return reinterpret_cast<RawObject**>(ParamAddress(fp, -stack_slot));
156 } else { 149 } else {
157 return reinterpret_cast<RawObject**>( 150 return reinterpret_cast<RawObject**>(
158 LocalVarAddress(fp, kFirstLocalSlotFromFp - stack_slot)); 151 LocalVarAddress(fp, kFirstLocalSlotFromFp - stack_slot));
159 } 152 }
160 #endif 153 #endif
161 } 154 }
162 155
163
164 class ExceptionHandlerFinder : public StackResource { 156 class ExceptionHandlerFinder : public StackResource {
165 public: 157 public:
166 explicit ExceptionHandlerFinder(Thread* thread) 158 explicit ExceptionHandlerFinder(Thread* thread)
167 : StackResource(thread), thread_(thread), cache_(NULL), metadata_(NULL) {} 159 : StackResource(thread), thread_(thread), cache_(NULL), metadata_(NULL) {}
168 160
169 // Iterate through the stack frames and try to find a frame with an 161 // Iterate through the stack frames and try to find a frame with an
170 // exception handler. Once found, set the pc, sp and fp so that execution 162 // exception handler. Once found, set the pc, sp and fp so that execution
171 // can continue in that frame. Sets 'needs_stacktrace' if there is no 163 // can continue in that frame. Sets 'needs_stacktrace' if there is no
172 // cath-all handler or if a stack-trace is specified in the catch. 164 // cath-all handler or if a stack-trace is specified in the catch.
173 bool Find() { 165 bool Find() {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader; 332 typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader;
341 Thread* thread_; 333 Thread* thread_;
342 CatchEntryStateCache* cache_; 334 CatchEntryStateCache* cache_;
343 Code* code_; 335 Code* code_;
344 bool handler_pc_set_; 336 bool handler_pc_set_;
345 intptr_t* metadata_; // MetaData generated from deopt. 337 intptr_t* metadata_; // MetaData generated from deopt.
346 CatchEntryState cached_; // Value of per PC MetaData cache. 338 CatchEntryState cached_; // Value of per PC MetaData cache.
347 intptr_t pc_; // Current pc in the handler frame. 339 intptr_t pc_; // Current pc in the handler frame.
348 }; 340 };
349 341
350
351 static void FindErrorHandler(uword* handler_pc, 342 static void FindErrorHandler(uword* handler_pc,
352 uword* handler_sp, 343 uword* handler_sp,
353 uword* handler_fp) { 344 uword* handler_fp) {
354 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames, 345 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames,
355 Thread::Current(), 346 Thread::Current(),
356 StackFrameIterator::kNoCrossThreadIteration); 347 StackFrameIterator::kNoCrossThreadIteration);
357 StackFrame* frame = frames.NextFrame(); 348 StackFrame* frame = frames.NextFrame();
358 ASSERT(frame != NULL); 349 ASSERT(frame != NULL);
359 while (!frame->IsEntryFrame()) { 350 while (!frame->IsEntryFrame()) {
360 frame = frames.NextFrame(); 351 frame = frames.NextFrame();
361 ASSERT(frame != NULL); 352 ASSERT(frame != NULL);
362 } 353 }
363 ASSERT(frame->IsEntryFrame()); 354 ASSERT(frame->IsEntryFrame());
364 *handler_pc = frame->pc(); 355 *handler_pc = frame->pc();
365 *handler_sp = frame->sp(); 356 *handler_sp = frame->sp();
366 *handler_fp = frame->fp(); 357 *handler_fp = frame->fp();
367 } 358 }
368 359
369
370 static uword RemapExceptionPCForDeopt(Thread* thread, 360 static uword RemapExceptionPCForDeopt(Thread* thread,
371 uword program_counter, 361 uword program_counter,
372 uword frame_pointer) { 362 uword frame_pointer) {
373 #if !defined(TARGET_ARCH_DBC) 363 #if !defined(TARGET_ARCH_DBC)
374 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = 364 MallocGrowableArray<PendingLazyDeopt>* pending_deopts =
375 thread->isolate()->pending_deopts(); 365 thread->isolate()->pending_deopts();
376 if (pending_deopts->length() > 0) { 366 if (pending_deopts->length() > 0) {
377 // Check if the target frame is scheduled for lazy deopt. 367 // Check if the target frame is scheduled for lazy deopt.
378 for (intptr_t i = 0; i < pending_deopts->length(); i++) { 368 for (intptr_t i = 0; i < pending_deopts->length(); i++) {
379 if ((*pending_deopts)[i].fp() == frame_pointer) { 369 if ((*pending_deopts)[i].fp() == frame_pointer) {
380 // Deopt should now resume in the catch handler instead of after the 370 // Deopt should now resume in the catch handler instead of after the
381 // call. 371 // call.
382 (*pending_deopts)[i].set_pc(program_counter); 372 (*pending_deopts)[i].set_pc(program_counter);
383 373
384 // Jump to the deopt stub instead of the catch handler. 374 // Jump to the deopt stub instead of the catch handler.
385 program_counter = 375 program_counter =
386 StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint(); 376 StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint();
387 if (FLAG_trace_deoptimization) { 377 if (FLAG_trace_deoptimization) {
388 THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n", 378 THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n",
389 frame_pointer); 379 frame_pointer);
390 } 380 }
391 break; 381 break;
392 } 382 }
393 } 383 }
394 } 384 }
395 #endif // !DBC 385 #endif // !DBC
396 return program_counter; 386 return program_counter;
397 } 387 }
398 388
399
400 static void ClearLazyDeopts(Thread* thread, uword frame_pointer) { 389 static void ClearLazyDeopts(Thread* thread, uword frame_pointer) {
401 #if !defined(TARGET_ARCH_DBC) 390 #if !defined(TARGET_ARCH_DBC)
402 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = 391 MallocGrowableArray<PendingLazyDeopt>* pending_deopts =
403 thread->isolate()->pending_deopts(); 392 thread->isolate()->pending_deopts();
404 if (pending_deopts->length() > 0) { 393 if (pending_deopts->length() > 0) {
405 // We may be jumping over frames scheduled for lazy deopt. Remove these 394 // We may be jumping over frames scheduled for lazy deopt. Remove these
406 // frames from the pending deopt table, but only after unmarking them so 395 // frames from the pending deopt table, but only after unmarking them so
407 // any stack walk that happens before the stack is unwound will still work. 396 // any stack walk that happens before the stack is unwound will still work.
408 { 397 {
409 DartFrameIterator frames(thread, 398 DartFrameIterator frames(thread,
(...skipping 23 matching lines...) Expand all
433 } 422 }
434 } 423 }
435 424
436 #if defined(DEBUG) 425 #if defined(DEBUG)
437 ValidateFrames(); 426 ValidateFrames();
438 #endif 427 #endif
439 } 428 }
440 #endif // !DBC 429 #endif // !DBC
441 } 430 }
442 431
443
444 static void JumpToExceptionHandler(Thread* thread, 432 static void JumpToExceptionHandler(Thread* thread,
445 uword program_counter, 433 uword program_counter,
446 uword stack_pointer, 434 uword stack_pointer,
447 uword frame_pointer, 435 uword frame_pointer,
448 const Object& exception_object, 436 const Object& exception_object,
449 const Object& stacktrace_object) { 437 const Object& stacktrace_object) {
450 uword remapped_pc = 438 uword remapped_pc =
451 RemapExceptionPCForDeopt(thread, program_counter, frame_pointer); 439 RemapExceptionPCForDeopt(thread, program_counter, frame_pointer);
452 thread->set_active_exception(exception_object); 440 thread->set_active_exception(exception_object);
453 thread->set_active_stacktrace(stacktrace_object); 441 thread->set_active_stacktrace(stacktrace_object);
454 thread->set_resume_pc(remapped_pc); 442 thread->set_resume_pc(remapped_pc);
455 uword run_exception_pc = StubCode::RunExceptionHandler_entry()->EntryPoint(); 443 uword run_exception_pc = StubCode::RunExceptionHandler_entry()->EntryPoint();
456 Exceptions::JumpToFrame(thread, run_exception_pc, stack_pointer, 444 Exceptions::JumpToFrame(thread, run_exception_pc, stack_pointer,
457 frame_pointer, false /* do not clear deopt */); 445 frame_pointer, false /* do not clear deopt */);
458 } 446 }
459 447
460
461 void Exceptions::JumpToFrame(Thread* thread, 448 void Exceptions::JumpToFrame(Thread* thread,
462 uword program_counter, 449 uword program_counter,
463 uword stack_pointer, 450 uword stack_pointer,
464 uword frame_pointer, 451 uword frame_pointer,
465 bool clear_deopt_at_target) { 452 bool clear_deopt_at_target) {
466 uword fp_for_clearing = 453 uword fp_for_clearing =
467 (clear_deopt_at_target ? frame_pointer + 1 : frame_pointer); 454 (clear_deopt_at_target ? frame_pointer + 1 : frame_pointer);
468 ClearLazyDeopts(thread, fp_for_clearing); 455 ClearLazyDeopts(thread, fp_for_clearing);
469 #if defined(USING_SIMULATOR) 456 #if defined(USING_SIMULATOR)
470 // Unwinding of the C++ frames and destroying of their stack resources is done 457 // Unwinding of the C++ frames and destroying of their stack resources is done
(...skipping 21 matching lines...) Expand all
492 // Unpoison the stack before we tear it down in the generated stub code. 479 // Unpoison the stack before we tear it down in the generated stub code.
493 uword current_sp = Thread::GetCurrentStackPointer() - 1024; 480 uword current_sp = Thread::GetCurrentStackPointer() - 1024;
494 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp), 481 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp),
495 stack_pointer - current_sp); 482 stack_pointer - current_sp);
496 483
497 func(program_counter, stack_pointer, frame_pointer, thread); 484 func(program_counter, stack_pointer, frame_pointer, thread);
498 #endif 485 #endif
499 UNREACHABLE(); 486 UNREACHABLE();
500 } 487 }
501 488
502
503 static RawField* LookupStackTraceField(const Instance& instance) { 489 static RawField* LookupStackTraceField(const Instance& instance) {
504 if (instance.GetClassId() < kNumPredefinedCids) { 490 if (instance.GetClassId() < kNumPredefinedCids) {
505 // 'class Error' is not a predefined class. 491 // 'class Error' is not a predefined class.
506 return Field::null(); 492 return Field::null();
507 } 493 }
508 Thread* thread = Thread::Current(); 494 Thread* thread = Thread::Current();
509 Zone* zone = thread->zone(); 495 Zone* zone = thread->zone();
510 Isolate* isolate = thread->isolate(); 496 Isolate* isolate = thread->isolate();
511 Class& error_class = 497 Class& error_class =
512 Class::Handle(zone, isolate->object_store()->error_class()); 498 Class::Handle(zone, isolate->object_store()->error_class());
(...skipping 12 matching lines...) Expand all
525 Symbols::_stackTrace()); 511 Symbols::_stackTrace());
526 } 512 }
527 type = test_class.super_type(); 513 type = test_class.super_type();
528 if (type.IsNull()) return Field::null(); 514 if (type.IsNull()) return Field::null();
529 test_class = type.type_class(); 515 test_class = type.type_class();
530 } 516 }
531 UNREACHABLE(); 517 UNREACHABLE();
532 return Field::null(); 518 return Field::null();
533 } 519 }
534 520
535
536 RawStackTrace* Exceptions::CurrentStackTrace() { 521 RawStackTrace* Exceptions::CurrentStackTrace() {
537 return GetStackTraceForException(); 522 return GetStackTraceForException();
538 } 523 }
539 524
540
541 static void ThrowExceptionHelper(Thread* thread, 525 static void ThrowExceptionHelper(Thread* thread,
542 const Instance& incoming_exception, 526 const Instance& incoming_exception,
543 const Instance& existing_stacktrace, 527 const Instance& existing_stacktrace,
544 const bool is_rethrow) { 528 const bool is_rethrow) {
545 Zone* zone = thread->zone(); 529 Zone* zone = thread->zone();
546 Isolate* isolate = thread->isolate(); 530 Isolate* isolate = thread->isolate();
547 bool use_preallocated_stacktrace = false; 531 bool use_preallocated_stacktrace = false;
548 Instance& exception = Instance::Handle(zone, incoming_exception.raw()); 532 Instance& exception = Instance::Handle(zone, incoming_exception.raw());
549 if (exception.IsNull()) { 533 if (exception.IsNull()) {
550 exception ^= 534 exception ^=
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 // the isolate etc.). 614 // the isolate etc.).
631 const UnhandledException& unhandled_exception = UnhandledException::Handle( 615 const UnhandledException& unhandled_exception = UnhandledException::Handle(
632 zone, UnhandledException::New(exception, stacktrace)); 616 zone, UnhandledException::New(exception, stacktrace));
633 stacktrace = StackTrace::null(); 617 stacktrace = StackTrace::null();
634 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, 618 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp,
635 unhandled_exception, stacktrace); 619 unhandled_exception, stacktrace);
636 } 620 }
637 UNREACHABLE(); 621 UNREACHABLE();
638 } 622 }
639 623
640
641 // Static helpers for allocating, initializing, and throwing an error instance. 624 // Static helpers for allocating, initializing, and throwing an error instance.
642 625
643 // Return the script of the Dart function that called the native entry or the 626 // Return the script of the Dart function that called the native entry or the
644 // runtime entry. The frame iterator points to the callee. 627 // runtime entry. The frame iterator points to the callee.
645 RawScript* Exceptions::GetCallerScript(DartFrameIterator* iterator) { 628 RawScript* Exceptions::GetCallerScript(DartFrameIterator* iterator) {
646 StackFrame* caller_frame = iterator->NextFrame(); 629 StackFrame* caller_frame = iterator->NextFrame();
647 ASSERT(caller_frame != NULL && caller_frame->IsDartFrame()); 630 ASSERT(caller_frame != NULL && caller_frame->IsDartFrame());
648 const Function& caller = Function::Handle(caller_frame->LookupDartFunction()); 631 const Function& caller = Function::Handle(caller_frame->LookupDartFunction());
649 ASSERT(!caller.IsNull()); 632 ASSERT(!caller.IsNull());
650 return caller.script(); 633 return caller.script();
651 } 634 }
652 635
653
654 // Allocate a new instance of the given class name. 636 // Allocate a new instance of the given class name.
655 // TODO(hausner): Rename this NewCoreInstance to call out the fact that 637 // TODO(hausner): Rename this NewCoreInstance to call out the fact that
656 // the class name is resolved in the core library implicitly? 638 // the class name is resolved in the core library implicitly?
657 RawInstance* Exceptions::NewInstance(const char* class_name) { 639 RawInstance* Exceptions::NewInstance(const char* class_name) {
658 Thread* thread = Thread::Current(); 640 Thread* thread = Thread::Current();
659 Zone* zone = thread->zone(); 641 Zone* zone = thread->zone();
660 const String& cls_name = 642 const String& cls_name =
661 String::Handle(zone, Symbols::New(thread, class_name)); 643 String::Handle(zone, Symbols::New(thread, class_name));
662 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 644 const Library& core_lib = Library::Handle(Library::CoreLibrary());
663 // No ambiguity error expected: passing NULL. 645 // No ambiguity error expected: passing NULL.
664 Class& cls = Class::Handle(core_lib.LookupClass(cls_name)); 646 Class& cls = Class::Handle(core_lib.LookupClass(cls_name));
665 ASSERT(!cls.IsNull()); 647 ASSERT(!cls.IsNull());
666 // There are no parameterized error types, so no need to set type arguments. 648 // There are no parameterized error types, so no need to set type arguments.
667 return Instance::New(cls); 649 return Instance::New(cls);
668 } 650 }
669 651
670
671 // Allocate, initialize, and throw a TypeError or CastError. 652 // Allocate, initialize, and throw a TypeError or CastError.
672 // If error_msg is not null, throw a TypeError, even for a type cast. 653 // If error_msg is not null, throw a TypeError, even for a type cast.
673 void Exceptions::CreateAndThrowTypeError(TokenPosition location, 654 void Exceptions::CreateAndThrowTypeError(TokenPosition location,
674 const AbstractType& src_type, 655 const AbstractType& src_type,
675 const AbstractType& dst_type, 656 const AbstractType& dst_type,
676 const String& dst_name, 657 const String& dst_name,
677 const String& bound_error_msg) { 658 const String& bound_error_msg) {
678 ASSERT(!dst_name.IsNull()); // Pass Symbols::Empty() instead. 659 ASSERT(!dst_name.IsNull()); // Pass Symbols::Empty() instead.
679 Thread* thread = Thread::Current(); 660 Thread* thread = Thread::Current();
680 Zone* zone = thread->zone(); 661 Zone* zone = thread->zone();
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 THR_Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ", 752 THR_Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ",
772 String::Handle(zone, script.url()).ToCString(), line, column); 753 String::Handle(zone, script.url()).ToCString(), line, column);
773 THR_Print("%s\n", error_msg.ToCString()); 754 THR_Print("%s\n", error_msg.ToCString());
774 } 755 }
775 756
776 // Throw TypeError or CastError instance. 757 // Throw TypeError or CastError instance.
777 Exceptions::ThrowByType(exception_type, args); 758 Exceptions::ThrowByType(exception_type, args);
778 UNREACHABLE(); 759 UNREACHABLE();
779 } 760 }
780 761
781
782 void Exceptions::Throw(Thread* thread, const Instance& exception) { 762 void Exceptions::Throw(Thread* thread, const Instance& exception) {
783 // Do not notify debugger on stack overflow and out of memory exceptions. 763 // Do not notify debugger on stack overflow and out of memory exceptions.
784 // The VM would crash when the debugger calls back into the VM to 764 // The VM would crash when the debugger calls back into the VM to
785 // get values of variables. 765 // get values of variables.
786 if (FLAG_support_debugger) { 766 if (FLAG_support_debugger) {
787 Isolate* isolate = thread->isolate(); 767 Isolate* isolate = thread->isolate();
788 if (exception.raw() != isolate->object_store()->out_of_memory() && 768 if (exception.raw() != isolate->object_store()->out_of_memory() &&
789 exception.raw() != isolate->object_store()->stack_overflow()) { 769 exception.raw() != isolate->object_store()->stack_overflow()) {
790 isolate->debugger()->PauseException(exception); 770 isolate->debugger()->PauseException(exception);
791 } 771 }
792 } 772 }
793 // Null object is a valid exception object. 773 // Null object is a valid exception object.
794 ThrowExceptionHelper(thread, exception, StackTrace::Handle(thread->zone()), 774 ThrowExceptionHelper(thread, exception, StackTrace::Handle(thread->zone()),
795 false); 775 false);
796 } 776 }
797 777
798
799 void Exceptions::ReThrow(Thread* thread, 778 void Exceptions::ReThrow(Thread* thread,
800 const Instance& exception, 779 const Instance& exception,
801 const Instance& stacktrace) { 780 const Instance& stacktrace) {
802 // Null object is a valid exception object. 781 // Null object is a valid exception object.
803 ThrowExceptionHelper(thread, exception, stacktrace, true); 782 ThrowExceptionHelper(thread, exception, stacktrace, true);
804 } 783 }
805 784
806
807 void Exceptions::PropagateError(const Error& error) { 785 void Exceptions::PropagateError(const Error& error) {
808 Thread* thread = Thread::Current(); 786 Thread* thread = Thread::Current();
809 Zone* zone = thread->zone(); 787 Zone* zone = thread->zone();
810 ASSERT(thread->top_exit_frame_info() != 0); 788 ASSERT(thread->top_exit_frame_info() != 0);
811 if (error.IsUnhandledException()) { 789 if (error.IsUnhandledException()) {
812 // If the error object represents an unhandled exception, then 790 // If the error object represents an unhandled exception, then
813 // rethrow the exception in the normal fashion. 791 // rethrow the exception in the normal fashion.
814 const UnhandledException& uhe = UnhandledException::Cast(error); 792 const UnhandledException& uhe = UnhandledException::Cast(error);
815 const Instance& exc = Instance::Handle(zone, uhe.exception()); 793 const Instance& exc = Instance::Handle(zone, uhe.exception());
816 const Instance& stk = Instance::Handle(zone, uhe.stacktrace()); 794 const Instance& stk = Instance::Handle(zone, uhe.stacktrace());
817 Exceptions::ReThrow(thread, exc, stk); 795 Exceptions::ReThrow(thread, exc, stk);
818 } else { 796 } else {
819 // Return to the invocation stub and return this error object. The 797 // Return to the invocation stub and return this error object. The
820 // C++ code which invoked this dart sequence can check and do the 798 // C++ code which invoked this dart sequence can check and do the
821 // appropriate thing. 799 // appropriate thing.
822 uword handler_pc = 0; 800 uword handler_pc = 0;
823 uword handler_sp = 0; 801 uword handler_sp = 0;
824 uword handler_fp = 0; 802 uword handler_fp = 0;
825 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); 803 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp);
826 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error, 804 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error,
827 StackTrace::Handle(zone)); // Null stacktrace. 805 StackTrace::Handle(zone)); // Null stacktrace.
828 } 806 }
829 UNREACHABLE(); 807 UNREACHABLE();
830 } 808 }
831 809
832
833 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) { 810 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) {
834 Thread* thread = Thread::Current(); 811 Thread* thread = Thread::Current();
835 const Object& result = 812 const Object& result =
836 Object::Handle(thread->zone(), Create(type, arguments)); 813 Object::Handle(thread->zone(), Create(type, arguments));
837 if (result.IsError()) { 814 if (result.IsError()) {
838 // We got an error while constructing the exception object. 815 // We got an error while constructing the exception object.
839 // Propagate the error instead of throwing the exception. 816 // Propagate the error instead of throwing the exception.
840 PropagateError(Error::Cast(result)); 817 PropagateError(Error::Cast(result));
841 } else { 818 } else {
842 ASSERT(result.IsInstance()); 819 ASSERT(result.IsInstance());
843 Throw(thread, Instance::Cast(result)); 820 Throw(thread, Instance::Cast(result));
844 } 821 }
845 } 822 }
846 823
847
848 void Exceptions::ThrowOOM() { 824 void Exceptions::ThrowOOM() {
849 Thread* thread = Thread::Current(); 825 Thread* thread = Thread::Current();
850 Isolate* isolate = thread->isolate(); 826 Isolate* isolate = thread->isolate();
851 const Instance& oom = Instance::Handle( 827 const Instance& oom = Instance::Handle(
852 thread->zone(), isolate->object_store()->out_of_memory()); 828 thread->zone(), isolate->object_store()->out_of_memory());
853 Throw(thread, oom); 829 Throw(thread, oom);
854 } 830 }
855 831
856
857 void Exceptions::ThrowStackOverflow() { 832 void Exceptions::ThrowStackOverflow() {
858 Thread* thread = Thread::Current(); 833 Thread* thread = Thread::Current();
859 Isolate* isolate = thread->isolate(); 834 Isolate* isolate = thread->isolate();
860 const Instance& stack_overflow = Instance::Handle( 835 const Instance& stack_overflow = Instance::Handle(
861 thread->zone(), isolate->object_store()->stack_overflow()); 836 thread->zone(), isolate->object_store()->stack_overflow());
862 Throw(thread, stack_overflow); 837 Throw(thread, stack_overflow);
863 } 838 }
864 839
865
866 void Exceptions::ThrowArgumentError(const Instance& arg) { 840 void Exceptions::ThrowArgumentError(const Instance& arg) {
867 const Array& args = Array::Handle(Array::New(1)); 841 const Array& args = Array::Handle(Array::New(1));
868 args.SetAt(0, arg); 842 args.SetAt(0, arg);
869 Exceptions::ThrowByType(Exceptions::kArgument, args); 843 Exceptions::ThrowByType(Exceptions::kArgument, args);
870 } 844 }
871 845
872
873 void Exceptions::ThrowRangeError(const char* argument_name, 846 void Exceptions::ThrowRangeError(const char* argument_name,
874 const Integer& argument_value, 847 const Integer& argument_value,
875 intptr_t expected_from, 848 intptr_t expected_from,
876 intptr_t expected_to) { 849 intptr_t expected_to) {
877 const Array& args = Array::Handle(Array::New(4)); 850 const Array& args = Array::Handle(Array::New(4));
878 args.SetAt(0, argument_value); 851 args.SetAt(0, argument_value);
879 args.SetAt(1, Integer::Handle(Integer::New(expected_from))); 852 args.SetAt(1, Integer::Handle(Integer::New(expected_from)));
880 args.SetAt(2, Integer::Handle(Integer::New(expected_to))); 853 args.SetAt(2, Integer::Handle(Integer::New(expected_to)));
881 args.SetAt(3, String::Handle(String::New(argument_name))); 854 args.SetAt(3, String::Handle(String::New(argument_name)));
882 Exceptions::ThrowByType(Exceptions::kRange, args); 855 Exceptions::ThrowByType(Exceptions::kRange, args);
883 } 856 }
884 857
885
886 void Exceptions::ThrowRangeErrorMsg(const char* msg) { 858 void Exceptions::ThrowRangeErrorMsg(const char* msg) {
887 const Array& args = Array::Handle(Array::New(1)); 859 const Array& args = Array::Handle(Array::New(1));
888 args.SetAt(0, String::Handle(String::New(msg))); 860 args.SetAt(0, String::Handle(String::New(msg)));
889 Exceptions::ThrowByType(Exceptions::kRangeMsg, args); 861 Exceptions::ThrowByType(Exceptions::kRangeMsg, args);
890 } 862 }
891 863
892
893 void Exceptions::ThrowCompileTimeError(const LanguageError& error) { 864 void Exceptions::ThrowCompileTimeError(const LanguageError& error) {
894 const Array& args = Array::Handle(Array::New(1)); 865 const Array& args = Array::Handle(Array::New(1));
895 args.SetAt(0, String::Handle(error.FormatMessage())); 866 args.SetAt(0, String::Handle(error.FormatMessage()));
896 Exceptions::ThrowByType(Exceptions::kCompileTimeError, args); 867 Exceptions::ThrowByType(Exceptions::kCompileTimeError, args);
897 } 868 }
898 869
899
900 RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) { 870 RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) {
901 Library& library = Library::Handle(); 871 Library& library = Library::Handle();
902 const String* class_name = NULL; 872 const String* class_name = NULL;
903 const String* constructor_name = &Symbols::Dot(); 873 const String* constructor_name = &Symbols::Dot();
904 switch (type) { 874 switch (type) {
905 case kNone: 875 case kNone:
906 case kStackOverflow: 876 case kStackOverflow:
907 case kOutOfMemory: 877 case kOutOfMemory:
908 UNREACHABLE(); 878 UNREACHABLE();
909 break; 879 break;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 class_name = &Symbols::_CompileTimeError(); 951 class_name = &Symbols::_CompileTimeError();
982 break; 952 break;
983 } 953 }
984 954
985 Thread* thread = Thread::Current(); 955 Thread* thread = Thread::Current();
986 NoReloadScope no_reload_scope(thread->isolate(), thread); 956 NoReloadScope no_reload_scope(thread->isolate(), thread);
987 return DartLibraryCalls::InstanceCreate(library, *class_name, 957 return DartLibraryCalls::InstanceCreate(library, *class_name,
988 *constructor_name, arguments); 958 *constructor_name, arguments);
989 } 959 }
990 960
991
992 } // namespace dart 961 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/exceptions.h ('k') | runtime/vm/exceptions_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698