[gjs/mozjs78] Initial stab at mozjs78.



commit 019ef2d96f95d37c2d52d3d7eb0f8424706c907f
Author: Evan Welsh <noreply evanwelsh com>
Date:   Sat Jul 4 10:46:00 2020 -0500

    Initial stab at mozjs78.

 doc/CPP_Style_Guide.md      |   8 +--
 gi/arg.cpp                  |  15 ++---
 gi/boxed.cpp                |   2 +-
 gi/boxed.h                  |   4 --
 gi/function.cpp             |   5 +-
 gi/gerror.cpp               |   2 +-
 gi/gobject.cpp              |   2 +-
 gi/private.cpp              |  13 +++--
 gjs/atoms.cpp               |   3 +-
 gjs/console.cpp             |  30 +++++-----
 gjs/context-private.h       |   4 --
 gjs/context.cpp             |  12 ++--
 gjs/coverage.cpp            |   5 +-
 gjs/engine.cpp              |  25 ++++----
 gjs/global.cpp              |   7 ++-
 gjs/importer.cpp            |   9 +--
 gjs/jsapi-dynamic-class.cpp |   5 +-
 gjs/jsapi-util-error.cpp    |   5 +-
 gjs/jsapi-util-root.h       |   4 +-
 gjs/jsapi-util-string.cpp   |  16 +++---
 gjs/jsapi-util.cpp          |   8 +--
 meson.build                 |  38 ++++++-------
 modules/cairo-context.cpp   | 136 ++++++++++++++++++++++++--------------------
 modules/console.cpp         | 132 ++----------------------------------------
 test/gjs-test-rooting.cpp   |   2 +-
 test/gjs-tests.cpp          |   5 +-
 26 files changed, 197 insertions(+), 300 deletions(-)
---
diff --git a/doc/CPP_Style_Guide.md b/doc/CPP_Style_Guide.md
index 5d75c420..beac17d5 100644
--- a/doc/CPP_Style_Guide.md
+++ b/doc/CPP_Style_Guide.md
@@ -46,12 +46,12 @@ portable C++ code as the implementation language of choice.
 
 ### C++ Standard Versions ###
 
-GJS is currently written using C++14 conforming code, although we
+GJS is currently written using C++17 conforming code, although we
 restrict ourselves to features which are available in the major
 toolchains.
 
 Regardless of the supported features, code is expected to (when
-reasonable) be standard, portable, and modern C++14 code.
+reasonable) be standard, portable, and modern C++17 code.
 We avoid unnecessary vendor-specific extensions, etc., including
 `g_autoptr()` and friends.
 
@@ -65,9 +65,9 @@ and friends, for their type safety and memory management.
 There are some exceptions such as the standard I/O streams library which
 is avoided, and use in space-constrained situations.
 
-### Supported C++14 Language and Library Features ###
+### Supported C++17 Language and Library Features ###
 
-While GJS and SpiderMonkey use C++14, not all features are available in
+While GJS and SpiderMonkey use C++17, not all features are available in
 all of the toolchains which we support.
 A good rule of thumb is to check whether SpiderMonkey uses the feature.
 If so, it's okay to use in GJS.
diff --git a/gi/arg.cpp b/gi/arg.cpp
index ba706021..4f1796f0 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -34,6 +34,7 @@
 #include <glib-object.h>
 #include <glib.h>
 
+#include <js/Array.h>
 #include <js/CharacterEncoding.h>
 #include <js/Conversions.h>
 #include <js/GCVector.h>            // for RootedVector, MutableWrappedPtrOp...
@@ -778,7 +779,7 @@ gjs_array_from_strv(JSContext             *context,
             return false;
     }
 
-    JS::RootedObject obj(context, JS_NewArrayObject(context, elems));
+    JS::RootedObject obj(context, JS::NewArrayObject(context, elems));
     if (!obj)
         return false;
 
