summaryrefslogtreecommitdiff
path: root/gi/arg-cache.cpp
diff options
context:
space:
mode:
authorEvan Welsh <contact@evanwelsh.com>2021-08-06 22:27:14 -0700
committerEvan Welsh <contact@evanwelsh.com>2021-08-06 22:27:14 -0700
commit8c585c9706b19c213682af9319789642cdcb15c6 (patch)
tree279c195012b63f744a01cb71f5b5f0809c0589f2 /gi/arg-cache.cpp
parent469b38f367ed9707f2c17a1bdeb810d9c193e462 (diff)
downloadgjs-ewlsh/fix-function-pointers.tar.gz
Some really rough work on fixing function pointer supportewlsh/fix-function-pointers
Not sure if we should go this route or wrap in a callback, I'd prefer if we can go this route to avoid adding JS wrapping
Diffstat (limited to 'gi/arg-cache.cpp')
-rw-r--r--gi/arg-cache.cpp21
1 files changed, 18 insertions, 3 deletions
diff --git a/gi/arg-cache.cpp b/gi/arg-cache.cpp
index dd46b88a..2499fbe5 100644
--- a/gi/arg-cache.cpp
+++ b/gi/arg-cache.cpp
@@ -284,9 +284,24 @@ static bool gjs_marshal_callback_in(JSContext* cx, GjsArgumentCache* self,
return false;
}
- JS::RootedFunction func(cx, JS_GetObjectFunction(&value.toObject()));
+ JS::RootedObject obj(cx, &value.toObject());
+ JS::RootedFunction func(cx, JS_GetObjectFunction(obj));
+
GjsAutoCallableInfo callable_info =
g_type_info_get_interface(&self->type_info);
+
+ if (!func && gjs_is_function(cx, obj)) {
+ GCallback callback = nullptr;
+ if (!gjs_function_to_callback(cx, obj, callable_info, &callback))
+ return false;
+ gjs_arg_set(arg, callback);
+ // Prevent GJS from attempting to cleanup this argument...
+ self->contents.callback.raw_pointer = true;
+ return true;
+ } else {
+ self->contents.callback.raw_pointer = false;
+ }
+
bool is_object_method = !!state->instance_object;
trampoline = GjsCallbackTrampoline::create(
cx, func, callable_info, self->contents.callback.scope,
@@ -925,12 +940,12 @@ static bool gjs_marshal_caller_allocates_release(JSContext*, GjsArgumentCache*,
}
GJS_JSAPI_RETURN_CONVENTION
-static bool gjs_marshal_callback_release(JSContext*, GjsArgumentCache*,
+static bool gjs_marshal_callback_release(JSContext*, GjsArgumentCache* cache,
GjsFunctionCallState*,
GIArgument* in_arg,
GIArgument* out_arg [[maybe_unused]]) {
auto* closure = gjs_arg_get<ffi_closure*>(in_arg);
- if (!closure)
+ if (!closure || !!cache->contents.callback.raw_pointer)
return true;
g_closure_unref(static_cast<GClosure*>(closure->user_data));