[gjs: 10/16] object: Make ObjectPrototype constructor fallible
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 10/16] object: Make ObjectPrototype constructor fallible
- Date: Sat, 3 Nov 2018 02:42:04 +0000 (UTC)
commit cf857bcd9fc83ad37fd2afd6b39449311c9729df
Author: Philip Chimento <philip chimento gmail com>
Date: Sun Oct 28 16:53:12 2018 -0400
object: Make ObjectPrototype constructor fallible
ObjectPrototype has two GC hash tables whose construction is also
fallible, so it needs to be fallible itself. The usual pattern in
SpiderMonkey for this is to add an `init()` method that must be called
after construction, which is fallible.
gi/object.cpp | 24 ++++++++++++++++--------
gi/object.h | 4 +++-
2 files changed, 19 insertions(+), 9 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 4e2acbb9..30d57d24 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -1409,10 +1409,13 @@ ObjectInstance::ObjectInstance(JSContext* cx, JS::HandleObject object)
debug_lifecycle("Instance constructor");
}
-ObjectPrototype* ObjectPrototype::new_for_js_object(GIObjectInfo* info,
+ObjectPrototype* ObjectPrototype::new_for_js_object(JSContext* cx,
+ GIObjectInfo* info,
GType gtype) {
auto* priv = g_slice_new0(ObjectPrototype);
new (priv) ObjectPrototype(info, gtype);
+ if (!priv->init(cx))
+ return nullptr;
return priv;
}
@@ -1423,16 +1426,18 @@ ObjectPrototype::ObjectPrototype(GIObjectInfo* info, GType gtype)
g_type_class_ref(gtype);
- if (!m_property_cache.init())
- g_error("Out of memory for property cache of %s", type_name());
-
- if (!m_field_cache.init())
- g_error("Out of memory for field cache of %s", type_name());
-
GJS_INC_COUNTER(object_prototype);
debug_lifecycle("Prototype constructor");
}
+bool ObjectPrototype::init(JSContext* cx) {
+ if (!m_property_cache.init() || !m_field_cache.init()) {
+ JS_ReportOutOfMemory(cx);
+ return false;
+ }
+ return true;
+}
+
static void
update_heap_wrapper_weak_pointers(JSContext *cx,
JSCompartment *compartment,
@@ -2237,7 +2242,10 @@ gjs_define_object_class(JSContext *context,
GJS_MODULE_PROP_FLAGS))
return false;
- JS_SetPrivate(prototype, ObjectPrototype::new_for_js_object(info, gtype));
+ auto* priv = ObjectPrototype::new_for_js_object(context, info, gtype);
+ if (!priv)
+ return false;
+ JS_SetPrivate(prototype, priv);
gjs_debug(GJS_DEBUG_GOBJECT, "Defined class for %s (%s), prototype %p, "
"JSClass %p, in object %p", constructor_name, g_type_name(gtype),
diff --git a/gi/object.h b/gi/object.h
index babf36d5..536aea87 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -285,12 +285,14 @@ class ObjectPrototype : public ObjectBase {
FieldCache m_field_cache;
ObjectPrototype(GIObjectInfo* info, GType gtype);
+ GJS_JSAPI_RETURN_CONVENTION bool init(JSContext* cx);
~ObjectPrototype();
public:
/* Public constructor for instances (uses GSlice allocator) */
GJS_USE
- static ObjectPrototype* new_for_js_object(GIObjectInfo* info, GType gtype);
+ static ObjectPrototype* new_for_js_object(JSContext* cx, GIObjectInfo* info,
+ GType gtype);
GJS_USE
static ObjectPrototype* for_js(JSContext* cx, JS::HandleObject obj) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]