Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
exceptions.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include <setjmp.h>
6
7#include "vm/exceptions.h"
8
11
12#include "lib/stacktrace.h"
13
14#include "vm/dart_api_impl.h"
15#include "vm/dart_entry.h"
16#include "vm/datastream.h"
17#include "vm/debugger.h"
19#include "vm/flags.h"
20#include "vm/log.h"
21#include "vm/longjump.h"
22#include "vm/object.h"
23#include "vm/object_store.h"
24#include "vm/stack_frame.h"
25#include "vm/stub_code.h"
26#include "vm/symbols.h"
27
28namespace dart {
29
30DECLARE_FLAG(bool, trace_deoptimization);
32 print_stacktrace_at_throw,
33 false,
34 "Prints a stack trace everytime a throw occurs.");
35
37 public:
39 virtual ~StackTraceBuilder() {}
40
41 virtual void AddFrame(const Object& code, uword pc_offset) = 0;
42};
43
45 public:
46 explicit PreallocatedStackTraceBuilder(const Instance& stacktrace)
47 : stacktrace_(StackTrace::Cast(stacktrace)),
48 cur_index_(0),
49 dropped_frames_(0) {
50 ASSERT(
51 stacktrace_.ptr() ==
52 Isolate::Current()->isolate_object_store()->preallocated_stack_trace());
53 }
55
56 void AddFrame(const Object& code, uword pc_offset) override;
57
58 private:
59 static constexpr int kNumTopframes = StackTrace::kPreallocatedStackdepth / 2;
60
61 const StackTrace& stacktrace_;
62 intptr_t cur_index_;
63 intptr_t dropped_frames_;
64
66};
67
69 uword pc_offset) {
70 if (cur_index_ >= StackTrace::kPreallocatedStackdepth) {
71 // The number of frames is overflowing the preallocated stack trace object.
72 Object& frame_code = Object::Handle();
73 intptr_t start = StackTrace::kPreallocatedStackdepth - (kNumTopframes - 1);
74 intptr_t null_slot = start - 2;
75 // We are going to drop one frame.
76 dropped_frames_++;
77 // Add an empty slot to indicate the overflow so that the toString
78 // method can account for the overflow.
79 if (stacktrace_.CodeAtFrame(null_slot) != Code::null()) {
80 stacktrace_.SetCodeAtFrame(null_slot, frame_code);
81 // We drop an extra frame here too.
82 dropped_frames_++;
83 }
84 // Encode the number of dropped frames into the pc offset.
85 stacktrace_.SetPcOffsetAtFrame(null_slot, dropped_frames_);
86 // Move frames one slot down so that we can accommodate the new frame.
87 for (intptr_t i = start; i < StackTrace::kPreallocatedStackdepth; i++) {
88 intptr_t prev = (i - 1);
89 frame_code = stacktrace_.CodeAtFrame(i);
90 const uword frame_offset = stacktrace_.PcOffsetAtFrame(i);
91 stacktrace_.SetCodeAtFrame(prev, frame_code);
92 stacktrace_.SetPcOffsetAtFrame(prev, frame_offset);
93 }
94 cur_index_ = (StackTrace::kPreallocatedStackdepth - 1);
95 }
96 stacktrace_.SetCodeAtFrame(cur_index_, code);
97 stacktrace_.SetPcOffsetAtFrame(cur_index_, pc_offset);
98 cur_index_ += 1;
99}
100
101static void BuildStackTrace(StackTraceBuilder* builder) {
105 StackFrame* frame = frames.NextFrame();
106 ASSERT(frame != nullptr); // We expect to find a dart invocation frame.
107 Code& code = Code::Handle();
108 for (; frame != nullptr; frame = frames.NextFrame()) {
109 if (!frame->IsDartFrame()) {
110 continue;
111 }
112 code = frame->LookupDartCode();
113 ASSERT(code.ContainsInstructionAt(frame->pc()));
114 const uword pc_offset = frame->pc() - code.PayloadStart();
115 builder->AddFrame(code, pc_offset);
116 }
117}
118
120 public:
123
124 // Iterate through the stack frames and try to find a frame with an
125 // exception handler. Once found, set the pc, sp and fp so that execution
126 // can continue in that frame. Sets 'needs_stacktrace' if there is no
127 // catch-all handler or if a stack-trace is specified in the catch.
128 bool Find() {
132 StackFrame* frame = frames.NextFrame();
133 if (frame == nullptr) return false; // No Dart frame.
134 handler_pc_set_ = false;
135 needs_stacktrace = false;
136 bool is_catch_all = false;
137 uword temp_handler_pc = kUwordMax;
138 bool is_optimized = false;
139 code_ = nullptr;
140 catch_entry_moves_cache_ = thread_->isolate()->catch_entry_moves_cache();
141
142 while (!frame->IsEntryFrame()) {
143 if (frame->IsDartFrame()) {
144 if (frame->FindExceptionHandler(thread_, &temp_handler_pc,
145 &needs_stacktrace, &is_catch_all,
146 &is_optimized)) {
147 if (!handler_pc_set_) {
148 handler_pc_set_ = true;
149 handler_pc = temp_handler_pc;
150 handler_sp = frame->sp();
151 handler_fp = frame->fp();
152 if (is_optimized &&
153 (handler_pc !=
154 StubCode::AsyncExceptionHandler().EntryPoint())) {
155 pc_ = frame->pc();
156 code_ = &Code::Handle(frame->LookupDartCode());
157 CatchEntryMovesRefPtr* cached_catch_entry_moves =
158 catch_entry_moves_cache_->Lookup(pc_);
159 if (cached_catch_entry_moves != nullptr) {
160 cached_catch_entry_moves_ = *cached_catch_entry_moves;
161 }
162 if (cached_catch_entry_moves_.IsEmpty()) {
163#if defined(DART_PRECOMPILED_RUNTIME)
164 // Only AOT mode is supported.
165 ReadCompressedCatchEntryMoves();
166#elif defined(DART_PRECOMPILER)
167 // Both AOT and JIT modes are supported.
168 if (FLAG_precompiled_mode) {
169 ReadCompressedCatchEntryMoves();
170 } else {
172 }
173#else
174 // Only JIT mode is supported.
175 ASSERT(!FLAG_precompiled_mode);
177#endif
178 }
179 }
180 }
181 if (needs_stacktrace || is_catch_all) {
182 return true;
183 }
184 }
185 } // if frame->IsDartFrame
186 frame = frames.NextFrame();
187 ASSERT(frame != nullptr);
188 } // while !frame->IsEntryFrame
189 ASSERT(frame->IsEntryFrame());
190 if (!handler_pc_set_) {
191 handler_pc = frame->pc();
192 handler_sp = frame->sp();
193 handler_fp = frame->fp();
194 }
195 // No catch-all encountered, needs stacktrace.
196 needs_stacktrace = true;
197 return handler_pc_set_;
198 }
199
200 // When entering catch block in the optimized code we need to execute
201 // catch entry moves that would morph the state of the frame into
202 // what catch entry expects.
204 if (code_ == nullptr || !code_->is_optimized()) {
205 return;
206 }
207
208 if (cached_catch_entry_moves_.IsEmpty()) {
209 catch_entry_moves_cache_->Insert(
210 pc_, CatchEntryMovesRefPtr(catch_entry_moves_));
211 } else {
212 catch_entry_moves_ = &cached_catch_entry_moves_.moves();
213 }
214
215 ExecuteCatchEntryMoves(*catch_entry_moves_);
216 }
217
219 Zone* zone = Thread::Current()->zone();
220 auto& value = Object::Handle(zone);
221 GrowableArray<Object*> dst_values;
222
224 ObjectPool* pool = nullptr;
225 for (int j = 0; j < moves.count(); j++) {
226 const CatchEntryMove& move = moves.At(j);
227
228 switch (move.source_kind()) {
230 if (pool == nullptr) {
232 }
233 value = pool->ObjectAt(move.src_slot());
234 break;
235
237 value = *TaggedSlotAt(fp, move.src_slot());
238 break;
239
241 value = Double::New(*SlotAt<float>(fp, move.src_slot()));
242 break;
243
245 value = Double::New(*SlotAt<double>(fp, move.src_slot()));
246 break;
247
249 value = Float32x4::New(*SlotAt<simd128_value_t>(fp, move.src_slot()));
250 break;
251
253 value = Float64x2::New(*SlotAt<simd128_value_t>(fp, move.src_slot()));
254 break;
255
257 value = Int32x4::New(*SlotAt<simd128_value_t>(fp, move.src_slot()));
258 break;
259
262 Utils::LowHighTo64Bits(*SlotAt<uint32_t>(fp, move.src_lo_slot()),
263 *SlotAt<int32_t>(fp, move.src_hi_slot())));
264 break;
265
267 value = Integer::New(*SlotAt<int64_t>(fp, move.src_slot()));
268 break;
269
271 value = Integer::New(*SlotAt<int32_t>(fp, move.src_slot()));
272 break;
273
275 value = Integer::New(*SlotAt<uint32_t>(fp, move.src_slot()));
276 break;
277
278 default:
279 UNREACHABLE();
280 }
281
282 dst_values.Add(&Object::Handle(zone, value.ptr()));
283 }
284
285 {
287 NoSafepointScope no_safepoint_scope(thread);
288
289 for (int j = 0; j < moves.count(); j++) {
290 const CatchEntryMove& move = moves.At(j);
291 *TaggedSlotAt(fp, move.dest_slot()) = dst_values[j]->ptr();
292 }
293
294 // Update the return address in the stack so the correct stack map is used
295 // for any stack walks that happen before we jump to the handler.
298 bool found = false;
299 for (StackFrame* frame = frames.NextFrame(); frame != nullptr;
300 frame = frames.NextFrame()) {
301 if (frame->fp() == handler_fp) {
302 ASSERT_EQUAL(frame->pc(), static_cast<uword>(pc_));
303 frame->set_pc(handler_pc);
304 found = true;
305 break;
306 }
307 }
308 ASSERT(found);
309 }
310 }
311
312#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
313 void ReadCompressedCatchEntryMoves() {
314 const intptr_t pc_offset = pc_ - code_->PayloadStart();
315 const auto& td = TypedData::Handle(code_->catch_entry_moves_maps());
316
317 CatchEntryMovesMapReader reader(td);
318 catch_entry_moves_ = reader.ReadMovesForPcOffset(pc_offset);
319 }
320#endif // defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
321
322#if !defined(DART_PRECOMPILED_RUNTIME)
323 void GetCatchEntryMovesFromDeopt(intptr_t num_vars, StackFrame* frame) {
324 Isolate* isolate = thread_->isolate();
325 DeoptContext* deopt_context =
327 nullptr, true, false /* deoptimizing_code */);
328 isolate->set_deopt_context(deopt_context);
329
330 catch_entry_moves_ = deopt_context->ToCatchEntryMoves(num_vars);
331
332 isolate->set_deopt_context(nullptr);
333 delete deopt_context;
334 }
335#endif // !defined(DART_PRECOMPILED_RUNTIME)
336
341
342 private:
343 template <typename T>
344 static T* SlotAt(uword fp, int stack_slot) {
345 const intptr_t frame_slot =
347 return reinterpret_cast<T*>(fp + frame_slot * kWordSize);
348 }
349
350 static ObjectPtr* TaggedSlotAt(uword fp, int stack_slot) {
351 return SlotAt<ObjectPtr>(fp, stack_slot);
352 }
353
354 typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader;
355 Thread* thread_;
356 Code* code_;
357 bool handler_pc_set_;
358 intptr_t pc_; // Current pc in the handler frame.
359
360 const CatchEntryMoves* catch_entry_moves_ = nullptr;
361 CatchEntryMovesCache* catch_entry_moves_cache_ = nullptr;
362 CatchEntryMovesRefPtr cached_catch_entry_moves_;
363};
364
366 using Reader = ReadStream::Raw<sizeof(int32_t), int32_t>;
367 const int32_t src = Reader::Read(stream);
368 const int32_t dest_and_kind = Reader::Read(stream);
369 return CatchEntryMove(src, dest_and_kind);
370}
371
372#if !defined(DART_PRECOMPILED_RUNTIME)
374 using Writer = BaseWriteStream::Raw<sizeof(int32_t), int32_t>;
375 Writer::Write(stream, src_);
376 Writer::Write(stream, dest_and_kind_);
377}
378#endif
379
380#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
381static intptr_t SlotIndexToFrameIndex(intptr_t slot) {
383}
384
385static intptr_t SlotIndexToFpRelativeOffset(intptr_t slot) {
386 return SlotIndexToFrameIndex(slot) * compiler::target::kWordSize;
387}
388
389const char* CatchEntryMove::ToCString() const {
390 char from[256];
391
392 switch (source_kind()) {
394 Utils::SNPrint(from, ARRAY_SIZE(from), "pp[%" Pd "]",
396 break;
397
399 Utils::SNPrint(from, ARRAY_SIZE(from), "fp[%" Pd "]",
401 break;
402
404 Utils::SNPrint(from, ARRAY_SIZE(from), "f32 [fp%+" Pd "]",
406 break;
407
409 Utils::SNPrint(from, ARRAY_SIZE(from), "f64 [fp%+" Pd "]",
411 break;
412
414 Utils::SNPrint(from, ARRAY_SIZE(from), "f32x4 [fp%+" Pd "]",
416 break;
417
419 Utils::SNPrint(from, ARRAY_SIZE(from), "f64x2 [fp%+" Pd "]",
421 break;
422
424 Utils::SNPrint(from, ARRAY_SIZE(from), "i32x4 [fp%+" Pd "]",
426 break;
427
429 Utils::SNPrint(from, ARRAY_SIZE(from), "i64 ([fp%+" Pd "], [fp%+" Pd "])",
432 break;
433
435 Utils::SNPrint(from, ARRAY_SIZE(from), "i64 [fp%+" Pd "]",
437 break;
438
440 Utils::SNPrint(from, ARRAY_SIZE(from), "i32 [fp%+" Pd "]",
442 break;
443
445 Utils::SNPrint(from, ARRAY_SIZE(from), "u32 [fp + %" Pd "]",
447 break;
448
449 default:
450 UNREACHABLE();
451 }
452
454 "fp[%+" Pd "] <- %s", SlotIndexToFrameIndex(dest_slot()), from);
455}
456
458 NoSafepointScope no_safepoint;
459
460 using Reader = ReadStream::Raw<sizeof(intptr_t), intptr_t>;
461
462 ReadStream stream(static_cast<uint8_t*>(bytes_.DataAddr(0)), bytes_.Length());
463
464 while (stream.PendingBytes() > 0) {
465 const intptr_t stream_position = stream.Position();
466 const intptr_t target_pc_offset = Reader::Read(&stream);
467 const intptr_t prefix_length = Reader::Read(&stream);
468 const intptr_t suffix_length = Reader::Read(&stream);
469 const intptr_t length = prefix_length + suffix_length;
470 Reader::Read(&stream); // Skip suffix_offset
471 for (intptr_t j = 0; j < prefix_length; j++) {
473 }
474
475 ReadStream inner_stream(static_cast<uint8_t*>(bytes_.DataAddr(0)),
476 bytes_.Length());
477 CatchEntryMoves* moves = ReadCompressedCatchEntryMovesSuffix(
478 &inner_stream, stream_position, length);
479 THR_Print(" [code+0x%08" Px "]: (% " Pd " moves)\n", target_pc_offset,
480 moves->count());
481 for (intptr_t i = 0; i < moves->count(); i++) {
482 THR_Print(" %s\n", moves->At(i).ToCString());
483 }
485 }
486}
487#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
488
490 intptr_t pc_offset) {
491 NoSafepointScope no_safepoint;
492
493 ReadStream stream(static_cast<uint8_t*>(bytes_.DataAddr(0)), bytes_.Length());
494
495 intptr_t position = 0;
496 intptr_t length = 0;
497 FindEntryForPc(&stream, pc_offset, &position, &length);
498
499 return ReadCompressedCatchEntryMovesSuffix(&stream, position, length);
500}
501
502void CatchEntryMovesMapReader::FindEntryForPc(ReadStream* stream,
503 intptr_t pc_offset,
504 intptr_t* position,
505 intptr_t* length) {
506 using Reader = ReadStream::Raw<sizeof(intptr_t), intptr_t>;
507
508 while (stream->PendingBytes() > 0) {
509 const intptr_t stream_position = stream->Position();
510 const intptr_t target_pc_offset = Reader::Read(stream);
511 const intptr_t prefix_length = Reader::Read(stream);
512 const intptr_t suffix_length = Reader::Read(stream);
513 Reader::Read(stream); // Skip suffix_offset
514 if (pc_offset == target_pc_offset) {
515 *position = stream_position;
516 *length = prefix_length + suffix_length;
517 return;
518 }
519
520 // Skip the prefix moves.
521 for (intptr_t j = 0; j < prefix_length; j++) {
523 }
524 }
525
526 UNREACHABLE();
527}
528
529CatchEntryMoves* CatchEntryMovesMapReader::ReadCompressedCatchEntryMovesSuffix(
530 ReadStream* stream,
531 intptr_t offset,
532 intptr_t length) {
533 using Reader = ReadStream::Raw<sizeof(intptr_t), intptr_t>;
534
535 CatchEntryMoves* moves = CatchEntryMoves::Allocate(length);
536
537 intptr_t remaining_length = length;
538
539 intptr_t moves_offset = 0;
540 while (remaining_length > 0) {
541 stream->SetPosition(offset);
542 Reader::Read(stream); // skip pc_offset
543 Reader::Read(stream); // skip prefix length
544 const intptr_t suffix_length = Reader::Read(stream);
545 const intptr_t suffix_offset = Reader::Read(stream);
546 const intptr_t to_read = remaining_length - suffix_length;
547 if (to_read > 0) {
548 for (int j = 0; j < to_read; j++) {
549 // The prefix is written from the back.
550 moves->At(moves_offset + to_read - j - 1) =
552 }
553 remaining_length -= to_read;
554 moves_offset += to_read;
555 }
556 offset = suffix_offset;
557 }
558
559 return moves;
560}
561
562static void FindErrorHandler(uword* handler_pc,
563 uword* handler_sp,
564 uword* handler_fp) {
568 StackFrame* frame = frames.NextFrame();
569 ASSERT(frame != nullptr);
570 while (!frame->IsEntryFrame()) {
571 frame = frames.NextFrame();
572 ASSERT(frame != nullptr);
573 }
574 ASSERT(frame->IsEntryFrame());
575 *handler_pc = frame->pc();
576 *handler_sp = frame->sp();
577 *handler_fp = frame->fp();
578}
579
580static void ClearLazyDeopts(Thread* thread, uword frame_pointer) {
581 if (thread->pending_deopts().HasPendingDeopts()) {
582 // We may be jumping over frames scheduled for lazy deopt. Remove these
583 // frames from the pending deopt table, but only after unmarking them so
584 // any stack walk that happens before the stack is unwound will still work.
585 {
586 DartFrameIterator frames(thread,
588 for (StackFrame* frame = frames.NextFrame(); frame != nullptr;
589 frame = frames.NextFrame()) {
590 if (frame->fp() >= frame_pointer) {
591 break;
592 }
593 if (frame->IsMarkedForLazyDeopt()) {
594 frame->UnmarkForLazyDeopt();
595 }
596 }
597 }
598
599#if defined(DEBUG)
600 ValidateFrames();
601#endif
602
604 frame_pointer, PendingDeopts::kClearDueToThrow);
605
606#if defined(DEBUG)
607 ValidateFrames();
608#endif
609 }
610}
611
612static void JumpToExceptionHandler(Thread* thread,
613 uword program_counter,
614 uword stack_pointer,
615 uword frame_pointer,
616 const Object& exception_object,
617 const Object& stacktrace_object) {
618 bool clear_deopt = false;
619 uword remapped_pc = thread->pending_deopts().RemapExceptionPCForDeopt(
620 program_counter, frame_pointer, &clear_deopt);
621 thread->set_active_exception(exception_object);
622 thread->set_active_stacktrace(stacktrace_object);
623 thread->set_resume_pc(remapped_pc);
624 uword run_exception_pc = StubCode::RunExceptionHandler().EntryPoint();
625 Exceptions::JumpToFrame(thread, run_exception_pc, stack_pointer,
626 frame_pointer, clear_deopt);
627}
628
629NO_SANITIZE_SAFE_STACK // This function manipulates the safestack pointer.
630 void
632 uword program_counter,
633 uword stack_pointer,
634 uword frame_pointer,
635 bool clear_deopt_at_target) {
637 const uword fp_for_clearing =
638 (clear_deopt_at_target ? frame_pointer + 1 : frame_pointer);
639 ClearLazyDeopts(thread, fp_for_clearing);
640
641#if defined(USING_SIMULATOR)
642 // Unwinding of the C++ frames and destroying of their stack resources is done
643 // by the simulator, because the target stack_pointer is a simulated stack
644 // pointer and not the C++ stack pointer.
645
646 // Continue simulating at the given pc in the given frame after setting up the
647 // exception object in the kExceptionObjectReg register and the stacktrace
648 // object (may be raw null) in the kStackTraceObjectReg register.
649
650 Simulator::Current()->JumpToFrame(program_counter, stack_pointer,
651 frame_pointer, thread);
652#else
653
654 // Prepare for unwinding frames by destroying all the stack resources
655 // in the previous frames.
656 StackResource::Unwind(thread);
657
658 // Unpoison the stack before we tear it down in the generated stub code.
659 uword current_sp = OSThread::GetCurrentStackPointer() - 1024;
660 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp),
661 stack_pointer - current_sp);
662
663 // We are jumping over C++ frames, so we have to set the safestack pointer
664 // back to what it was when we entered the runtime from Dart code.
665#if defined(USING_SAFE_STACK)
666 const uword saved_ssp = thread->saved_safestack_limit();
667 OSThread::SetCurrentSafestackPointer(saved_ssp);
668#endif
669
670#if defined(USING_SHADOW_CALL_STACK)
671 // The shadow call stack register will be restored by the JumpToFrame stub.
672#endif
673
674#if defined(USING_THREAD_SANITIZER)
675 if (thread->exit_through_ffi() == Thread::kExitThroughRuntimeCall) {
676 auto tsan_utils = thread->tsan_utils();
677 tsan_utils->exception_pc = program_counter;
678 tsan_utils->exception_sp = stack_pointer;
679 tsan_utils->exception_fp = frame_pointer;
680 longjmp(*(tsan_utils->setjmp_buffer), 1);
681 }
682#endif // defined(USING_THREAD_SANITIZER)
683
684 // Call a stub to set up the exception object in kExceptionObjectReg,
685 // to set up the stacktrace object in kStackTraceObjectReg, and to
686 // continue execution at the given pc in the given frame.
687 typedef void (*ExcpHandler)(uword, uword, uword, Thread*);
688 ExcpHandler func =
689 reinterpret_cast<ExcpHandler>(StubCode::JumpToFrame().EntryPoint());
690
691 if (thread->is_unwind_in_progress()) {
692 thread->SetUnwindErrorInProgress(true);
693 }
694 func(program_counter, stack_pointer, frame_pointer, thread);
695
696#endif
697 UNREACHABLE();
698}
699
700static FieldPtr LookupStackTraceField(const Instance& instance) {
701 if (instance.GetClassId() < kNumPredefinedCids) {
702 // 'class Error' is not a predefined class.
703 return Field::null();
704 }
705 Thread* thread = Thread::Current();
706 Zone* zone = thread->zone();
707 auto isolate_group = thread->isolate_group();
708 const auto& error_class =
709 Class::Handle(zone, isolate_group->object_store()->error_class());
710 // If instance class extends 'class Error' return '_stackTrace' field.
711 Class& test_class = Class::Handle(zone, instance.clazz());
713 while (true) {
714 if (test_class.ptr() == error_class.ptr()) {
715 return error_class.LookupInstanceFieldAllowPrivate(
716 Symbols::_stackTrace());
717 }
718 type = test_class.super_type();
719 if (type.IsNull()) return Field::null();
720 test_class = type.type_class();
721 }
722 UNREACHABLE();
723 return Field::null();
724}
725
728}
729
730DART_NORETURN
731static void ThrowExceptionHelper(Thread* thread,
732 const Instance& incoming_exception,
733 const Instance& existing_stacktrace,
734 const bool is_rethrow,
735 const bool bypass_debugger) {
736 // SuspendLongJumpScope during Dart entry ensures that if a longjmp base is
737 // available, it is the innermost error handler. If one is available, so
738 // should jump there instead.
739 RELEASE_ASSERT(thread->long_jump_base() == nullptr);
740 Zone* zone = thread->zone();
741 auto object_store = thread->isolate_group()->object_store();
742 Isolate* isolate = thread->isolate();
743#if !defined(PRODUCT)
744 if (!bypass_debugger) {
745 // Do not notify debugger on stack overflow and out of memory exceptions.
746 // The VM would crash when the debugger calls back into the VM to
747 // get values of variables.
748 if (incoming_exception.ptr() != object_store->out_of_memory() &&
749 incoming_exception.ptr() != object_store->stack_overflow()) {
750 isolate->debugger()->PauseException(incoming_exception);
751 }
752 }
753#endif
754 bool use_preallocated_stacktrace = false;
755 Instance& exception = Instance::Handle(zone, incoming_exception.ptr());
756 if (exception.IsNull()) {
757 const Array& args = Array::Handle(zone, Array::New(4));
758 const Smi& line_col = Smi::Handle(zone, Smi::New(-1));
759 args.SetAt(0, Symbols::OptimizedOut());
760 args.SetAt(1, line_col);
761 args.SetAt(2, line_col);
762 args.SetAt(3, String::Handle(String::New("Throw of null.")));
764 } else if (existing_stacktrace.IsNull() &&
765 (exception.ptr() == object_store->out_of_memory() ||
766 exception.ptr() == object_store->stack_overflow())) {
767 use_preallocated_stacktrace = true;
768 }
769 // Find the exception handler and determine if the handler needs a
770 // stacktrace.
771 ExceptionHandlerFinder finder(thread);
772 bool handler_exists = finder.Find();
773 uword handler_pc = finder.handler_pc;
774 uword handler_sp = finder.handler_sp;
775 uword handler_fp = finder.handler_fp;
776 bool handler_needs_stacktrace = finder.needs_stacktrace;
777 Instance& stacktrace = Instance::Handle(zone);
778 if (use_preallocated_stacktrace) {
779 if (handler_pc == 0) {
780 // No Dart frame.
781 ASSERT(incoming_exception.ptr() == object_store->out_of_memory());
783 zone,
784 isolate->isolate_object_store()->preallocated_unhandled_exception());
785 thread->long_jump_base()->Jump(1, error);
786 UNREACHABLE();
787 }
788 stacktrace = isolate->isolate_object_store()->preallocated_stack_trace();
789 PreallocatedStackTraceBuilder frame_builder(stacktrace);
790 ASSERT(existing_stacktrace.IsNull() ||
791 (existing_stacktrace.ptr() == stacktrace.ptr()));
792 ASSERT(existing_stacktrace.IsNull() || is_rethrow);
793 if (handler_needs_stacktrace && existing_stacktrace.IsNull()) {
794 BuildStackTrace(&frame_builder);
795 }
796 } else {
797 if (!existing_stacktrace.IsNull()) {
798 stacktrace = existing_stacktrace.ptr();
799 // If this is not a rethrow, it's a "throw with stacktrace".
800 // Set an Error object's stackTrace field if needed.
801 if (!is_rethrow) {
802 const Field& stacktrace_field =
803 Field::Handle(zone, LookupStackTraceField(exception));
804 if (!stacktrace_field.IsNull() &&
805 (exception.GetField(stacktrace_field) == Object::null())) {
806 exception.SetField(stacktrace_field, stacktrace);
807 }
808 }
809 } else {
810 // Get stacktrace field of class Error to determine whether we have a
811 // subclass of Error which carries around its stack trace.
812 const Field& stacktrace_field =
813 Field::Handle(zone, LookupStackTraceField(exception));
814 if (!stacktrace_field.IsNull() || handler_needs_stacktrace) {
815 // Collect the stacktrace if needed.
816 ASSERT(existing_stacktrace.IsNull());
817 stacktrace = Exceptions::CurrentStackTrace();
818 // If we have an Error object, then set its stackTrace field only if it
819 // not yet initialized.
820 if (!stacktrace_field.IsNull() &&
821 (exception.GetField(stacktrace_field) == Object::null())) {
822 exception.SetField(stacktrace_field, stacktrace);
823 }
824 }
825 }
826 }
827 // We expect to find a handler_pc, if the exception is unhandled
828 // then we expect to at least have the dart entry frame on the
829 // stack as Exceptions::Throw should happen only after a dart
830 // invocation has been done.
831 ASSERT(handler_pc != 0);
832
833 if (FLAG_print_stacktrace_at_throw) {
834 THR_Print("Exception '%s' thrown:\n", exception.ToCString());
835 THR_Print("%s\n", stacktrace.ToCString());
836 }
837 if (handler_exists) {
839 // Found a dart handler for the exception, jump to it.
840 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp,
841 exception, stacktrace);
842 } else {
843 // No dart exception handler found in this invocation sequence,
844 // so we create an unhandled exception object and return to the
845 // invocation stub so that it returns this unhandled exception
846 // object. The C++ code which invoked this dart sequence can check
847 // and do the appropriate thing (rethrow the exception to the
848 // dart invocation sequence above it, print diagnostics and terminate
849 // the isolate etc.). This can happen in the compiler, which is not
850 // allowed to allocate in new space, so we pass the kOld argument.
851 const UnhandledException& unhandled_exception = UnhandledException::Handle(
852 zone, exception.ptr() == object_store->out_of_memory()
853 ? isolate->isolate_object_store()
854 ->preallocated_unhandled_exception()
855 : UnhandledException::New(exception, stacktrace, Heap::kOld));
856 stacktrace = StackTrace::null();
857 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp,
858 unhandled_exception, stacktrace);
859 }
860 UNREACHABLE();
861}
862
863// Static helpers for allocating, initializing, and throwing an error instance.
864
865// Return the script of the Dart function that called the native entry or the
866// runtime entry. The frame iterator points to the callee.
868 StackFrame* caller_frame = iterator->NextFrame();
869 ASSERT(caller_frame != nullptr && caller_frame->IsDartFrame());
870 const Function& caller = Function::Handle(caller_frame->LookupDartFunction());
871#if defined(DART_PRECOMPILED_RUNTIME)
872 if (caller.IsNull()) return Script::null();
873#else
874 ASSERT(!caller.IsNull());
875#endif
876 return caller.script();
877}
878
879// Allocate a new instance of the given class name.
880// TODO(hausner): Rename this NewCoreInstance to call out the fact that
881// the class name is resolved in the core library implicitly?
882InstancePtr Exceptions::NewInstance(const char* class_name) {
883 Thread* thread = Thread::Current();
884 Zone* zone = thread->zone();
885 const String& cls_name =
886 String::Handle(zone, Symbols::New(thread, class_name));
887 const Library& core_lib = Library::Handle(Library::CoreLibrary());
888 // No ambiguity error expected: passing nullptr.
889 Class& cls = Class::Handle(core_lib.LookupClass(cls_name));
890 ASSERT(!cls.IsNull());
891 // There are no parameterized error types, so no need to set type arguments.
892 return Instance::New(cls);
893}
894
895// Allocate, initialize, and throw a TypeError.
897 const AbstractType& src_type,
898 const AbstractType& dst_type,
899 const String& dst_name) {
900 ASSERT(!dst_name.IsNull()); // Pass Symbols::Empty() instead.
901 Thread* thread = Thread::Current();
902 Zone* zone = thread->zone();
903 const Array& args = Array::Handle(zone, Array::New(4));
904
905 ExceptionType exception_type = kType;
906
907 DartFrameIterator iterator(thread,
909 const Script& script = Script::Handle(zone, GetCallerScript(&iterator));
910 const String& url = String::Handle(
911 zone, script.IsNull() ? Symbols::OptimizedOut().ptr() : script.url());
912 intptr_t line = -1;
913 intptr_t column = -1;
914 if (!script.IsNull()) {
915 script.GetTokenLocation(location, &line, &column);
916 }
917 // Initialize '_url', '_line', and '_column' arguments.
918 args.SetAt(0, url);
919 args.SetAt(1, Smi::Handle(zone, Smi::New(line)));
920 args.SetAt(2, Smi::Handle(zone, Smi::New(column)));
921
922 // Construct '_errorMsg'.
923 const GrowableObjectArray& pieces =
925
926 if (!dst_type.IsNull()) {
927 // Describe the type error.
928 if (!src_type.IsNull()) {
929 pieces.Add(Symbols::TypeQuote());
930 pieces.Add(String::Handle(zone, src_type.UserVisibleName()));
931 pieces.Add(Symbols::QuoteIsNotASubtypeOf());
932 }
933 pieces.Add(Symbols::TypeQuote());
934 pieces.Add(String::Handle(zone, dst_type.UserVisibleName()));
935 pieces.Add(Symbols::SingleQuote());
936 if (dst_name.Length() > 0) {
937 if (dst_name.ptr() == Symbols::InTypeCast().ptr()) {
938 pieces.Add(dst_name);
939 } else {
940 pieces.Add(Symbols::SpaceOfSpace());
941 pieces.Add(Symbols::SingleQuote());
942 pieces.Add(dst_name);
943 pieces.Add(Symbols::SingleQuote());
944 }
945 }
946 // Print ambiguous URIs of src and dst types.
947 URIs uris(zone, 12);
948 if (!src_type.IsNull()) {
949 src_type.EnumerateURIs(&uris);
950 }
951 if (!dst_type.IsDynamicType() && !dst_type.IsVoidType() &&
952 !dst_type.IsNeverType()) {
953 dst_type.EnumerateURIs(&uris);
954 }
955 const String& formatted_uris =
957 if (formatted_uris.Length() > 0) {
958 pieces.Add(Symbols::SpaceWhereNewLine());
959 pieces.Add(formatted_uris);
960 }
961 }
962 const Array& arr = Array::Handle(zone, Array::MakeFixedLength(pieces));
963 const String& error_msg = String::Handle(zone, String::ConcatAll(arr));
964 args.SetAt(3, error_msg);
965
966 // Type errors in the core library may be difficult to diagnose.
967 // Print type error information before throwing the error when debugging.
968 if (FLAG_print_stacktrace_at_throw) {
969 THR_Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ",
970 String::Handle(zone, script.url()).ToCString(), line, column);
971 THR_Print("%s\n", error_msg.ToCString());
972 }
973
974 // Throw TypeError instance.
975 Exceptions::ThrowByType(exception_type, args);
976 UNREACHABLE();
977}
978
979void Exceptions::Throw(Thread* thread, const Instance& exception) {
980 // Null object is a valid exception object.
981 ThrowExceptionHelper(thread, exception, StackTrace::Handle(thread->zone()),
982 /*is_rethrow=*/false,
983 /*bypass_debugger=*/false);
984}
985
987 const Instance& exception,
988 const Instance& stacktrace,
989 bool bypass_debugger /* = false */) {
990 // Null object is a valid exception object.
991 ThrowExceptionHelper(thread, exception, stacktrace, /*is_rethrow=*/true,
992 bypass_debugger);
993}
994
996 const Instance& exception,
997 const Instance& stacktrace) {
998 // Null object is a valid exception object.
999 ThrowExceptionHelper(thread, exception, stacktrace, /*is_rethrow=*/false,
1000 /*bypass_debugger=*/false);
1001}
1002
1004 ASSERT(!error.IsNull());
1005 Thread* thread = Thread::Current();
1006 // SuspendLongJumpScope during Dart entry ensures that if a longjmp base is
1007 // available, it is the innermost error handler. If one is available, so
1008 // should jump there instead.
1009 RELEASE_ASSERT(thread->long_jump_base() == nullptr);
1010 Zone* zone = thread->zone();
1011 if (error.IsUnhandledException()) {
1012 // If the error object represents an unhandled exception, then
1013 // rethrow the exception in the normal fashion.
1014 const UnhandledException& uhe = UnhandledException::Cast(error);
1015 const Instance& exc = Instance::Handle(zone, uhe.exception());
1016 const Instance& stk = Instance::Handle(zone, uhe.stacktrace());
1017 Exceptions::ReThrow(thread, exc, stk);
1018 } else {
1019 // Return to the invocation stub and return this error object. The
1020 // C++ code which invoked this dart sequence can check and do the
1021 // appropriate thing.
1022 uword handler_pc = 0;
1023 uword handler_sp = 0;
1024 uword handler_fp = 0;
1025 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp);
1026 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error,
1027 StackTrace::Handle(zone)); // Null stacktrace.
1028 }
1029 UNREACHABLE();
1030}
1031
1033 Thread* thread = Thread::Current();
1034 Zone* zone = thread->zone();
1035 ASSERT(thread->top_exit_frame_info() != 0);
1036 Instance& stacktrace = Instance::Handle(zone);
1037 if (error.IsUnhandledException()) {
1038 const UnhandledException& uhe = UnhandledException::Cast(error);
1039 stacktrace = uhe.stacktrace();
1040 } else {
1041 stacktrace = Exceptions::CurrentStackTrace();
1042 }
1043 uword handler_pc = 0;
1044 uword handler_sp = 0;
1045 uword handler_fp = 0;
1046 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp);
1047 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error,
1048 stacktrace);
1049 UNREACHABLE();
1050}
1051
1053 Thread* thread = Thread::Current();
1054 const Object& result =
1055 Object::Handle(thread->zone(), Create(type, arguments));
1056 if (result.IsError()) {
1057 // We got an error while constructing the exception object.
1058 // Propagate the error instead of throwing the exception.
1059 PropagateError(Error::Cast(result));
1060 } else {
1061 ASSERT(result.IsInstance());
1062 Throw(thread, Instance::Cast(result));
1063 }
1064}
1065
1067 auto thread = Thread::Current();
1068 auto isolate_group = thread->isolate_group();
1069 const Instance& oom = Instance::Handle(
1070 thread->zone(), isolate_group->object_store()->out_of_memory());
1071 Throw(thread, oom);
1072}
1073
1075 auto thread = Thread::Current();
1076 auto isolate_group = thread->isolate_group();
1077 const Instance& stack_overflow = Instance::Handle(
1078 thread->zone(), isolate_group->object_store()->stack_overflow());
1079 Throw(thread, stack_overflow);
1080}
1081
1087
1089 const Array& args = Array::Handle(Array::New(1));
1090 args.SetAt(0, arg);
1092}
1093
1094void Exceptions::ThrowRangeError(const char* argument_name,
1095 const Integer& argument_value,
1096 intptr_t expected_from,
1097 intptr_t expected_to) {
1098 const Array& args = Array::Handle(Array::New(4));
1099 args.SetAt(0, argument_value);
1100 args.SetAt(1, Integer::Handle(Integer::New(expected_from)));
1101 args.SetAt(2, Integer::Handle(Integer::New(expected_to)));
1102 args.SetAt(3, String::Handle(String::New(argument_name)));
1104}
1105
1111
1117
1123
1131
1133 Library& library = Library::Handle();
1134 const String* class_name = nullptr;
1135 const String* constructor_name = &Symbols::Dot();
1136 switch (type) {
1137 case kNone:
1138 case kStackOverflow:
1139 case kOutOfMemory:
1140 UNREACHABLE();
1141 break;
1142 case kRange:
1143 library = Library::CoreLibrary();
1144 class_name = &Symbols::RangeError();
1145 constructor_name = &Symbols::DotRange();
1146 break;
1147 case kRangeMsg:
1148 library = Library::CoreLibrary();
1149 class_name = &Symbols::RangeError();
1150 constructor_name = &Symbols::Dot();
1151 break;
1152 case kArgument:
1153 library = Library::CoreLibrary();
1154 class_name = &Symbols::ArgumentError();
1155 break;
1156 case kArgumentValue:
1157 library = Library::CoreLibrary();
1158 class_name = &Symbols::ArgumentError();
1159 constructor_name = &Symbols::DotValue();
1160 break;
1161 case kState:
1162 library = Library::CoreLibrary();
1163 class_name = &Symbols::StateError();
1164 break;
1166 library = Library::CoreLibrary();
1167 class_name = &Symbols::IntegerDivisionByZeroException();
1168 break;
1169 case kNoSuchMethod:
1170 library = Library::CoreLibrary();
1171 class_name = &Symbols::NoSuchMethodError();
1172 constructor_name = &Symbols::DotWithType();
1173 break;
1174 case kFormat:
1175 library = Library::CoreLibrary();
1176 class_name = &Symbols::FormatException();
1177 break;
1178 case kUnsupported:
1179 library = Library::CoreLibrary();
1180 class_name = &Symbols::UnsupportedError();
1181 break;
1182 case kIsolateSpawn:
1183 library = Library::IsolateLibrary();
1184 class_name = &Symbols::IsolateSpawnException();
1185 break;
1186 case kAssertion:
1187 library = Library::CoreLibrary();
1188 class_name = &Symbols::AssertionError();
1189 constructor_name = &Symbols::DotCreate();
1190 break;
1191 case kType:
1192 library = Library::CoreLibrary();
1193 class_name = &Symbols::TypeError();
1194 constructor_name = &Symbols::DotCreate();
1195 break;
1197#if defined(DART_PRECOMPILED_RUNTIME)
1198 UNREACHABLE();
1199#else
1200 library = Library::MirrorsLibrary();
1201 class_name = &Symbols::AbstractClassInstantiationError();
1202 constructor_name = &Symbols::DotCreate();
1203 break;
1204#endif
1206 library = Library::CoreLibrary();
1207 class_name = &Symbols::_CyclicInitializationError();
1208 break;
1209 case kCompileTimeError:
1210 library = Library::CoreLibrary();
1211 class_name = &Symbols::_CompileTimeError();
1212 break;
1214 library = Library::InternalLibrary();
1215 class_name = &Symbols::LateError();
1216 constructor_name = &Symbols::DotFieldADI();
1217 break;
1219 library = Library::InternalLibrary();
1220 class_name = &Symbols::LateError();
1221 constructor_name = &Symbols::DotFieldNI();
1222 break;
1223 }
1224
1226 *constructor_name, arguments);
1227}
1228
1229UnhandledExceptionPtr Exceptions::CreateUnhandledException(Zone* zone,
1231 const char* msg) {
1232 const String& error_str = String::Handle(zone, String::New(msg));
1233 const Array& args = Array::Handle(zone, Array::New(1));
1234 args.SetAt(0, error_str);
1235
1237 const StackTrace& stacktrace = StackTrace::Handle(zone);
1238 return UnhandledException::New(Instance::Cast(result), stacktrace);
1239}
1240
1241} // namespace dart
AutoreleasePool pool
static float prev(float f)
static sk_sp< Effect > Create()
#define ASAN_UNPOISON(ptr, len)
#define UNREACHABLE()
Definition assert.h:248
#define ASSERT_EQUAL(expected, actual)
Definition assert.h:309
#define RELEASE_ASSERT(cond)
Definition assert.h:327
StringPtr UserVisibleName() const
Definition object.cc:21392
bool IsVoidType() const
Definition object.h:9169
static StringPtr PrintURIs(URIs *uris)
Definition object.cc:21340
bool IsDynamicType() const
Definition object.h:9166
virtual void EnumerateURIs(URIs *uris) const
Definition object.cc:21306
bool IsNeverType() const
Definition object.cc:21432
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
static ArrayPtr MakeFixedLength(const GrowableObjectArray &growable_array, bool unique=false)
Definition object.cc:25014
void Add(const T &value)
intptr_t dest_slot() const
Definition exceptions.h:180
intptr_t src_hi_slot() const
Definition exceptions.h:175
const char * ToCString() const
void WriteTo(BaseWriteStream *stream)
intptr_t src_slot() const
Definition exceptions.h:165
SourceKind source_kind() const
Definition exceptions.h:161
static CatchEntryMove ReadFrom(ReadStream *stream)
intptr_t src_lo_slot() const
Definition exceptions.h:170
CatchEntryMoves * ReadMovesForPcOffset(intptr_t pc_offset)
const CatchEntryMoves & moves()
Definition exceptions.h:331
intptr_t count() const
Definition exceptions.h:265
static void Free(const CatchEntryMoves *moves)
Definition exceptions.h:261
static CatchEntryMoves * Allocate(intptr_t num_moves)
Definition exceptions.h:254
CatchEntryMove & At(intptr_t i)
Definition exceptions.h:266
TypePtr super_type() const
Definition object.h:1433
bool is_optimized() const
Definition object.h:6790
ObjectPoolPtr GetObjectPool() const
Definition object.cc:17773
intptr_t num_variables() const
Definition object.cc:17722
uword PayloadStart() const
Definition object.h:6823
StackFrame * NextFrame()
static ObjectPtr InstanceCreate(const Library &library, const String &exception_name, const String &constructor_name, const Array &arguments)
void PauseException(const Instance &exc)
Definition debugger.cc:1914
const CatchEntryMoves * ToCatchEntryMoves(intptr_t num_vars)
static DoublePtr New(double d, Heap::Space space=Heap::kNew)
Definition object.cc:23481
void ExecuteCatchEntryMoves(const CatchEntryMoves &moves)
void GetCatchEntryMovesFromDeopt(intptr_t num_vars, StackFrame *frame)
ExceptionHandlerFinder(Thread *thread)
static DART_NORETURN void ThrowStateError(const Instance &arg)
static DART_NORETURN void ThrowStackOverflow()
static DART_NORETURN void JumpToFrame(Thread *thread, uword program_counter, uword stack_pointer, uword frame_pointer, bool clear_deopt_at_target)
static DART_NORETURN void ThrowByType(ExceptionType type, const Array &arguments)
static DART_NORETURN void ThrowOOM()
static DART_NORETURN void ThrowRangeError(const char *argument_name, const Integer &argument_value, intptr_t expected_from, intptr_t expected_to)
static DART_NORETURN void ThrowUnsupportedError(const char *msg)
static InstancePtr NewInstance(const char *class_name)
static DART_NORETURN void ThrowLateFieldAssignedDuringInitialization(const String &name)
static DART_NORETURN void Throw(Thread *thread, const Instance &exception)
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
static DART_NORETURN void PropagateToEntry(const Error &error)
static ScriptPtr GetCallerScript(DartFrameIterator *iterator)
@ kAbstractClassInstantiation
Definition exceptions.h:69
@ kLateFieldAssignedDuringInitialization
Definition exceptions.h:72
@ kIntegerDivisionByZeroException
Definition exceptions.h:60
static StackTracePtr CurrentStackTrace()
static DART_NORETURN void ThrowLateFieldNotInitialized(const String &name)
static DART_NORETURN void ThrowCompileTimeError(const LanguageError &error)
static ObjectPtr Create(ExceptionType type, const Array &arguments)
static UnhandledExceptionPtr CreateUnhandledException(Zone *zone, ExceptionType type, const char *msg)
static DART_NORETURN void ReThrow(Thread *thread, const Instance &exception, const Instance &stacktrace, bool bypass_debugger=false)
static void CreateAndThrowTypeError(TokenPosition location, const AbstractType &src_type, const AbstractType &dst_type, const String &dst_name)
static DART_NORETURN void ThrowWithStackTrace(Thread *thread, const Instance &exception, const Instance &stacktrace)
static DART_NORETURN void PropagateError(const Error &error)
void Insert(K key, V value)
Definition fixed_cache.h:43
V * Lookup(K key)
Definition fixed_cache.h:35
static Float32x4Ptr New(float value0, float value1, float value2, float value3, Heap::Space space=Heap::kNew)
Definition object.cc:25386
static Float64x2Ptr New(double value0, double value1, Heap::Space space=Heap::kNew)
Definition object.cc:25554
ScriptPtr script() const
Definition object.cc:10939
void Add(const Object &value, Heap::Space space=Heap::kNew) const
Definition object.cc:25070
static GrowableObjectArrayPtr New(Heap::Space space=Heap::kNew)
Definition object.h:11118
@ kOld
Definition heap.h:39
ObjectPtr GetField(const Field &field) const
Definition object.cc:20516
void SetField(const Field &field, const Object &value) const
Definition object.cc:20535
static InstancePtr New(const Class &cls, Heap::Space space=Heap::kNew)
Definition object.cc:20976
static Int32x4Ptr New(int32_t value0, int32_t value1, int32_t value2, int32_t value3, Heap::Space space=Heap::kNew)
Definition object.cc:25470
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition object.cc:23063
ObjectStore * object_store() const
Definition isolate.h:505
void set_deopt_context(DeoptContext *value)
Definition isolate.h:1209
static Isolate * Current()
Definition isolate.h:939
IsolateObjectStore * isolate_object_store() const
Definition isolate.h:960
Debugger * debugger() const
Definition isolate.h:1061
CatchEntryMovesCache * catch_entry_moves_cache()
Definition isolate.h:1405
static LibraryPtr CoreLibrary()
Definition object.cc:14834
static LibraryPtr MirrorsLibrary()
Definition object.cc:14863
static LibraryPtr IsolateLibrary()
Definition object.cc:14854
ClassPtr LookupClass(const String &name) const
Definition object.cc:14152
static LibraryPtr InternalLibrary()
Definition object.cc:14850
DART_NORETURN void Jump(int value, const Error &error)
Definition longjump.cc:22
static uword GetCurrentStackPointer()
Definition os_thread.cc:132
static ObjectPtr null()
Definition object.h:433
ObjectPtr ptr() const
Definition object.h:332
virtual const char * ToCString() const
Definition object.h:366
bool IsNull() const
Definition object.h:363
static Object & Handle()
Definition object.h:407
void ClearPendingDeoptsBelow(uword fp, ClearReason reason)
uword RemapExceptionPCForDeopt(uword program_counter, uword frame_pointer, bool *clear_deopt)
void AddFrame(const Object &code, uword pc_offset) override
Definition exceptions.cc:68
PreallocatedStackTraceBuilder(const Instance &stacktrace)
Definition exceptions.cc:46
void JumpToFrame(uword pc, uword sp, uword fp, Thread *thread)
static Simulator * Current()
static SmiPtr New(intptr_t value)
Definition object.h:9985
virtual bool IsDartFrame(bool validate=true) const
Definition stack_frame.h:97
FunctionPtr LookupDartFunction() const
ThreadState * thread() const
Definition allocation.h:33
static void Unwind(ThreadState *thread)
Definition allocation.h:36
virtual void AddFrame(const Object &code, uword pc_offset)=0
void SetPcOffsetAtFrame(intptr_t frame_index, uword pc_offset) const
Definition object.cc:26121
void SetCodeAtFrame(intptr_t frame_index, const Object &code) const
Definition object.cc:26109
static constexpr int kPreallocatedStackdepth
Definition object.h:12532
uword PcOffsetAtFrame(intptr_t frame_index) const
Definition object.cc:26115
ObjectPtr CodeAtFrame(intptr_t frame_index) const
Definition object.cc:26104
intptr_t Length() const
Definition object.h:10189
static StringPtr ConcatAll(const Array &strings, Heap::Space space=Heap::kNew)
Definition object.cc:24127
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition object.cc:23777
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition object.cc:24205
static const String & SingleQuote()
Definition symbols.h:656
static StringPtr New(Thread *thread, const char *cstr)
Definition symbols.h:722
static const String & Dot()
Definition symbols.h:612
Zone * zone() const
LongJumpScope * long_jump_base() const
void set_active_stacktrace(const Object &value)
Definition thread.cc:226
static Thread * Current()
Definition thread.h:361
PendingDeopts & pending_deopts()
Definition thread.h:1131
void set_resume_pc(uword value)
Definition thread.h:861
void SetUnwindErrorInProgress(bool value)
Definition thread.h:1003
@ kExitThroughRuntimeCall
Definition thread.h:471
bool is_unwind_in_progress() const
Definition thread.h:638
uword top_exit_frame_info() const
Definition thread.h:678
ExecutionState execution_state() const
Definition thread.h:1027
Isolate * isolate() const
Definition thread.h:533
IsolateGroup * isolate_group() const
Definition thread.h:540
void set_active_exception(const Object &value)
Definition thread.cc:222
intptr_t Length() const
Definition object.h:11492
void * DataAddr(intptr_t byte_offset) const
Definition object.h:11545
InstancePtr exception() const
Definition object.h:8117
static UnhandledExceptionPtr New(const Instance &exception, const Instance &stacktrace, Heap::Space space=Heap::kNew)
Definition object.cc:19989
InstancePtr stacktrace() const
Definition object.h:8122
static int SNPrint(char *str, size_t size, const char *format,...) PRINTF_ATTRIBUTE(3
static int64_t LowHighTo64Bits(uint32_t low, int32_t high)
Definition utils.h:362
char * PrintToString(const char *format,...) PRINTF_ATTRIBUTE(2
Definition zone.cc:313
#define THR_Print(format,...)
Definition log.h:20
#define ASSERT(E)
VkInstance instance
Definition main.cc:48
double frame
Definition examples.cpp:31
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
#define DECLARE_FLAG(type, name)
Definition flags.h:14
#define DEFINE_FLAG(type, name, default_value, comment)
Definition flags.h:16
size_t length
const char *const name
StackTracePtr GetStackTraceForException()
Definition stacktrace.cc:56
const char *const class_name
@ kNumPredefinedCids
Definition class_id.h:257
static void ClearLazyDeopts(Thread *thread, uword frame_pointer)
constexpr uword kUwordMax
Definition globals.h:519
uintptr_t uword
Definition globals.h:501
const uint32_t fp
FixedCache< intptr_t, CatchEntryMovesRefPtr, 16 > CatchEntryMovesCache
Definition isolate.h:130
static void BuildStackTrace(StackTraceBuilder *builder)
static intptr_t SlotIndexToFrameIndex(intptr_t slot)
FrameLayout runtime_frame_layout
static void FindErrorHandler(uword *handler_pc, uword *handler_sp, uword *handler_fp)
static FieldPtr LookupStackTraceField(const Instance &instance)
static intptr_t SlotIndexToFpRelativeOffset(intptr_t slot)
constexpr intptr_t kWordSize
Definition globals.h:509
static DART_NORETURN void ThrowExceptionHelper(Thread *thread, const Instance &incoming_exception, const Instance &existing_stacktrace, const bool is_rethrow, const bool bypass_debugger)
static void JumpToExceptionHandler(Thread *thread, uword program_counter, uword stack_pointer, uword frame_pointer, const Object &exception_object, const Object &stacktrace_object)
#define Px
Definition globals.h:410
#define Pd
Definition globals.h:408
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
#define T
#define NO_SANITIZE_SAFE_STACK
Definition safe_stack.h:17
Point offset
intptr_t FrameSlotForVariableIndex(intptr_t index) const
#define ARRAY_SIZE(array)
Definition globals.h:72