[gjs: 7/26] gerror: Move to C++-style API



commit 91434941066ac61a792780de0046a175151839b5
Author: Philip Chimento <philip chimento gmail com>
Date:   Sun Jan 20 18:41:38 2019 -0800

    gerror: Move to C++-style API
    
    This allows cleaning up the public API in gerror.h a bit, adding missing
    error checks in calling code, removing C API that only called C++ API,
    and creating an ErrorInstance::object_for_c_ptr() method.
    
    The idea is to gradually provide more typesafe, C++-style APIs for all
    of the GI wrapper classes, and change calling code to use them rather
    than the old C-style APIs.

 gi/arg.cpp    |  8 ++++----
 gi/boxed.cpp  |  4 ++--
 gi/gerror.cpp | 31 ++++++++++++-------------------
 gi/gerror.h   | 20 ++++++++++----------
 gi/repo.cpp   |  2 +-
 gi/value.cpp  |  8 +++++---
 6 files changed, 34 insertions(+), 39 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index c68f9ef5..c6a8678b 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -2770,7 +2770,8 @@ gjs_value_from_g_argument (JSContext             *context,
     case GI_TYPE_TAG_ERROR:
         {
             if (arg->v_pointer) {
-                JSObject *obj = gjs_error_from_gerror(context, (GError *) arg->v_pointer, false);
+                JSObject* obj = ErrorInstance::object_for_c_ptr(
+                    context, static_cast<GError*>(arg->v_pointer));
                 if (obj) {
                     value_p.setObject(*obj);
                     return true;
@@ -2868,9 +2869,8 @@ gjs_value_from_g_argument (JSContext             *context,
                 goto out;
             }
             if (g_type_is_a(gtype, G_TYPE_ERROR)) {
-                JSObject *obj;
-
-                obj = gjs_error_from_gerror(context, (GError *) arg->v_pointer, false);
+                JSObject* obj = ErrorInstance::object_for_c_ptr(
+                    context, static_cast<GError*>(arg->v_pointer));
                 if (obj)
                     value = JS::ObjectValue(*obj);
                 else
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index b9cc3191..71b3c224 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -971,8 +971,8 @@ bool BoxedPrototype::define_class(JSContext* context,
         return false;
 
     if (gtype == G_TYPE_ERROR &&
-        !JS_DefineFunction(context, prototype, "toString", gjs_gerror_to_string,
-                           0, GJS_MODULE_PROP_FLAGS))
+        !JS_DefineFunction(context, prototype, "toString",
+                           &ErrorBase::to_string, 0, GJS_MODULE_PROP_FLAGS))
         return false;
 
     return true;
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 056ca7e0..e3f43243 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -123,10 +123,6 @@ bool ErrorBase::get_code(JSContext* cx, unsigned argc, JS::Value* vp) {
     return true;
 }
 
-bool gjs_gerror_to_string(JSContext* context, unsigned argc, JS::Value* vp) {
-    return ErrorBase::to_string(context, argc, vp);
-}
-
 // JSNative implementation of `toString()`.
 bool ErrorBase::to_string(JSContext* context, unsigned argc, JS::Value* vp) {
     GJS_GET_THIS(context, argc, vp, rec, self);
@@ -134,7 +130,7 @@ bool ErrorBase::to_string(JSContext* context, unsigned argc, JS::Value* vp) {
     GjsAutoChar descr;
 
     // An error created via `new GLib.Error` will have a Boxed* private pointer,
-    // not an Error*, so we can't call regular gjs_gerror_to_string() on it.
+    // not an Error*, so we can't call regular to_string() on it.
     if (BoxedBase::typecheck(context, self, nullptr, G_TYPE_ERROR,
                              BoxedBase::TypecheckNoThrow())) {
         auto* gerror = BoxedBase::to_c_ptr<GError>(context, self);
@@ -230,8 +226,9 @@ bool ErrorPrototype::get_parent_proto(JSContext* cx,
     return !!proto;
 }
 
-bool gjs_define_error_class(JSContext* context, JS::HandleObject in_object,
-                            GIEnumInfo* info) {
+bool ErrorPrototype::define_class(JSContext* context,
+                                  JS::HandleObject in_object,
+                                  GIEnumInfo* info) {
     JS::RootedObject prototype(context), constructor(context);
     if (!ErrorPrototype::create_class(context, in_object, info, G_TYPE_ERROR,
                                       &constructor, &prototype))
@@ -352,11 +349,7 @@ gjs_error_from_js_gerror(JSContext *cx,
     return JS_New(cx, error_constructor, error_args);
 }
 
-JSObject*
-gjs_error_from_gerror(JSContext             *context,
-                      GError                *gerror,
-                      bool                   add_stack)
-{
+JSObject* ErrorInstance::object_for_c_ptr(JSContext* context, GError* gerror) {
     GIEnumInfo *info;
 
     if (gerror == NULL)
@@ -392,9 +385,6 @@ gjs_error_from_gerror(JSContext             *context,
     ErrorInstance* priv = ErrorInstance::new_for_js_object(context, obj);
     priv->copy_gerror(gerror);
 
-    if (add_stack && !gjs_define_error_properties(context, obj))
-        return nullptr;
-
     return obj;
 }
 
@@ -512,11 +502,14 @@ bool gjs_throw_gerror(JSContext* cx, GError* error) {
 
     JSAutoRequest ar(cx);
 
-    JS::RootedValue err(
-        cx, JS::ObjectOrNullValue(gjs_error_from_gerror(cx, error, true)));
+    JS::RootedObject err_obj(cx, ErrorInstance::object_for_c_ptr(cx, error));
+    if (!err_obj || !gjs_define_error_properties(cx, err_obj))
+        return false;
+
     g_error_free(error);
-    if (!err.isNull())
-        JS_SetPendingException(cx, err);
+
+    JS::RootedValue err(cx, JS::ObjectValue(*err_obj));
+    JS_SetPendingException(cx, err);
 
     return false;
 }
diff --git a/gi/gerror.h b/gi/gerror.h
index f6fc1544..dfce2a9a 100644
--- a/gi/gerror.h
+++ b/gi/gerror.h
@@ -124,6 +124,10 @@ class ErrorPrototype : public GIWrapperPrototype<ErrorBase, ErrorPrototype,
 
  public:
     GJS_USE GQuark domain(void) const { return m_domain; }
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static bool define_class(JSContext* cx, JS::HandleObject in_object,
+                             GIEnumInfo* info);
 };
 
 class ErrorInstance : public GIWrapperInstance<ErrorBase, ErrorPrototype,
@@ -154,24 +158,20 @@ class ErrorInstance : public GIWrapperInstance<ErrorBase, ErrorPrototype,
     GJS_JSAPI_RETURN_CONVENTION
     bool constructor_impl(JSContext* cx, JS::HandleObject obj,
                           const JS::CallArgs& args);
+
+    // Public API
+
+ public:
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* object_for_c_ptr(JSContext* cx, GError* gerror);
 };
 
 G_BEGIN_DECLS
 
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_define_error_class(JSContext* cx, JS::HandleObject in_object,
-                            GIEnumInfo* info);
-GJS_JSAPI_RETURN_CONVENTION
-JSObject* gjs_error_from_gerror        (JSContext             *context,
-                                        GError                *gerror,
-                                        bool                   add_stack);
 GJS_JSAPI_RETURN_CONVENTION
 GError *gjs_gerror_make_from_error(JSContext       *cx,
                                    JS::HandleObject obj);
 
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_gerror_to_string(JSContext* cx, unsigned argc, JS::Value* vp);
-
 GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_error_properties(JSContext* cx, JS::HandleObject obj);
 
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 9dc6eec1..9ad42ad7 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -476,7 +476,7 @@ gjs_define_info(JSContext       *context,
     case GI_INFO_TYPE_ENUM:
         if (g_enum_info_get_error_domain((GIEnumInfo*) info)) {
             /* define as GError subclass */
-            if (!gjs_define_error_class(context, in_object, info))
+            if (!ErrorPrototype::define_class(context, in_object, info))
                 return false;
             break;
         }
diff --git a/gi/value.cpp b/gi/value.cpp
index c9309aac..20adaac8 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -839,9 +839,11 @@ gjs_value_from_g_value_internal(JSContext             *context,
 
         /* special case GError */
         if (g_type_is_a(gtype, G_TYPE_ERROR)) {
-            obj = gjs_error_from_gerror(context, (GError*) gboxed, false);
-            value_p.setObjectOrNull(obj);
-
+            obj = ErrorInstance::object_for_c_ptr(context,
+                                                  static_cast<GError*>(gboxed));
+            if (!obj)
+                return false;
+            value_p.setObject(*obj);
             return true;
         }
 


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