[gjs/wip/ptomato/mozjs52: 28/36] js: Replace error reporter callbacks



commit 34c8449b90a96a39d0eb357fa057bf0f923a645f
Author: Philip Chimento <philip chimento gmail com>
Date:   Sat Jun 10 18:13:23 2017 -0700

    js: Replace error reporter callbacks
    
    JS_SetErrorReporter() goes away in SpiderMonkey 52, and is replaced by
    JS::SetWarningReporter(). Errors should now be reported manually after
    each call into JS code. (We don't actually have to change much, since we
    already used the DontReportUncaught option and reported uncaught
    exceptions manually already. This is now the only choice.)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=784196

 gjs/jsapi-private.cpp    |   10 ++++++----
 gjs/jsapi-util-error.cpp |   29 +++++++++++++++++++++++++++++
 gjs/jsapi-util.h         |    8 +++++---
 gjs/runtime.cpp          |    2 +-
 modules/console.cpp      |   29 +++++++++++++++++++----------
 5 files changed, 60 insertions(+), 18 deletions(-)
---
diff --git a/gjs/jsapi-private.cpp b/gjs/jsapi-private.cpp
index cf16f73..f6584ef 100644
--- a/gjs/jsapi-private.cpp
+++ b/gjs/jsapi-private.cpp
@@ -32,13 +32,14 @@
 #include "jsapi-wrapper.h"
 
 void
