| OLD | NEW |
| 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 "vm/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/debugger.h" | 9 #include "vm/debugger.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 void __asan_unpoison_memory_region(void* ignore1, size_t ignore2) {} | 27 void __asan_unpoison_memory_region(void* ignore1, size_t ignore2) {} |
| 28 #endif // defined(__has_feature) | 28 #endif // defined(__has_feature) |
| 29 | 29 |
| 30 | 30 |
| 31 namespace dart { | 31 namespace dart { |
| 32 | 32 |
| 33 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, | 33 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, |
| 34 "Prints a stack trace everytime a throw occurs."); | 34 "Prints a stack trace everytime a throw occurs."); |
| 35 DEFINE_FLAG(bool, verbose_stacktrace, false, | 35 DEFINE_FLAG(bool, verbose_stacktrace, false, |
| 36 "Stack traces will include methods marked invisible."); | 36 "Stack traces will include methods marked invisible."); |
| 37 DEFINE_FLAG(int, stacktrace_depth_on_warning, 5, | |
| 38 "Maximal number of stack frames to print after a runtime warning."); | |
| 39 DECLARE_FLAG(bool, silent_warnings); | |
| 40 DECLARE_FLAG(bool, warning_as_error); | |
| 41 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | |
| 42 | 37 |
| 43 | 38 |
| 44 const char* Exceptions::kCastErrorDstName = "type cast"; | 39 const char* Exceptions::kCastErrorDstName = "type cast"; |
| 45 | 40 |
| 46 | 41 |
| 47 class StacktraceBuilder : public ValueObject { | 42 class StacktraceBuilder : public ValueObject { |
| 48 public: | 43 public: |
| 49 StacktraceBuilder() { } | 44 StacktraceBuilder() { } |
| 50 virtual ~StacktraceBuilder() { } | 45 virtual ~StacktraceBuilder() { } |
| 51 | 46 |
| (...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 } | 735 } |
| 741 | 736 |
| 742 return DartLibraryCalls::InstanceCreate(library, | 737 return DartLibraryCalls::InstanceCreate(library, |
| 743 *class_name, | 738 *class_name, |
| 744 *constructor_name, | 739 *constructor_name, |
| 745 arguments); | 740 arguments); |
| 746 } | 741 } |
| 747 | 742 |
| 748 | 743 |
| 749 // Throw JavascriptCompatibilityError exception. | 744 // Throw JavascriptCompatibilityError exception. |
| 750 static void ThrowJavascriptCompatibilityError(const char* msg) { | 745 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) { |
| 751 const Array& exc_args = Array::Handle(Array::New(1)); | 746 const Array& exc_args = Array::Handle(Array::New(1)); |
| 752 const String& msg_str = String::Handle(String::New(msg)); | 747 const String& msg_str = String::Handle(String::New(msg)); |
| 753 exc_args.SetAt(0, msg_str); | 748 exc_args.SetAt(0, msg_str); |
| 754 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); | 749 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); |
| 755 } | 750 } |
| 756 | 751 |
| 757 | |
| 758 void Exceptions::JSWarning(StackFrame* caller_frame, const char* format, ...) { | |
| 759 ASSERT(caller_frame != NULL); | |
| 760 ASSERT(FLAG_warn_on_javascript_compatibility); | |
| 761 if (FLAG_silent_warnings) return; | |
| 762 Isolate* isolate = Isolate::Current(); | |
| 763 const Code& caller_code = Code::Handle(isolate, | |
| 764 caller_frame->LookupDartCode()); | |
| 765 ASSERT(!caller_code.IsNull()); | |
| 766 const uword caller_pc = caller_frame->pc(); | |
| 767 const intptr_t token_pos = caller_code.GetTokenIndexOfPC(caller_pc); | |
| 768 const Function& caller = Function::Handle(isolate, caller_code.function()); | |
| 769 const Script& script = Script::Handle(isolate, caller.script()); | |
| 770 va_list args; | |
| 771 va_start(args, format); | |
| 772 const Error& error = Error::Handle(isolate, | |
| 773 LanguageError::NewFormattedV(Error::Handle(isolate), // No prev error. | |
| 774 script, token_pos, LanguageError::kWarning, | |
| 775 Heap::kNew, format, args)); | |
| 776 va_end(args); | |
| 777 if (FLAG_warning_as_error) { | |
| 778 ThrowJavascriptCompatibilityError(error.ToErrorCString()); | |
| 779 } else { | |
| 780 OS::Print("javascript compatibility warning: %s", error.ToErrorCString()); | |
| 781 va_start(args, format); | |
| 782 TraceJSWarningV(script, token_pos, format, args); | |
| 783 va_end(args); | |
| 784 } | |
| 785 const Stacktrace& stacktrace = | |
| 786 Stacktrace::Handle(isolate, Exceptions::CurrentStacktrace()); | |
| 787 intptr_t idx = 0; | |
| 788 OS::Print("%s", | |
| 789 stacktrace.ToCStringInternal(&idx, | |
| 790 FLAG_stacktrace_depth_on_warning)); | |
| 791 } | |
| 792 | |
| 793 | |
| 794 void Exceptions::TraceJSWarningF(const Script& script, intptr_t token_pos, | |
| 795 const char* format, ...) { | |
| 796 va_list args; | |
| 797 va_start(args, format); | |
| 798 TraceJSWarningV(script, token_pos, format, args); | |
| 799 va_end(args); | |
| 800 } | |
| 801 | |
| 802 | |
| 803 void Exceptions::TraceJSWarningV(const Script& script, intptr_t token_pos, | |
| 804 const char* format, va_list args) { | |
| 805 const int64_t micros = OS::GetCurrentTimeMicros(); | |
| 806 Isolate* isolate = Isolate::Current(); | |
| 807 TraceBuffer* trace_buffer = isolate->trace_buffer(); | |
| 808 if (trace_buffer == NULL) { | |
| 809 TraceBuffer::Init(isolate); | |
| 810 trace_buffer = isolate->trace_buffer(); | |
| 811 } | |
| 812 JSONStream js; | |
| 813 { | |
| 814 JSONObject trace_warning(&js); | |
| 815 trace_warning.AddProperty("type", "JSCompatibilityWarning"); | |
| 816 trace_warning.AddProperty("script", script); | |
| 817 trace_warning.AddProperty("tokenPos", token_pos); | |
| 818 va_list args_copy; | |
| 819 va_copy(args_copy, args); | |
| 820 const intptr_t len = OS::VSNPrint(NULL, 0, format, args_copy); | |
| 821 va_end(args_copy); | |
| 822 char* msg = reinterpret_cast<char*>(malloc(len + 1)); | |
| 823 va_copy(args_copy, args); | |
| 824 OS::VSNPrint(msg, len + 1, format, args_copy); | |
| 825 va_end(args_copy); | |
| 826 trace_warning.AddProperty("message", msg); | |
| 827 } | |
| 828 trace_buffer->Trace(micros, js.ToCString(), true); // Already escaped. | |
| 829 } | |
| 830 | |
| 831 } // namespace dart | 752 } // namespace dart |
| OLD | NEW |