[gjs: 11/14] arg: Dynamically get the gtype from JS object when none is provided
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 11/14] arg: Dynamically get the gtype from JS object when none is provided
- Date: Sat, 17 Apr 2021 04:36:48 +0000 (UTC)
commit ff7d5b3a66295db708c3d9724fa2a5223e69cb04
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Fri Apr 9 07:36:17 2021 +0200
arg: Dynamically get the gtype from JS object when none is provided
In some cases we're handing interfaces with unsed GType, a case is
GTypeInstance. When this happen we should rely on fallback marshaller
and try to figure out the actual C container for this type getting the
gtype from the JS object.
This allows to use g_value_init_from_instance() correctly between the
others cases.
gi/arg-cache.cpp | 9 ++++++++
gi/arg.cpp | 38 +++++++++++++++++++++++++++-------
installed-tests/js/testGObjectValue.js | 9 ++++++++
3 files changed, 49 insertions(+), 7 deletions(-)
---
diff --git a/gi/arg-cache.cpp b/gi/arg-cache.cpp
index 10b15fcc..7f1cead6 100644
--- a/gi/arg-cache.cpp
+++ b/gi/arg-cache.cpp
@@ -1389,6 +1389,15 @@ static bool gjs_arg_cache_build_interface_in_arg(JSContext* cx,
case GI_INFO_TYPE_INTERFACE:
case GI_INFO_TYPE_UNION: {
GType gtype = g_registered_type_info_get_g_type(interface_info);
+
+ if (!is_instance_param && interface_type == GI_INFO_TYPE_STRUCT &&
+ gtype == G_TYPE_NONE &&
+ !g_struct_info_is_gtype_struct(interface_info)) {
+ // This covers cases such as GTypeInstance
+ self->marshallers = &fallback_in_marshallers;
+ return true;
+ }
+
self->contents.object.gtype = gtype;
self->contents.object.info = g_base_info_ref(interface_info);
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 4574f98c..49224e83 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -1279,10 +1279,26 @@ static bool value_to_interface_gi_argument(
gjs_arg_set(arg, klass);
return true;
+ }
+
+ GType arg_gtype = gtype;
+ if (interface_type == GI_INFO_TYPE_STRUCT && gtype == G_TYPE_NONE &&
+ !g_struct_info_is_foreign(interface_info)) {
+ GType actual_gtype = G_TYPE_NONE;
+ // In case we have no known type from gi we should try to be
+ // more dynamic and try to get the type from JS, to handle the
+ // case in which we're handling a gpointer such as GTypeInstance
+ // FIXME(3v1n0): would be nice to know if GI would give this info
+ if (!gjs_gtype_get_actual_gtype(cx, obj, &actual_gtype))
+ return false;
+
+ if (G_TYPE_IS_INSTANTIATABLE(actual_gtype))
+ gtype = actual_gtype;
+ }
- } else if ((interface_type == GI_INFO_TYPE_STRUCT ||
- interface_type == GI_INFO_TYPE_BOXED) &&
- !g_type_is_a(gtype, G_TYPE_CLOSURE)) {
+ if ((interface_type == GI_INFO_TYPE_STRUCT ||
+ interface_type == GI_INFO_TYPE_BOXED) &&
+ !g_type_is_a(gtype, G_TYPE_CLOSURE)) {
// Handle Struct/Union first since we don't necessarily need a GType
// for them. We special case Closures later, so skip them here.
if (g_type_is_a(gtype, G_TYPE_BYTES) && JS_IsUint8Array(obj)) {
@@ -1293,14 +1309,22 @@ static bool value_to_interface_gi_argument(
return ErrorBase::transfer_to_gi_argument(
cx, obj, arg, GI_DIRECTION_IN, transfer);
}
- return BoxedBase::transfer_to_gi_argument(
- cx, obj, arg, GI_DIRECTION_IN, transfer, gtype, interface_info);
+ if (arg_gtype != G_TYPE_NONE || gtype == G_TYPE_NONE ||
+ g_type_is_a(gtype, G_TYPE_BOXED) ||
+ g_type_is_a(gtype, G_TYPE_VALUE) ||
+ g_type_is_a(gtype, G_TYPE_VARIANT)) {
+ return BoxedBase::transfer_to_gi_argument(
+ cx, obj, arg, GI_DIRECTION_IN, transfer, gtype,
+ interface_info);
+ }
+ }
- } else if (interface_type == GI_INFO_TYPE_UNION) {
+ if (interface_type == GI_INFO_TYPE_UNION) {
return UnionBase::transfer_to_gi_argument(
cx, obj, arg, GI_DIRECTION_IN, transfer, gtype, interface_info);
+ }
- } else if (gtype != G_TYPE_NONE) {
+ if (gtype != G_TYPE_NONE) {
if (g_type_is_a(gtype, G_TYPE_OBJECT)) {
return ObjectBase::transfer_to_gi_argument(
cx, obj, arg, GI_DIRECTION_IN, transfer, gtype);
diff --git a/installed-tests/js/testGObjectValue.js b/installed-tests/js/testGObjectValue.js
index e890cf49..fc5147c4 100644
--- a/installed-tests/js/testGObjectValue.js
+++ b/installed-tests/js/testGObjectValue.js
@@ -169,6 +169,15 @@ describe('GObject value (GValue)', function () {
}).pend('https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/268');
});
+ INSTANCED_TYPES.forEach(type => {
+ it(`initializes from instance of ${type}`, function () {
+ skipUnsupported(type);
+ const instance = getDefaultContentByType(type);
+ v.init_from_instance(instance);
+ expect(getContent(v, type)).toEqual(instance);
+ });
+ });
+
afterEach(function () {
v.unset();
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]