static gboolean closure_source_func(void *data) { jsval retval; GClosure *closure; JSBool bool_val; JSContext *context; closure = data; context = gjs_closure_get_context(closure); if (context == NULL) { /* closure is invalid now */ return FALSE; } JS_BeginRequest(context); retval = JSVAL_VOID; JS_AddRoot(context, &retval); gjs_closure_invoke(closure, 0, NULL, &retval); /* ValueToBoolean pretty much always succeeds, just as * JavaScript always makes some sense of any value in * an "if (value) {}" context. */ if (!JS_ValueToBoolean(context, retval, &bool_val)) bool_val = FALSE; JS_RemoveRoot(context, &retval); JS_EndRequest(context); return bool_val; }
static void closure_marshal(GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { JSRuntime *runtime; JSContext *context; int argc; jsval *argv; jsval rval; int i; GSignalQuery signal_query = { 0, }; gjs_debug_marshal(GJS_DEBUG_GCLOSURE, "Marshal closure %p", closure); if (!gjs_closure_is_valid(closure)) { /* We were destroyed; become a no-op */ return; } runtime = gjs_closure_get_runtime(closure); context = gjs_runtime_get_current_context(runtime); JS_BeginRequest(context); argc = n_param_values; argv = g_newa(jsval, n_param_values); rval = JSVAL_VOID; gjs_set_values(context, argv, argc, JSVAL_VOID); gjs_root_value_locations(context, argv, argc); JS_AddValueRoot(context, &rval); if (marshal_data) { /* we are used for a signal handler */ guint signal_id; signal_id = GPOINTER_TO_UINT(marshal_data); g_signal_query(signal_id, &signal_query); if (!signal_query.signal_id) { gjs_debug(GJS_DEBUG_GCLOSURE, "Signal handler being called on invalid signal"); goto cleanup; } if (signal_query.n_params + 1 != n_param_values) { gjs_debug(GJS_DEBUG_GCLOSURE, "Signal handler being called with wrong number of parameters"); goto cleanup; } } for (i = 0; i < argc; ++i) { const GValue *gval = ¶m_values[i]; gboolean no_copy; no_copy = FALSE; if (i >= 1 && signal_query.signal_id) { no_copy = (signal_query.param_types[i - 1] & G_SIGNAL_TYPE_STATIC_SCOPE) != 0; } if (!gjs_value_from_g_value_internal(context, &argv[i], gval, no_copy, &signal_query, i)) { gjs_debug(GJS_DEBUG_GCLOSURE, "Unable to convert arg %d in order to invoke closure", i); gjs_log_exception(context, NULL); goto cleanup; } } gjs_closure_invoke(closure, argc, argv, &rval); if (return_value != NULL) { if (JSVAL_IS_VOID(rval)) { /* something went wrong invoking, error should be set already */ goto cleanup; } if (!gjs_value_to_g_value(context, rval, return_value)) { gjs_debug(GJS_DEBUG_GCLOSURE, "Unable to convert return value when invoking closure"); gjs_log_exception(context, NULL); goto cleanup; } } cleanup: gjs_unroot_value_locations(context, argv, argc); JS_RemoveValueRoot(context, &rval); JS_EndRequest(context); }