[gjs/ewlsh/use-new-gi-callable-api] gi: Use new GObject Introspection callable API
- From: Evan Welsh <ewlsh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/ewlsh/use-new-gi-callable-api] gi: Use new GObject Introspection callable API
- Date: Sun, 6 Mar 2022 22:37:52 +0000 (UTC)
commit 21f85e8beb08b0a0e2c7d9d84295820dc53b55af
Author: Evan Welsh <contact evanwelsh com>
Date: Sun Mar 6 14:36:10 2022 -0800
gi: Use new GObject Introspection callable API
This avoids misusing the closure pointer by creating a clear
separation between the native closure pointer and the pointer
to the libffi closure.
Fixes #428
gi/arg-cache.cpp | 2 +-
gi/function.cpp | 39 ++++++++++++++++++++++++---------------
gi/function.h | 9 ++++++++-
gi/object.cpp | 4 ++--
4 files changed, 35 insertions(+), 19 deletions(-)
---
diff --git a/gi/arg-cache.cpp b/gi/arg-cache.cpp
index 83c4ad4da..177f246f4 100644
--- a/gi/arg-cache.cpp
+++ b/gi/arg-cache.cpp
@@ -826,7 +826,7 @@ GJS_JSAPI_RETURN_CONVENTION
bool CallbackIn::in(JSContext* cx, GjsFunctionCallState* state, GIArgument* arg,
JS::HandleValue value) {
GjsCallbackTrampoline* trampoline;
- ffi_closure* closure;
+ void* closure;
if (value.isNull() && m_nullable) {
closure = nullptr;
diff --git a/gi/function.cpp b/gi/function.cpp
index 716acc8ec..5c4fa4a28 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -640,8 +640,13 @@ GjsCallbackTrampoline::GjsCallbackTrampoline(
}
GjsCallbackTrampoline::~GjsCallbackTrampoline() {
- if (m_info && m_closure)
+ if (m_info && m_closure) {
+#if GI_CHECK_VERSION(1, 71, 0)
+ g_callable_info_destroy_closure(m_info, m_closure);
+#else
g_callable_info_free_closure(m_info, m_closure);
+#endif
+ }
}
void GjsCallbackTrampoline::mark_forever() {
@@ -652,6 +657,23 @@ void GjsCallbackTrampoline::prepare_shutdown() {
s_forever_closure_list.clear();
}
+ffi_closure* GjsCallbackTrampoline::create_closure() {
+ auto callback = [](ffi_cif*, void* result, void** ffi_args, void* data) {
+ auto** args = reinterpret_cast<GIArgument**>(ffi_args);
+ g_assert(data && "Trampoline data is not set");
+ Gjs::Closure::Ptr trampoline(static_cast<GjsCallbackTrampoline*>(data),
+ GjsAutoTakeOwnership());
+
+ trampoline.as<GjsCallbackTrampoline>()->callback_closure(args, result);
+ };
+
+#if GI_CHECK_VERSION(1, 71, 0)
+ return g_callable_info_create_closure(m_info, &m_cif, callback, this);
+#else
+ return g_callable_info_prepare_closure(m_info, &m_cif, callback, this);
+#endif
+}
+
bool GjsCallbackTrampoline::initialize() {
g_assert(is_valid());
g_assert(!m_closure);
@@ -720,20 +742,7 @@ bool GjsCallbackTrampoline::initialize() {
}
}
- m_closure = g_callable_info_prepare_closure(
- m_info, &m_cif,
- [](ffi_cif*, void* result, void** ffi_args, void* data) {
- auto** args = reinterpret_cast<GIArgument**>(ffi_args);
- g_assert(data && "Trampoline data is not set");
- Gjs::Closure::Ptr trampoline(
- static_cast<GjsCallbackTrampoline*>(data),
- GjsAutoTakeOwnership());
-
- trampoline.as<GjsCallbackTrampoline>()->callback_closure(args,
- result);
- },
- this);
-
+ m_closure = create_closure();
return true;
}
diff --git a/gi/function.h b/gi/function.h
index a6e9b82dd..799c14903 100644
--- a/gi/function.h
+++ b/gi/function.h
@@ -49,13 +49,20 @@ struct GjsCallbackTrampoline : public Gjs::Closure {
~GjsCallbackTrampoline();
- constexpr ffi_closure* closure() const { return m_closure; }
+ void* closure() const {
+#if GI_CHECK_VERSION(1, 71, 0)
+ return g_callable_info_get_closure_native_address(m_info, m_closure);
+#else
+ return m_closure;
+#endif
+ }
void mark_forever();
static void prepare_shutdown();
private:
+ ffi_closure* create_closure();
GJS_JSAPI_RETURN_CONVENTION bool initialize();
GjsCallbackTrampoline(JSContext* cx, JS::HandleFunction function,
GICallableInfo* callable_info, GIScopeType scope,
diff --git a/gi/object.cpp b/gi/object.cpp
index a53f9e525..45457202d 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -3004,7 +3004,7 @@ bool ObjectPrototype::hook_up_vfunc_impl(JSContext* cx,
if (field_info) {
gint offset;
- gpointer method_ptr;
+ void* method_ptr;
GjsCallbackTrampoline *trampoline;
offset = g_field_info_get_offset(field_info);
@@ -3032,7 +3032,7 @@ bool ObjectPrototype::hook_up_vfunc_impl(JSContext* cx,
trampoline, nullptr,
[](void*, GClosure* closure) { g_closure_unref(closure); });
- *reinterpret_cast<ffi_closure**>(method_ptr) = trampoline->closure();
+ *reinterpret_cast<void**>(method_ptr) = trampoline->closure();
}
return true;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]