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

Unified Diff: runtime/vm/exceptions.cc

Issue 260713008: Add support for javascript incompatibility warnings. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/exceptions.cc
===================================================================
--- runtime/vm/exceptions.cc (revision 35921)
+++ runtime/vm/exceptions.cc (working copy)
@@ -4,6 +4,7 @@
#include "vm/exceptions.h"
+#include "vm/code_patcher.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
@@ -34,7 +35,13 @@
"Prints a stack trace everytime a throw occurs.");
DEFINE_FLAG(bool, verbose_stacktrace, false,
"Stack traces will include methods marked invisible.");
+DEFINE_FLAG(int, stacktrace_depth_on_warning, 5,
+ "Maximal number of stack frames to print after a runtime warning.");
+DECLARE_FLAG(bool, silent_warnings);
+DECLARE_FLAG(bool, warning_as_error);
+DECLARE_FLAG(bool, warn_on_javascript_incompatibility);
+
const char* Exceptions::kCastErrorDstName = "type cast";
@@ -689,6 +696,10 @@
library = Library::CoreLibrary();
class_name = &Symbols::JavascriptIntegerOverflowError();
break;
+ case kJavascriptCompatibilityError:
+ library = Library::CoreLibrary();
+ class_name = &Symbols::JavascriptCompatibilityError();
+ break;
case kAssertion:
library = Library::CoreLibrary();
class_name = &Symbols::AssertionError();
@@ -726,4 +737,83 @@
arguments);
}
+
+// Throw JavascriptCompatibilityError exception.
+static void ThrowJavascriptCompatibilityError(const char* msg) {
+ const Array& exc_args = Array::Handle(Array::New(1));
+ const String& msg_str = String::Handle(String::New(msg));
+ exc_args.SetAt(0, msg_str);
+ Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args);
+}
+
+
+bool Exceptions::MayIssueJSWarning(const ICData& ic_data, bool check_issued) {
+ if (check_issued && ic_data.IssuedJSWarning()) {
+ return false;
+ }
+ const String& target_name = String::Handle(ic_data.target_name());
+ if (target_name.Equals(Library::PrivateCoreLibName(Symbols::_instanceOf())) ||
+ target_name.Equals(Library::PrivateCoreLibName(Symbols::_as())) ||
+ target_name.Equals(Symbols::toString())) {
+ return true;
+ }
+ return false;
+}
+
+
+void Exceptions::JSWarning(const ICData& ic_data, const char* format, ...) {
srdjan 2014/05/08 18:11:05 Try always passing ICData and do the necessary cod
regis 2014/05/09 21:03:42 Done.
+ ASSERT(FLAG_warn_on_javascript_incompatibility);
+ if (FLAG_silent_warnings) return;
+ if (!ic_data.IsNull()) {
+ // Report warning only if not already reported at this location.
+ if (ic_data.IssuedJSWarning()) {
+ // Warning was already reported at this location.
+ return;
+ }
+ ic_data.SetIssuedJSWarning();
+ }
+ DartFrameIterator iterator;
+ if (ic_data.IsNull()) {
+ iterator.NextFrame(); // Skip native call.
+ }
+ StackFrame* caller_frame = iterator.NextFrame();
+ ASSERT(caller_frame != NULL);
+ const Code& caller_code = Code::Handle(caller_frame->LookupDartCode());
+ ASSERT(!caller_code.IsNull());
+ const uword caller_pc = caller_frame->pc();
+ if (ic_data.IsNull()) {
+ // Assume an instance call.
+ ICData& inst_call_ic_data = ICData::Handle();
+ CodePatcher::GetInstanceCallAt(caller_pc, caller_code, &inst_call_ic_data);
+ ASSERT(!inst_call_ic_data.IsNull());
+ // Report warning only if not already reported at this location.
+ if (inst_call_ic_data.IssuedJSWarning()) {
+ // Warning was already reported at this location.
+ return;
+ }
+ inst_call_ic_data.SetIssuedJSWarning();
+ }
+ const intptr_t token_pos = caller_code.GetTokenIndexOfPC(caller_pc);
+ const Function& caller = Function::Handle(caller_code.function());
+ const Script& script = Script::Handle(caller.script());
+ va_list args;
+ va_start(args, format);
+ const Error& error = Error::Handle(
+ LanguageError::NewFormattedV(Error::Handle(), // No previous error.
+ script, token_pos, LanguageError::kWarning,
+ Heap::kNew, format, args));
+ va_end(args);
+ if (FLAG_warning_as_error) {
+ ThrowJavascriptCompatibilityError(error.ToErrorCString());
+ } else {
+ OS::Print("%s", error.ToErrorCString());
+ }
+ const Stacktrace& stacktrace =
+ Stacktrace::Handle(Exceptions::CurrentStacktrace());
+ intptr_t idx = 0;
+ OS::Print("%s",
+ stacktrace.ToCStringInternal(&idx,
+ FLAG_stacktrace_depth_on_warning));
+}
+
} // namespace dart

Powered by Google App Engine
This is Rietveld 408576698