diff options
author | Marco Trevisan (TreviƱo) <mail@3v1n0.net> | 2020-09-02 19:44:10 +0200 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2020-09-20 14:59:58 -0700 |
commit | f298f86c80c42c2ff26bb2a8d5028ce124e392a0 (patch) | |
tree | abb5acab7c9056b99765ee4d11c04e225f72b952 | |
parent | e2f9cf808fd3672f14326befabc3d523842c7d7e (diff) | |
download | gjs-f298f86c80c42c2ff26bb2a8d5028ce124e392a0.tar.gz |
function: Define a trampoline autopointer cleanup function and use it
-rw-r--r-- | gi/arg-cache.cpp | 4 | ||||
-rw-r--r-- | gi/function.cpp | 18 | ||||
-rw-r--r-- | gi/function.h | 5 |
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; |