[gjs/gnome-40: 3/30] 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/gnome-40: 3/30] fundamental: Support converting an empty GValue to a null fundamental
- Date: Wed, 5 May 2021 20:41:25 +0000 (UTC)
commit 7b0267841ac2a0a228b0bcd21aee0d37d8c5d172
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
(cherry-picked from commit commit 6580339f)
gi/fundamental.cpp | 29 +++++++++++++++++++----------
gi/fundamental.h | 5 +++--
gi/value.cpp | 10 +++++-----
installed-tests/js/testFundamental.js | 10 ++++++++++
4 files changed, 37 insertions(+), 17 deletions(-)
---
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index e443dc7a..41c2fd3a 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -437,22 +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 to a fundamental instance");
- 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 fea7f9da..5447dc96 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -1018,12 +1018,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 3274cf6c..8093773c 100644
--- a/installed-tests/js/testFundamental.js
+++ b/installed-tests/js/testFundamental.js
@@ -47,4 +47,14 @@ describe('Fundamental type support', function () {
expect(() => obj.emit('test-fundamental-value-funcs', fund)).toThrowError(
/conversion to a GValue/);
}).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]