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

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

Issue 340203003: Cleanup of error and warning reporting. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/report.h ('k') | runtime/vm/report_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
(Empty)
1 // Copyright (c) 2014, 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 "vm/report.h"
6
7 #include "vm/code_patcher.h"
8 #include "vm/exceptions.h"
9 #include "vm/flags.h"
10 #include "vm/longjump.h"
11 #include "vm/object.h"
12 #include "vm/stack_frame.h"
13 #include "vm/symbols.h"
14
15 namespace dart {
16
17 DEFINE_FLAG(int, stacktrace_depth_on_warning, 5,
18 "Maximal number of stack frames to print after a runtime warning.");
19 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
20 DEFINE_FLAG(bool, warn_on_javascript_compatibility, false,
21 "Warn on incompatibilities between vm and dart2js.");
22 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors.");
23
24
25 RawString* Report::PrependSnippet(Kind kind,
26 const Script& script,
27 intptr_t token_pos,
28 const String& message) {
29 const char* message_header;
30 switch (kind) {
31 case kWarning: message_header = "warning"; break;
32 case kJSWarning: message_header = "javascript compatibility warning"; break;
33 case kError: message_header = "error"; break;
34 case kMalformedType: message_header = "malformed type"; break;
35 case kMalboundedType: message_header = "malbounded type"; break;
36 case kBailout: message_header = "bailout"; break;
37 default: message_header = ""; UNREACHABLE();
38 }
39 String& result = String::Handle();
40 if (!script.IsNull()) {
41 const String& script_url = String::Handle(script.url());
42 if (token_pos >= 0) {
43 intptr_t line, column;
44 script.GetTokenLocation(token_pos, &line, &column);
45 // Only report the line position if we have the original source. We still
46 // need to get a valid column so that we can report the ^ mark below the
47 // snippet.
48 if (script.HasSource()) {
49 result = String::NewFormatted("'%s': %s: line %" Pd " pos %" Pd ": ",
50 script_url.ToCString(),
51 message_header,
52 line,
53 column);
54 } else {
55 result = String::NewFormatted("'%s': %s: line %" Pd ": ",
56 script_url.ToCString(),
57 message_header,
58 line);
59 }
60 // Append the formatted error or warning message.
61 result = String::Concat(result, message);
62 // Append the source line.
63 const String& script_line = String::Handle(script.GetLine(line));
64 ASSERT(!script_line.IsNull());
65 result = String::Concat(result, Symbols::NewLine());
66 result = String::Concat(result, script_line);
67 result = String::Concat(result, Symbols::NewLine());
68 // Append the column marker.
69 const String& column_line = String::Handle(
70 String::NewFormatted("%*s\n", static_cast<int>(column), "^"));
71 result = String::Concat(result, column_line);
72 } else {
73 // Token position is unknown.
74 result = String::NewFormatted("'%s': %s: ",
75 script_url.ToCString(),
76 message_header);
77 result = String::Concat(result, message);
78 }
79 } else {
80 // Script is unknown.
81 // Append the formatted error or warning message.
82 result = String::NewFormatted("%s: ", message_header);
83 result = String::Concat(result, message);
84 }
85 return result.raw();
86 }
87
88
89 void Report::LongJump(const Error& error) {
90 Isolate::Current()->long_jump_base()->Jump(1, error);
91 UNREACHABLE();
92 }
93
94
95 void Report::LongJumpF(const Error& prev_error,
96 const Script& script, intptr_t token_pos,
97 const char* format, ...) {
98 va_list args;
99 va_start(args, format);
100 LongJumpV(prev_error, script, token_pos, format, args);
101 va_end(args);
102 UNREACHABLE();
103 }
104
105
106 void Report::LongJumpV(const Error& prev_error,
107 const Script& script, intptr_t token_pos,
108 const char* format, va_list args) {
109 const Error& error = Error::Handle(LanguageError::NewFormattedV(
110 prev_error, script, token_pos,
111 kError, Heap::kNew,
112 format, args));
113 LongJump(error);
114 UNREACHABLE();
115 }
116
117
118 void Report::MessageF(Kind kind, const Script& script, intptr_t token_pos,
119 const char* format, ...) {
120 va_list args;
121 va_start(args, format);
122 MessageV(kind, script, token_pos, format, args);
123 va_end(args);
124 }
125
126
127 void Report::MessageV(Kind kind, const Script& script, intptr_t token_pos,
128 const char* format, va_list args) {
129 if (kind < kError) {
130 // Reporting a warning.
131 if (FLAG_silent_warnings) {
132 return;
133 }
134 if (!FLAG_warning_as_error) {
135 const String& msg = String::Handle(String::NewFormattedV(format, args));
136 const String& snippet_msg = String::Handle(
137 PrependSnippet(kind, script, token_pos, msg));
138 OS::Print("%s", snippet_msg.ToCString());
139 if (kind == kJSWarning) {
140 TraceJSWarning(script, token_pos, msg);
141 // Do not print stacktrace if we have not executed Dart code yet.
142 if (Isolate::Current()->top_exit_frame_info() != 0) {
143 const Stacktrace& stacktrace =
144 Stacktrace::Handle(Exceptions::CurrentStacktrace());
145 intptr_t idx = 0;
146 OS::Print("%s", stacktrace.ToCStringInternal(
147 &idx, FLAG_stacktrace_depth_on_warning));
148 }
149 }
150 return;
151 }
152 }
153 // Reporting an error (or a warning as error).
154 const Error& error = Error::Handle(
155 LanguageError::NewFormattedV(Error::Handle(), // No previous error.
156 script, token_pos,
157 kind, Heap::kNew,
158 format, args));
159 if (kind == kJSWarning) {
160 Exceptions::ThrowJavascriptCompatibilityError(error.ToErrorCString());
161 UNREACHABLE();
162 }
163 LongJump(error);
164 UNREACHABLE();
165 }
166
167
168 void Report::JSWarningFromNative(bool is_static_native, const char* msg) {
169 DartFrameIterator iterator;
170 iterator.NextFrame(); // Skip native call.
171 StackFrame* caller_frame = iterator.NextFrame();
172 ASSERT(caller_frame != NULL);
173 const Code& caller_code = Code::Handle(caller_frame->LookupDartCode());
174 ASSERT(!caller_code.IsNull());
175 const uword caller_pc = caller_frame->pc();
176 ICData& ic_data = ICData::Handle();
177 if (is_static_native) {
178 // Assume an unoptimized static call. Optimization was prevented.
179 CodePatcher::GetUnoptimizedStaticCallAt(caller_pc, caller_code, &ic_data);
180 } else {
181 // Assume an instance call.
182 CodePatcher::GetInstanceCallAt(caller_pc, caller_code, &ic_data);
183 }
184 ASSERT(!ic_data.IsNull());
185 // Report warning only if not already reported at this location.
186 if (!ic_data.IssuedJSWarning()) {
187 ic_data.SetIssuedJSWarning();
188 Report::JSWarningFromFrame(caller_frame, msg);
189 }
190 }
191
192
193 void Report::JSWarningFromIC(const ICData& ic_data, const char* msg) {
194 DartFrameIterator iterator;
195 StackFrame* caller_frame = iterator.NextFrame();
196 ASSERT(caller_frame != NULL);
197 // Report warning only if not already reported at this location.
198 if (!ic_data.IssuedJSWarning()) {
199 ic_data.SetIssuedJSWarning();
200 JSWarningFromFrame(caller_frame, msg);
201 }
202 }
203
204
205 void Report::JSWarningFromFrame(StackFrame* caller_frame, const char* msg) {
206 ASSERT(caller_frame != NULL);
207 ASSERT(FLAG_warn_on_javascript_compatibility);
208 if (FLAG_silent_warnings) return;
209 Isolate* isolate = Isolate::Current();
210 const Code& caller_code = Code::Handle(isolate,
211 caller_frame->LookupDartCode());
212 ASSERT(!caller_code.IsNull());
213 const uword caller_pc = caller_frame->pc();
214 const intptr_t token_pos = caller_code.GetTokenIndexOfPC(caller_pc);
215 const Function& caller = Function::Handle(isolate, caller_code.function());
216 const Script& script = Script::Handle(isolate, caller.script());
217 MessageF(kJSWarning, script, token_pos, "%s", msg);
218 }
219
220
221 void Report::TraceJSWarning(const Script& script,
222 intptr_t token_pos,
223 const String& message) {
224 const int64_t micros = OS::GetCurrentTimeMicros();
225 Isolate* isolate = Isolate::Current();
226 TraceBuffer* trace_buffer = isolate->trace_buffer();
227 if (trace_buffer == NULL) {
228 TraceBuffer::Init(isolate);
229 trace_buffer = isolate->trace_buffer();
230 }
231 JSONStream js;
232 {
233 JSONObject trace_warning(&js);
234 trace_warning.AddProperty("type", "JSCompatibilityWarning");
235 trace_warning.AddProperty("script", script);
236 trace_warning.AddProperty("tokenPos", token_pos);
237 trace_warning.AddProperty("message", message);
238 }
239 trace_buffer->Trace(micros, js.ToCString(), true); // Already escaped.
240 }
241
242 } // namespace dart
243
OLDNEW
« no previous file with comments | « runtime/vm/report.h ('k') | runtime/vm/report_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698