OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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/report.h" | 5 #include "vm/report.h" |
6 | 6 |
7 #include "vm/code_patcher.h" | 7 #include "vm/code_patcher.h" |
8 #include "vm/exceptions.h" | 8 #include "vm/exceptions.h" |
9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
11 #include "vm/object.h" | 11 #include "vm/object.h" |
12 #include "vm/stack_frame.h" | 12 #include "vm/stack_frame.h" |
13 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
14 | 14 |
15 namespace dart { | 15 namespace dart { |
16 | 16 |
17 DEFINE_FLAG(int, stacktrace_depth_on_warning, 5, | 17 DEFINE_FLAG(int, stacktrace_depth_on_warning, 5, |
18 "Maximal number of stack frames to print after a runtime warning."); | 18 "Maximal number of stack frames to print after a runtime warning."); |
19 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); | 19 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); |
20 DEFINE_FLAG(bool, warn_on_javascript_compatibility, false, | 20 DEFINE_FLAG(bool, warn_on_javascript_compatibility, false, |
21 "Warn on incompatibilities between vm and dart2js."); | 21 "Warn on incompatibilities between vm and dart2js."); |
22 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); | 22 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); |
23 | 23 |
24 DECLARE_FLAG(bool, always_megamorphic_calls); | 24 DECLARE_FLAG(bool, always_megamorphic_calls); |
25 | 25 |
26 RawString* Report::PrependSnippet(Kind kind, | 26 RawString* Report::PrependSnippet(Kind kind, |
27 const Script& script, | 27 const Script& script, |
28 intptr_t token_pos, | 28 TokenPosition token_pos, |
29 bool report_after_token, | 29 bool report_after_token, |
30 const String& message) { | 30 const String& message) { |
31 const char* message_header; | 31 const char* message_header; |
32 switch (kind) { | 32 switch (kind) { |
33 case kWarning: message_header = "warning"; break; | 33 case kWarning: message_header = "warning"; break; |
34 case kJSWarning: message_header = "javascript compatibility warning"; break; | 34 case kJSWarning: message_header = "javascript compatibility warning"; break; |
35 case kError: message_header = "error"; break; | 35 case kError: message_header = "error"; break; |
36 case kMalformedType: message_header = "malformed type"; break; | 36 case kMalformedType: message_header = "malformed type"; break; |
37 case kMalboundedType: message_header = "malbounded type"; break; | 37 case kMalboundedType: message_header = "malbounded type"; break; |
38 case kBailout: message_header = "bailout"; break; | 38 case kBailout: message_header = "bailout"; break; |
39 default: message_header = ""; UNREACHABLE(); | 39 default: message_header = ""; UNREACHABLE(); |
40 } | 40 } |
41 String& result = String::Handle(); | 41 String& result = String::Handle(); |
42 if (!script.IsNull()) { | 42 if (!script.IsNull()) { |
43 const String& script_url = String::Handle(script.url()); | 43 const String& script_url = String::Handle(script.url()); |
44 if (token_pos >= 0) { | 44 if (token_pos.IsReal()) { |
45 intptr_t line, column, token_len; | 45 intptr_t line, column, token_len; |
46 script.GetTokenLocation(token_pos, &line, &column, &token_len); | 46 script.GetTokenLocation(token_pos, &line, &column, &token_len); |
47 if (report_after_token) { | 47 if (report_after_token) { |
48 column += token_len; | 48 column += token_len; |
49 } | 49 } |
50 // Only report the line position if we have the original source. We still | 50 // Only report the line position if we have the original source. We still |
51 // need to get a valid column so that we can report the ^ mark below the | 51 // need to get a valid column so that we can report the ^ mark below the |
52 // snippet. | 52 // snippet. |
53 // Allocate formatted strings in old sapce as they may be created during | 53 // Allocate formatted strings in old sapce as they may be created during |
54 // optimizing compilation. Those strings are created rarely and should not | 54 // optimizing compilation. Those strings are created rarely and should not |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 } | 103 } |
104 | 104 |
105 | 105 |
106 void Report::LongJump(const Error& error) { | 106 void Report::LongJump(const Error& error) { |
107 Thread::Current()->long_jump_base()->Jump(1, error); | 107 Thread::Current()->long_jump_base()->Jump(1, error); |
108 UNREACHABLE(); | 108 UNREACHABLE(); |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 void Report::LongJumpF(const Error& prev_error, | 112 void Report::LongJumpF(const Error& prev_error, |
113 const Script& script, intptr_t token_pos, | 113 const Script& script, TokenPosition token_pos, |
114 const char* format, ...) { | 114 const char* format, ...) { |
115 va_list args; | 115 va_list args; |
116 va_start(args, format); | 116 va_start(args, format); |
117 LongJumpV(prev_error, script, token_pos, format, args); | 117 LongJumpV(prev_error, script, token_pos, format, args); |
118 va_end(args); | 118 va_end(args); |
119 UNREACHABLE(); | 119 UNREACHABLE(); |
120 } | 120 } |
121 | 121 |
122 | 122 |
123 void Report::LongJumpV(const Error& prev_error, | 123 void Report::LongJumpV(const Error& prev_error, |
124 const Script& script, intptr_t token_pos, | 124 const Script& script, TokenPosition token_pos, |
125 const char* format, va_list args) { | 125 const char* format, va_list args) { |
126 const Error& error = Error::Handle(LanguageError::NewFormattedV( | 126 const Error& error = Error::Handle(LanguageError::NewFormattedV( |
127 prev_error, script, token_pos, Report::AtLocation, | 127 prev_error, script, token_pos, Report::AtLocation, |
128 kError, Heap::kNew, | 128 kError, Heap::kNew, |
129 format, args)); | 129 format, args)); |
130 LongJump(error); | 130 LongJump(error); |
131 UNREACHABLE(); | 131 UNREACHABLE(); |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 void Report::MessageF(Kind kind, const Script& script, intptr_t token_pos, | 135 void Report::MessageF(Kind kind, |
136 bool report_after_token, const char* format, ...) { | 136 const Script& script, |
| 137 TokenPosition token_pos, |
| 138 bool report_after_token, |
| 139 const char* format, ...) { |
137 va_list args; | 140 va_list args; |
138 va_start(args, format); | 141 va_start(args, format); |
139 MessageV(kind, script, token_pos, report_after_token, format, args); | 142 MessageV(kind, script, token_pos, report_after_token, format, args); |
140 va_end(args); | 143 va_end(args); |
141 } | 144 } |
142 | 145 |
143 | 146 |
144 void Report::MessageV(Kind kind, | 147 void Report::MessageV(Kind kind, |
145 const Script& script, | 148 const Script& script, |
146 intptr_t token_pos, | 149 TokenPosition token_pos, |
147 bool report_after_token, | 150 bool report_after_token, |
148 const char* format, va_list args) { | 151 const char* format, va_list args) { |
149 if (kind < kError) { | 152 if (kind < kError) { |
150 // Reporting a warning. | 153 // Reporting a warning. |
151 if (FLAG_silent_warnings) { | 154 if (FLAG_silent_warnings) { |
152 return; | 155 return; |
153 } | 156 } |
154 if (!FLAG_warning_as_error) { | 157 if (!FLAG_warning_as_error) { |
155 const String& msg = String::Handle(String::NewFormattedV(format, args)); | 158 const String& msg = String::Handle(String::NewFormattedV(format, args)); |
156 const String& snippet_msg = String::Handle( | 159 const String& snippet_msg = String::Handle( |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 | 232 |
230 void Report::JSWarningFromFrame(StackFrame* caller_frame, const char* msg) { | 233 void Report::JSWarningFromFrame(StackFrame* caller_frame, const char* msg) { |
231 ASSERT(caller_frame != NULL); | 234 ASSERT(caller_frame != NULL); |
232 ASSERT(FLAG_warn_on_javascript_compatibility); | 235 ASSERT(FLAG_warn_on_javascript_compatibility); |
233 if (FLAG_silent_warnings) return; | 236 if (FLAG_silent_warnings) return; |
234 Zone* zone = Thread::Current()->zone(); | 237 Zone* zone = Thread::Current()->zone(); |
235 const Code& caller_code = Code::Handle(zone, | 238 const Code& caller_code = Code::Handle(zone, |
236 caller_frame->LookupDartCode()); | 239 caller_frame->LookupDartCode()); |
237 ASSERT(!caller_code.IsNull()); | 240 ASSERT(!caller_code.IsNull()); |
238 const uword caller_pc = caller_frame->pc(); | 241 const uword caller_pc = caller_frame->pc(); |
239 const intptr_t token_pos = caller_code.GetTokenIndexOfPC(caller_pc); | 242 const TokenPosition token_pos = caller_code.GetTokenIndexOfPC(caller_pc); |
240 const Function& caller = Function::Handle(zone, caller_code.function()); | 243 const Function& caller = Function::Handle(zone, caller_code.function()); |
241 const Script& script = Script::Handle(zone, caller.script()); | 244 const Script& script = Script::Handle(zone, caller.script()); |
242 MessageF(kJSWarning, script, token_pos, Report::AtLocation, "%s", msg); | 245 MessageF(kJSWarning, script, token_pos, Report::AtLocation, "%s", msg); |
243 } | 246 } |
244 | 247 |
245 | 248 |
246 void Report::TraceJSWarning(const Script& script, | 249 void Report::TraceJSWarning(const Script& script, |
247 intptr_t token_pos, | 250 TokenPosition token_pos, |
248 const String& message) { | 251 const String& message) { |
249 const int64_t micros = OS::GetCurrentTimeMicros(); | 252 const int64_t micros = OS::GetCurrentTimeMicros(); |
250 Isolate* isolate = Isolate::Current(); | 253 Isolate* isolate = Isolate::Current(); |
251 TraceBuffer* trace_buffer = isolate->trace_buffer(); | 254 TraceBuffer* trace_buffer = isolate->trace_buffer(); |
252 if (trace_buffer == NULL) { | 255 if (trace_buffer == NULL) { |
253 TraceBuffer::Init(isolate); | 256 TraceBuffer::Init(isolate); |
254 trace_buffer = isolate->trace_buffer(); | 257 trace_buffer = isolate->trace_buffer(); |
255 } | 258 } |
256 JSONStream js; | 259 JSONStream js; |
257 { | 260 { |
258 JSONObject trace_warning(&js); | 261 JSONObject trace_warning(&js); |
259 trace_warning.AddProperty("type", "JSCompatibilityWarning"); | 262 trace_warning.AddProperty("type", "JSCompatibilityWarning"); |
260 trace_warning.AddProperty("script", script); | 263 trace_warning.AddProperty("script", script); |
261 trace_warning.AddProperty("tokenPos", token_pos); | 264 trace_warning.AddProperty("tokenPos", token_pos); |
262 trace_warning.AddProperty("message", message); | 265 trace_warning.AddProperty("message", message); |
263 } | 266 } |
264 trace_buffer->Trace(micros, js.ToCString(), true); // Already escaped. | 267 trace_buffer->Trace(micros, js.ToCString(), true); // Already escaped. |
265 } | 268 } |
266 | 269 |
267 } // namespace dart | 270 } // namespace dart |
268 | 271 |
OLD | NEW |