[gjs/ewlsh/fix-fundamental-assert] Fix fundamental conversion with missing functions.




commit 41cf009fbf60429fb8b956b615282870a5905675
Author: Evan Welsh <contact evanwelsh com>
Date:   Thu Feb 11 18:01:32 2021 -0800

    Fix fundamental conversion with missing functions.
    
    Fundamentals don't have to specify all of the functions they can
    implement such as get-value, set-value, ref, and unref. As such,
    we should handle these failures gracefully instead of asserting.
    
    Fixes #365.

 gi/fundamental.cpp | 15 ++++++++-------
 gi/fundamental.h   | 34 ++++++++++++++++++++++++++--------
 2 files changed, 34 insertions(+), 15 deletions(-)
---
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 94519df9..a4d1e32c 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -222,10 +222,6 @@ FundamentalPrototype::FundamentalPrototype(GIObjectInfo* info, GType gtype)
       m_get_value_function(g_object_info_get_get_value_function_pointer(info)),
       m_set_value_function(g_object_info_get_set_value_function_pointer(info)),
       m_constructor_info(find_fundamental_constructor(info)) {
-    g_assert(m_ref_function);
-    g_assert(m_unref_function);
-    g_assert(m_set_value_function);
-    g_assert(m_get_value_function);
     GJS_INC_COUNTER(fundamental_prototype);
 }
 
@@ -445,8 +441,8 @@ JSObject* FundamentalInstance::object_for_gvalue(JSContext* cx,
                                                  const GValue* value,
                                                  GType gtype) {
     auto* proto_priv = FundamentalPrototype::for_gtype(cx, gtype);
-    void* fobj = proto_priv->call_get_value_function(value);
-    if (!fobj) {
+    void* fobj;
+    if (!proto_priv->call_get_value_function(value, &fobj)) {
         gjs_throw(cx, "Failed to convert GValue to a fundamental instance");
         return nullptr;
     }
@@ -461,7 +457,12 @@ bool FundamentalBase::to_gvalue(JSContext* cx, JS::HandleObject obj,
         !priv->check_is_instance(cx, "convert to GValue"))
         return false;
 
-    priv->to_instance()->set_value(gvalue);
+    if (!priv->to_instance()->set_value(gvalue)) {
+        gjs_throw(cx,
+                  "Fundamental object does not support conversion to a GValue");
+        return false;
+    }
+
     return true;
 }
 
diff --git a/gi/fundamental.h b/gi/fundamental.h
index 27afb1e2..927f11af 100644
--- a/gi/fundamental.h
+++ b/gi/fundamental.h
@@ -82,13 +82,31 @@ class FundamentalPrototype
         return m_constructor_info;
     }
 
-    void* call_ref_function(void* ptr) const { return m_ref_function(ptr); }
-    void call_unref_function(void* ptr) const { m_unref_function(ptr); }
-    [[nodiscard]] void* call_get_value_function(const GValue* value) const {
-        return m_get_value_function(value);
+    void* call_ref_function(void* ptr) const {
+        if (!m_ref_function)
+            return ptr;
+
+        return m_ref_function(ptr);
+    }
+    void call_unref_function(void* ptr) const {
+        if (m_unref_function)
+            m_unref_function(ptr);
     }
-    void call_set_value_function(GValue* value, void* object) const {
-        m_set_value_function(value, object);
+    [[nodiscard]] bool call_get_value_function(const GValue* value,
+                                               void** ptr_out) const {
+        if (!m_get_value_function)
+            return false;
+
+        *ptr_out = m_get_value_function(value);
+        return true;
+    }
+    bool call_set_value_function(GValue* value, void* object) const {
+        if (m_set_value_function) {
+            m_set_value_function(value, object);
+            return true;
+        }
+
+        return false;
     }
 
     // Helper methods
@@ -137,8 +155,8 @@ class FundamentalInstance
 
     void ref(void) { get_prototype()->call_ref_function(m_ptr); }
     void unref(void) { get_prototype()->call_unref_function(m_ptr); }
-    void set_value(GValue* gvalue) const {
-        get_prototype()->call_set_value_function(gvalue, m_ptr);
+    [[nodiscard]] bool set_value(GValue* gvalue) const {
+        return get_prototype()->call_set_value_function(gvalue, m_ptr);
     }
 
     GJS_JSAPI_RETURN_CONVENTION


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