[gjs/mozjs91] WIP: Initial ESR 91 port




commit 7b33bedcb518d863a222d97fa055264d3a861784
Author: Evan Welsh <contact evanwelsh com>
Date:   Sat Jun 5 13:40:31 2021 -0700

    WIP: Initial ESR 91 port

 doc/SpiderMonkey_Memory.md  |  6 ++-
 gi/arg-cache.cpp            |  2 +
 gi/arg.cpp                  |  1 +
 gi/cwrapper.h               | 13 +++---
 gi/function.cpp             |  4 +-
 gi/fundamental.cpp          |  4 +-
 gi/gerror.cpp               |  8 +++-
 gi/gobject.cpp              | 32 ++++++++++-----
 gi/gtype.cpp                |  2 +-
 gi/ns.cpp                   |  6 +--
 gi/object.cpp               |  2 +-
 gi/param.cpp                | 10 ++---
 gi/repo.cpp                 |  2 +-
 gi/value.cpp                |  1 +
 gi/wrapperutils.h           | 14 +++----
 gjs/byteArray.cpp           | 11 ++---
 gjs/context.cpp             | 44 ++++++++++++++------
 gjs/deprecation.cpp         |  1 +
 gjs/engine.cpp              | 12 +-----
 gjs/global.cpp              |  8 ++--
 gjs/importer.cpp            | 14 ++++---
 gjs/internal.cpp            |  5 ++-
 gjs/jsapi-dynamic-class.cpp | 16 ++++++--
 gjs/jsapi-util-error.cpp    |  7 +++-
 gjs/jsapi-util-string.cpp   | 15 +++----
 gjs/jsapi-util.cpp          |  8 ++--
 gjs/module.cpp              | 98 +++++++++++++++++++++++++++++++++------------
 gjs/module.h                |  6 +--
 gjs/stack.cpp               |  1 +
 meson.build                 |  2 +-
 modules/cairo-context.cpp   |  2 +-
 modules/cairo-path.cpp      |  4 +-
 modules/cairo-pattern.cpp   |  6 +--
 modules/cairo-surface.cpp   |  6 +--
 modules/console.cpp         |  4 +-
 modules/system.cpp          |  7 +++-
 test/gjs-test-rooting.cpp   |  6 +--
 37 files changed, 251 insertions(+), 139 deletions(-)
---
diff --git a/doc/SpiderMonkey_Memory.md b/doc/SpiderMonkey_Memory.md
index 3e30a7c7..5348e852 100644
--- a/doc/SpiderMonkey_Memory.md
+++ b/doc/SpiderMonkey_Memory.md
@@ -69,7 +69,7 @@ Note that the wrapped T in `JS::PersistentRooted<T>` is the location of your val
 Here is the trickier part. If you create an object, say:
 
 ```c++
-JSObject *obj = JS_New(cx, whatever, ...);
+JSObject *obj = JS::Construct(cx, whatever, ...);
 ```
 
 `obj` is NOT now referenced by any other object. If the GC ran right away, `obj` would be collected.
@@ -84,7 +84,9 @@ Any SpiderMonkey APIs that can cause a garbage collection will force you to use
 So instead of the above code, you would write
 
 ```c++
-JS::RootedObject obj(cx, JS_New(cx, whatever, ...));
+JS::RootedObject obj(cx);
+if (!JS::Construct(cx, whatever, ..., &obj))
+  ...
 ```
 
 ### JSFunctionSpec and extra local roots ###
diff --git a/gi/arg-cache.cpp b/gi/arg-cache.cpp
index dfc76557..1643db59 100644
--- a/gi/arg-cache.cpp
+++ b/gi/arg-cache.cpp
@@ -20,6 +20,7 @@
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
 #include <js/Value.h>
+#include <js/experimental/TypedData.h>
 #include <jsapi.h>        // for JS_TypeOfValue
 #include <jsfriendapi.h>  // for JS_GetObjectFunction
 #include <jspubtd.h>      // for JSTYPE_FUNCTION
