[gjs/ewlsh/fix-threading-with-logging: 1/2] Initial port to mozjs102
- From: Evan Welsh <ewlsh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/ewlsh/fix-threading-with-logging: 1/2] Initial port to mozjs102
- Date: Thu, 7 Jul 2022 06:56:17 +0000 (UTC)
commit de8d431b08cdb44c1cad34c3f57f69f05487fb68
Author: Evan Welsh <contact evanwelsh com>
Date: Sun Jul 3 17:24:18 2022 -0400
Initial port to mozjs102
gi/boxed.cpp | 21 ++++++-------
gi/cwrapper.h | 28 ++++++++++-------
gi/function.cpp | 14 +++++----
gi/fundamental.cpp | 3 +-
gi/gerror.cpp | 2 +-
gi/gtype.cpp | 9 ++++--
gi/interface.cpp | 6 ++--
gi/ns.cpp | 13 ++++----
gi/object.cpp | 38 +++++++++++------------
gi/object.h | 15 +++++----
gi/param.cpp | 19 ++++++------
gi/repo.cpp | 4 +--
gi/union.cpp | 2 +-
gi/wrapperutils.h | 29 ++++++++++--------
gjs/atoms.cpp | 2 +-
gjs/context.cpp | 2 +-
gjs/engine.cpp | 9 ++----
gjs/global.cpp | 3 +-
gjs/importer.cpp | 12 ++++----
gjs/jsapi-util-root.h | 13 ++++----
gjs/jsapi-util-string.cpp | 6 ++--
gjs/module.cpp | 12 +++++---
meson.build | 5 +--
modules/cairo-context.cpp | 17 ++++-------
modules/cairo-path.cpp | 7 +++--
modules/cairo-pattern.cpp | 6 ++--
modules/cairo-private.h | 64 ++++++++++++++++++++++-----------------
modules/cairo-region.cpp | 2 +-
modules/cairo-surface.cpp | 6 ++--
modules/core/overrides/GObject.js | 2 +-
test/gjs-test-rooting.cpp | 20 ++++++------
31 files changed, 208 insertions(+), 183 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index bc005a540..c10c92eee 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -101,7 +101,7 @@ bool BoxedPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
if (flags & GI_FUNCTION_IS_METHOD) {
const char* name = meth_info.name();
jsid id = gjs_intern_string_to_id(cx, name);
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
if (!properties.append(id)) {
JS_ReportOutOfMemory(cx);
@@ -170,8 +170,7 @@ std::unique_ptr<BoxedPrototype::FieldMap> BoxedPrototype::create_field_map(
// We get the string as a jsid later, which is interned. We intern the
// string here as well, so it will be the same string pointer
- JS::RootedString name(cx, JS_NewStringCopyZ(cx, field_info.name()));
- JSString* atom = JS_AtomizeAndPinJSString(cx, name);
+ JSString* atom = JS_AtomizeAndPinString(cx, field_info.name());
result->putNewInfallible(atom, std::move(field_info));
}
@@ -506,7 +505,7 @@ bool BoxedInstance::get_nested_interface_object(
/* We never actually read the reserved slot, but we put the parent object
* into it to hold onto the parent object.
*/
- JS_SetReservedSlot(obj, 0, JS::ObjectValue(*parent_obj));
+ JS::SetReservedSlot(obj, 1, JS::ObjectValue(*parent_obj));
value.setObject(*obj);
return true;
@@ -761,7 +760,6 @@ const struct JSClassOps BoxedBase::class_ops = {
nullptr, // mayResolve
&BoxedBase::finalize,
nullptr, // call
- nullptr, // hasInstance
nullptr, // construct
&BoxedBase::trace
};
@@ -773,8 +771,7 @@ const struct JSClassOps BoxedBase::class_ops = {
*/
const struct JSClass BoxedBase::klass = {
"GObject_Boxed",
- JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE |
- JSCLASS_HAS_RESERVED_SLOTS(1),
+ JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_FOREGROUND_FINALIZE,
&BoxedBase::class_ops
};
// clang-format on
@@ -928,7 +925,7 @@ BoxedPrototype::BoxedPrototype(GIStructInfo* info, GType gtype)
: GIWrapperPrototype(info, gtype),
m_zero_args_constructor(-1),
m_default_constructor(-1),
- m_default_constructor_name(JSID_VOID),
+ m_default_constructor_name(JS::PropertyKey::Void()),
m_can_allocate_directly(struct_is_simple(info)) {
if (!m_can_allocate_directly) {
m_can_allocate_directly_without_pointers = false;
@@ -943,8 +940,8 @@ BoxedPrototype::BoxedPrototype(GIStructInfo* info, GType gtype)
bool BoxedPrototype::init(JSContext* context) {
int i, n_methods;
int first_constructor = -1;
- jsid first_constructor_name = JSID_VOID;
- jsid zero_args_constructor_name = JSID_VOID;
+ jsid first_constructor_name = JS::PropertyKey::Void();
+ jsid zero_args_constructor_name = JS::PropertyKey::Void();
if (m_gtype != G_TYPE_NONE) {
/* If the structure is registered as a boxed, we can create a new instance by
@@ -965,7 +962,7 @@ bool BoxedPrototype::init(JSContext* context) {
first_constructor = i;
first_constructor_name =
gjs_intern_string_to_id(context, func_info.name());
- if (first_constructor_name == JSID_VOID)
+ if (first_constructor_name.isVoid())
return false;
}
@@ -974,7 +971,7 @@ bool BoxedPrototype::init(JSContext* context) {
m_zero_args_constructor = i;
zero_args_constructor_name =
gjs_intern_string_to_id(context, func_info.name());
- if (zero_args_constructor_name == JSID_VOID)
+ if (zero_args_constructor_name.isVoid())
return false;
}
diff --git a/gi/cwrapper.h b/gi/cwrapper.h
index ebe1d1d7a..965f1e821 100644
--- a/gi/cwrapper.h
+++ b/gi/cwrapper.h
@@ -81,8 +81,12 @@ class CWrapperPointerOps {
*/
[[nodiscard]] static Wrapped* for_js(JSContext* cx,
JS::HandleObject wrapper) {
- return static_cast<Wrapped*>(
- JS_GetInstancePrivate(cx, wrapper, &Base::klass, nullptr));
+ if (!JS_InstanceOf(cx, wrapper, &Base::klass, nullptr)) {
+ return nullptr;
+ }
+ JS::RootedValue v(cx, JS::GetReservedSlot(wrapper, 0));
+
+ return JS::GetMaybePtrFromReservedSlot<Wrapped>(wrapper, 0);
}
/*
@@ -135,7 +139,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 JS::GetMaybePtrFromReservedSlot<Wrapped>(wrapper, 0);
}
};
@@ -162,7 +166,7 @@ class CWrapperPointerOps {
* class_spec's flags member.
* - static constexpr unsigned constructor_nargs: number of arguments that the
* constructor takes. If you implement constructor_impl() then also add this.
- * - void finalize_impl(JSFreeOp*, Wrapped*): called when the JS object is
+ * - void finalize_impl(JS::GCContext*, Wrapped*): called when the JS object is
* garbage collected, use this to free the C pointer and do any other cleanup
*
* Add optional functionality by setting members of class_spec:
@@ -214,7 +218,8 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
Wrapped* priv = Base::constructor_impl(cx, args);
if (!priv)
return false;
- JS::SetPrivate(object, priv);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(object, 0, JS::PrivateValue(priv));
args.rval().setObject(*object);
return true;
@@ -249,17 +254,18 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
debug_jsprop(message, gjs_debug_id(id).c_str(), obj);
}
- static void finalize(JSFreeOp* fop, JSObject* obj) {
+ static void finalize(JS::GCContext* gcx, JSObject* obj) {
Wrapped* priv = Base::for_js_nocheck(obj);
// Call only CWrapper's original method here, not any overrides; e.g.,
// we don't want to deal with a read barrier.
CWrapper::debug_lifecycle(priv, obj, "Finalize");
- Base::finalize_impl(fop, priv);
+ Base::finalize_impl(gcx, priv);
// Remove the pointer from the JSObject
- JS::SetPrivate(obj, nullptr);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(obj, 0, JS::PrivateValue(nullptr));
}
static constexpr JSClassOps class_ops = {
@@ -466,7 +472,7 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
in_obj = gjs_get_import_global(cx);
JS::RootedId class_name(
cx, gjs_intern_string_to_id(cx, Base::klass.name));
- if (class_name == JSID_VOID ||
+ if (class_name.isVoid() ||
!JS_DefinePropertyById(cx, in_obj, class_name, ctor_obj,
GJS_MODULE_PROP_FLAGS))
return nullptr;
@@ -495,8 +501,8 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
if (!wrapper)
return nullptr;
- assert(!JS::GetPrivate(wrapper));
- JS::SetPrivate(wrapper, Base::copy_ptr(ptr));
+ assert(!JS::GetMaybePtrFromReservedSlot<Base>(wrapper, 0));
+ JS::SetReservedSlot(wrapper, 0, JS::PrivateValue(Base::copy_ptr(ptr)));
debug_lifecycle(ptr, wrapper, "from_c_ptr");
diff --git a/gi/function.cpp b/gi/function.cpp
index 5c4fa4a28..91af2070b 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -109,7 +109,7 @@ class Function : public CWrapper<Function> {
GJS_JSAPI_RETURN_CONVENTION
static bool call(JSContext* cx, unsigned argc, JS::Value* vp);
- static void finalize_impl(JSFreeOp*, Function* priv);
+ static void finalize_impl(JS::GCContext* gcx, Function* priv);
GJS_JSAPI_RETURN_CONVENTION
static bool get_length(JSContext* cx, unsigned argc, JS::Value* vp);
@@ -149,8 +149,8 @@ class Function : public CWrapper<Function> {
static constexpr JSClass klass = {
"GIRepositoryFunction",
- JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE, &Function::class_ops,
- &Function::class_spec};
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
+ &Function::class_ops, &Function::class_spec};
public:
GJS_JSAPI_RETURN_CONVENTION
@@ -1162,7 +1162,7 @@ Function::~Function() {
GJS_DEC_COUNTER(function);
}
-void Function::finalize_impl(JSFreeOp*, Function* priv) {
+void Function::finalize_impl(JS::GCContext*, Function* priv) {
if (priv == NULL)
return; /* we are the prototype, not a real instance, so constructor never called */
delete priv;
@@ -1334,8 +1334,10 @@ 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::GetMaybePtrFromReservedSlot<Function>(function, 0) &&
+ "Function should be a fresh object");
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(function, 0, JS::PrivateValue(priv));
debug_lifecycle(function, priv, "Constructor");
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 956b7303c..26ac2dd76 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -242,14 +242,13 @@ const struct JSClassOps FundamentalBase::class_ops = {
nullptr, // mayResolve
&FundamentalBase::finalize,
nullptr, // call
- nullptr, // hasInstance
nullptr, // construct
&FundamentalBase::trace
};
const struct JSClass FundamentalBase::klass = {
"GFundamental_Object",
- JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
&FundamentalBase::class_ops
};
// clang-format on
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 06ea26354..eb2667c15 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -192,7 +192,7 @@ const struct JSClassOps ErrorBase::class_ops = {
const struct JSClass ErrorBase::klass = {
"GLib_Error",
- JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&ErrorBase::class_ops
};
diff --git a/gi/gtype.cpp b/gi/gtype.cpp
index d6589250d..1b25c4b26 100644
--- a/gi/gtype.cpp
+++ b/gi/gtype.cpp
@@ -47,7 +47,7 @@ class GTypeObj : public CWrapper<GTypeObj, void> {
// No private data is allocated, it's stuffed directly in the private field
// of JSObject, so nothing to free
- static void finalize_impl(JSFreeOp*, void*) {}
+ static void finalize_impl(JS::GCContext*, void*) {}
// Properties
@@ -97,7 +97,8 @@ class GTypeObj : public CWrapper<GTypeObj, void> {
js::ClassSpec::DontDefineConstructor};
static constexpr JSClass klass = {
- "GIRepositoryGType", JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
+ "GIRepositoryGType",
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
>ypeObj::class_ops, >ypeObj::class_spec};
GJS_JSAPI_RETURN_CONVENTION
@@ -171,7 +172,9 @@ class GTypeObj : public CWrapper<GTypeObj, void> {
if (!gtype_wrapper)
return nullptr;
- JS::SetPrivate(gtype_wrapper, GSIZE_TO_POINTER(gtype));
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(gtype_wrapper, 0,
+ JS::PrivateValue(GSIZE_TO_POINTER(gtype)));
gjs->gtype_table().put(gtype, gtype_wrapper);
diff --git a/gi/interface.cpp b/gi/interface.cpp
index dc6c018dc..f574ffb7f 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -9,7 +9,7 @@
#include <js/Class.h>
#include <js/ErrorReport.h> // for JS_ReportOutOfMemory
-#include <js/Id.h> // for JSID_VOID, PropertyKey, jsid
+#include <js/Id.h> // for JS::PropertyKey::Void(), PropertyKey, jsid
#include <js/TypeDecls.h>
#include <js/Utility.h> // for UniqueChars
@@ -50,7 +50,7 @@ static bool append_inferface_properties(JSContext* cx,
if (flags & GI_FUNCTION_IS_METHOD) {
const char* name = meth_info.name();
jsid id = gjs_intern_string_to_id(cx, name);
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
properties.infallibleAppend(id);
}
@@ -177,7 +177,7 @@ const struct JSClassOps InterfaceBase::class_ops = {
const struct JSClass InterfaceBase::klass = {
"GObject_Interface",
- JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&InterfaceBase::class_ops
};
diff --git a/gi/ns.cpp b/gi/ns.cpp
index a5d5feb3a..5ee0dd772 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -145,7 +145,7 @@ class Ns : private GjsAutoChar, public CWrapper<Ns> {
const char* name = info.name();
jsid id = gjs_intern_string_to_id(cx, name);
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
properties.infallibleAppend(id);
}
@@ -153,7 +153,7 @@ class Ns : private GjsAutoChar, public CWrapper<Ns> {
return true;
}
- static void finalize_impl(JSFreeOp* fop [[maybe_unused]], Ns* priv) {
+ static void finalize_impl(JS::GCContext* gcx [[maybe_unused]], Ns* priv) {
g_assert(priv && "Finalize called on wrong object");
delete priv;
}
@@ -203,8 +203,8 @@ class Ns : private GjsAutoChar, public CWrapper<Ns> {
static constexpr JSClass klass = {
"GIRepositoryNamespace",
- JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE, &Ns::class_ops,
- &Ns::class_spec};
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
+ &Ns::class_ops, &Ns::class_spec};
public:
GJS_JSAPI_RETURN_CONVENTION
@@ -219,8 +219,9 @@ 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::GetMaybePtrFromReservedSlot<Ns>(ns, 0));
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(ns, 0, JS::PrivateValue(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 6c85631c9..0790a053d 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -676,7 +676,7 @@ static bool interface_getter(JSContext* cx, unsigned argc, JS::Value* vp) {
g_assert(v_override_symbol.isSymbol() &&
"override symbol must be a symbol");
JS::RootedSymbol override_symbol(cx, v_override_symbol.toSymbol());
- JS::RootedId override_id(cx, SYMBOL_TO_JSID(override_symbol));
+ JS::RootedId override_id(cx, JS::PropertyKey::Symbol(override_symbol));
JS::RootedObject this_obj(cx);
if (!args.computeThis(cx, &this_obj))
@@ -696,7 +696,7 @@ static bool interface_getter(JSContext* cx, unsigned argc, JS::Value* vp) {
g_assert(v_prototype.isObject() && "prototype must be an object");
JS::RootedObject prototype(cx, &v_prototype.toObject());
- JS::RootedId id(cx, JS::PropertyKey::fromNonIntAtom(JS_GetFunctionId(
+ JS::RootedId id(cx, JS::PropertyKey::NonIntAtom(JS_GetFunctionId(
JS_GetObjectFunction(&args.callee()))));
return JS_GetPropertyById(cx, prototype, id, args.rval());
}
@@ -720,7 +720,7 @@ static bool interface_setter(JSContext* cx, unsigned argc, JS::Value* vp) {
JS::RootedObject this_obj(cx);
if (!args.computeThis(cx, &this_obj))
return false;
- JS::RootedId override_id(cx, SYMBOL_TO_JSID(symbol));
+ JS::RootedId override_id(cx, JS::PropertyKey::Symbol(symbol));
return JS_SetPropertyById(cx, this_obj, override_id, args[0]);
}
@@ -1122,7 +1122,7 @@ bool ObjectPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
if (flags & GI_FUNCTION_IS_METHOD) {
const char* name = meth_info.name();
jsid id = gjs_intern_string_to_id(cx, name);
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
properties.infallibleAppend(id);
}
@@ -1136,7 +1136,7 @@ bool ObjectPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
GjsAutoChar js_name = gjs_hyphen_to_underscore(prop_info.name());
jsid id = gjs_intern_string_to_id(cx, js_name);
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
properties.infallibleAppend(id);
}
@@ -1161,7 +1161,7 @@ bool ObjectPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
if (flags & GI_FUNCTION_IS_METHOD) {
const char* name = meth_info.name();
jsid id = gjs_intern_string_to_id(cx, name);
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
properties.infallibleAppend(id);
}
@@ -1174,7 +1174,7 @@ bool ObjectPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
GjsAutoChar js_name = gjs_hyphen_to_underscore(prop_info.name());
jsid id = gjs_intern_string_to_id(cx, js_name);
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
properties.infallibleAppend(id);
}
@@ -1192,7 +1192,7 @@ bool ObjectPrototype::props_to_g_parameters(JSContext* context,
size_t ix, length;
JS::RootedId prop_id(context);
JS::RootedValue value(context);
- JS::Rooted<JS::IdVector> ids(context);
+ JS::Rooted<JS::IdVector> ids(context, context);
std::unordered_set<GParamSpec*> visited_params;
if (!JS_Enumerate(context, props, &ids)) {
gjs_throw(context, "Failed to create property iterator for object props hash");
@@ -1581,7 +1581,7 @@ ObjectPrototype::ObjectPrototype(GIObjectInfo* info, GType gtype)
* Private callback, called after the JS engine finishes garbage collection, and
* notifies when weak pointers need to be either moved or swept.
*/
-void ObjectInstance::update_heap_wrapper_weak_pointers(JSContext*,
+void ObjectInstance::update_heap_wrapper_weak_pointers(JSTracer* trc,
JS::Compartment*,
void*) {
gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Weak pointer update callback, "
@@ -1593,15 +1593,15 @@ void ObjectInstance::update_heap_wrapper_weak_pointers(JSContext*,
auto locked_queue = ToggleQueue::get_default();
ObjectInstance::remove_wrapped_gobjects_if(
- std::mem_fn(&ObjectInstance::weak_pointer_was_finalized),
+ [&trc](ObjectInstance* instance) -> bool {
+ return instance->weak_pointer_was_finalized(trc);
+ },
std::mem_fn(&ObjectInstance::disassociate_js_gobject));
s_wrapped_gobject_list.shrink_to_fit();
}
-bool
-ObjectInstance::weak_pointer_was_finalized(void)
-{
+bool ObjectInstance::weak_pointer_was_finalized(JSTracer* trc) {
if (has_wrapper() && !wrapper_is_rooted()) {
bool toggle_down_queued, toggle_up_queued;
@@ -1612,7 +1612,7 @@ ObjectInstance::weak_pointer_was_finalized(void)
if (!toggle_down_queued && toggle_up_queued)
return false;
- if (!update_after_gc())
+ if (!update_after_gc(trc))
return false;
if (toggle_down_queued)
@@ -1900,14 +1900,14 @@ void ObjectPrototype::trace_impl(JSTracer* tracer) {
Gjs::Closure::for_gclosure(closure)->trace(tracer);
}
-void ObjectInstance::finalize_impl(JSFreeOp* fop, JSObject* obj) {
+void ObjectInstance::finalize_impl(JS::GCContext* gcx, JSObject* obj) {
GTypeQuery query;
type_query_dynamic_safe(&query);
if (G_LIKELY(query.type))
JS::RemoveAssociatedMemory(obj, query.instance_size,
MemoryUse::GObjectInstanceStruct);
- GIWrapperInstance::finalize_impl(fop, obj);
+ GIWrapperInstance::finalize_impl(gcx, obj);
}
ObjectInstance::~ObjectInstance() {
@@ -2531,13 +2531,12 @@ const struct JSClassOps ObjectBase::class_ops = {
&ObjectBase::finalize,
NULL,
NULL,
- NULL,
&ObjectBase::trace,
};
const struct JSClass ObjectBase::klass = {
"GObject_Object",
- JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
&ObjectBase::class_ops
};
@@ -2724,7 +2723,8 @@ ObjectInstance* ObjectInstance::new_for_gobject(JSContext* cx, GObject* gobj) {
ObjectInstance* priv = new ObjectInstance(prototype, obj);
- JS::SetPrivate(obj, priv);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(obj, 0, JS::PrivateValue(priv));
g_object_ref_sink(gobj);
priv->associate_js_gobject(cx, obj, gobj);
diff --git a/gi/object.h b/gi/object.h
index 886f13eaf..3af70b555 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -173,7 +173,8 @@ struct IdHasher {
return js::DefaultHasher<JSString*>::hash(id.toString());
if (id.isSymbol())
return js::DefaultHasher<JS::Symbol*>::hash(id.toSymbol());
- return mozilla::HashGeneric(JSID_BITS(id));
+
+ return mozilla::HashGeneric(id.asRawBits());
}
static bool match(jsid id1, jsid id2) { return id1 == id2; }
};
@@ -336,17 +337,19 @@ class ObjectInstance : public GIWrapperInstance<ObjectBase, ObjectPrototype,
void discard_wrapper(void) { m_wrapper.reset(); }
void switch_to_rooted(JSContext* cx) { m_wrapper.switch_to_rooted(cx); }
void switch_to_unrooted(JSContext* cx) { m_wrapper.switch_to_unrooted(cx); }
- [[nodiscard]] bool update_after_gc() { return m_wrapper.update_after_gc(); }
+ [[nodiscard]] bool update_after_gc(JSTracer* trc) {
+ return m_wrapper.update_after_gc(trc);
+ }
[[nodiscard]] bool wrapper_is_rooted() const { return m_wrapper.rooted(); }
void release_native_object(void);
void associate_js_gobject(JSContext* cx, JS::HandleObject obj,
GObject* gobj);
void disassociate_js_gobject(void);
void handle_context_dispose(void);
- [[nodiscard]] bool weak_pointer_was_finalized();
+ [[nodiscard]] bool weak_pointer_was_finalized(JSTracer* trc);
static void ensure_weak_pointer_callback(JSContext* cx);
- static void update_heap_wrapper_weak_pointers(JSContext* cx,
- JS::Compartment* compartment,
+ static void update_heap_wrapper_weak_pointers(JSTracer* trc,
+ JS::Compartment* comp,
void* data);
public:
@@ -421,7 +424,7 @@ class ObjectInstance : public GIWrapperInstance<ObjectBase, ObjectPrototype,
GJS_JSAPI_RETURN_CONVENTION
bool add_property_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
JS::HandleValue value);
- void finalize_impl(JSFreeOp* fop, JSObject* obj);
+ void finalize_impl(JS::GCContext* gcx, JSObject* obj);
void trace_impl(JSTracer* trc);
/* JS property getters/setters */
diff --git a/gi/param.cpp b/gi/param.cpp
index 7a3f88174..4fe95aecf 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -37,8 +37,8 @@ struct Param : GjsAutoParam {
[[nodiscard]] static GParamSpec* param_value(JSContext* cx,
JS::HandleObject obj) {
- auto* priv = static_cast<Param*>(
- JS_GetInstancePrivate(cx, obj, &gjs_param_class, nullptr));
+ auto* priv = JS::GetMaybePtrFromReservedSlot<Param>(obj, 0);
+
return priv ? priv->get() : nullptr;
}
@@ -113,15 +113,16 @@ static bool gjs_param_constructor(JSContext* cx, unsigned argc, JS::Value* vp) {
return true;
}
-static void param_finalize(JSFreeOp*, JSObject* obj) {
- Param* priv = static_cast<Param*>(JS::GetPrivate(obj));
+static void param_finalize(JS::GCContext*, JSObject* obj) {
+ Param* priv = JS::GetMaybePtrFromReservedSlot<Param>(obj, 0);
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);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(obj, 0, JS::PrivateValue(nullptr));
delete priv;
}
@@ -140,9 +141,8 @@ static const struct JSClassOps gjs_param_class_ops = {
struct JSClass gjs_param_class = {
"GObject_ParamSpec",
- JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
- &gjs_param_class_ops
-};
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
+ &gjs_param_class_ops};
GJS_JSAPI_RETURN_CONVENTION
static JSObject*
@@ -220,7 +220,8 @@ gjs_param_from_g_param(JSContext *context,
GJS_INC_COUNTER(param);
auto* priv = new Param(gparam);
- JS::SetPrivate(obj, priv);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(obj, 0, JS::PrivateValue(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 9f5d4e1f3..e40299587 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -18,7 +18,7 @@
#include <js/Class.h>
#include <js/ComparisonOperators.h>
#include <js/Exception.h>
-#include <js/Id.h> // for JSID_VOID
+#include <js/Id.h> // for JS::PropertyKey::Void()
#include <js/Object.h> // for GetClass
#include <js/PropertyDescriptor.h> // for JSPROP_PERMANENT, JSPROP_RESOLVING
#include <js/RootingAPI.h>
@@ -481,7 +481,7 @@ gjs_lookup_namespace_object(JSContext *context,
}
JS::RootedId ns_name(context, gjs_intern_string_to_id(context, ns));
- if (ns_name == JSID_VOID)
+ if (ns_name.isVoid())
return nullptr;
return gjs_lookup_namespace_object_by_name(context, ns_name);
}
diff --git a/gi/union.cpp b/gi/union.cpp
index dca235926..e29bfbba0 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -148,7 +148,7 @@ const struct JSClassOps UnionBase::class_ops = {
const struct JSClass UnionBase::klass = {
"GObject_Union",
- JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
&UnionBase::class_ops
};
// clang-format on
diff --git a/gi/wrapperutils.h b/gi/wrapperutils.h
index aa50cdd05..747e72699 100644
--- a/gi/wrapperutils.h
+++ b/gi/wrapperutils.h
@@ -394,7 +394,7 @@ class GIWrapperBase : public CWrapperPointerOps<Base> {
* necessary to include a finalize_impl() function in Prototype or Instance.
* Any needed finalization should be done in ~Prototype() and ~Instance().
*/
- static void finalize(JSFreeOp* fop, JSObject* obj) {
+ static void finalize(JS::GCContext* gcx, JSObject* obj) {
Base* priv = Base::for_js_nocheck(obj);
if (!priv)
return; // construction didn't finish
@@ -404,12 +404,13 @@ class GIWrapperBase : public CWrapperPointerOps<Base> {
static_cast<GIWrapperBase*>(priv)->debug_lifecycle(obj, "Finalize");
if (priv->is_prototype())
- priv->to_prototype()->finalize_impl(fop, obj);
+ priv->to_prototype()->finalize_impl(gcx, obj);
else
- priv->to_instance()->finalize_impl(fop, obj);
+ priv->to_instance()->finalize_impl(gcx, obj);
// Remove the pointer from the JSObject
- JS::SetPrivate(obj, nullptr);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(obj, 0, JS::PrivateValue(nullptr));
}
/*
@@ -902,7 +903,8 @@ 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);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(prototype, 0, JS::PrivateValue(proto));
if (!gjs_wrapper_define_gtype_prop(cx, constructor, gtype))
return nullptr;
@@ -949,7 +951,8 @@ class GIWrapperPrototype : public Base {
return nullptr;
Prototype* proto = priv.release();
- JS::SetPrivate(prototype, proto);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(prototype, 0, JS::PrivateValue(proto));
if (!proto->define_static_methods(cx, constructor))
return nullptr;
@@ -1013,7 +1016,7 @@ class GIWrapperPrototype : public Base {
// JSClass operations
protected:
- void finalize_impl(JSFreeOp*, JSObject*) { release(); }
+ void finalize_impl(JS::GCContext*, JSObject*) { release(); }
// Override if necessary
void trace_impl(JSTracer*) {}
@@ -1060,24 +1063,26 @@ class GIWrapperInstance : public Base {
*/
[[nodiscard]] static Instance* new_for_js_object(JSContext* cx,
JS::HandleObject obj) {
- g_assert(!JS::GetPrivate(obj));
+ g_assert(!JS::GetMaybePtrFromReservedSlot<Instance>(obj, 0));
Prototype* prototype = Prototype::for_js_prototype(cx, obj);
auto* priv = new Instance(prototype, 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);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(obj, 0, JS::PrivateValue(priv));
return priv;
}
[[nodiscard]] static Instance* new_for_js_object(Prototype* prototype,
JS::HandleObject obj) {
- g_assert(!JS::GetPrivate(obj));
+ g_assert(!JS::GetMaybePtrFromReservedSlot<Instance>(obj, 0));
auto* priv = new Instance(prototype, obj);
- JS::SetPrivate(obj, priv);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(obj, 0, JS::PrivateValue(priv));
return priv;
}
@@ -1110,7 +1115,7 @@ class GIWrapperInstance : public Base {
// JSClass operations
protected:
- void finalize_impl(JSFreeOp*, JSObject*) {
+ void finalize_impl(JS::GCContext*, JSObject*) {
delete static_cast<Instance*>(this);
}
diff --git a/gjs/atoms.cpp b/gjs/atoms.cpp
index 6cb04f89b..46dae1444 100644
--- a/gjs/atoms.cpp
+++ b/gjs/atoms.cpp
@@ -31,7 +31,7 @@ bool GjsSymbolAtom::init(JSContext* cx, const char* str) {
JS::Symbol* symbol = JS::NewSymbol(cx, descr);
if (!symbol)
return false;
- m_jsid = JS::Heap<jsid>{SYMBOL_TO_JSID(symbol)};
+ m_jsid = JS::Heap<jsid>{JS::PropertyKey::Symbol(symbol)};
return true;
}
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 4e22825d0..a9dde93db 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -433,7 +433,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::GetReservedSlot(, 0) to access the
* context
*/
gjs_debug(GJS_DEBUG_CONTEXT, "Final triggered GC");
diff --git a/gjs/engine.cpp b/gjs/engine.cpp
index 16d84cc19..35ac265dd 100644
--- a/gjs/engine.cpp
+++ b/gjs/engine.cpp
@@ -32,7 +32,7 @@
#include "gjs/jsapi-util.h"
#include "util/log.h"
-static void gjs_finalize_callback(JSFreeOp*, JSFinalizeStatus status,
+static void gjs_finalize_callback(JS::GCContext*, JSFinalizeStatus status,
void* data) {
auto* gjs = static_cast<GjsContextPrivate*>(data);
gjs->set_finalize_status(status);
@@ -167,12 +167,7 @@ JSContext* gjs_create_js_context(GjsContextPrivate* uninitialized_gjs) {
if (enable_jit) {
gjs_debug(GJS_DEBUG_CONTEXT, "Enabling JIT");
}
- JS::ContextOptionsRef(cx)
- .setAsmJS(enable_jit)
- .setTopLevelAwait(true)
- .setClassStaticBlocks(true)
- .setPrivateClassFields(true)
- .setPrivateClassMethods(true);
+ JS::ContextOptionsRef(cx).setAsmJS(enable_jit);
uint32_t value = enable_jit ? 1 : 0;
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 56fe8602b..3533e507d 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -74,6 +74,7 @@ class GjsBaseGlobal {
JSContext* cx, const JSClass* clasp,
JS::RealmCreationOptions options = JS::RealmCreationOptions()) {
options.setNewCompartmentAndZone();
+ options.setFreezeBuiltins(false);
return base(cx, clasp, options);
}
@@ -111,7 +112,7 @@ class GjsBaseGlobal {
return false;
JS::RootedValue ignored(cx);
- return JS::CloneAndExecuteScript(cx, compiled_script, &ignored);
+ return JS_ExecuteScript(cx, compiled_script, &ignored);
}
GJS_JSAPI_RETURN_CONVENTION
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index c8bc553ef..1a3118a30 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -171,9 +171,9 @@ define_meta_properties(JSContext *context,
module_path, attrs))
return false;
- JS::RootedId to_string_tag_name(context,
- SYMBOL_TO_JSID(JS::GetWellKnownSymbol(context,
- JS::SymbolCode::toStringTag)));
+ JS::RootedId to_string_tag_name(
+ context, JS::PropertyKey::Symbol(JS::GetWellKnownSymbol(
+ context, JS::SymbolCode::toStringTag)));
return JS_DefinePropertyById(context, module_obj, to_string_tag_name,
to_string_tag, attrs);
}
@@ -283,7 +283,7 @@ gjs_import_native_module(JSContext *cx,
cx, gjs_get_native_registry(gjs_get_import_global(cx)));
JS::RootedId id(cx, gjs_intern_string_to_id(cx, parse_name));
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
JS::RootedObject module(cx);
@@ -692,7 +692,7 @@ static bool importer_new_enumerate(JSContext* context, JS::HandleObject object,
if (g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY) {
jsid id = gjs_intern_string_to_id(context, filename);
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
if (!properties.append(id)) {
JS_ReportOutOfMemory(context);
@@ -703,7 +703,7 @@ static bool importer_new_enumerate(JSContext* context, JS::HandleObject object,
GjsAutoChar filename_noext =
g_strndup(filename, strlen(filename) - 3);
jsid id = gjs_intern_string_to_id(context, filename_noext);
- if (id == JSID_VOID)
+ if (id.isVoid())
return false;
if (!properties.append(id)) {
JS_ReportOutOfMemory(context);
diff --git a/gjs/jsapi-util-root.h b/gjs/jsapi-util-root.h
index 7f4e27495..80f4d875a 100644
--- a/gjs/jsapi-util-root.h
+++ b/gjs/jsapi-util-root.h
@@ -62,8 +62,9 @@ struct GjsHeapOperation {
template<>
struct GjsHeapOperation<JSObject *> {
- [[nodiscard]] static bool update_after_gc(JS::Heap<JSObject*>* location) {
- JS_UpdateWeakPointerAfterGC(location);
+ [[nodiscard]] static bool update_after_gc(JSTracer* trc,
+ JS::Heap<JSObject*>* location) {
+ JS_UpdateWeakPointerAfterGC(trc, location);
return (location->unbarrieredGet() == nullptr);
}
@@ -178,7 +179,7 @@ class GjsMaybeOwned {
void root(JSContext* cx, const T& thing) {
debug("root()");
g_assert(!m_root);
- g_assert(m_heap.get() == JS::SafelyInitialized<T>());
+ g_assert(m_heap.get() == JS::SafelyInitialized<T>::create());
m_heap.~Heap();
m_root = std::make_unique<JS::PersistentRooted<T>>(cx, thing);
}
@@ -204,7 +205,7 @@ class GjsMaybeOwned {
void reset() {
debug("reset()");
if (!m_root) {
- m_heap = JS::SafelyInitialized<T>();
+ m_heap = JS::SafelyInitialized<T>::create();
return;
}
@@ -251,10 +252,10 @@ class GjsMaybeOwned {
/* If not tracing, then you must call this method during GC in order to
* update the object's location if it was moved, or null it out if it was
* finalized. If the object was finalized, returns true. */
- bool update_after_gc() {
+ bool update_after_gc(JSTracer* trc) {
debug("update_after_gc()");
g_assert(!m_root);
- return GjsHeapOperation<T>::update_after_gc(&m_heap);
+ return GjsHeapOperation<T>::update_after_gc(trc, &m_heap);
}
[[nodiscard]] constexpr bool rooted() const { return m_root != nullptr; }
diff --git a/gjs/jsapi-util-string.cpp b/gjs/jsapi-util-string.cpp
index a39a0c055..89abe087e 100644
--- a/gjs/jsapi-util-string.cpp
+++ b/gjs/jsapi-util-string.cpp
@@ -437,7 +437,7 @@ bool gjs_get_string_id(JSContext* cx, jsid id, JS::UniqueChars* name_p) {
return true;
}
- JSLinearString* lstr = JSID_TO_LINEAR_STRING(id);
+ JSLinearString* lstr = id.toLinearString();
JS::RootedString s(cx, JS_FORGET_STRING_LINEARNESS(lstr));
*name_p = JS_EncodeStringToUTF8(cx, s);
return !!*name_p;
@@ -474,7 +474,7 @@ gjs_intern_string_to_id(JSContext *cx,
{
JS::RootedString str(cx, JS_AtomizeAndPinString(cx, string));
if (!str)
- return JSID_VOID;
+ return JS::PropertyKey::Void();
return JS::PropertyKey::fromPinnedString(str);
}
@@ -661,6 +661,6 @@ std::string
gjs_debug_id(jsid id)
{
if (id.isString())
- return gjs_debug_linear_string(JSID_TO_LINEAR_STRING(id), NoQuotes);
+ return gjs_debug_linear_string(id.toLinearString(), NoQuotes);
return gjs_debug_value(js::IdToValue(id));
}
diff --git a/gjs/module.cpp b/gjs/module.cpp
index 3b54a3fca..471280b73 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -72,13 +72,15 @@ class GjsScriptModule {
/* Private data accessors */
[[nodiscard]] static inline GjsScriptModule* priv(JSObject* module) {
- return static_cast<GjsScriptModule*>(JS::GetPrivate(module));
+ return JS::GetMaybePtrFromReservedSlot<GjsScriptModule>(module, 0);
}
/* 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));
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(module, 0,
+ JS::PrivateValue(new GjsScriptModule(name)));
return module;
}
@@ -210,7 +212,9 @@ class GjsScriptModule {
return priv(module)->resolve_impl(cx, module, id, resolved);
}
- static void finalize(JSFreeOp*, JSObject* module) { delete priv(module); }
+ static void finalize(JS::GCContext*, JSObject* module) {
+ delete priv(module);
+ }
static constexpr JSClassOps class_ops = {
nullptr, // addProperty
@@ -224,7 +228,7 @@ class GjsScriptModule {
static constexpr JSClass klass = {
"GjsScriptModule",
- JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&GjsScriptModule::class_ops,
};
diff --git a/meson.build b/meson.build
index 9f8cdacc9..5a1619847 100644
--- a/meson.build
+++ b/meson.build
@@ -127,7 +127,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-91', version: '>= 91.3.0')
+spidermonkey = dependency('mozjs-103a1', version: '>= 103.0a1')
# We might need to look for the headers and lib's for Cairo
# manually on MSVC/clang-cl builds...
@@ -322,7 +322,8 @@ header_conf.set('ENABLE_PROFILER', build_profiler,
description: 'Build the profiler')
# COMPAT: SpiderMonkey headers in some places use DEBUG instead of JS_DEBUG
# https://bugzilla.mozilla.org/show_bug.cgi?id=1261161 */
-header_conf.set('DEBUG', not nondebug_spidermonkey,
+# TODO: DEBUG is not being set properly
+header_conf.set('DEBUG', 1,
description: 'SpiderMonkey was compiled with --enable-debug')
header_conf.set('HAVE_DTRACE', get_option('dtrace'),
description: 'Using dtrace probes')
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index 463e06215..762b74e48 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -86,9 +86,7 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
return false; \
cfunc(cr, &arg1, &arg2); \
if (cairo_status(cr) == CAIRO_STATUS_SUCCESS) { \
- JS::RootedObject array( \
- context, \
- JS::NewArrayObject(context, JS::HandleValueArray::empty())); \
+ JS::RootedObject array(context, JS::NewArrayObject(context, 2)); \
if (!array) \
return false; \
JS::RootedValue r(context, JS::NumberValue(arg1)); \
@@ -107,9 +105,7 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
_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())); \
+ JS::RootedObject array(context, JS::NewArrayObject(context, 2)); \
if (!array) \
return false; \
JS::RootedValue r(context, JS::NumberValue(arg1)); \
@@ -128,9 +124,7 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
_GJS_CAIRO_CONTEXT_CHECK_NO_ARGS(method) \
cfunc(cr, &arg1, &arg2, &arg3, &arg4); \
{ \
- JS::RootedObject array( \
- context, \
- JS::NewArrayObject(context, JS::HandleValueArray::empty())); \
+ JS::RootedObject array(context, JS::NewArrayObject(context, 4)); \
if (!array) \
return false; \
JS::RootedValue r(context, JS::NumberValue(arg1)); \
@@ -268,7 +262,7 @@ cairo_t* CairoContext::constructor_impl(JSContext* context,
return cr;
}
-void CairoContext::finalize_impl(JSFreeOp*, cairo_t* cr) {
+void CairoContext::finalize_impl(JS::GCContext*, cairo_t* cr) {
if (!cr)
return;
cairo_destroy(cr);
@@ -369,7 +363,8 @@ dispose_func(JSContext *context,
_GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, rec, obj);
cairo_destroy(cr);
- JS::SetPrivate(obj, nullptr);
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(obj, 0, JS::PrivateValue(nullptr));
rec.rval().setUndefined();
return true;
diff --git a/modules/cairo-path.cpp b/modules/cairo-path.cpp
index 76a879dfa..2ae3f72b5 100644
--- a/modules/cairo-path.cpp
+++ b/modules/cairo-path.cpp
@@ -38,15 +38,16 @@ 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::GetMaybePtrFromReservedSlot<cairo_path_t>(wrapper, 0));
+ // TODO: Install 0 slot
+ JS::SetReservedSlot(wrapper, 0, JS::PrivateValue(ptr));
debug_lifecycle(ptr, wrapper, "take_c_ptr");
return wrapper;
}
-void CairoPath::finalize_impl(JSFreeOp*, cairo_path_t* path) {
+void CairoPath::finalize_impl(JS::GCContext*, cairo_path_t* path) {
if (!path)
return;
cairo_path_destroy(path);
diff --git a/modules/cairo-pattern.cpp b/modules/cairo-pattern.cpp
index 1a6d07da3..b0da27b89 100644
--- a/modules/cairo-pattern.cpp
+++ b/modules/cairo-pattern.cpp
@@ -64,14 +64,14 @@ const JSFunctionSpec CairoPattern::proto_funcs[] = {
/**
* CairoPattern::finalize_impl:
- * @fop: the free op
+ * @gcx: the free op
* @pattern: pointer to free
*
* Destroys the resources associated with a pattern wrapper.
*
* This is mainly used for subclasses.
*/
-void CairoPattern::finalize_impl(JSFreeOp*, cairo_pattern_t* pattern) {
+void CairoPattern::finalize_impl(JS::GCContext*, cairo_pattern_t* pattern) {
if (!pattern)
return;
cairo_pattern_destroy(pattern);
@@ -136,5 +136,5 @@ cairo_pattern_t* CairoPattern::for_js(JSContext* cx,
return nullptr;
}
- return static_cast<cairo_pattern_t*>(JS::GetPrivate(pattern_wrapper));
+ return JS::GetMaybePtrFromReservedSlot<cairo_pattern_t>(pattern_wrapper, 0);
}
diff --git a/modules/cairo-private.h b/modules/cairo-private.h
index a470a94a5..1c3eb4ac9 100644
--- a/modules/cairo-private.h
+++ b/modules/cairo-private.h
@@ -55,7 +55,7 @@ class CairoRegion : public CWrapper<CairoRegion, cairo_region_t> {
static cairo_region_t* constructor_impl(JSContext* cx,
const JS::CallArgs& args);
- static void finalize_impl(JSFreeOp* fop, cairo_region_t* cr);
+ static void finalize_impl(JS::GCContext* gcx, cairo_region_t* cr);
static const JSFunctionSpec proto_funcs[];
static const JSPropertySpec proto_props[];
@@ -69,7 +69,7 @@ class CairoRegion : public CWrapper<CairoRegion, cairo_region_t> {
CairoRegion::define_gtype_prop,
};
static constexpr JSClass klass = {
- "Region", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "Region", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoRegion::class_ops, &CairoRegion::class_spec};
};
@@ -95,7 +95,7 @@ class CairoContext : public CWrapper<CairoContext, cairo_t> {
GJS_JSAPI_RETURN_CONVENTION
static cairo_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
- static void finalize_impl(JSFreeOp* fop, cairo_t* cr);
+ static void finalize_impl(JS::GCContext* gcx, cairo_t* cr);
static const JSFunctionSpec proto_funcs[];
static const JSPropertySpec proto_props[];
@@ -109,7 +109,7 @@ class CairoContext : public CWrapper<CairoContext, cairo_t> {
CairoContext::define_gtype_prop,
};
static constexpr JSClass klass = {
- "Context", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "Context", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoContext::class_ops, &CairoContext::class_spec};
};
@@ -130,7 +130,7 @@ class CairoPath : public CWrapper<CairoPath, cairo_path_t> {
GjsGlobalSlot::PROTOTYPE_cairo_path;
static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_CAIRO;
- static void finalize_impl(JSFreeOp* fop, cairo_path_t* path);
+ static void finalize_impl(JS::GCContext* gcx, cairo_path_t* path);
static const JSPropertySpec proto_props[];
static constexpr js::ClassSpec class_spec = {
@@ -143,7 +143,7 @@ class CairoPath : public CWrapper<CairoPath, cairo_path_t> {
nullptr, // finishInit
};
static constexpr JSClass klass = {
- "Path", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "Path", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoPath::class_ops, &CairoPath::class_spec};
public:
@@ -171,7 +171,7 @@ class CairoSurface : public CWrapper<CairoSurface, cairo_surface_t> {
static GType gtype() { return CAIRO_GOBJECT_TYPE_SURFACE; }
- static void finalize_impl(JSFreeOp* fop, cairo_surface_t* surface);
+ static void finalize_impl(JS::GCContext* gcx, cairo_surface_t* surface);
static const JSFunctionSpec proto_funcs[];
static const JSPropertySpec proto_props[];
@@ -185,7 +185,7 @@ class CairoSurface : public CWrapper<CairoSurface, cairo_surface_t> {
&CairoSurface::define_gtype_prop,
};
static constexpr JSClass klass = {
- "Surface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "Surface", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoSurface::class_ops, &CairoSurface::class_spec};
static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
@@ -229,14 +229,15 @@ class CairoImageSurface : public CWrapper<CairoImageSurface, cairo_surface_t> {
&CairoSurface::define_gtype_prop,
};
static constexpr JSClass klass = {
- "ImageSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "ImageSurface",
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoSurface::class_ops, &CairoImageSurface::class_spec};
static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
return cairo_surface_reference(surface);
}
- static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+ static void finalize_impl(JS::GCContext*, cairo_surface_t*) {}
GJS_JSAPI_RETURN_CONVENTION
static cairo_surface_t* constructor_impl(JSContext* cx,
@@ -268,14 +269,15 @@ class CairoPSSurface : public CWrapper<CairoPSSurface, cairo_surface_t> {
&CairoSurface::define_gtype_prop,
};
static constexpr JSClass klass = {
- "PSSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "PSSurface",
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoSurface::class_ops, &CairoPSSurface::class_spec};
static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
return cairo_surface_reference(surface);
}
- static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+ static void finalize_impl(JS::GCContext*, cairo_surface_t*) {}
GJS_JSAPI_RETURN_CONVENTION
static cairo_surface_t* constructor_impl(JSContext* cx,
@@ -313,14 +315,15 @@ class CairoPDFSurface : public CWrapper<CairoPDFSurface, cairo_surface_t> {
&CairoSurface::define_gtype_prop,
};
static constexpr JSClass klass = {
- "PDFSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "PDFSurface",
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoSurface::class_ops, &CairoPDFSurface::class_spec};
static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
return cairo_surface_reference(surface);
}
- static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+ static void finalize_impl(JS::GCContext*, cairo_surface_t*) {}
GJS_JSAPI_RETURN_CONVENTION
static cairo_surface_t* constructor_impl(JSContext* cx,
@@ -358,14 +361,15 @@ class CairoSVGSurface : public CWrapper<CairoSVGSurface, cairo_surface_t> {
&CairoSurface::define_gtype_prop,
};
static constexpr JSClass klass = {
- "SVGSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "SVGSurface",
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoSurface::class_ops, &CairoSVGSurface::class_spec};
static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
return cairo_surface_reference(surface);
}
- static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+ static void finalize_impl(JS::GCContext*, cairo_surface_t*) {}
GJS_JSAPI_RETURN_CONVENTION
static cairo_surface_t* constructor_impl(JSContext* cx,
@@ -410,7 +414,7 @@ class CairoPattern : public CWrapper<CairoPattern, cairo_pattern_t> {
&CairoPattern::define_gtype_prop,
};
static constexpr JSClass klass = {
- "Pattern", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "Pattern", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoPattern::class_ops, &CairoPattern::class_spec};
static GType gtype() { return CAIRO_GOBJECT_TYPE_PATTERN; }
@@ -423,7 +427,7 @@ class CairoPattern : public CWrapper<CairoPattern, cairo_pattern_t> {
static bool getType_func(JSContext* context, unsigned argc, JS::Value* vp);
protected:
- static void finalize_impl(JSFreeOp* fop, cairo_pattern_t* pattern);
+ static void finalize_impl(JS::GCContext* gcx, cairo_pattern_t* pattern);
public:
static cairo_pattern_t* for_js(JSContext* cx,
@@ -459,10 +463,10 @@ class CairoGradient : public CWrapper<CairoGradient, cairo_pattern_t> {
&CairoPattern::define_gtype_prop,
};
static constexpr JSClass klass = {
- "Gradient", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "Gradient", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoPattern::class_ops, &CairoGradient::class_spec};
- static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+ static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
};
class CairoLinearGradient
@@ -490,7 +494,8 @@ class CairoLinearGradient
&CairoPattern::define_gtype_prop,
};
static constexpr JSClass klass = {
- "LinearGradient", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "LinearGradient",
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoPattern::class_ops, &CairoLinearGradient::class_spec};
static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
@@ -501,7 +506,7 @@ class CairoLinearGradient
static cairo_pattern_t* constructor_impl(JSContext* cx,
const JS::CallArgs& args);
- static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+ static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
};
class CairoRadialGradient
@@ -529,7 +534,8 @@ class CairoRadialGradient
&CairoPattern::define_gtype_prop,
};
static constexpr JSClass klass = {
- "RadialGradient", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "RadialGradient",
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoPattern::class_ops, &CairoRadialGradient::class_spec};
static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
@@ -540,7 +546,7 @@ class CairoRadialGradient
static cairo_pattern_t* constructor_impl(JSContext* cx,
const JS::CallArgs& args);
- static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+ static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
};
class CairoSurfacePattern
@@ -568,7 +574,8 @@ class CairoSurfacePattern
&CairoPattern::define_gtype_prop,
};
static constexpr JSClass klass = {
- "SurfacePattern", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "SurfacePattern",
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoPattern::class_ops, &CairoSurfacePattern::class_spec};
static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
@@ -579,7 +586,7 @@ class CairoSurfacePattern
static cairo_pattern_t* constructor_impl(JSContext* cx,
const JS::CallArgs& args);
- static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+ static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
};
class CairoSolidPattern : public CWrapper<CairoSolidPattern, cairo_pattern_t> {
@@ -605,14 +612,15 @@ class CairoSolidPattern : public CWrapper<CairoSolidPattern, cairo_pattern_t> {
&CairoPattern::define_gtype_prop,
};
static constexpr JSClass klass = {
- "SolidPattern", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ "SolidPattern",
+ JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
&CairoPattern::class_ops, &CairoSolidPattern::class_spec};
static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
return cairo_pattern_reference(pattern);
}
- static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+ static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
};
#endif // MODULES_CAIRO_PRIVATE_H_
diff --git a/modules/cairo-region.cpp b/modules/cairo-region.cpp
index a6333f777..99f04b679 100644
--- a/modules/cairo-region.cpp
+++ b/modules/cairo-region.cpp
@@ -219,7 +219,7 @@ cairo_region_t* CairoRegion::constructor_impl(JSContext* context,
return cairo_region_create();
}
-void CairoRegion::finalize_impl(JSFreeOp*, cairo_region_t* region) {
+void CairoRegion::finalize_impl(JS::GCContext*, cairo_region_t* region) {
if (!region)
return;
diff --git a/modules/cairo-surface.cpp b/modules/cairo-surface.cpp
index 710e8c1bf..9c5b2914c 100644
--- a/modules/cairo-surface.cpp
+++ b/modules/cairo-surface.cpp
@@ -207,14 +207,14 @@ const JSFunctionSpec CairoSurface::proto_funcs[] = {
/**
* CairoSurface::finalize_impl:
- * @fop: the free op
+ * @gcx: the free op
* @surface: the pointer to finalize
*
* Destroys the resources associated with a surface wrapper.
*
* This is mainly used for subclasses.
*/
-void CairoSurface::finalize_impl(JSFreeOp*, cairo_surface_t* surface) {
+void CairoSurface::finalize_impl(JS::GCContext*, cairo_surface_t* surface) {
if (!surface)
return;
cairo_surface_destroy(surface);
@@ -272,7 +272,7 @@ cairo_surface_t* CairoSurface::for_js(JSContext* cx,
return nullptr;
}
- return static_cast<cairo_surface_t*>(JS::GetPrivate(surface_wrapper));
+ return JS::GetMaybePtrFromReservedSlot<cairo_surface_t>(surface_wrapper, 0);
}
[[nodiscard]] static bool surface_to_g_argument(
diff --git a/modules/core/overrides/GObject.js b/modules/core/overrides/GObject.js
index df6f9dc27..364ff2477 100644
--- a/modules/core/overrides/GObject.js
+++ b/modules/core/overrides/GObject.js
@@ -401,7 +401,7 @@ function _init() {
};
GObject.ParamSpec.jsobject = function (name, nick, blurb, flags) {
- return GObject.param_spec_boxed(name, nick, blurb, Object.$gtype, flags);
+ return GObject.param_spec_boxed(name, nick, blurb, GObject.TYPE_JSOBJECT, flags);
};
GObject.ParamSpec.param = function (name, nick, blurb, flags, paramType) {
diff --git a/test/gjs-test-rooting.cpp b/test/gjs-test-rooting.cpp
index 7a82f70df..a015359f0 100644
--- a/test/gjs-test-rooting.cpp
+++ b/test/gjs-test-rooting.cpp
@@ -37,8 +37,8 @@ struct GjsRootingFixture {
GjsMaybeOwned<JSObject *> *obj; /* only used in callback test cases */
};
-static void test_obj_finalize(JSFreeOp*, JSObject* obj) {
- bool* finalized_p = static_cast<bool*>(JS::GetPrivate(obj));
+static void test_obj_finalize(JS::GCContext*, JSObject* obj) {
+ bool* finalized_p = JS::GetMaybePtrFromReservedSlot<bool>(obj, 0);
g_assert_false(*finalized_p);
*finalized_p = true;
}
@@ -53,16 +53,17 @@ static const JSClassOps test_obj_class_ops = {
test_obj_finalize};
static JSClass test_obj_class = {
- "TestObj",
- JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
- &test_obj_class_ops
-};
+ "TestObj", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
+ &test_obj_class_ops};
static JSObject *
test_obj_new(GjsRootingFixture *fx)
{
JSObject *retval = JS_NewObject(PARENT(fx)->cx, &test_obj_class);
- JS::SetPrivate(retval, &fx->finalized);
+ // // TODO: Install 0 slot
+ JS::SetReservedSlot(retval, 0, JS::PrivateValue(&fx->finalized));
+ JS::SetReservedSlot(retval, 0, JS::PrivateValue(&fx->finalized));
+
return retval;
}
@@ -145,10 +146,11 @@ static void test_maybe_owned_rooted_is_collected_after_reset(
delete obj;
}
-static void update_weak_pointer(JSContext*, JS::Compartment*, void* data) {
+static void update_weak_pointer(JSTracer* trc, JS::Compartment* comp,
+ void* data) {
auto* obj = static_cast<GjsMaybeOwned<JSObject*>*>(data);
if (*obj)
- obj->update_after_gc();
+ obj->update_after_gc(trc);
}
static void test_maybe_owned_weak_pointer_is_collected_by_gc(
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]