summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2020-09-02 19:44:10 +0200
committerPhilip Chimento <philip.chimento@gmail.com>2020-09-20 14:59:58 -0700
commitf298f86c80c42c2ff26bb2a8d5028ce124e392a0 (patch)
treeabb5acab7c9056b99765ee4d11c04e225f72b952
parente2f9cf808fd3672f14326befabc3d523842c7d7e (diff)
downloadgjs-f298f86c80c42c2ff26bb2a8d5028ce124e392a0.tar.gz
function: Define a trampoline autopointer cleanup function and use it
-rw-r--r--gi/arg-cache.cpp4
-rw-r--r--gi/function.cpp18
-rw-r--r--gi/function.h5
3 files changed, 13 insertions, 14 deletions
diff --git a/gi/arg-cache.cpp b/gi/arg-cache.cpp
index c8fa3796..f06e905c 100644
--- a/gi/arg-cache.cpp
+++ b/gi/arg-cache.cpp
@@ -911,11 +911,11 @@ static bool gjs_marshal_callback_release(JSContext*, GjsArgumentCache*,
if (!closure)
return true;
- auto trampoline = static_cast<GjsCallbackTrampoline*>(closure->user_data);
+ GjsAutoCallbackTrampoline trampoline =
+ static_cast<GjsCallbackTrampoline*>(closure->user_data);
// CallbackTrampolines are refcounted because for notified/async closures
// it is possible to destroy it while in call, and therefore we cannot
// check its scope at this point
- gjs_callback_trampoline_unref(trampoline);
gjs_arg_unset<void*>(in_arg);
return true;
}
diff --git a/gi/function.cpp b/gi/function.cpp
index b0cb101b..e1e326cd 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -27,6 +27,7 @@
#include <stdlib.h> // for exit
#include <string.h> // for strcmp, memset, size_t
+#include <memory> // for unique_ptr
#include <new>
#include <string>
#include <type_traits>
@@ -237,22 +238,20 @@ warn_about_illegal_js_callback(const GjsCallbackTrampoline *trampoline,
static void gjs_callback_closure(ffi_cif* cif [[maybe_unused]], void* result,
void** ffi_args, void* data) {
JSContext *context;
- GjsCallbackTrampoline *trampoline;
int i, n_args, n_jsargs, n_outargs, c_args_offset = 0;
GITypeInfo ret_type;
bool success = false;
auto args = reinterpret_cast<GIArgument **>(ffi_args);
- trampoline = (GjsCallbackTrampoline *) data;
- g_assert(trampoline);
- gjs_callback_trampoline_ref(trampoline);
+ g_assert(data && "Trampoline data is not set");
+ GjsAutoCallbackTrampoline trampoline(
+ static_cast<GjsCallbackTrampoline*>(data), GjsAutoTakeOwnership());
if (G_UNLIKELY(!gjs_closure_is_valid(trampoline->js_function))) {
warn_about_illegal_js_callback(trampoline, "during shutdown",
"destroying a Clutter actor or GTK widget with ::destroy signal "
"connected, or using the destroy(), dispose(), or remove() vfuncs");
gjs_dumpstack();
- gjs_callback_trampoline_unref(trampoline);
return;
}
@@ -263,14 +262,12 @@ static void gjs_callback_closure(ffi_cif* cif [[maybe_unused]], void* result,
"destroying a Clutter actor or GTK widget with ::destroy signal "
"connected, or using the destroy(), dispose(), or remove() vfuncs");
gjs_dumpstack();
- gjs_callback_trampoline_unref(trampoline);
return;
}
if (G_UNLIKELY(!gjs->is_owner_thread())) {
warn_about_illegal_js_callback(trampoline, "on a different thread",
"an API not intended to be used in JS");
- gjs_callback_trampoline_unref(trampoline);
return;
}
@@ -532,7 +529,6 @@ out:
completed_trampolines = g_slist_prepend(completed_trampolines, trampoline);
}
- gjs_callback_trampoline_unref(trampoline);
gjs->schedule_gc_if_needed();
}
@@ -540,7 +536,7 @@ GjsCallbackTrampoline* gjs_callback_trampoline_new(
JSContext* context, JS::HandleFunction function,
GICallableInfo* callable_info, GIScopeType scope, bool has_scope_object,
bool is_vfunc) {
- GjsCallbackTrampoline *trampoline;
+ GjsAutoCallbackTrampoline trampoline;
int n_args, i;
g_assert(function);
@@ -588,7 +584,6 @@ GjsCallbackTrampoline* gjs_callback_trampoline_new(
is_vfunc ? "VFunc" : "Callback",
g_base_info_get_name(callable_info));
g_base_info_unref(interface_info);
- gjs_callback_trampoline_unref(trampoline);
return NULL;
}
g_base_info_unref(interface_info);
@@ -606,7 +601,6 @@ GjsCallbackTrampoline* gjs_callback_trampoline_new(
"length argument. This is not supported",
is_vfunc ? "VFunc" : "Callback",
g_base_info_get_name(callable_info));
- gjs_callback_trampoline_unref(trampoline);
return NULL;
}
@@ -631,7 +625,7 @@ GjsCallbackTrampoline* gjs_callback_trampoline_new(
trampoline->scope = scope;
trampoline->is_vfunc = is_vfunc;
- return trampoline;
+ return trampoline.release();
}
/* Intended for error messages. Return value must be freed */
diff --git a/gi/function.h b/gi/function.h
index 98d09d0f..b295154c 100644
--- a/gi/function.h
+++ b/gi/function.h
@@ -34,6 +34,7 @@
#include <js/RootingAPI.h>
#include <js/TypeDecls.h>
+#include "gjs/jsapi-util.h"
#include "gjs/macros.h"
namespace JS {
@@ -70,6 +71,10 @@ void gjs_callback_trampoline_unref(GjsCallbackTrampoline *trampoline);
GjsCallbackTrampoline* gjs_callback_trampoline_ref(
GjsCallbackTrampoline* trampoline);
+using GjsAutoCallbackTrampoline =
+ GjsAutoPointer<GjsCallbackTrampoline, GjsCallbackTrampoline,
+ gjs_callback_trampoline_unref, gjs_callback_trampoline_ref>;
+
// Stack allocation only!
struct GjsFunctionCallState {
GIArgument* in_cvalues;