@@ -1198,7 +1199,7 @@ gjs_array_from_flat_gvalue_array(JSContext             *context,
 
     // a null array pointer takes precedence over whatever `length` says
     if (!values) {
-        JSObject* jsarray = JS_NewArrayObject(context, 0);
+        JSObject* jsarray = JS::NewArrayObject(context, 0);
         if (!jsarray)
             return false;
         value.setObject(*jsarray);
@@ -1223,7 +1224,7 @@ gjs_array_from_flat_gvalue_array(JSContext             *context,
 
     if (result) {
         JSObject *jsarray;
-        jsarray = JS_NewArrayObject(context, elems);
+        jsarray = JS::NewArrayObject(context, elems);
         value.setObjectOrNull(jsarray);
     }
 
@@ -2435,7 +2436,7 @@ gjs_array_from_g_list (JSContext             *context,
         }
     }
 
-    JS::RootedObject obj(context, JS_NewArrayObject(context, elems));
+    JS::RootedObject obj(context, JS::NewArrayObject(context, elems));
     if (!obj)
         return false;
 
@@ -2491,7 +2492,7 @@ gjs_array_from_carray_internal (JSContext             *context,
 
     // a null array pointer takes precedence over whatever `length` says
     if (!array) {
-        JSObject* jsarray = JS_NewArrayObject(context, 0);
+        JSObject* jsarray = JS::NewArrayObject(context, 0);
         if (!jsarray)
             return false;
         value_p.setObject(*jsarray);
@@ -2592,7 +2593,7 @@ gjs_array_from_carray_internal (JSContext             *context,
 
 #undef ITERATE
 
-    JS::RootedObject obj(context, JS_NewArrayObject(context, elems));
+    JS::RootedObject obj(context, JS::NewArrayObject(context, elems));
     if (!obj)
         return false;
 
@@ -2799,7 +2800,7 @@ gjs_array_from_zero_terminated_c_array (JSContext             *context,
 
 #undef ITERATE
 
-    JS::RootedObject obj(context, JS_NewArrayObject(context, elems));
+    JS::RootedObject obj(context, JS::NewArrayObject(context, elems));
     if (!obj)
         return false;
 
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 9c1bd8a7..a7d8253a 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -608,7 +608,7 @@ bool BoxedInstance::set_nested_interface_object(JSContext* context,
      */
     BoxedBase* source_priv = get_copy_source(context, value);
     if (!source_priv) {
-        JS::AutoValueArray<1> args(context);
+        JS::RootedValueArray<1> args(context);
         args[0].set(value);
         JS::RootedObject tmp_object(context,
             gjs_construct_object_dynamic(context, proto, args));
diff --git a/gi/boxed.h b/gi/boxed.h
index e69ffe2a..483d98e7 100644
--- a/gi/boxed.h
+++ b/gi/boxed.h
@@ -50,10 +50,6 @@ class CallArgs;
 namespace js {
 class SystemAllocPolicy;
 }
-namespace mozilla {
-template <class Key>
-struct DefaultHasher;
-}
 
 /* To conserve memory, we have two different kinds of private data for GBoxed
  * JS wrappers: BoxedInstance, and BoxedPrototype. Both inherit from BoxedBase
diff --git a/gi/function.cpp b/gi/function.cpp
index 9706e84e..01b93e33 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -36,6 +36,7 @@
 #include <glib-object.h>
 #include <glib.h>
 
+#include <js/Array.h>
 #include <js/CallArgs.h>
 #include <js/Class.h>
 #include <js/GCVector.h>
@@ -392,7 +393,7 @@ static void gjs_callback_closure(ffi_cif* cif G_GNUC_UNUSED, void* result,
         }
     } else {
         bool is_array = rval.isObject();
-        if (!JS_IsArrayObject(context, rval, &is_array))
+        if (!JS::IsArrayObject(context, rval, &is_array))
             goto out;
 
         if (!is_array) {
@@ -1413,7 +1414,7 @@ release:
                 args.rval().set(return_values[0]);
             } else {
                 JSObject *array;
-                array = JS_NewArrayObject(context, return_values);
+                array = JS::NewArrayObject(context, return_values);
                 if (array == NULL) {
                     failed = true;
                 } else {
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 38e1e577..81f07c57 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -349,7 +349,7 @@ static JSObject *
 gjs_error_from_js_gerror(JSContext *cx,
                          GError    *gerror)
 {
-    JS::AutoValueArray<1> error_args(cx);
+    JS::RootedValueArray<1> error_args(cx);
     if (!gjs_string_from_utf8(cx, gerror->message, error_args[0]))
         return nullptr;
 
diff --git a/gi/gobject.cpp b/gi/gobject.cpp
index 5e16d77c..fdd78c10 100644
--- a/gi/gobject.cpp
+++ b/gi/gobject.cpp
@@ -128,7 +128,7 @@ static GObject* gjs_object_constructor(
                                      construct_properties[i].pspec))
                 return nullptr;
 
-        JS::AutoValueArray<1> args(cx);
+        JS::RootedValueArray<1> args(cx);
         args[0].set(JS::ObjectValue(*props_hash));
         object = JS_New(cx, constructor, args);
     } else {
diff --git a/gi/private.cpp b/gi/private.cpp
index 9159776d..44b418db 100644
--- a/gi/private.cpp
+++ b/gi/private.cpp
@@ -29,13 +29,14 @@
 #include <glib-object.h>
 #include <glib.h>
 
+#include <js/Array.h>
 #include <js/CallArgs.h>
 #include <js/Id.h>  // for JSID_TO_SYMBOL
 #include <js/PropertySpec.h>
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
-#include <jsapi.h>       // for JS_GetArrayLength, JS_GetElement
+#include <jsapi.h>       // for JS::GetArrayLength, JS_GetElement
 
 #include "gi/gobject.h"
 #include "gi/gtype.h"
@@ -106,7 +107,7 @@ static bool validate_interfaces_and_properties_args(JSContext* cx,
                                                     uint32_t* n_interfaces,
                                                     uint32_t* n_properties) {
     bool is_array;
-    if (!JS_IsArrayObject(cx, interfaces, &is_array))
+    if (!JS::IsArrayObject(cx, interfaces, &is_array))
         return false;
     if (!is_array) {
         gjs_throw(cx, "Invalid parameter interfaces (expected Array)");
@@ -114,10 +115,10 @@ static bool validate_interfaces_and_properties_args(JSContext* cx,
     }
 
     uint32_t n_int;
-    if (!JS_GetArrayLength(cx, interfaces, &n_int))
+    if (!JS::GetArrayLength(cx, interfaces, &n_int))
         return false;
 
-    if (!JS_IsArrayObject(cx, properties, &is_array))
+    if (!JS::IsArrayObject(cx, properties, &is_array))
         return false;
     if (!is_array) {
         gjs_throw(cx, "Invalid parameter properties (expected Array)");
@@ -125,7 +126,7 @@ static bool validate_interfaces_and_properties_args(JSContext* cx,
     }
 
     uint32_t n_prop;
-    if (!JS_GetArrayLength(cx, properties, &n_prop))
+    if (!JS::GetArrayLength(cx, properties, &n_prop))
         return false;
 
     if (n_interfaces)
@@ -384,7 +385,7 @@ static bool gjs_signal_new(JSContext* cx, unsigned argc, JS::Value* vp) {
     }
 
     uint32_t n_parameters;
-    if (!JS_GetArrayLength(cx, params_obj, &n_parameters))
+    if (!JS::GetArrayLength(cx, params_obj, &n_parameters))
         return false;
 
     GType* params = g_newa(GType, n_parameters);
diff --git a/gjs/atoms.cpp b/gjs/atoms.cpp
index 5329ddc2..a349d0e7 100644
--- a/gjs/atoms.cpp
+++ b/gjs/atoms.cpp
@@ -39,7 +39,8 @@ bool GjsAtom::init(JSContext* cx, const char* str) {
     JSString* s = JS_AtomizeAndPinString(cx, str);
     if (!s)
         return false;
-    m_jsid = JS::Heap<jsid>{INTERNED_STRING_TO_JSID(cx, s)};
+
+    m_jsid = JS::Heap<jsid>{JS::PropertyKey::fromPinnedString(s)};
     return true;
 }
 
diff --git a/gjs/console.cpp b/gjs/console.cpp
index 9e335594..f7100cca 100644
--- a/gjs/console.cpp
+++ b/gjs/console.cpp
@@ -37,6 +37,8 @@
 #include <glib-object.h>
 #include <glib.h>
 
+#include <jsfriendapi.h>
+
 #include <gjs/gjs.h>
 
 static char **include_path = NULL;
@@ -215,7 +217,7 @@ main(int argc, char **argv)
     GOptionContext *context;
     GError *error = NULL;
     GjsContext *js_context;
-    GjsCoverage *coverage = NULL;
+    GjsCoverage* gjs_coverage = NULL;
     char *script;
     const char *filename;
     const char *program_name;
@@ -335,12 +337,6 @@ main(int argc, char **argv)
         g_unsetenv("GJS_TRACE_FD");         /* ignore env var in eval() */
     }
 
-    js_context = (GjsContext*) g_object_new(GJS_TYPE_CONTEXT,
-                                            "search-path", include_path,
-                                            "program-name", program_name,
-                                            "profiler-enabled", enable_profiler,
-                                            NULL);
-
     env_coverage_output_path = g_getenv("GJS_COVERAGE_OUTPUT");
     if (env_coverage_output_path != NULL) {
         g_free(coverage_output_path);
@@ -357,12 +353,18 @@ main(int argc, char **argv)
     if (coverage_prefixes) {
         if (!coverage_output_path)
             g_error("--coverage-output is required when taking coverage statistics");
+    }
+
+    js_context = (GjsContext*)g_object_new(
+        GJS_TYPE_CONTEXT, "search-path", include_path, "program-name",
+        program_name, "profiler-enabled", enable_profiler, NULL);
+
+    if (coverage_prefixes) {
+        GFile* output = g_file_new_for_commandline_arg(coverage_output_path);
+        gjs_coverage = gjs_coverage_new(coverage_prefixes, js_context, output);
 
-        GFile *output = g_file_new_for_commandline_arg(coverage_output_path);
-        coverage = gjs_coverage_new(coverage_prefixes, js_context, output);
         g_object_unref(output);
     }
-
     if (enable_profiler && profile_output_path) {
         GjsProfiler *profiler = gjs_context_get_profiler(js_context);
         gjs_profiler_set_filename(profiler, profile_output_path);
@@ -388,14 +390,14 @@ main(int argc, char **argv)
     g_strfreev(gjs_argv_addr);
 
     /* Probably doesn't make sense to write statistics on failure */
-    if (coverage && code == 0)
-        gjs_coverage_write_statistics(coverage);
+    if (gjs_coverage && code == 0)
+        gjs_coverage_write_statistics(gjs_coverage);
 
     g_free(coverage_output_path);
     g_free(profile_output_path);
     g_strfreev(coverage_prefixes);
-    if (coverage)
-        g_object_unref(coverage);
+    if (gjs_coverage)
+        g_object_unref(gjs_coverage);
     g_object_unref(js_context);
     g_free(script);
 
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 1b1e5562..fff054a4 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -50,10 +50,6 @@
 #include "gjs/macros.h"
 #include "gjs/profiler.h"
 
-namespace mozilla {
-template <class Key>
-struct DefaultHasher;
-}
 class GjsAtoms;
 
 using JobQueueStorage =
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 04f28f73..761e8f66 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -388,7 +388,7 @@ void GjsContextPrivate::dispose(void) {
          * context
          */
         gjs_debug(GJS_DEBUG_CONTEXT, "Final triggered GC");
-        JS_GC(m_cx);
+        // FIXME(mozjs78): JS_GC(m_cx);
 
         gjs_debug(GJS_DEBUG_CONTEXT, "Destroying JS context");
         m_destroying = true;
@@ -616,9 +616,13 @@ void GjsContextPrivate::schedule_gc_internal(bool force_gc) {
     if (force_gc)
         gjs_debug_lifecycle(GJS_DEBUG_CONTEXT, "Big Hammer scheduled");
 
-    m_auto_gc_id = g_timeout_add_seconds_full(G_PRIORITY_LOW, 10,
-                                              trigger_gc_if_needed, this,
-                                              nullptr);
+    // FIXME(mozjs78): This causes "Assertion failure:
+    // trc->runtime()->gc.state() == State::NotActive ||
+    // trc->runtime()->gc.state() == State::MarkRoots, at
+    // /js/src/gc/Marking.cpp:410" m_auto_gc_id =
+    // g_timeout_add_seconds_full(G_PRIORITY_LOW, 10,
+    //                                           trigger_gc_if_needed, this,
+    //                                           nullptr);
 }
 
 /*
diff --git a/gjs/coverage.cpp b/gjs/coverage.cpp
index cbeeafcb..614aea4a 100644
--- a/gjs/coverage.cpp
+++ b/gjs/coverage.cpp
@@ -233,8 +233,7 @@ write_statistics_internal(GjsCoverage *coverage,
     GFile *output_file = g_file_get_child(priv->output_dir, "coverage.lcov");
 
     size_t lcov_length;
-    GjsAutoPointer<char, void, free> lcov(
-        js::GetCodeCoverageSummary(cx, &lcov_length));
+    JS::UniqueChars lcov = js::GetCodeCoverageSummary(cx, &lcov_length);
 
     GjsAutoUnref<GOutputStream> ostream =
         G_OUTPUT_STREAM(g_file_append_to(output_file,
@@ -244,7 +243,7 @@ write_statistics_internal(GjsCoverage *coverage,
     if (!ostream)
         return nullptr;
 
-    GjsAutoStrv lcov_lines = g_strsplit(lcov, "\n", -1);
+    GjsAutoStrv lcov_lines = g_strsplit(lcov.get(), "\n", -1);
     const char* test_name = NULL;
     bool ignoring_file = false;
 
diff --git a/gjs/engine.cpp b/gjs/engine.cpp
index e3bd937a..2e41068f 100644
--- a/gjs/engine.cpp
+++ b/gjs/engine.cpp
@@ -102,7 +102,8 @@ static void gjs_finalize_callback(JSFreeOp*, JSFinalizeStatus status,
         gjs->set_sweeping(false);
 }
 
-static void on_garbage_collect(JSContext*, JSGCStatus status, void*) {
+static void on_garbage_collect(JSContext*, JSGCStatus status,
+                               JS::GCReason reason, void*) {
     /* We finalize any pending toggle refs before doing any garbage collection,
      * so that we can collect the JS wrapper objects, and in order to minimize
      * the chances of objects having a pending toggle up queued when they are
@@ -116,7 +117,7 @@ static void on_garbage_collect(JSContext*, JSGCStatus status, void*) {
 }
 
 static void on_promise_unhandled_rejection(
-    JSContext* cx, JS::HandleObject promise,
+    JSContext* cx, bool, JS::HandleObject promise,
     JS::PromiseRejectionHandlingState state, void* data) {
     auto gjs = static_cast<GjsContextPrivate*>(data);
     uint64_t id = JS::GetPromiseID(promise);
@@ -213,13 +214,10 @@ JSContext* gjs_create_js_context(GjsContextPrivate* uninitialized_gjs) {
 
     // commented are defaults in moz-24
     JS_SetNativeStackQuota(cx, 1024 * 1024);
-    JS_SetGCParameter(cx, JSGC_MAX_MALLOC_BYTES, 128 * 1024 * 1024);
     JS_SetGCParameter(cx, JSGC_MAX_BYTES, -1);
     JS_SetGCParameter(cx, JSGC_MODE, JSGC_MODE_INCREMENTAL);
-    JS_SetGCParameter(cx, JSGC_SLICE_TIME_BUDGET, 10); /* ms */
+    JS_SetGCParameter(cx, JSGC_SLICE_TIME_BUDGET_MS, 10); /* ms */
     // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_TIME_LIMIT, 1000); /* ms */
-    JS_SetGCParameter(cx, JSGC_DYNAMIC_MARK_SLICE, true);
-    JS_SetGCParameter(cx, JSGC_DYNAMIC_HEAP_GROWTH, true);
     // JS_SetGCParameter(cx, JSGC_LOW_FREQUENCY_HEAP_GROWTH, 150);
     // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, 150);
     // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, 300);
@@ -246,18 +244,21 @@ JSContext* gjs_create_js_context(GjsContextPrivate* uninitialized_gjs) {
     js::SetSourceHook(cx, std::move(hook));
 
     /* setExtraWarnings: Be extra strict about code that might hide a bug */
-    if (!g_getenv("GJS_DISABLE_EXTRA_WARNINGS")) {
-        gjs_debug(GJS_DEBUG_CONTEXT, "Enabling extra warnings");
-        JS::ContextOptionsRef(cx).setExtraWarnings(true);
-    }
+    // TODO(mozjs78): Extra warnings no longer exists in SpiderMonkey
+    // if (!g_getenv("GJS_DISABLE_EXTRA_WARNINGS")) {
+    //    gjs_debug(GJS_DEBUG_CONTEXT, "Enabling extra warnings");
+    //    JS::ContextOptionsRef(cx).setExtraWarnings(true);
+    // }
 
     bool enable_jit = !(g_getenv("GJS_DISABLE_JIT"));
     if (enable_jit) {
         gjs_debug(GJS_DEBUG_CONTEXT, "Enabling JIT");
     }
+
+    // TODO(mozjs78): Do these options do the same thing?
     JS::ContextOptionsRef(cx)
-        .setIon(enable_jit)
-        .setBaseline(enable_jit)
+        .setWasmBaseline(enable_jit)
+        .setWasmIon(enable_jit)
         .setAsmJS(enable_jit);
 
     return cx;
diff --git a/gjs/global.cpp b/gjs/global.cpp
index dd2ad2a9..4ed887ed 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -251,8 +251,11 @@ class GjsGlobal {
         JS::RealmBehaviors behaviors;
 
         JS::RealmCreationOptions creation;
-        creation.setFieldsEnabled(true);
-        creation.setBigIntEnabled(true);
+        //  Now default.
+        // enable uneval
+        creation.setToSourceEnabled(true);
+        // creation.setFieldsEnabled(true);
+        // creation.setBigIntEnabled(true);
 
         JS::RealmOptions options(creation, behaviors);
 
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 628d3cad..d43130d9 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -36,6 +36,7 @@
 #include <gio/gio.h>
 #include <glib.h>
 
+#include <js/Array.h>
 #include <js/CallArgs.h>
 #include <js/CharacterEncoding.h>
 #include <js/Class.h>
@@ -478,14 +479,14 @@ static bool do_import(JSContext* context, JS::HandleObject obj, Importer* priv,
                                      atoms.search_path(), &search_path))
         return false;
 
-    if (!JS_IsArrayObject(context, search_path, &is_array))
+    if (!JS::IsArrayObject(context, search_path, &is_array))
         return false;
     if (!is_array) {
         gjs_throw(context, "searchPath property on importer is not an array");
         return false;
     }
 
-    if (!JS_GetArrayLength(context, search_path, &search_path_len)) {
+    if (!JS::GetArrayLength(context, search_path, &search_path_len)) {
         gjs_throw(context, "searchPath array has no length");
         return false;
     }
@@ -633,14 +634,14 @@ static bool importer_new_enumerate(JSContext* context, JS::HandleObject object,
                                      atoms.search_path(), &search_path))
         return false;
 
-    if (!JS_IsArrayObject(context, search_path, &is_array))
+    if (!JS::IsArrayObject(context, search_path, &is_array))
         return false;
     if (!is_array) {
         gjs_throw(context, "searchPath property on importer is not an array");
         return false;
     }
 
-    if (!JS_GetArrayLength(context, search_path, &search_path_len)) {
+    if (!JS::GetArrayLength(context, search_path, &search_path_len)) {
         gjs_throw(context, "searchPath array has no length");
         return false;
     }
diff --git a/gjs/jsapi-dynamic-class.cpp b/gjs/jsapi-dynamic-class.cpp
index 3cacb0e3..9f22b112 100644
--- a/gjs/jsapi-dynamic-class.cpp
+++ b/gjs/jsapi-dynamic-class.cpp
@@ -90,8 +90,9 @@ bool gjs_init_class_dynamic(JSContext* context, JS::HandleObject in_object,
     if (clasp->cOps->resolve) {
         JSPropertySpec *ps_iter;
         JSFunctionSpec *fs_iter;
-        for (ps_iter = proto_ps; ps_iter && ps_iter->name; ps_iter++)
-            ps_iter->flags |= JSPROP_RESOLVING;
+        // FIXME(mozjs78): https://phabricator.services.mozilla.com/D72528
+        // for (ps_iter = proto_ps; ps_iter && ps_iter->name; ps_iter++)
+        //    ps_iter->flags |= JSPROP_RESOLVING;
         for (fs_iter = proto_fs; fs_iter && fs_iter->name; fs_iter++)
             fs_iter->flags |= JSPROP_RESOLVING;
     }
diff --git a/gjs/jsapi-util-error.cpp b/gjs/jsapi-util-error.cpp
index 509e3c92..ebc09cc5 100644
--- a/gjs/jsapi-util-error.cpp
+++ b/gjs/jsapi-util-error.cpp
@@ -83,7 +83,7 @@ gjs_throw_valist(JSContext       *context,
     JS::RootedObject constructor(context);
     JS::RootedValue v_constructor(context), exc_val(context);
     JS::RootedObject new_exc(context);
-    JS::AutoValueArray<1> error_args(context);
+    JS::RootedValueArray<1> error_args(context);
     result = false;
 
     if (!gjs_string_from_utf8(context, s, error_args[0])) {
@@ -237,7 +237,6 @@ void gjs_warning_reporter(JSContext*, JSErrorReport* report) {
     g_assert(report);
 
     if (gjs_environment_variable_is_set("GJS_ABORT_ON_OOM") &&
-        report->flags == JSREPORT_ERROR &&
         report->errorNumber == 137) {
         /* 137, JSMSG_OUT_OF_MEMORY */
         g_error("GJS ran out of memory at %s: %i.",
@@ -245,7 +244,7 @@ void gjs_warning_reporter(JSContext*, JSErrorReport* report) {
                 report->lineno);
     }
 
-    if ((report->flags & JSREPORT_WARNING) != 0) {
+    if (report->isWarning()) {
         warning = "WARNING";
         level = G_LOG_LEVEL_MESSAGE;
 
diff --git a/gjs/jsapi-util-root.h b/gjs/jsapi-util-root.h
index b06d83ee..09f48b0c 100644
--- a/gjs/jsapi-util-root.h
+++ b/gjs/jsapi-util-root.h
@@ -94,7 +94,7 @@ struct GjsHeapOperation<JSObject *> {
     static void expose_to_js(JS::Heap<JSObject *>& thing) {
         JSObject *obj = thing.unbarrieredGet();
         /* If the object has been swept already, then the zone is nullptr */
-        if (!obj || !js::gc::detail::GetGCThingZone(uintptr_t(obj)))
+        if (!obj || !js::gc::detail::GetTenuredGCThingZone(uintptr_t(obj)))
             return;
         if (!JS::RuntimeHeapIsCollecting())
             JS::ExposeObjectToActiveJS(obj);
@@ -105,7 +105,7 @@ template <>
 struct GjsHeapOperation<JSFunction*> {
     static void expose_to_js(const JS::Heap<JSFunction*>& thing) {
         JSFunction* func = thing.unbarrieredGet();
-        if (!func || !js::gc::detail::GetGCThingZone(uintptr_t(func)))
+        if (!func || !js::gc::detail::GetTenuredGCThingZone(uintptr_t(func)))
             return;
         if (!JS::RuntimeHeapIsCollecting())
             js::gc::ExposeGCThingToActiveJS(JS::GCCellPtr(func));
diff --git a/gjs/jsapi-util-string.cpp b/gjs/jsapi-util-string.cpp
index 5c6d9e56..7605c3e9 100644
--- a/gjs/jsapi-util-string.cpp
+++ b/gjs/jsapi-util-string.cpp
@@ -340,7 +340,8 @@ bool gjs_get_string_id(JSContext* cx, jsid id, JS::UniqueChars* name_p) {
         return true;
     }
 
-    JS::RootedString s(cx, JS_FORGET_STRING_FLATNESS(JSID_TO_FLAT_STRING(id)));
+    JSLinearString* lstr = JSID_TO_LINEAR_STRING(id);
+    JS::RootedString s(cx, JS_FORGET_STRING_LINEARNESS(lstr));
     *name_p = JS_EncodeStringToUTF8(cx, s);
     return !!*name_p;
 }
@@ -377,14 +378,11 @@ gjs_intern_string_to_id(JSContext  *cx,
     JS::RootedString str(cx, JS_AtomizeAndPinString(cx, string));
     if (!str)
         return JSID_VOID;
-    return INTERNED_STRING_TO_JSID(cx, str);
+    return JS::PropertyKey::fromPinnedString(str);
 }
 
 GJS_USE
-static std::string
-gjs_debug_flat_string(JSFlatString *fstr)
-{
-    JSLinearString *str = js::FlatStringToLinearString(fstr);
+static std::string gjs_debug_linear_string(JSLinearString* str) {
     size_t len = js::GetLinearStringLength(str);
 
     JS::AutoCheckCannotGC nogc;
@@ -416,12 +414,12 @@ gjs_debug_string(JSString *str)
 {
     if (!str)
         return "<null string>";
-    if (!JS_StringIsFlat(str)) {
+    if (!JS_StringIsLinear(str)) {
         std::ostringstream out("<non-flat string of length ");
         out << JS_GetStringLength(str) << '>';
         return out.str();
     }
-    return gjs_debug_flat_string(JS_ASSERT_STRING_IS_FLAT(str));
+    return gjs_debug_linear_string(JS_ASSERT_STRING_IS_LINEAR(str));
 }
 
 std::string
@@ -522,6 +520,6 @@ std::string
 gjs_debug_id(jsid id)
 {
     if (JSID_IS_STRING(id))
-        return gjs_debug_flat_string(JSID_TO_FLAT_STRING(id));
+        return gjs_debug_linear_string(JSID_TO_LINEAR_STRING(id));
     return gjs_debug_value(js::IdToValue(id));
 }
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index 4d7193b2..98ec4aca 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -38,6 +38,7 @@
 #include <utility>  // for move
 #include <vector>
 
+#include <js/Array.h>
 #include <js/CallArgs.h>
 #include <js/CharacterEncoding.h>
 #include <js/Class.h>
@@ -236,7 +237,7 @@ JSObject* gjs_build_string_array(JSContext* context,
         elems.infallibleAppend(element);
     }
 
-    return JS_NewArrayObject(context, elems);
+    return JS::NewArrayObject(context, elems);
 }
 
 JSObject* gjs_define_string_array(JSContext* context,
@@ -407,12 +408,11 @@ bool gjs_log_exception_full(JSContext* context, JS::HandleValue exc,
     bool is_syntax = false, is_internal = false;
     if (exc.isObject()) {
         exc_obj = &exc.toObject();
-        const JSClass* syntax_error =
-            js::Jsvalify(js::ProtoKeyToClass(JSProto_SyntaxError));
+        const JSClass* syntax_error = js::ProtoKeyToClass(JSProto_SyntaxError);
         is_syntax = JS_InstanceOf(context, exc_obj, syntax_error, nullptr);
 
         const JSClass* internal_error =
-            js::Jsvalify(js::ProtoKeyToClass(JSProto_InternalError));
+            js::ProtoKeyToClass(JSProto_InternalError);
         is_internal = JS_InstanceOf(context, exc_obj, internal_error, nullptr);
     }
 
diff --git a/meson.build b/meson.build
index 574ae1b1..9c31f450 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project('gjs', 'cpp', 'c', version: '1.65.4', license: ['MIT', 'LGPL2+'],
     meson_version: '>= 0.52.0',
-    default_options: ['cpp_std=c++14', 'c_std=c99', 'warning_level=2'])
+    default_options: ['cpp_std=c++17', 'c_std=c99', 'warning_level=2'])
 
 api_version = '1.0'
 api_name = '@0@-@1@'.format(meson.project_name(), api_version)
@@ -115,7 +115,7 @@ gio = dependency('gio-2.0', version: glib_required_version,
 ffi = dependency('libffi', fallback: ['libffi', 'ffi_dep'])
 gi = dependency('gobject-introspection-1.0', version: '>= 1.61.2',
     fallback: ['gobject-introspection', 'girepo_dep'])
-spidermonkey = dependency('mozjs-68')
+spidermonkey = dependency('mozjs-78')
 
 # We might need to look for the headers and lib's for Cairo
 # manually on MSVC builds...
@@ -221,23 +221,23 @@ endif
 # Check if a minimal SpiderMonkey program compiles, links, and runs. If not,
 # it's most likely the case that SpiderMonkey was configured incorrectly, for
 # example by building mozglue as a shared library.
-minimal_program = cxx.run('''
-#include <js/Initialization.h>
-int main(void) {
-    if (!JS_Init()) return 1;
-    JS_ShutDown();
-    return 0;
-}
-''',
-    args: debug_arg, dependencies: spidermonkey,
-    name: 'SpiderMonkey sanity check')
-
-if not minimal_program.compiled() or minimal_program.returncode() != 0
-    error('''A minimal SpiderMonkey program
-could not be compiled, linked, or run. Most likely you should build it with a
-different configuration. Check the recommended configuration:
-https://github.com/spidermonkey-embedders/spidermonkey-embedding-examples/blob/esr60/docs/Building%20SpiderMonkey.md''')
-endif
+# minimal_program = cxx.run('''
+# #include <js/Initialization.h>
+# int main(void) {
+#     if (!JS_Init()) return 1;
+#     JS_ShutDown();
+#     return 0;
+# }
+# ''',
+#     args: debug_arg, dependencies: spidermonkey,
+#     name: 'SpiderMonkey sanity check')
+
+# if not minimal_program.compiled() or minimal_program.returncode() != 0
+#     error('''A minimal SpiderMonkey program
+# could not be compiled, linked, or run. Most likely you should build it with a
+# different configuration. Check the recommended configuration:
+# 
https://github.com/spidermonkey-embedders/spidermonkey-embedding-examples/blob/esr60/docs/Building%20SpiderMonkey.md''')
+# endif
 
 have_printf_alternative_int = cc.compiles('''
 #include <stdio.h>
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index 52b7734c..44101bfe 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -29,6 +29,7 @@
 #include <girepository.h>
 #include <glib.h>
 
+#include <js/Array.h>
 #include <js/CallArgs.h>
 #include <js/Class.h>
 #include <js/Conversions.h>
@@ -37,7 +38,7 @@
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
 #include <js/Value.h>
-#include <jsapi.h>  // for JS_SetElement, JS_NewArrayObject
+#include <jsapi.h>  // for JS_SetElement, JS::NewArrayObject
 
 #include "gi/arg.h"
 #include "gi/foreign.h"
@@ -87,65 +88,76 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method)                               \
     argv.rval().setBoolean(ret);                                           \
 _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
 
-#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC2FFAFF(method, cfunc, n1, n2)        \
-_GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method)                               \
-    double arg1, arg2;                                                     \
-    if (!gjs_parse_call_args(context, #method, argv, "ff",                 \
-                             #n1, &arg1, #n2, &arg2))                      \
-        return false;                                                      \
-    cfunc(cr, &arg1, &arg2);                                               \
-    if (cairo_status(cr) == CAIRO_STATUS_SUCCESS) {                        \
-      JS::RootedObject array(context,                                      \
-          JS_NewArrayObject(context, JS::HandleValueArray::empty()));      \
-      if (!array)                                                          \
-        return false;                                                      \
-      JS::RootedValue r(context, JS::NumberValue(arg1));                   \
-      if (!JS_SetElement(context, array, 0, r)) return false;              \
-      r.setNumber(arg2);                                                   \
-      if (!JS_SetElement(context, array, 1, r)) return false;              \
-      argv.rval().setObject(*array);                                       \
-    }                                                                      \
-_GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
-
-#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC0AFF(method, cfunc)                  \
-_GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method)                               \
-    double arg1, arg2;                                                     \
-   _GJS_CAIRO_CONTEXT_CHECK_NO_ARGS(method)                                \
-    cfunc(cr, &arg1, &arg2);                                               \
-    if (cairo_status(cr) == CAIRO_STATUS_SUCCESS) {                        \
-      JS::RootedObject array(context,                                      \
-          JS_NewArrayObject(context, JS::HandleValueArray::empty()));      \
-      if (!array)                                                          \
-        return false;                                                      \
-      JS::RootedValue r(context, JS::NumberValue(arg1));                   \
-      if (!JS_SetElement(context, array, 0, r)) return false;              \
-      r.setNumber(arg2);                                                   \
-      if (!JS_SetElement(context, array, 1, r)) return false;              \
-      argv.rval().setObject(*array);                                       \
-    }                                                                      \
-_GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
-
-#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC0AFFFF(method, cfunc)                \
-_GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method)                               \
-    double arg1, arg2, arg3, arg4;                                         \
-   _GJS_CAIRO_CONTEXT_CHECK_NO_ARGS(method)                                \
-    cfunc(cr, &arg1, &arg2, &arg3, &arg4);                                 \
-    {                                                                      \
-      JS::RootedObject array(context,                                      \
-          JS_NewArrayObject(context, JS::HandleValueArray::empty()));      \
-      if (!array)                                                          \
-        return false;                                                      \
-      JS::RootedValue r(context, JS::NumberValue(arg1));                   \
-      if (!JS_SetElement(context, array, 0, r)) return false;              \
-      r.setNumber(arg2);                                                   \
-      if (!JS_SetElement(context, array, 1, r)) return false;              \
-      r.setNumber(arg3);                                                   \
-      if (!JS_SetElement(context, array, 2, r)) return false;              \
-      r.setNumber(arg4);                                                   \
-      if (!JS_SetElement(context, array, 3, r)) return false;              \
-      argv.rval().setObject(*array);                                       \
-    }                                                                      \
-_GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
+#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC2FFAFF(method, cfunc, n1, n2)         \
+    _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method)                            \
+    double arg1, arg2;                                                      \
+    if (!gjs_parse_call_args(context, #method, argv, "ff", #n1, &arg1, #n2, \
+                             &arg2))                                        \
+        return false;                                                       \
+    cfunc(cr, &arg1, &arg2);                                                \
+    if (cairo_status(cr) == CAIRO_STATUS_SUCCESS) {                         \
+        JS::RootedObject array(                                             \
+            context,                                                        \
+            JS::NewArrayObject(context, JS::HandleValueArray::empty()));    \
+        if (!array)                                                         \
+            return false;                                                   \
+        JS::RootedValue r(context, JS::NumberValue(arg1));                  \
+        if (!JS_SetElement(context, array, 0, r))                           \
+            return false;                                                   \
+        r.setNumber(arg2);                                                  \
+        if (!JS_SetElement(context, array, 1, r))                           \
+            return false;                                                   \
+        argv.rval().setObject(*array);                                      \
+    }                                                                       \
+    _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
+
+#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC0AFF(method, cfunc)                \
+    _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method)                         \
+    double arg1, arg2;                                                   \
+    _GJS_CAIRO_CONTEXT_CHECK_NO_ARGS(method)                             \
+    cfunc(cr, &arg1, &arg2);                                             \
+    if (cairo_status(cr) == CAIRO_STATUS_SUCCESS) {                      \
+        JS::RootedObject array(                                          \
+            context,                                                     \
+            JS::NewArrayObject(context, JS::HandleValueArray::empty())); \
+        if (!array)                                                      \
+            return false;                                                \
+        JS::RootedValue r(context, JS::NumberValue(arg1));               \
+        if (!JS_SetElement(context, array, 0, r))                        \
+            return false;                                                \
+        r.setNumber(arg2);                                               \
+        if (!JS_SetElement(context, array, 1, r))                        \
+            return false;                                                \
+        argv.rval().setObject(*array);                                   \
+    }                                                                    \
+    _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
+
+#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC0AFFFF(method, cfunc)              \
+    _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method)                         \
+    double arg1, arg2, arg3, arg4;                                       \
+    _GJS_CAIRO_CONTEXT_CHECK_NO_ARGS(method)                             \
+    cfunc(cr, &arg1, &arg2, &arg3, &arg4);                               \
+    {                                                                    \
+        JS::RootedObject array(                                          \
+            context,                                                     \
+            JS::NewArrayObject(context, JS::HandleValueArray::empty())); \
+        if (!array)                                                      \
+            return false;                                                \
+        JS::RootedValue r(context, JS::NumberValue(arg1));               \
+        if (!JS_SetElement(context, array, 0, r))                        \
+            return false;                                                \
+        r.setNumber(arg2);                                               \
+        if (!JS_SetElement(context, array, 1, r))                        \
+            return false;                                                \
+        r.setNumber(arg3);                                               \
+        if (!JS_SetElement(context, array, 2, r))                        \
+            return false;                                                \
+        r.setNumber(arg4);                                               \
+        if (!JS_SetElement(context, array, 3, r))                        \
+            return false;                                                \
+        argv.rval().setObject(*array);                                   \
+    }                                                                    \
+    _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
 
 #define _GJS_CAIRO_CONTEXT_DEFINE_FUNC0F(method, cfunc)                    \
 _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method)                               \
@@ -543,14 +555,14 @@ setDash_func(JSContext *context,
                              "offset", &offset))
         return false;
 
-    if (!JS_IsArrayObject(context, dashes, &is_array))
+    if (!JS::IsArrayObject(context, dashes, &is_array))
         return false;
     if (!is_array) {
         gjs_throw(context, "dashes must be an array");
         return false;
     }
 
-    if (!JS_GetArrayLength(context, dashes, &len)) {
+    if (!JS::GetArrayLength(context, dashes, &len)) {
         gjs_throw(context, "Can't get length of dashes");
         return false;
     }
diff --git a/modules/console.cpp b/modules/console.cpp
index 7f8b9477..03dcae71 100644
--- a/modules/console.cpp
+++ b/modules/console.cpp
@@ -55,6 +55,7 @@
 #include <js/CompilationAndEvaluation.h>
 #include <js/CompileOptions.h>
 #include <js/ErrorReport.h>
+#include <js/Exception.h>
 #include <js/RootingAPI.h>
 #include <js/SourceText.h>
 #include <js/TypeDecls.h>
@@ -73,128 +74,6 @@ namespace mozilla {
 union Utf8Unit;
 }
 
-enum class PrintErrorKind { Error, Warning, StrictWarning, Note };
-
-template <typename T>
-static void print_single_error(T* report, PrintErrorKind kind);
-static void print_error_line(const char* prefix, JSErrorReport* report);
-static void print_error_line(const char*, JSErrorNotes::Note*) {}
-
-static void
-gjs_console_print_error(JSErrorReport *report)
-{
-    // Code modified from SpiderMonkey js/src/vm/JSContext.cpp, js::PrintError()
-
-    g_assert(report);
-
-    PrintErrorKind kind = PrintErrorKind::Error;
-    if (JSREPORT_IS_WARNING(report->flags)) {
-        if (JSREPORT_IS_STRICT(report->flags))
-            kind = PrintErrorKind::StrictWarning;
-        else
-            kind = PrintErrorKind::Warning;
-    }
-    print_single_error(report, kind);
-
-    if (report->notes) {
-        for (auto&& note : *report->notes)
-            print_single_error(note.get(), PrintErrorKind::Note);
-    }
-
-    return;
-}
-
-template <typename T>
-static void print_single_error(T* report, PrintErrorKind kind) {
-    JS::UniqueChars prefix;
-    if (report->filename)
-        prefix.reset(g_strdup_printf("%s:", report->filename));
-
-    if (report->lineno) {
-        prefix.reset(g_strdup_printf("%s%u:%u ", prefix ? prefix.get() : "",
-                                     report->lineno, report->column));
-    }
-
-    if (kind != PrintErrorKind::Error) {
-        const char* kindPrefix = nullptr;
-        switch (kind) {
-            case PrintErrorKind::Warning:
-                kindPrefix = "warning";
-                break;
-            case PrintErrorKind::StrictWarning:
-                kindPrefix = "strict warning";
-                break;
-            case PrintErrorKind::Note:
-                kindPrefix = "note";
-                break;
-            case PrintErrorKind::Error:
-            default:
-                g_assert_not_reached();
-        }
-
-        prefix.reset(
-            g_strdup_printf("%s%s: ", prefix ? prefix.get() : "", kindPrefix));
-    }
-
-    const char* message = report->message().c_str();
-
-    /* embedded newlines -- argh! */
-    const char *ctmp;
-    while ((ctmp = strchr(message, '\n')) != 0) {
-        ctmp++;
-        if (prefix)
-            fputs(prefix.get(), stderr);
-        mozilla::Unused << fwrite(message, 1, ctmp - message, stderr);
-        message = ctmp;
-    }
-
-    /* If there were no filename or lineno, the prefix might be empty */
-    if (prefix)
-        fputs(prefix.get(), stderr);
-    fputs(message, stderr);
-
-    print_error_line(prefix.get(), report);
-    fputc('\n', stderr);
-
-    fflush(stderr);
-}
-
-static void print_error_line(const char* prefix, JSErrorReport* report) {
-    if (const char16_t* linebuf = report->linebuf()) {
-        size_t n = report->linebufLength();
-
-        fputs(":\n", stderr);
-        if (prefix)
-            fputs(prefix, stderr);
-
-        for (size_t i = 0; i < n; i++)
-            fputc(static_cast<char>(linebuf[i]), stderr);
-
-        // linebuf usually ends with a newline. If not, add one here.
-        if (n == 0 || linebuf[n - 1] != '\n')
-            fputc('\n', stderr);
-
-        if (prefix)
-            fputs(prefix, stderr);
-
-        n = report->tokenOffset();
-        for (size_t i = 0, j = 0; i < n; i++) {
-            if (linebuf[i] == '\t') {
-                for (size_t k = (j + 8) & ~7; j < k; j++)
-                    fputc('.', stderr);
-                continue;
-            }
-            fputc('.', stderr);
-            j++;
-        }
-        fputc('^', stderr);
-    }
-}
-
-static void gjs_console_warning_reporter(JSContext*, JSErrorReport* report) {
-    gjs_console_print_error(report);
-}
-
 /* Based on js::shell::AutoReportException from SpiderMonkey. */
 class AutoReportException {
     JSContext *m_cx;
@@ -226,8 +105,7 @@ public:
 
         JSErrorReport* report = error_from_exception_value(v_exn);
         if (report) {
-            g_assert(!JSREPORT_IS_WARNING(report->flags));
-            gjs_console_print_error(report);
+            JS::PrintError(m_cx, stderr, report, false);
         } else {
             GjsAutoChar display_str = gjs_value_debug_string(m_cx, v_exn);
             g_printerr("error: %s\n", display_str.get());
@@ -325,9 +203,11 @@ gjs_console_interact(JSContext *context,
     int lineno;
     int startline;
 
-    JS::SetWarningReporter(context, gjs_console_warning_reporter);
+    JS::SetWarningReporter(context, [](JSContext* cx, JSErrorReport* report) {
+        JS::PrintError(cx, stderr, report, true);
+    });
 
-        /* It's an interactive filehandle; drop into read-eval-print loop. */
+    /* It's an interactive filehandle; drop into read-eval-print loop. */
     lineno = 1;
     do {
         /*
diff --git a/test/gjs-test-rooting.cpp b/test/gjs-test-rooting.cpp
index 3dfa4cd4..029e8633 100644
--- a/test/gjs-test-rooting.cpp
+++ b/test/gjs-test-rooting.cpp
@@ -55,7 +55,7 @@ test_obj_new(GjsRootingFixture *fx)
     return retval;
 }
 
-static void on_gc(JSContext*, JSGCStatus status, void*) {
+static void on_gc(JSContext*, JSGCStatus status, JS::GCReason reason, void*) {
     if (status != JSGC_END)
         return;
 
diff --git a/test/gjs-tests.cpp b/test/gjs-tests.cpp
index 8c2e596c..eea68366 100644
--- a/test/gjs-tests.cpp
+++ b/test/gjs-tests.cpp
@@ -31,6 +31,7 @@
 #include <glib.h>
 #include <glib/gstdio.h>  // for g_unlink
 
+#include <js/Array.h>
 #include <js/CharacterEncoding.h>
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
@@ -309,10 +310,10 @@ static void test_jsapi_util_debug_string_object_with_complicated_to_string(
         0xd83c, 0xdf6a,  /* cookie */
         0xd83c, 0xdf69,  /* doughnut */
     };
-    JS::AutoValueArray<2> contents(fx->cx);
+    JS::RootedValueArray<2> contents(fx->cx);
     contents[0].setString(JS_NewUCStringCopyN(fx->cx, desserts, 2));
     contents[1].setString(JS_NewUCStringCopyN(fx->cx, desserts + 2, 2));
-    JS::RootedObject array(fx->cx, JS_NewArrayObject(fx->cx, contents));
+    JS::RootedObject array(fx->cx, JS::NewArrayObject(fx->cx, contents));
     JS::RootedValue v_array(fx->cx, JS::ObjectValue(*array));
     char *debug_output = gjs_value_debug_string(fx->cx, v_array);
 



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