@@ -654,6 +655,7 @@ static bool gjs_marshal_gbytes_in_in(JSContext* cx, GjsArgumentCache* self,
         return report_gtype_mismatch(cx, self->arg_name, value, G_TYPE_BYTES);
 
     JS::RootedObject object(cx, &value.toObject());
+
     if (JS_IsUint8Array(object)) {
         gjs_arg_set(arg, gjs_byte_array_get_bytes(object));
         return true;
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 2a82b07b..30f48073 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -24,6 +24,7 @@
 #include <js/Utility.h>  // for UniqueChars
 #include <js/Value.h>
 #include <js/ValueArray.h>
+#include <js/experimental/TypedData.h>
 #include <jsapi.h>        // for JS_ReportOutOfMemory, JS_GetElement
 #include <jsfriendapi.h>  // for JS_IsUint8Array, JS_GetObjectFunc...
 
diff --git a/gi/cwrapper.h b/gi/cwrapper.h
index 436eefd2..e99fbdf4 100644
--- a/gi/cwrapper.h
+++ b/gi/cwrapper.h
@@ -17,6 +17,7 @@
 #include <js/Class.h>
 #include <js/ComparisonOperators.h>
 #include <js/Id.h>
+#include <js/Object.h>
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
 #include <js/Value.h>
@@ -116,7 +117,7 @@ class CWrapperPointerOps {
     static bool for_js_typecheck(JSContext* cx, JS::HandleObject wrapper,
                                  Wrapped** out) {
         if (!typecheck(cx, wrapper)) {
-            const JSClass* obj_class = JS_GetClass(wrapper);
+            const JSClass* obj_class = JS::GetClass(wrapper);
             gjs_throw_custom(cx, JSProto_TypeError, nullptr,
                              "Object %p is not a subclass of %s, it's a %s",
                              wrapper.get(), Base::klass.name, obj_class->name);
@@ -134,7 +135,7 @@ class CWrapperPointerOps {
      * (It can return null if no private data has been set yet on the wrapper.)
      */
     [[nodiscard]] static Wrapped* for_js_nocheck(JSObject* wrapper) {
-        return static_cast<Wrapped*>(JS_GetPrivate(wrapper));
+        return static_cast<Wrapped*>(JS::GetPrivate(wrapper));
     }
 };
 
@@ -213,7 +214,7 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
         Wrapped* priv = Base::constructor_impl(cx, args);
         if (!priv)
             return false;
-        JS_SetPrivate(object, priv);
+        JS::SetPrivate(object, priv);
 
         args.rval().setObject(*object);
         return true;
@@ -258,7 +259,7 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
         Base::finalize_impl(fop, priv);
 
         // Remove the pointer from the JSObject
-        JS_SetPrivate(obj, nullptr);
+        JS::SetPrivate(obj, nullptr);
     }
 
     static constexpr JSClassOps class_ops = {
@@ -494,8 +495,8 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
         if (!wrapper)
             return nullptr;
 
-        assert(!JS_GetPrivate(wrapper));
-        JS_SetPrivate(wrapper, Base::copy_ptr(ptr));
+        assert(!JS::GetPrivate(wrapper));
+        JS::SetPrivate(wrapper, Base::copy_ptr(ptr));
 
         debug_lifecycle(ptr, wrapper, "from_c_ptr");
 
diff --git a/gi/function.cpp b/gi/function.cpp
index aa272471..d60e23af 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -1315,8 +1315,8 @@ JSObject* Function::create(JSContext* context, GType gtype,
 
     auto* priv = new Function(info);
 
-    g_assert(!JS_GetPrivate(function) && "Function should be a fresh object");
-    JS_SetPrivate(function, priv);
+    g_assert(!JS::GetPrivate(function) && "Function should be a fresh object");
+    JS::SetPrivate(function, priv);
 
     debug_lifecycle(function, priv, "Constructor");
 
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 72b69259..2d80e9a9 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -14,7 +14,7 @@
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
-#include <jsapi.h>  // for InformalValueTypeName, JS_GetClass
+#include <jsapi.h>       // for InformalValueTypeName, JS::GetClass
 #include <mozilla/HashTable.h>
 
 #include "gi/arg-inl.h"
@@ -408,7 +408,7 @@ JSObject* FundamentalInstance::object_for_c_ptr(JSContext* context,
         return nullptr;
 
     JS::RootedObject object(context, JS_NewObjectWithGivenProto(
-                                         context, JS_GetClass(proto), proto));
+                                         context, JS::GetClass(proto), proto));
 
     if (!object)
         return nullptr;
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 08745a59..d3a2fb60 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -335,8 +335,14 @@ gjs_error_from_js_gerror(JSContext *cx,
     JS::RootedObject error_constructor(cx);
     if (!JS_GetClassObject(cx, error_kind, &error_constructor))
         return nullptr;
+    JS::RootedValue error_constructorv(cx);
+    error_constructorv.setObject(*error_constructor);
 
-    return JS_New(cx, error_constructor, error_args);
+    JS::RootedObject object(cx);
+    if (!JS::Construct(cx, error_constructorv, error_args, &object))
+        return nullptr;
+
+    return object;
 }
 
 JSObject* ErrorInstance::object_for_c_ptr(JSContext* context, GError* gerror) {
diff --git a/gi/gobject.cpp b/gi/gobject.cpp
index 2c1dc987..373664cb 100644
--- a/gi/gobject.cpp
+++ b/gi/gobject.cpp
@@ -58,28 +58,32 @@ static bool jsobj_set_gproperty(JSContext* cx, JS::HandleObject object,
     if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
         unsigned flags = GJS_MODULE_PROP_FLAGS | JSPROP_READONLY;
         GjsAutoChar camel_name = gjs_hyphen_to_camel(pspec->name);
-        JS::Rooted<JS::PropertyDescriptor> jsprop(cx);
+        JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> jsprop(cx);
+        JS::RootedObject holder(cx);
 
         // Ensure to call any associated setter method
         if (!g_str_equal(underscore_name.get(), pspec->name)) {
-            if (!JS_GetPropertyDescriptor(cx, object, underscore_name, &jsprop))
+            if (!JS_GetPropertyDescriptor(cx, object, underscore_name, &jsprop,
+                                          &holder))
                 return false;
-            if (jsprop.setter() &&
+            if (jsprop.isSome() && jsprop.value().setter() &&
                 !JS_SetProperty(cx, object, underscore_name, jsvalue))
                 return false;
         }
 
         if (!g_str_equal(camel_name.get(), pspec->name)) {
-            if (!JS_GetPropertyDescriptor(cx, object, camel_name, &jsprop))
+            if (!JS_GetPropertyDescriptor(cx, object, camel_name, &jsprop,
+                                          &holder))
                 return false;
-            if (jsprop.setter() &&
+            if (jsprop.isSome() && jsprop.value().setter() &&
                 !JS_SetProperty(cx, object, camel_name, jsvalue))
                 return false;
         }
 
-        if (!JS_GetPropertyDescriptor(cx, object, pspec->name, &jsprop))
+        if (!JS_GetPropertyDescriptor(cx, object, pspec->name, &jsprop,
+                                      &holder))
             return false;
-        if (jsprop.setter() &&
+        if (jsprop.isSome() && jsprop.value().setter() &&
             !JS_SetProperty(cx, object, pspec->name, jsvalue))
             return false;
 
@@ -134,7 +138,10 @@ static GObject* gjs_object_constructor(
     if (!constructor)
         return nullptr;
 
-    JSObject* object;
+    JS::RootedValue constructorv(cx);
+    constructorv.setObject(*constructor);
+
+    JS::RootedObject object(cx);
     if (n_construct_properties) {
         JS::RootedObject props_hash(cx, JS_NewPlainObject(cx));
 
@@ -146,9 +153,12 @@ static GObject* gjs_object_constructor(
 
         JS::RootedValueArray<1> args(cx);
         args[0].set(JS::ObjectValue(*props_hash));
-        object = JS_New(cx, constructor, args);
-    } else {
-        object = JS_New(cx, constructor, JS::HandleValueArray::empty());
+
+        if (!JS::Construct(cx, constructorv, args, &object))
+            return nullptr;
+    } else if (!JS::Construct(cx, constructorv, JS::HandleValueArray::empty(),
+                              &object)) {
+        return nullptr;
     }
 
     if (!object)
diff --git a/gi/gtype.cpp b/gi/gtype.cpp
index 7ccb8099..28eb0acd 100644
--- a/gi/gtype.cpp
+++ b/gi/gtype.cpp
@@ -170,7 +170,7 @@ class GTypeObj : public CWrapper<GTypeObj, void> {
         if (!gtype_wrapper)
             return nullptr;
 
-        JS_SetPrivate(gtype_wrapper, GSIZE_TO_POINTER(gtype));
+        JS::SetPrivate(gtype_wrapper, GSIZE_TO_POINTER(gtype));
 
         gjs->gtype_table().put(gtype, gtype_wrapper);
 
diff --git a/gi/ns.cpp b/gi/ns.cpp
index 5a30ca73..210892b6 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -16,7 +16,7 @@
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
-#include <jsapi.h>       // for JS_GetPrivate, JS_NewObjectWithGivenProto
+#include <jsapi.h>       // for JS::GetPrivate, JS_NewObjectWithGivenProto
 
 #include "gi/cwrapper.h"
 #include "gi/ns.h"
@@ -175,8 +175,8 @@ class Ns : private GjsAutoChar, public CWrapper<Ns> {
             return nullptr;
 
         auto* priv = new Ns(ns_name);
-        g_assert(!JS_GetPrivate(ns));
-        JS_SetPrivate(ns, priv);
+        g_assert(!JS::GetPrivate(ns));
+        JS::SetPrivate(ns, priv);
 
         gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE,
                             "ns constructor, obj %p priv %p", ns.get(), priv);
diff --git a/gi/object.cpp b/gi/object.cpp
index 03cfd7bc..52bfb096 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -2526,7 +2526,7 @@ ObjectInstance* ObjectInstance::new_for_gobject(JSContext* cx, GObject* gobj) {
         return nullptr;
 
     JS::RootedObject obj(
-        cx, JS_NewObjectWithGivenProto(cx, JS_GetClass(proto), proto));
+        cx, JS_NewObjectWithGivenProto(cx, JS::GetClass(proto), proto));
     if (!obj)
         return nullptr;
 
diff --git a/gi/param.cpp b/gi/param.cpp
index 29d2e6f0..cc903a73 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -12,7 +12,7 @@
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
-#include <jsapi.h>       // for JS_GetClass, JS_GetPropertyById
+#include <jsapi.h>       // for JS::GetClass, JS_GetPropertyById
 #include <jspubtd.h>     // for JSProto_TypeError
 
 #include "gi/cwrapper.h"
@@ -113,14 +113,14 @@ static bool gjs_param_constructor(JSContext* cx, unsigned argc, JS::Value* vp) {
 }
 
 static void param_finalize(JSFreeOp*, JSObject* obj) {
-    Param* priv = static_cast<Param*>(JS_GetPrivate(obj));
+    Param* priv = static_cast<Param*>(JS::GetPrivate(obj));
     gjs_debug_lifecycle(GJS_DEBUG_GPARAM, "finalize, obj %p priv %p", obj,
                         priv);
     if (!priv)
         return; /* wrong class? */
 
     GJS_DEC_COUNTER(param);
-    JS_SetPrivate(obj, nullptr);
+    JS::SetPrivate(obj, nullptr);
     delete priv;
 }
 
@@ -215,11 +215,11 @@ gjs_param_from_g_param(JSContext    *context,
 
     JS::RootedObject proto(context, gjs_lookup_param_prototype(context));
 
-    obj = JS_NewObjectWithGivenProto(context, JS_GetClass(proto), proto);
+    obj = JS_NewObjectWithGivenProto(context, JS::GetClass(proto), proto);
 
     GJS_INC_COUNTER(param);
     auto* priv = new Param(gparam);
-    JS_SetPrivate(obj, priv);
+    JS::SetPrivate(obj, priv);
 
     gjs_debug(GJS_DEBUG_GPARAM,
               "JSObject created with param instance %p type %s", gparam,
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 87030fd4..2435f647 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -720,5 +720,5 @@ JSObject* gjs_new_object_with_generic_prototype(JSContext* cx,
     if (!proto)
         return nullptr;
 
-    return JS_NewObjectWithGivenProto(cx, JS_GetClass(proto), proto);
+    return JS_NewObjectWithGivenProto(cx, JS::GetClass(proto), proto);
 }
diff --git a/gi/value.cpp b/gi/value.cpp
index df427464..e4033e7d 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -21,6 +21,7 @@
 #include <js/Utility.h>  // for UniqueChars
 #include <js/Value.h>
 #include <js/ValueArray.h>
+#include <js/experimental/TypedData.h>
 #include <jsapi.h>  // for InformalValueTypeName, JS_ClearPendingException
 #include <jsfriendapi.h>
 
diff --git a/gi/wrapperutils.h b/gi/wrapperutils.h
index 777fb72c..e5dba017 100644
--- a/gi/wrapperutils.h
+++ b/gi/wrapperutils.h
@@ -22,7 +22,7 @@
 #include <js/MemoryFunctions.h>
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
-#include <jsapi.h>       // for JS_GetPrivate, JS_SetPrivate, JS_Ge...
+#include <jsapi.h>       // for JS::GetPrivate, JS::SetPrivate, JS_Ge...
 #include <jspubtd.h>     // for JSProto_TypeError
 
 #include "gi/arg-inl.h"
@@ -369,7 +369,7 @@ class GIWrapperBase : public CWrapperPointerOps<Base> {
             priv->to_instance()->finalize_impl(fop, obj);
 
         // Remove the pointer from the JSObject
-        JS_SetPrivate(obj, nullptr);
+        JS::SetPrivate(obj, nullptr);
     }
 
     /*
@@ -429,7 +429,7 @@ class GIWrapperBase : public CWrapperPointerOps<Base> {
         JS::RootedObject proto(cx);
         if (!JS_GetPrototype(cx, obj, &proto))
             return false;
-        if (JS_GetClass(proto) != &Base::klass) {
+        if (JS::GetClass(proto) != &Base::klass) {
             gjs_throw(cx, "Tried to construct an object without a GType");
             return false;
         }
@@ -775,7 +775,7 @@ class GIWrapperPrototype : public Base {
                   "Defined class for %s (%s), prototype %p, "
                   "JSClass %p, in object %p",
                   Base::name(), Base::type_name(), prototype.get(),
-                  JS_GetClass(prototype), in_object.get());
+                  JS::GetClass(prototype), in_object.get());
 
         return true;
     }
@@ -852,7 +852,7 @@ class GIWrapperPrototype : public Base {
         // a garbage collection or error happens subsequently, then this object
         // might be traced and we would end up dereferencing a null pointer.
         Prototype* proto = priv.release();
-        JS_SetPrivate(prototype, proto);
+        JS::SetPrivate(prototype, proto);
 
         if (!gjs_wrapper_define_gtype_prop(cx, constructor, gtype))
             return nullptr;
@@ -970,13 +970,13 @@ class GIWrapperInstance : public Base {
      */
     [[nodiscard]] static Instance* new_for_js_object(JSContext* cx,
                                                      JS::HandleObject obj) {
-        g_assert(!JS_GetPrivate(obj));
+        g_assert(!JS::GetPrivate(obj));
         auto* priv = new Instance(cx, obj);
 
         // Init the private variable before we do anything else. If a garbage
         // collection happens when calling the constructor, then this object
         // might be traced and we would end up dereferencing a null pointer.
-        JS_SetPrivate(obj, priv);
+        JS::SetPrivate(obj, priv);
 
         return priv;
     }
diff --git a/gjs/byteArray.cpp b/gjs/byteArray.cpp
index 1635e902..5be485f0 100644
--- a/gjs/byteArray.cpp
+++ b/gjs/byteArray.cpp
@@ -17,7 +17,8 @@
 #include <js/PropertySpec.h>
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
-#include <js/Utility.h>   // for UniqueChars
+#include <js/Utility.h>  // for UniqueChars
+#include <js/experimental/TypedData.h>
 #include <jsapi.h>        // for JS_DefineFunctionById, JS_DefineFun...
 #include <jsfriendapi.h>  // for JS_NewUint8ArrayWithBuffer, GetUint...
 
@@ -98,7 +99,7 @@ static bool to_string_impl(JSContext* context, JS::HandleObject byte_array,
         encoding_is_utf8 = true;
     }
 
-    uint32_t len;
+    size_t len;
     bool is_shared_memory;
     js::GetUint8ArrayLengthAndData(byte_array, &len, &is_shared_memory, &data);
 
@@ -125,7 +126,7 @@ static bool to_string_impl(JSContext* context, JS::HandleObject byte_array,
     }
 
     uint8_t* current_data;
-    uint32_t current_len;
+    size_t current_len;
     bool ignore_val;
 
     // If a garbage collection occurs between when we call
@@ -268,7 +269,7 @@ from_string_func(JSContext *context,
             JS::AutoCheckCannotGC nogc;
             size_t len;
 
-            if (JS_StringHasLatin1Chars(str)) {
+            if (JS::StringHasLatin1Chars(str)) {
                 const JS::Latin1Char *chars =
                     JS_GetLatin1StringCharsAndLength(context, nogc, str, &len);
                 if (chars == NULL)
@@ -399,7 +400,7 @@ JSObject* gjs_byte_array_from_byte_array(JSContext* cx, GByteArray* array) {
 
 GBytes* gjs_byte_array_get_bytes(JSObject* obj) {
     bool is_shared_memory;
-    uint32_t len;
+    size_t len;
     uint8_t* data;
 
     js::GetUint8ArrayLengthAndData(obj, &len, &is_shared_memory, &data);
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 948ca8c6..e1df9d55 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -39,10 +39,10 @@
 #include <js/CompilationAndEvaluation.h>
 #include <js/CompileOptions.h>
 #include <js/ErrorReport.h>
-#include <js/Exception.h>           // for StealPendingExceptionStack
-#include <js/GCAPI.h>               // for JS_GC, JS_AddExtraGCRootsTr...
-#include <js/GCHashTable.h>         // for WeakCache
-#include <js/GCVector.h>            // for RootedVector
+#include <js/Exception.h>    // for StealPendingExceptionStack
+#include <js/GCAPI.h>        // for JS_GC, JS_AddExtraGCRootsTr...
+#include <js/GCHashTable.h>  // for WeakCache
+#include <js/GCVector.h>     // for RootedVector
 #include <js/Id.h>
 #include <js/Modules.h>
 #include <js/Promise.h>             // for JobQueue::SavedJobQueue
@@ -54,6 +54,7 @@
 #include <js/UniquePtr.h>
 #include <js/Value.h>
 #include <js/ValueArray.h>
+#include <js/friend/DumpFunctions.h>
 #include <jsapi.h>        // for JS_IsExceptionPending, ...
 #include <jsfriendapi.h>  // for DumpHeap, IgnoreNurseryObjects
 #include <mozilla/UniquePtr.h>
@@ -397,7 +398,7 @@ void GjsContextPrivate::dispose(void) {
         m_gtype_table->clear();
 
         /* Do a full GC here before tearing down, since once we do
-         * that we may not have the JS_GetPrivate() to access the
+         * that we may not have the JS::GetPrivate() to access the
          * context
          */
         gjs_debug(GJS_DEBUG_CONTEXT, "Final triggered GC");
@@ -607,7 +608,9 @@ GjsContextPrivate::GjsContextPrivate(JSContext* cx, GjsContext* public_context)
         g_error("Failed to instantiate module loader module.");
     }
 
-    if (!JS::ModuleEvaluate(cx, loader)) {
+    // TODO: This is the value returned for TLA (top-level await)
+    JS::RootedValue ignore(m_cx);
+    if (!JS::ModuleEvaluate(cx, loader, &ignore)) {
         gjs_log_exception(cx);
         g_error("Failed to evaluate module loader module.");
     }
@@ -1190,7 +1193,9 @@ bool GjsContextPrivate::eval_module(const char* identifier,
     }
 
     bool ok = true;
-    if (!JS::ModuleEvaluate(m_cx, obj))
+    // TODO: This is the value returned for TLA (top-level await)
+    JS::RootedValue ignore(m_cx);
+    if (!JS::ModuleEvaluate(m_cx, obj, &ignore))
         ok = false;
 
     /* The promise job queue should be drained even on error, to finish
@@ -1282,7 +1287,7 @@ bool gjs_context_eval_module_file(GjsContext* js_context, const char* filename,
  * Otherwise, the global definitions are just discarded.
  */
 bool GjsContextPrivate::eval_with_scope(JS::HandleObject scope_object,
-                                        const char* script, ssize_t script_len,
+                                        const char* script_, ssize_t script_len,
                                         const char* filename,
                                         JS::MutableHandleValue retval) {
     /* log and clear exception if it's set (should not be, normally...) */
@@ -1295,7 +1300,7 @@ bool GjsContextPrivate::eval_with_scope(JS::HandleObject scope_object,
     if (!eval_obj)
         eval_obj = JS_NewPlainObject(m_cx);
 
-    std::u16string utf16_string = gjs_utf8_script_to_utf16(script, script_len);
+    std::u16string utf16_string = gjs_utf8_script_to_utf16(script_, script_len);
     // COMPAT: This could use JS::SourceText<mozilla::Utf8Unit> directly,
     // but that messes up code coverage. See bug
     // https://bugzilla.mozilla.org/show_bug.cgi?id=1404784
@@ -1311,7 +1316,9 @@ bool GjsContextPrivate::eval_with_scope(JS::HandleObject scope_object,
     }
 
     JS::CompileOptions options(m_cx);
-    options.setFileAndLine(filename, 1);
+    options.setFileAndLine(filename, 1)
+        .setdeferDebugMetadata()
+        .setNonSyntacticScope(true);
 
     GjsAutoUnref<GFile> file = g_file_new_for_commandline_arg(filename);
     GjsAutoChar uri = g_file_get_uri(file);
@@ -1319,9 +1326,22 @@ bool GjsContextPrivate::eval_with_scope(JS::HandleObject scope_object,
     if (!priv)
         return false;
 
-    options.setPrivateValue(JS::ObjectValue(*priv));
+    JS::RootedValue privv(m_cx);
+    privv.setObject(*priv);
+    JS::RootedScript script(m_cx);
+    script.set(JS::Compile(m_cx, options, buf));
 
-    if (!JS::Evaluate(m_cx, scope_chain, options, buf, retval))
+    if (!script)
+        return false;
+
+    // TODO -
+    // 
https://github.com/mozilla/gecko-dev/commit/810f80185c290c08ef83d24daf8dfc64ef42e378#diff-35d2bbb110db1669ead652e8dd00f4abd7a25dd44d9b24fa26d6c86cde123cfd
+    if (!JS::UpdateDebugMetadata(m_cx, script, options, privv, nullptr, nullptr,
+                                 nullptr)) {
+        return false;
+    }
+
+    if (!JS_ExecuteScript(m_cx, scope_chain, script, retval))
         return false;
 
     schedule_gc_if_needed();
diff --git a/gjs/deprecation.cpp b/gjs/deprecation.cpp
index 3fdd64d4..6d313983 100644
--- a/gjs/deprecation.cpp
+++ b/gjs/deprecation.cpp
@@ -19,6 +19,7 @@
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
 #include <js/Value.h>
+#include <js/friend/DumpFunctions.h>
 #include <jsapi.h>        // for MaxFrames, CaptureCurrentStack
 #include <jsfriendapi.h>  // for FormatStackDump
 
diff --git a/gjs/engine.cpp b/gjs/engine.cpp
index 4908c775..a536974c 100644
--- a/gjs/engine.cpp
+++ b/gjs/engine.cpp
@@ -195,19 +195,11 @@ JSContext* gjs_create_js_context(GjsContextPrivate* uninitialized_gjs) {
         return nullptr;
     }
 
-    // commented are defaults in moz-24
     JS_SetNativeStackQuota(cx, 1024 * 1024);
     JS_SetGCParameter(cx, JSGC_MAX_BYTES, -1);
-    JS_SetGCParameter(cx, JSGC_MODE, JSGC_MODE_INCREMENTAL);
+    // See https://bugzilla.mozilla.org/show_bug.cgi?id=1686249
+    JS_SetGCParameter(cx, JSGC_INCREMENTAL_GC_ENABLED, 1);
     JS_SetGCParameter(cx, JSGC_SLICE_TIME_BUDGET_MS, 10); /* ms */
-    // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_TIME_LIMIT, 1000); /* ms */
-    // 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);
-    // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_LOW_LIMIT, 100);
-    // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_HIGH_LIMIT, 500);
-    // JS_SetGCParameter(cx, JSGC_ALLOCATION_THRESHOLD, 30);
-    // JS_SetGCParameter(cx, JSGC_DECOMMIT_THRESHOLD, 32);
 
     /* set ourselves as the private data */
     JS_SetContextPrivate(cx, uninitialized_gjs);
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 1883c445..5b5ef860 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -17,6 +17,7 @@
 #include <js/CompilationAndEvaluation.h>
 #include <js/CompileOptions.h>
 #include <js/Id.h>
+#include <js/Object.h>
 #include <js/PropertyDescriptor.h>  // for JSPROP_PERMANENT, JSPROP_RE...
 #include <js/PropertySpec.h>
 #include <js/Realm.h>  // for GetObjectRealmOrNull, SetRealmPrivate
@@ -98,7 +99,8 @@ class GjsBaseGlobal {
                          JS::SourceOwnership::TakeOwnership))
             return false;
 
-        JS::RootedScript compiled_script(cx, JS::Compile(cx, options, source));
+        JS::RootedScript compiled_script(cx);
+        compiled_script.set(JS::Compile(cx, options, source));
         if (!compiled_script)
             return false;
 
@@ -521,11 +523,11 @@ bool gjs_define_global_properties(JSContext* cx, JS::HandleObject global,
 }
 
 void detail::set_global_slot(JSObject* global, uint32_t slot, JS::Value value) {
-    JS_SetReservedSlot(global, JSCLASS_GLOBAL_SLOT_COUNT + slot, value);
+    JS::SetReservedSlot(global, JSCLASS_GLOBAL_SLOT_COUNT + slot, value);
 }
 
 JS::Value detail::get_global_slot(JSObject* global, uint32_t slot) {
-    return JS_GetReservedSlot(global, JSCLASS_GLOBAL_SLOT_COUNT + slot);
+    return JS::GetReservedSlot(global, JSCLASS_GLOBAL_SLOT_COUNT + slot);
 }
 
 decltype(GjsGlobal::klass) constexpr GjsGlobal::klass;
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 5076ce9a..e0625af7 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -63,7 +63,7 @@ importer_to_string(JSContext *cx,
 
     GjsAutoChar output;
 
-    const JSClass* klass = JS_GetClass(importer);
+    const JSClass* klass = JS::GetClass(importer);
     const GjsAtoms& atoms = GjsContextPrivate::atoms(cx);
     JS::RootedValue module_path(cx);
     if (!JS_GetPropertyById(cx, importer, atoms.module_path(), &module_path))
@@ -198,17 +198,21 @@ seal_import(JSContext       *cx,
             JS::HandleId     id,
             const char      *name)
 {
-    JS::Rooted<JS::PropertyDescriptor> descr(cx);
+    JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> descr(cx);
 
-    if (!JS_GetOwnPropertyDescriptorById(cx, obj, id, &descr) || !descr.object()) {
+    if (!JS_GetOwnPropertyDescriptorById(cx, obj, id, &descr) ||
+        descr.isNothing()) {
         gjs_debug(GJS_DEBUG_IMPORTER,
                   "Failed to get attributes to seal '%s' in importer",
                   name);
         return false;
     }
 
-    descr.setConfigurable(false);
-    if (!JS_DefinePropertyById(cx, descr.object(), id, descr)) {
+    JS::Rooted<JS::PropertyDescriptor> descr_(cx, descr.value());
+
+    descr_.setConfigurable(false);
+
+    if (!JS_DefinePropertyById(cx, obj, id, descr_)) {
         gjs_debug(GJS_DEBUG_IMPORTER,
                   "Failed to redefine attributes to seal '%s' in importer",
                   name);
diff --git a/gjs/internal.cpp b/gjs/internal.cpp
index dff83e47..71205c8c 100644
--- a/gjs/internal.cpp
+++ b/gjs/internal.cpp
@@ -102,8 +102,11 @@ bool gjs_load_internal_module(JSContext* cx, const char* identifier) {
 
     JS::RootedId key(cx, gjs_intern_string_to_id(cx, full_path));
 
+    // TODO: This is the value returned for TLA (top-level await)
+    JS::RootedValue ignore(cx);
     if (!gjs_global_registry_set(cx, registry, key, module) ||
-        !JS::ModuleInstantiate(cx, module) || !JS::ModuleEvaluate(cx, module)) {
+        !JS::ModuleInstantiate(cx, module) ||
+        !JS::ModuleEvaluate(cx, module, &ignore)) {
         return false;
     }
 
diff --git a/gjs/jsapi-dynamic-class.cpp b/gjs/jsapi-dynamic-class.cpp
index fa75a436..bd305364 100644
--- a/gjs/jsapi-dynamic-class.cpp
+++ b/gjs/jsapi-dynamic-class.cpp
@@ -115,7 +115,7 @@ gjs_typecheck_instance(JSContext       *context,
 {
     if (!JS_InstanceOf(context, obj, static_clasp, NULL)) {
         if (throw_error) {
-            const JSClass *obj_class = JS_GetClass(obj);
+            const JSClass* obj_class = JS::GetClass(obj);
 
             gjs_throw_custom(context, JSProto_TypeError, nullptr,
                              "Object %p is not a subclass of %s, it's a %s",
@@ -141,7 +141,15 @@ gjs_construct_object_dynamic(JSContext                  *context,
                                      atoms.constructor(), &constructor))
         return NULL;
 
-    return JS_New(context, constructor, args);
+    JS::RootedValue constructorv(context);
+    constructorv.setObject(*constructor);
+
+    JS::RootedObject object(context);
+
+    if (!JS::Construct(context, constructorv, args, &object))
+        return nullptr;
+
+    return object;
 }
 
 GJS_JSAPI_RETURN_CONVENTION
@@ -208,7 +216,9 @@ gjs_define_property_dynamic(JSContext       *cx,
     if (!setter_obj)
         return false;
 
-    flags |= JSPROP_GETTER | JSPROP_SETTER;
+    // TODO(mozjs91): See for JSPROP_GETTER removal
+    // https://bugzilla.mozilla.org/show_bug.cgi?id=1713083 flags |=
+    // JSPROP_GETTER | JSPROP_SETTER;
 
     return JS_DefineProperty(cx, proto, prop_name, getter_obj, setter_obj,
                              flags);
diff --git a/gjs/jsapi-util-error.cpp b/gjs/jsapi-util-error.cpp
index a966f0f8..835a81b3 100644
--- a/gjs/jsapi-util-error.cpp
+++ b/gjs/jsapi-util-error.cpp
@@ -68,11 +68,14 @@
         goto out;
     }
 
-    if (!JS_GetClassObject(context, error_kind, &constructor))
+    if (!JS_GetClassObject(context, error_kind, &constructor) || !constructor)
         goto out;
 
+    v_constructor.setObject(*constructor);
+
     /* throw new Error(message) */
-    new_exc = JS_New(context, constructor, error_args);
+    if (!JS::Construct(context, v_constructor, error_args, &new_exc))
+        goto out;
 
     if (!new_exc)
         goto out;
diff --git a/gjs/jsapi-util-string.cpp b/gjs/jsapi-util-string.cpp
index 5b681005..3f9978bc 100644
--- a/gjs/jsapi-util-string.cpp
+++ b/gjs/jsapi-util-string.cpp
@@ -23,6 +23,7 @@
 #include <js/Id.h>     // for JSID_IS_STRING...
 #include <js/Promise.h>
 #include <js/RootingAPI.h>
+#include <js/String.h>
 #include <js/Symbol.h>
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
@@ -207,7 +208,7 @@ gjs_string_get_char16_data(JSContext       *context,
                            char16_t       **data_p,
                            size_t          *len_p)
 {
-    if (JS_StringHasLatin1Chars(str))
+    if (JS::StringHasLatin1Chars(str))
         return from_latin1(context, str, data_p, len_p);
 
     /* From this point on, crash if a GC is triggered while we are using
@@ -253,7 +254,7 @@ gjs_string_to_ucs4(JSContext       *cx,
     size_t len;
     GError *error = NULL;
 
-    if (JS_StringHasLatin1Chars(str))
+    if (JS::StringHasLatin1Chars(str))
         return from_latin1(cx, str, ucs4_string_p, len_p);
 
     /* From this point on, crash if a GC is triggered while we are using
@@ -400,22 +401,22 @@ enum Quotes {
 
 [[nodiscard]] static std::string gjs_debug_linear_string(JSLinearString* str,
                                                          Quotes quotes) {
-    size_t len = js::GetLinearStringLength(str);
+    size_t len = JS::GetLinearStringLength(str);
 
     std::ostringstream out;
     if (quotes == DoubleQuotes)
         out << '"';
 
     JS::AutoCheckCannotGC nogc;
-    if (js::LinearStringHasLatin1Chars(str)) {
-        const JS::Latin1Char *chars = js::GetLatin1LinearStringChars(nogc, str);
+    if (JS::LinearStringHasLatin1Chars(str)) {
+        const JS::Latin1Char* chars = JS::GetLatin1LinearStringChars(nogc, str);
         out << std::string(reinterpret_cast<const char*>(chars), len);
         if (quotes == DoubleQuotes)
             out << '"';
         return out.str();
     }
 
-    const char16_t *chars = js::GetTwoByteLinearStringChars(nogc, str);
+    const char16_t* chars = JS::GetTwoByteLinearStringChars(nogc, str);
     for (size_t ix = 0; ix < len; ix++) {
         char16_t c = chars[ix];
         if (c == '\n')
@@ -522,7 +523,7 @@ gjs_debug_object(JSObject * const obj)
         return out.str();
     }
 
-    const JSClass* clasp = JS_GetClass(obj);
+    const JSClass* clasp = JS::GetClass(obj);
     out << "<object " << clasp->name << " at " << obj <<  '>';
     return out.str();
 }
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index 6262ac2d..375e78f3 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -195,7 +195,7 @@ void gjs_throw_abstract_constructor_error(JSContext* context,
     JS::RootedObject callee(context, &args.callee());
     JS::RootedValue prototype(context);
     if (JS_GetPropertyById(context, callee, atoms.prototype(), &prototype)) {
-        proto_class = JS_GetClass(&prototype.toObject());
+        proto_class = JS::GetClass(&prototype.toObject());
         name = proto_class->name;
     }
 
@@ -329,7 +329,7 @@ std::string gjs_value_debug_string(JSContext* context, JS::HandleValue value) {
             /* Specifically the Call object (see jsfun.c in spidermonkey)
              * does not have a toString; there may be others also.
              */
-            const JSClass *klass = JS_GetClass(&value.toObject());
+            const JSClass* klass = JS::GetClass(&value.toObject());
             if (klass != NULL) {
                 str = JS_NewStringCopyZ(context, klass->name);
                 JS_ClearPendingException(context);
@@ -575,7 +575,9 @@ gjs_gc_if_needed (JSContext *context)
         uint64_t rss_usize = rss_size;
         if (rss_usize > linux_rss_trigger) {
             linux_rss_trigger = MIN(G_MAXUINT32, rss_usize * 1.25);
-            JS::NonIncrementalGC(context, GC_SHRINK, JS::GCReason::API);
+
+            JS::NonIncrementalGC(context, JS::GCOptions::Shrink,
+                                 JS::GCReason::API);
         } else if (rss_size < (0.75 * linux_rss_trigger)) {
             /* If we've shrunk by 75%, lower the trigger */
             linux_rss_trigger = rss_usize * 1.25;
diff --git a/gjs/module.cpp b/gjs/module.cpp
index 2c0840f7..516eefe1 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -26,6 +26,7 @@
 #include <js/PropertyDescriptor.h>
 #include <js/RootingAPI.h>
 #include <js/SourceText.h>
+#include <js/String.h>
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
 #include <js/Value.h>
@@ -63,13 +64,13 @@ class GjsScriptModule {
     /* Private data accessors */
 
     [[nodiscard]] static inline GjsScriptModule* priv(JSObject* module) {
-        return static_cast<GjsScriptModule*>(JS_GetPrivate(module));
+        return static_cast<GjsScriptModule*>(JS::GetPrivate(module));
     }
 
     /* Creates a JS module object. Use instead of the class's constructor */
     [[nodiscard]] static JSObject* create(JSContext* cx, const char* name) {
         JSObject* module = JS_NewObject(cx, &GjsScriptModule::klass);
-        JS_SetPrivate(module, new GjsScriptModule(name));
+        JS::SetPrivate(module, new GjsScriptModule(name));
         return module;
     }
 
@@ -94,10 +95,10 @@ class GjsScriptModule {
     /* Carries out the actual execution of the module code */
     GJS_JSAPI_RETURN_CONVENTION
     bool evaluate_import(JSContext* cx, JS::HandleObject module,
-                         const char* script, ssize_t script_len,
+                         const char* script_, ssize_t script_len,
                          const char* filename, const char* uri) {
         std::u16string utf16_string =
-            gjs_utf8_script_to_utf16(script, script_len);
+            gjs_utf8_script_to_utf16(script_, script_len);
         // COMPAT: This could use JS::SourceText<mozilla::Utf8Unit> directly,
         // but that messes up code coverage. See bug
         // https://bugzilla.mozilla.org/show_bug.cgi?id=1404784
@@ -113,13 +114,28 @@ class GjsScriptModule {
         }
 
         JS::CompileOptions options(cx);
-        options.setFileAndLine(filename, 1);
+        options.setFileAndLine(filename, 1)
+            .setdeferDebugMetadata()
+            .setNonSyntacticScope(true);
 
         JS::RootedObject priv(cx, build_private(cx, uri));
-        options.setPrivateValue(JS::ObjectValue(*priv));
+        JS::RootedValue privv(cx);
+        privv.setObject(*priv);
+        JS::RootedScript script(cx);
+        script.set(JS::Compile(cx, options, buf));
+
+        if (!script)
+            return false;
+
+        // TODO -
+        // 
https://github.com/mozilla/gecko-dev/commit/810f80185c290c08ef83d24daf8dfc64ef42e378#diff-35d2bbb110db1669ead652e8dd00f4abd7a25dd44d9b24fa26d6c86cde123cfd
+        if (!JS::UpdateDebugMetadata(cx, script, options, privv, nullptr,
+                                     nullptr, nullptr)) {
+            return false;
+        }
 
         JS::RootedValue ignored_retval(cx);
-        if (!JS::Evaluate(cx, scope_chain, options, buf, &ignored_retval))
+        if (!JS_ExecuteScript(cx, scope_chain, script, &ignored_retval))
             return false;
 
         GjsContextPrivate* gjs = GjsContextPrivate::from_cx(cx);
@@ -186,9 +202,17 @@ class GjsScriptModule {
                   "please fix your code anyway.",
                   gjs_debug_id(id).c_str(), m_name);
 
-        JS::Rooted<JS::PropertyDescriptor> desc(cx);
-        return JS_GetPropertyDescriptorById(cx, lexical, id, &desc) &&
-            JS_DefinePropertyById(cx, module, id, desc);
+        JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
+        JS::Rooted<JS::PropertyDescriptor> desc_(cx);
+        JS::RootedObject holder(cx);
+
+        if (!JS_GetPropertyDescriptorById(cx, lexical, id, &desc, &holder) ||
+            desc.isNothing())
+            return false;
+
+        desc_.set(desc.value());
+
+        return JS_DefinePropertyById(cx, module, id, desc_);
     }
 
     GJS_JSAPI_RETURN_CONVENTION
@@ -480,6 +504,17 @@ bool gjs_populate_module_meta(JSContext* cx, JS::HandleValue private_ref,
     return true;
 }
 
+static JSString* module_request_to_specifier(JSContext* cx,
+                                             JS::HandleObject moduleRequest) {
+    // TODO: Accessing specifier() is not public...
+    // 
https://github.com/mozilla/gecko-dev/blob/211b017ce99b573d742afe52c6e88b8734654dfb/js/src/builtin/ModuleObject.h#L59
+
+    JS::RootedValue specifierv(cx, JS::GetReservedSlot(moduleRequest, 0));
+    JS::RootedString specifier(cx, specifierv.toString());
+
+    return specifier;
+}
+
 /**
  * gjs_module_resolve:
  *
@@ -492,7 +527,7 @@ bool gjs_populate_module_meta(JSContext* cx, JS::HandleValue private_ref,
  * @returns whether an error occurred while resolving the specifier.
  */
 JSObject* gjs_module_resolve(JSContext* cx, JS::HandleValue importingModulePriv,
-                             JS::HandleString specifier) {
+                             JS::HandleObject moduleRequest) {
     g_assert((gjs_global_is_type(cx, GjsGlobalType::DEFAULT) ||
               gjs_global_is_type(cx, GjsGlobalType::INTERNAL)) &&
              "gjs_module_resolve can only be called from module-enabled "
@@ -500,6 +535,8 @@ JSObject* gjs_module_resolve(JSContext* cx, JS::HandleValue importingModulePriv,
     g_assert(importingModulePriv.isObject() &&
              "the importing module can't be null, don't add import to the "
              "bootstrap script");
+    JS::RootedString specifier(cx,
+                               module_request_to_specifier(cx, moduleRequest));
 
     JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
     JS::RootedValue v_loader(
@@ -528,29 +565,32 @@ JSObject* gjs_module_resolve(JSContext* cx, JS::HandleValue importingModulePriv,
 // Can fail in JS::FinishDynamicModuleImport(), but will assert if anything
 // fails in fetching the stashed values, since that would be a serious GJS bug.
 GJS_JSAPI_RETURN_CONVENTION
-static bool finish_import(JSContext* cx, const JS::CallArgs& args) {
+static bool finish_import(JSContext* cx, JS::DynamicImportStatus status,
+                          const JS::CallArgs& args) {
     JS::Value callback_priv = js::GetFunctionNativeReserved(&args.callee(), 0);
     g_assert(callback_priv.isObject() && "Wrong private value");
     JS::RootedObject callback_data(cx, &callback_priv.toObject());
 
     JS::RootedValue importing_module_priv(cx);
-    JS::RootedValue v_specifier(cx);
+    JS::RootedValue v_module_request(cx);
     JS::RootedValue v_internal_promise(cx);
     bool ok GJS_USED_ASSERT =
         JS_GetProperty(cx, callback_data, "priv", &importing_module_priv) &&
         JS_GetProperty(cx, callback_data, "promise", &v_internal_promise) &&
-        JS_GetProperty(cx, callback_data, "specifier", &v_specifier);
+        JS_GetProperty(cx, callback_data, "moduleRequest", &v_module_request);
     g_assert(ok && "Wrong properties on private value");
 
-    g_assert(v_specifier.isString() && "Wrong type for specifier");
+    g_assert(v_module_request.isObject() && "Wrong type for module request");
     g_assert(v_internal_promise.isObject() && "Wrong type for promise");
 
-    JS::RootedString specifier(cx, v_specifier.toString());
+    JS::RootedObject moduleRequest(cx, &v_module_request.toObject());
     JS::RootedObject internal_promise(cx, &v_internal_promise.toObject());
 
     args.rval().setUndefined();
-    return JS::FinishDynamicModuleImport(cx, importing_module_priv, specifier,
-                                         internal_promise);
+
+    // TODO: TLA and dynamic import status...
+    return JS::FinishDynamicModuleImport_NoTLA(
+        cx, status, importing_module_priv, moduleRequest, internal_promise);
 }
 
 // Failing a JSAPI function may result either in an exception pending on the
@@ -560,7 +600,7 @@ static bool finish_import(JSContext* cx, const JS::CallArgs& args) {
 GJS_JSAPI_RETURN_CONVENTION
 static bool fail_import(JSContext* cx, const JS::CallArgs& args) {
     if (JS_IsExceptionPending(cx))
-        return finish_import(cx, args);
+        return finish_import(cx, JS::DynamicImportStatus::Failed, args);
     return false;
 }
 
@@ -575,7 +615,7 @@ static bool import_rejected(JSContext* cx, unsigned argc, JS::Value* vp) {
     JS_SetPendingException(cx, args.get(0),
                            JS::ExceptionStackBehavior::DoNotCapture);
 
-    return finish_import(cx, args);
+    return finish_import(cx, JS::DynamicImportStatus::Failed, args);
 }
 
 GJS_JSAPI_RETURN_CONVENTION
@@ -590,15 +630,18 @@ static bool import_resolved(JSContext* cx, unsigned argc, JS::Value* vp) {
     g_assert(args[0].isObject());
     JS::RootedObject module(cx, &args[0].toObject());
 
-    if (!JS::ModuleInstantiate(cx, module) || !JS::ModuleEvaluate(cx, module))
+    // TODO: This is the value returned for TLA (top-level await)
+    JS::RootedValue ignore(cx);
+    if (!JS::ModuleInstantiate(cx, module) ||
+        !JS::ModuleEvaluate(cx, module, &ignore))
         return fail_import(cx, args);
 
-    return finish_import(cx, args);
+    return finish_import(cx, JS::DynamicImportStatus::Ok, args);
 }
 
 bool gjs_dynamic_module_resolve(JSContext* cx,
                                 JS::HandleValue importing_module_priv,
-                                JS::HandleString specifier,
+                                JS::Handle<JSObject*> moduleRequest,
                                 JS::HandleObject internal_promise) {
     g_assert(gjs_global_is_type(cx, GjsGlobalType::DEFAULT) &&
              "gjs_dynamic_module_resolve can only be called from the default "
@@ -611,10 +654,12 @@ bool gjs_dynamic_module_resolve(JSContext* cx,
         cx, gjs_get_global_slot(global, GjsGlobalSlot::MODULE_LOADER));
     g_assert(v_loader.isObject());
     JS::RootedObject loader(cx, &v_loader.toObject());
+    JS::RootedString specifier(cx,
+                               module_request_to_specifier(cx, moduleRequest));
 
     JS::RootedObject callback_data(cx, JS_NewPlainObject(cx));
     if (!callback_data ||
-        !JS_DefineProperty(cx, callback_data, "specifier", specifier,
+        !JS_DefineProperty(cx, callback_data, "moduleRequest", moduleRequest,
                            JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, callback_data, "promise", internal_promise,
                            JSPROP_PERMANENT) ||
@@ -634,8 +679,9 @@ bool gjs_dynamic_module_resolve(JSContext* cx,
 
     JS::RootedValue result(cx);
     if (!JS::Call(cx, loader, "moduleResolveAsyncHook", args, &result))
-        return JS::FinishDynamicModuleImport(cx, importing_module_priv,
-                                             specifier, internal_promise);
+        return JS::FinishDynamicModuleImport_NoTLA(
+            cx, JS::DynamicImportStatus::Failed, importing_module_priv,
+            moduleRequest, internal_promise);
 
     JS::RootedObject resolved(
         cx, JS_GetFunctionObject(js::NewFunctionWithReserved(
diff --git a/gjs/module.h b/gjs/module.h
index 39d550b4..f50d6eda 100644
--- a/gjs/module.h
+++ b/gjs/module.h
@@ -35,8 +35,8 @@ JSObject* gjs_module_load(JSContext* cx, const char* identifier,
                           const char* uri);
 
 GJS_JSAPI_RETURN_CONVENTION
-JSObject* gjs_module_resolve(JSContext* cx, JS::HandleValue mod_val,
-                             JS::HandleString specifier);
+JSObject* gjs_module_resolve(JSContext* cx, JS::HandleValue importingModulePriv,
+                             JS::HandleObject moduleRequest);
 
 GJS_JSAPI_RETURN_CONVENTION
 bool gjs_populate_module_meta(JSContext* cx, JS::HandleValue private_ref,
@@ -45,7 +45,7 @@ bool gjs_populate_module_meta(JSContext* cx, JS::HandleValue private_ref,
 GJS_JSAPI_RETURN_CONVENTION
 bool gjs_dynamic_module_resolve(JSContext* cx,
                                 JS::HandleValue importing_module_priv,
-                                JS::HandleString specifier,
+                                JS::Handle<JSObject*> moduleRequest,
                                 JS::HandleObject internal_promise);
 
 #endif  // GJS_MODULE_H_
diff --git a/gjs/stack.cpp b/gjs/stack.cpp
index a223ad0d..46aab583 100644
--- a/gjs/stack.cpp
+++ b/gjs/stack.cpp
@@ -10,6 +10,7 @@
 #include <glib.h>
 
 #include <js/TypeDecls.h>
+#include <js/friend/DumpFunctions.h>
 #include <jsfriendapi.h>  // for DumpBacktrace
 
 #include "gjs/context.h"
diff --git a/meson.build b/meson.build
index bf767296..23dc3c54 100644
--- a/meson.build
+++ b/meson.build
@@ -122,7 +122,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.66.0',
     fallback: ['gobject-introspection', 'girepo_dep'])
-spidermonkey = dependency('mozjs-78')
+spidermonkey = dependency('mozjs-91a1')
 
 # We might need to look for the headers and lib's for Cairo
 # manually on MSVC/clang-cl builds...
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index 803b9e19..d1176481 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -368,7 +368,7 @@ dispose_func(JSContext *context,
     _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, rec, obj);
 
     cairo_destroy(cr);
-    JS_SetPrivate(obj, nullptr);
+    JS::SetPrivate(obj, nullptr);
 
     rec.rval().setUndefined();
     return true;
diff --git a/modules/cairo-path.cpp b/modules/cairo-path.cpp
index a4a82725..e581f9c1 100644
--- a/modules/cairo-path.cpp
+++ b/modules/cairo-path.cpp
@@ -37,8 +37,8 @@ JSObject* CairoPath::take_c_ptr(JSContext* cx, cairo_path_t* ptr) {
     if (!wrapper)
         return nullptr;
 
-    g_assert(!JS_GetPrivate(wrapper));
-    JS_SetPrivate(wrapper, ptr);
+    g_assert(!JS::GetPrivate(wrapper));
+    JS::SetPrivate(wrapper, ptr);
 
     debug_lifecycle(ptr, wrapper, "take_c_ptr");
 
diff --git a/modules/cairo-pattern.cpp b/modules/cairo-pattern.cpp
index 093e6fd8..a7097520 100644
--- a/modules/cairo-pattern.cpp
+++ b/modules/cairo-pattern.cpp
@@ -13,7 +13,7 @@
 #include <js/PropertySpec.h>
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
-#include <jsapi.h>  // for JS_GetPrivate, JS_GetClass, ...
+#include <jsapi.h>  // for JS::GetPrivate, JS::GetClass, ...
 
 #include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util.h"
@@ -132,9 +132,9 @@ cairo_pattern_t* CairoPattern::for_js(JSContext* cx,
         return nullptr;
     if (!is_pattern_subclass) {
         gjs_throw(cx, "Expected Cairo.Pattern but got %s",
-                  JS_GetClass(pattern_wrapper)->name);
+                  JS::GetClass(pattern_wrapper)->name);
         return nullptr;
     }
 
-    return static_cast<cairo_pattern_t*>(JS_GetPrivate(pattern_wrapper));
+    return static_cast<cairo_pattern_t*>(JS::GetPrivate(pattern_wrapper));
 }
diff --git a/modules/cairo-surface.cpp b/modules/cairo-surface.cpp
index 287598e4..3e33d37c 100644
--- a/modules/cairo-surface.cpp
+++ b/modules/cairo-surface.cpp
@@ -15,7 +15,7 @@
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
 #include <js/Value.h>
-#include <jsapi.h>  // for JS_GetPrivate, JS_GetClass, ...
+#include <jsapi.h>  // for JS::GetPrivate, JS::GetClass, ...
 
 #include "gi/arg-inl.h"
 #include "gi/arg.h"
@@ -166,11 +166,11 @@ cairo_surface_t* CairoSurface::for_js(JSContext* cx,
         return nullptr;
     if (!is_surface_subclass) {
         gjs_throw(cx, "Expected Cairo.Surface but got %s",
-                  JS_GetClass(surface_wrapper)->name);
+                  JS::GetClass(surface_wrapper)->name);
         return nullptr;
     }
 
-    return static_cast<cairo_surface_t*>(JS_GetPrivate(surface_wrapper));
+    return static_cast<cairo_surface_t*>(JS::GetPrivate(surface_wrapper));
 }
 
 [[nodiscard]] static bool surface_to_g_argument(
diff --git a/modules/console.cpp b/modules/console.cpp
index 2ef511aa..d496ea94 100644
--- a/modules/console.cpp
+++ b/modules/console.cpp
@@ -48,7 +48,7 @@ union Utf8Unit;
 }
 
 static void gjs_console_warning_reporter(JSContext* cx, JSErrorReport* report) {
-    JS::PrintError(cx, stderr, report, /* reportWarnings = */ true);
+    JS::PrintError(stderr, report, /* reportWarnings = */ true);
 }
 
 /* Based on js::shell::AutoReportException from SpiderMonkey. */
@@ -75,7 +75,7 @@ public:
 
         g_assert(!report.report()->isWarning());
 
-        JS::PrintError(m_cx, stderr, report, /* reportWarnings = */ false);
+        JS::PrintError(stderr, report, /* reportWarnings = */ false);
 
         if (exnStack.stack()) {
             GjsAutoChar stack_str =
diff --git a/modules/system.cpp b/modules/system.cpp
index 29eb7770..039d75b6 100644
--- a/modules/system.cpp
+++ b/modules/system.cpp
@@ -17,7 +17,8 @@
 #include <js/PropertySpec.h>
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
-#include <js/Value.h>     // for NullValue
+#include <js/Value.h>  // for NullValue
+#include <js/friend/DumpFunctions.h>
 #include <jsapi.h>        // for JS_DefinePropertyById, JS_DefineF...
 #include <jsfriendapi.h>  // for DumpHeap, IgnoreNurseryObjects
 
@@ -251,9 +252,11 @@ gjs_js_define_system_stuff(JSContext              *context,
            JS_DefinePropertyById(context, module, gjs->atoms().program_path(),
                                  v_program_path,
                                  GJS_MODULE_PROP_FLAGS | JSPROP_READONLY) &&
+           // TODO(mozjs91): See for JSPROP_GETTER removal
+           // https://bugzilla.mozilla.org/show_bug.cgi?id=1713083
            JS_DefinePropertyById(context, module, gjs->atoms().program_args(),
                                  program_args_getter, nullptr,
-                                 GJS_MODULE_PROP_FLAGS | JSPROP_GETTER) &&
+                                 GJS_MODULE_PROP_FLAGS) &&
            JS_DefinePropertyById(context, module, gjs->atoms().version(),
                                  GJS_VERSION,
                                  GJS_MODULE_PROP_FLAGS | JSPROP_READONLY);
diff --git a/test/gjs-test-rooting.cpp b/test/gjs-test-rooting.cpp
index cb878554..7b8b7fd9 100644
--- a/test/gjs-test-rooting.cpp
+++ b/test/gjs-test-rooting.cpp
@@ -11,7 +11,7 @@
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
 #include <js/Value.h>
-#include <jsapi.h>  // for JS_GetPrivate, JS_NewObject, JS_Set...
+#include <jsapi.h>  // for JS::GetPrivate, JS_NewObject, JS_Set...
 
 #include "gjs/jsapi-util-root.h"
 #include "test/gjs-test-utils.h"
@@ -37,7 +37,7 @@ struct GjsRootingFixture {
 };
 
 static void test_obj_finalize(JSFreeOp*, JSObject* obj) {
-    bool *finalized_p = static_cast<bool *>(JS_GetPrivate(obj));
+    bool* finalized_p = static_cast<bool*>(JS::GetPrivate(obj));
     g_assert_false(*finalized_p);
     *finalized_p = true;
 }
@@ -61,7 +61,7 @@ static JSObject *
 test_obj_new(GjsRootingFixture *fx)
 {
     JSObject *retval = JS_NewObject(PARENT(fx)->cx, &test_obj_class);
-    JS_SetPrivate(retval, &fx->finalized);
+    JS::SetPrivate(retval, &fx->finalized);
     return retval;
 }
 


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