[gjs: 12/14] fundamental: Support converting an empty GValue to a null fundamental
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 12/14] fundamental: Support converting an empty GValue to a null fundamental
- Date: Sat, 17 Apr 2021 04:36:48 +0000 (UTC)
commit 6580339f1c30464dfd842fefe161d5174de346c0
Author: Marco Trevisan (Treviño) <mail 3v1n0 net>
Date: Fri Apr 9 07:46:21 2021 +0200
fundamental: Support converting an empty GValue to a null fundamental
An empty GValue of a valid gtype can be safely marshalled to a null
fundamental pointer, but we did not support this.
Added test
gi/fundamental.cpp | 32 +++++++++++++++++++-------------
gi/fundamental.h | 5 +++--
gi/value.cpp | 10 +++++-----
installed-tests/js/testFundamental.js | 10 ++++++++++
4 files changed, 37 insertions(+), 20 deletions(-)
---
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index e117907e..72b69259 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -437,25 +437,31 @@ FundamentalPrototype* FundamentalPrototype::for_gtype(JSContext* cx,
return FundamentalPrototype::for_js(cx, proto);
}
-JSObject* FundamentalInstance::object_for_gvalue(JSContext* cx,
- const GValue* value,
- GType gtype) {
+bool FundamentalInstance::object_for_gvalue(
+ JSContext* cx, const GValue* value, GType gtype,
+ JS::MutableHandleObject object_out) {
auto* proto_priv = FundamentalPrototype::for_gtype(cx, gtype);
- void* fobj;
+ void* fobj = nullptr;
+
if (!proto_priv->call_get_value_function(value, &fobj)) {
- if (G_VALUE_HOLDS(value, gtype) && g_value_fits_pointer(value)) {
- return FundamentalInstance::object_for_c_ptr(
- cx, g_value_peek_pointer(value));
+ if (!G_VALUE_HOLDS(value, gtype) || !g_value_fits_pointer(value)) {
+ gjs_throw(cx,
+ "Failed to convert GValue of type %s to a fundamental %s "
+ "instance",
+ G_VALUE_TYPE_NAME(value), g_type_name(gtype));
+ return false;
}
- gjs_throw(cx,
- "Failed to convert GValue of type %s to a fundamental %s "
- "instance",
- G_VALUE_TYPE_NAME(value), g_type_name(gtype));
- return nullptr;
+ fobj = g_value_peek_pointer(value);
+ }
+
+ if (!fobj) {
+ object_out.set(nullptr);
+ return true;
}
- return FundamentalInstance::object_for_c_ptr(cx, fobj);
+ object_out.set(FundamentalInstance::object_for_c_ptr(cx, fobj));
+ return object_out.get() != nullptr;
}
bool FundamentalBase::to_gvalue(JSContext* cx, JS::HandleObject obj,
diff --git a/gi/fundamental.h b/gi/fundamental.h
index 927f11af..7d2f8de0 100644
--- a/gi/fundamental.h
+++ b/gi/fundamental.h
@@ -173,8 +173,9 @@ class FundamentalInstance
GJS_JSAPI_RETURN_CONVENTION
static JSObject* object_for_c_ptr(JSContext* cx, void* gfundamental);
GJS_JSAPI_RETURN_CONVENTION
- static JSObject* object_for_gvalue(JSContext* cx, const GValue* gvalue,
- GType gtype);
+ static bool object_for_gvalue(JSContext* cx, const GValue* gvalue,
+ GType gtype,
+ JS::MutableHandleObject object_out);
static void* copy_ptr(JSContext* cx, GType gtype, void* gfundamental);
};
diff --git a/gi/value.cpp b/gi/value.cpp
index 75b99041..c17c6933 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -1035,12 +1035,12 @@ gjs_value_from_g_value_internal(JSContext *context,
} else if (G_TYPE_IS_INSTANTIATABLE(gtype)) {
/* The gtype is none of the above, it should be a custom
fundamental type. */
- JSObject* obj =
- FundamentalInstance::object_for_gvalue(context, gvalue, gtype);
- if (obj == NULL)
+ JS::RootedObject obj(context);
+ if (!FundamentalInstance::object_for_gvalue(context, gvalue, gtype,
+ &obj))
return false;
- else
- value_p.setObject(*obj);
+
+ value_p.setObjectOrNull(obj);
} else {
gjs_throw(context,
"Don't know how to convert GType %s to JavaScript object",
diff --git a/installed-tests/js/testFundamental.js b/installed-tests/js/testFundamental.js
index 0c939573..a4d0c0f7 100644
--- a/installed-tests/js/testFundamental.js
+++ b/installed-tests/js/testFundamental.js
@@ -108,4 +108,14 @@ describe('Fundamental type support', function () {
obj.emit('test-fundamental-value-funcs-subtype', fund);
expect(signalSpy).toHaveBeenCalled();
}).pend('https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/268');
+
+ it('can marshal to a null value', function () {
+ const v = new GObject.Value();
+ expect(v.init(Regress.TestFundamentalObject.$gtype)).toBeNull();
+ });
+
+ it('can marshal to a null value if has no getter function', function () {
+ const v = new GObject.Value();
+ expect(v.init(Regress.TestFundamentalObjectNoGetSetFunc.$gtype)).toBeNull();
+ }).pend('https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/268');
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]