Flutter Engine
The Flutter Engine
errors.cc
Go to the documentation of this file.
1// Copyright (c) 2012, 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
6#include "vm/exceptions.h"
7#include "vm/object_store.h"
8#include "vm/runtime_entry.h"
9#include "vm/stack_frame.h"
10#include "vm/symbols.h"
11
12namespace dart {
13
14// Scan the stack until we hit the first function in the _AssertionError
15// class. We then return the next frame's script taking inlining into account.
16static ScriptPtr FindScript(DartFrameIterator* iterator) {
17#if defined(DART_PRECOMPILED_RUNTIME)
18 // The precompiled runtime faces two issues in recovering the correct
19 // assertion text. First, the precompiled runtime does not include
20 // the inlining meta-data so we cannot walk the inline-aware stack trace.
21 // Second, the script text itself is missing so whatever script is returned
22 // from here will be missing the assertion expression text.
23 iterator->NextFrame(); // Skip _AssertionError._evaluateAssertion frame
24 return Exceptions::GetCallerScript(iterator);
25#else
26 StackFrame* stack_frame = iterator->NextFrame();
28 Function& func = Function::Handle();
29 const Class& assert_error_class =
30 Class::Handle(Library::LookupCoreClass(Symbols::AssertionError()));
31 ASSERT(!assert_error_class.IsNull());
32 bool hit_assertion_error = false;
33 for (; stack_frame != nullptr; stack_frame = iterator->NextFrame()) {
34 code = stack_frame->LookupDartCode();
35 if (code.is_optimized()) {
36 InlinedFunctionsIterator inlined_iterator(code, stack_frame->pc());
37 while (!inlined_iterator.Done()) {
38 func = inlined_iterator.function();
39 if (hit_assertion_error) {
40 return func.script();
41 }
42 ASSERT(!hit_assertion_error);
43 hit_assertion_error = (func.Owner() == assert_error_class.ptr());
44 inlined_iterator.Advance();
45 }
46 continue;
47 } else {
48 func = code.function();
49 }
50 ASSERT(!func.IsNull());
51 if (hit_assertion_error) {
52 return func.script();
53 }
54 ASSERT(!hit_assertion_error);
55 hit_assertion_error = (func.Owner() == assert_error_class.ptr());
56 }
58 return Script::null();
59#endif // defined(DART_PRECOMPILED_RUNTIME)
60}
61
62// Allocate and throw a new AssertionError.
63// Arg0: index of the first token of the failed assertion.
64// Arg1: index of the first token after the failed assertion.
65// Arg2: Message object or null.
66// Return value: none, throws an exception.
67DEFINE_NATIVE_ENTRY(AssertionError_throwNew, 0, 3) {
68 // No need to type check the arguments. This function can only be called
69 // internally from the VM.
70 const TokenPosition assertion_start = TokenPosition::Deserialize(
71 Smi::CheckedHandle(zone, arguments->NativeArgAt(0)).Value());
72 const TokenPosition assertion_end = TokenPosition::Deserialize(
73 Smi::CheckedHandle(zone, arguments->NativeArgAt(1)).Value());
74
75 const Instance& message =
76 Instance::CheckedHandle(zone, arguments->NativeArgAt(2));
77 const Array& args = Array::Handle(zone, Array::New(5));
78
79 DartFrameIterator iterator(thread,
81 iterator.NextFrame(); // Skip native call.
82 const Script& script = Script::Handle(FindScript(&iterator));
83
84 // Initialize argument 'failed_assertion' with source snippet.
85 auto& condition_text = String::Handle();
86 // Extract the assertion condition text (if source is available).
87 intptr_t from_line = -1, from_column = -1;
88 String& url = String::Handle();
89 if (!script.IsNull()) {
90 if (script.GetTokenLocation(assertion_start, &from_line, &from_column)) {
91 // Extract the assertion condition text (if source is available).
92 intptr_t to_line, to_column;
93 script.GetTokenLocation(assertion_end, &to_line, &to_column);
94 condition_text =
95 script.GetSnippet(from_line, from_column, to_line, to_column);
96 }
97 url = script.url();
98 }
99 if (condition_text.IsNull()) {
100 condition_text = Symbols::OptimizedOut().ptr();
101 }
102 args.SetAt(0, condition_text);
103
104 // Initialize location arguments starting at position 1.
105 args.SetAt(1, url);
106 args.SetAt(2, Smi::Handle(Smi::New(from_line)));
107 args.SetAt(3, Smi::Handle(Smi::New(from_column)));
108 args.SetAt(4, message);
109
111 UNREACHABLE();
112 return Object::null();
113}
114
115// Allocate and throw a new AssertionError.
116// Arg0: Source code snippet of failed assertion.
117// Arg1: Script url string.
118// Arg2: Line number.
119// Arg3: Column number.
120// Arg4: Message object or null.
121// Return value: none, throws an exception.
122DEFINE_NATIVE_ENTRY(AssertionError_throwNewSource, 0, 5) {
123 // No need to type check the arguments. This function can only be called
124 // internally from the VM.
125 const String& failed_assertion =
126 String::CheckedHandle(zone, arguments->NativeArgAt(0));
127 const String& script_url =
128 String::CheckedHandle(zone, arguments->NativeArgAt(1));
129 const intptr_t line =
130 Smi::CheckedHandle(zone, arguments->NativeArgAt(2)).Value();
131 const intptr_t column =
132 Smi::CheckedHandle(zone, arguments->NativeArgAt(3)).Value();
133 const Instance& message =
134 Instance::CheckedHandle(zone, arguments->NativeArgAt(4));
135
136 const Array& args = Array::Handle(zone, Array::New(5));
137
138 args.SetAt(0, failed_assertion);
139 args.SetAt(1, script_url);
140 args.SetAt(2, Smi::Handle(zone, Smi::New(line)));
141 args.SetAt(3, Smi::Handle(zone, Smi::New(column)));
142 args.SetAt(4, message);
143
145 UNREACHABLE();
146 return Object::null();
147}
148
149// Allocate and throw a new TypeError.
150// Arg0: index of the token of the failed type check.
151// Arg1: src value.
152// Arg2: dst type.
153// Arg3: dst name.
154// Return value: none, throws an exception.
155DEFINE_NATIVE_ENTRY(TypeError_throwNew, 0, 4) {
156 // No need to type check the arguments. This function can only be called
157 // internally from the VM.
159 Smi::CheckedHandle(zone, arguments->NativeArgAt(0)).Value());
160 const Instance& src_value =
161 Instance::CheckedHandle(zone, arguments->NativeArgAt(1));
162 const AbstractType& dst_type =
163 AbstractType::CheckedHandle(zone, arguments->NativeArgAt(2));
164 const String& dst_name =
165 String::CheckedHandle(zone, arguments->NativeArgAt(3));
166 const AbstractType& src_type =
168 Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name);
169 UNREACHABLE();
170 return Object::null();
171}
172
173// Rethrow an error with a stacktrace.
174DEFINE_NATIVE_ENTRY(Error_throwWithStackTrace, 0, 2) {
175 GET_NON_NULL_NATIVE_ARGUMENT(Instance, error, arguments->NativeArgAt(0));
176 GET_NON_NULL_NATIVE_ARGUMENT(Instance, stacktrace, arguments->NativeArgAt(1));
177 Exceptions::ThrowWithStackTrace(thread, error, stacktrace);
178 return Object::null();
179}
180
181} // namespace dart
#define UNREACHABLE()
Definition: assert.h:248
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.h:10959
StackFrame * NextFrame()
Definition: stack_frame.h:352
static DART_NORETURN void ThrowByType(ExceptionType type, const Array &arguments)
Definition: exceptions.cc:1052
static ScriptPtr GetCallerScript(DartFrameIterator *iterator)
Definition: exceptions.cc:867
static void CreateAndThrowTypeError(TokenPosition location, const AbstractType &src_type, const AbstractType &dst_type, const String &dst_name)
Definition: exceptions.cc:896
static DART_NORETURN void ThrowWithStackTrace(Thread *thread, const Instance &exception, const Instance &stacktrace)
Definition: exceptions.cc:995
ScriptPtr script() const
Definition: object.cc:10881
ClassPtr Owner() const
Definition: object.cc:10841
@ kNew
Definition: heap.h:38
FunctionPtr function() const
Definition: stack_frame.h:373
AbstractTypePtr GetType(Heap::Space space) const
Definition: object.cc:20520
static ClassPtr LookupCoreClass(const String &class_name)
Definition: object.cc:14689
static ObjectPtr null()
Definition: object.h:433
ObjectPtr ptr() const
Definition: object.h:332
bool IsNull() const
Definition: object.h:363
static Object & Handle()
Definition: object.h:407
static SmiPtr New(intptr_t value)
Definition: object.h:10006
uword pc() const
Definition: stack_frame.h:43
CodePtr LookupDartCode() const
Definition: stack_frame.cc:336
static TokenPosition Deserialize(int32_t value)
#define ASSERT(E)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
Win32Message message
Definition: dart_vm.cc:33
static ScriptPtr FindScript(DartFrameIterator *iterator)
Definition: errors.cc:16
DEFINE_NATIVE_ENTRY(List_allocate, 0, 2)
Definition: array.cc:13
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)
Definition: native_entry.h:74