-gjs_error_reporter(JSContext     *context,
-                   const char    *message,
-                   JSErrorReport *report)
+gjs_warning_reporter(JSContext     *context,
+                     JSErrorReport *report)
 {
     const char *warning;
     GLogLevelFlags level;
 
+    g_assert(report);
+
     if (gjs_environment_variable_is_set("GJS_ABORT_ON_OOM") &&
         report->flags == JSREPORT_ERROR &&
         report->errorNumber == 137) {
@@ -66,5 +67,6 @@ gjs_error_reporter(JSContext     *context,
         level = G_LOG_LEVEL_WARNING;
     }
 
-    g_log(G_LOG_DOMAIN, level, "JS %s: [%s %d]: %s", warning, report->filename, report->lineno, message);
+    g_log(G_LOG_DOMAIN, level, "JS %s: [%s %d]: %s", warning, report->filename,
+          report->lineno, report->message().c_str());
 }
diff --git a/gjs/jsapi-util-error.cpp b/gjs/jsapi-util-error.cpp
index ce1bbd5..1196bd0 100644
--- a/gjs/jsapi-util-error.cpp
+++ b/gjs/jsapi-util-error.cpp
@@ -202,3 +202,32 @@ gjs_throw_g_error (JSContext       *context,
 
     JS_EndRequest(context);
 }
+
+/**
+ * gjs_format_stack_trace:
+ * @cx: the #JSContext
+ * @saved_frame: a SavedFrame #JSObject
+ *
+ * Formats a stack trace as a string in filename encoding, suitable for
+ * printing to stderr. Ignores any errors.
+ *
+ * Returns: unique string in filename encoding, or nullptr if no stack trace
+ */
+GjsAutoChar
+gjs_format_stack_trace(JSContext       *cx,
+                       JS::HandleObject saved_frame)
+{
+    JS::AutoSaveExceptionState saved_exc(cx);
+
+    JS::RootedString stack_trace(cx);
+    GjsAutoJSChar stack_utf8(cx);
+    if (JS::BuildStackString(cx, saved_frame, &stack_trace, 2))
+        stack_utf8.reset(cx, JS_EncodeStringToUTF8(cx, stack_trace));
+
+    saved_exc.restore();
+
+    if (!stack_utf8)
+        return nullptr;
+
+    return g_filename_from_utf8(stack_utf8, -1, nullptr, nullptr, nullptr);
+}
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index f1c53f4..4978871 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -199,9 +199,8 @@ bool gjs_call_function_value(JSContext                  *context,
                              const JS::HandleValueArray& args,
                              JS::MutableHandleValue      rval);
 
-void        gjs_error_reporter               (JSContext       *context,
-                                              const char      *message,
-                                              JSErrorReport   *report);
+void gjs_warning_reporter(JSContext     *cx,
+                          JSErrorReport *report);
 
 bool        gjs_string_to_utf8               (JSContext       *context,
                                               const JS::Value  string_val,
@@ -316,6 +315,9 @@ bool gjs_object_has_property(JSContext       *cx,
 
 G_END_DECLS
 
+GjsAutoChar gjs_format_stack_trace(JSContext       *cx,
+                                   JS::HandleObject saved_frame);
+
 bool gjs_object_define_property(JSContext       *cx,
                                 JS::HandleObject obj,
                                 GjsConstString   property_name,
diff --git a/gjs/runtime.cpp b/gjs/runtime.cpp
index 3c9c206..3f7aaff 100644
--- a/gjs/runtime.cpp
+++ b/gjs/runtime.cpp
@@ -310,7 +310,7 @@ gjs_runtime_for_current_thread(void)
         // JS_SetGCParameter(runtime, JSGC_DECOMMIT_THRESHOLD, 32);
         JS_SetLocaleCallbacks(runtime, &gjs_locale_callbacks);
         JS_AddFinalizeCallback(runtime, gjs_finalize_callback, data);
-        JS_SetErrorReporter(runtime, gjs_error_reporter);
+        JS::SetWarningReporter(runtime, gjs_warning_reporter);
 
         g_private_set(&thread_runtime, runtime);
     }
diff --git a/modules/console.cpp b/modules/console.cpp
index f3d1ac0..77e237e 100644
--- a/modules/console.cpp
+++ b/modules/console.cpp
@@ -58,15 +58,11 @@
 #include "gjs/jsapi-wrapper.h"
 
 static void
-gjs_console_print_error(const char *message, JSErrorReport *report)
+gjs_console_print_error(JSErrorReport *report)
 {
     /* Code modified from SpiderMonkey js/src/jscntxt.cpp, js::PrintError() */
 
-    if (!report) {
-        fprintf(stderr, "%s\n", message);
-        fflush(stderr);
-        return;
-    }
+    g_assert(report);
 
     char *prefix = nullptr;
     if (report->filename)
@@ -85,6 +81,8 @@ gjs_console_print_error(const char *message, JSErrorReport *report)
         g_free(tmp);
     }
 
+    const char *message = report->message().c_str();
+
     /* embedded newlines -- argh! */
     const char *ctmp;
     while ((ctmp = strchr(message, '\n')) != 0) {
@@ -135,9 +133,9 @@ gjs_console_print_error(const char *message, JSErrorReport *report)
 }
 
 static void
-gjs_console_error_reporter(JSContext *cx, const char *message, JSErrorReport *report)
+gjs_console_warning_reporter(JSContext *cx, JSErrorReport *report)
 {
-    gjs_console_print_error(message, report);
+    gjs_console_print_error(report);
 }
 
 /* Based on js::shell::AutoReportException from SpiderMonkey. */
@@ -162,7 +160,18 @@ public:
 
         g_assert(!JSREPORT_IS_WARNING(report->flags));
 
-        JS_ReportPendingException(m_cx);
+        gjs_console_print_error(report);
+
+        JS::RootedObject stack(m_cx, ExceptionStackOrNull(exn));
+        if (stack) {
+            GjsAutoChar stack_str = gjs_format_stack_trace(m_cx, stack);
+            if (!stack_str)
+                g_printerr("(Unable to print stack trace)\n");
+            else
+                g_printerr("%s", stack_str.get());
+        }
+
+        JS_ClearPendingException(m_cx);
     }
 };
 
@@ -245,7 +254,7 @@ gjs_console_interact(JSContext *context,
     int startline;
     FILE *file = stdin;
 
-    JS_SetErrorReporter(JS_GetRuntime(context), gjs_console_error_reporter);
+    JS::SetWarningReporter(context, gjs_console_warning_reporter);
 
         /* It's an interactive filehandle; drop into read-eval-print loop. */
     lineno = 1;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]