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




commit 31ca6f35f8b318ed00ae280d52b862b69e055acd
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 | 10 +++++-----
 gi/fundamental.h   | 27 +++++++++++++++++++++------
 2 files changed, 26 insertions(+), 11 deletions(-)
---
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 94519df9..28ee94e9 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);
 }
 
@@ -461,7 +457,11 @@ 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, "Failed to convert fundamental instance to a GValue");
+        return false;
+    }
+
     return true;
 }
 
diff --git a/gi/fundamental.h b/gi/fundamental.h
index 27afb1e2..bf77a2ab 100644
--- a/gi/fundamental.h
+++ b/gi/fundamental.h
@@ -82,13 +82,28 @@ 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); }
+    void* call_ref_function(void* ptr) const {
+        if (!m_ref_function)
+            return nullptr;
+
+        return m_ref_function(ptr);
+    }
+    void call_unref_function(void* ptr) const {
+        if (m_unref_function)
+            m_unref_function(ptr);
+    }
     [[nodiscard]] void* call_get_value_function(const GValue* value) const {
+        if (!m_get_value_function)
+            return nullptr;
         return m_get_value_function(value);
     }
-    void call_set_value_function(GValue* value, void* object) const {
-        m_set_value_function(value, object);
+    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 +152,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]