static int seed_sqlite_exec_callback(SeedObject function, int argc, gchar ** argv, gchar ** azColName) { SeedGlobalContext ctx; SeedObject hash; int i; if (!function) return 0; ctx = seed_context_create(eng->group, NULL); hash = seed_make_object(ctx, 0, 0); for (i = 0; i < argc; i++) { seed_object_set_property(ctx, hash, azColName[i], seed_value_from_string(ctx, argv[i], 0)); } seed_object_call(ctx, function, 0, 1, &hash, 0); seed_context_unref(ctx); return 0; }
static void seed_handle_rl_closure(ffi_cif * cif, void *result, void **args, void *userdata) { SeedContext ctx = seed_context_create(eng->group, NULL); SeedValue exception = 0; SeedObject function = (SeedObject) userdata; seed_object_call(ctx, function, 0, 0, 0, &exception); if (exception) { gchar *mes = seed_exception_to_string(ctx, exception); g_warning("Exception in readline bind key closure. %s \n", mes); } seed_context_unref((SeedContext) ctx); }
static gboolean gio_marshal_func(GIOChannel * source, GIOCondition condition, gpointer data) { SeedGlobalContext ctx = seed_context_create(eng->group, 0); SeedValue jscondition = seed_value_from_long(ctx, (glong) condition, 0); SeedValue args[3], ret; marshal_privates *priv = (marshal_privates *) data; gboolean bret; args[0] = priv->source; args[1] = jscondition; args[2] = priv->user_data; ret = seed_object_call(ctx, priv->function, 0, 3, args, 0); bret = seed_value_to_boolean(ctx, ret, 0); seed_context_unref(ctx); if (!bret) g_free(priv); return bret; }
static gboolean peas_extension_seed_call (PeasExtensionWrapper *exten, const gchar *method_name, GIArgument *args, GIArgument *retval) { PeasExtensionSeed *sexten = PEAS_EXTENSION_SEED (exten); GType exten_type; SeedValue js_method; GICallableInfo *func_info; gint n_args, i; SeedValue *js_in_args; OutArg *out_args; SeedValue js_ret, val; SeedException exc = NULL; gchar *exc_string; gint n_in_args = 0; gint n_out_args = 0; GIArgument argument; g_return_val_if_fail (sexten->js_context != NULL, FALSE); g_return_val_if_fail (sexten->js_object != NULL, FALSE); exten_type = peas_extension_wrapper_get_extension_type (exten); /* Fetch the JS method we want to call */ js_method = seed_object_get_property (sexten->js_context, sexten->js_object, method_name); if (seed_value_is_undefined (sexten->js_context, js_method)) { g_warning ("Method '%s.%s' is not defined", g_type_name (exten_type), method_name); return FALSE; } /* We want to display an error if the method is defined but is not a function. */ if (!seed_value_is_function (sexten->js_context, js_method)) { g_warning ("Method '%s.%s' is not a function", g_type_name (exten_type), method_name); return FALSE; } /* Prepare the arguments */ func_info = peas_gi_get_method_info (exten_type, method_name); if (func_info == NULL) return FALSE; n_args = g_callable_info_get_n_args (func_info); g_return_val_if_fail (n_args >= 0, FALSE); js_in_args = g_newa (SeedValue, n_args); out_args = g_newa (OutArg, n_args + 1); /* We put the return value first in the out tuple, as it seems to be * the common behaviour for GI-based bindings */ g_callable_info_load_return_type (func_info, &out_args[0].type_info); if (g_type_info_get_tag (&out_args[0].type_info) != GI_TYPE_TAG_VOID) out_args[n_out_args++].ptr = &retval->v_pointer; /* Handle the other arguments */ for (i = 0; i < n_args && exc == NULL; i++) { GIArgInfo arg_info; GIDirection direction; g_callable_info_load_arg (func_info, i, &arg_info); direction = g_arg_info_get_direction (&arg_info); g_arg_info_load_type (&arg_info, &out_args[n_out_args].type_info); if (direction == GI_DIRECTION_IN) { js_in_args[n_in_args++] = seed_value_from_gi_argument (sexten->js_context, &args[i], &out_args[n_out_args].type_info, &exc); } if (direction == GI_DIRECTION_INOUT) { GIArgument arg; peas_gi_pointer_to_argument (&out_args[n_out_args].type_info, args[i].v_pointer, &arg); js_in_args[n_in_args++] = seed_value_from_gi_argument (sexten->js_context, &arg, &out_args[n_out_args].type_info, &exc); } if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) out_args[n_out_args++].ptr = args[i].v_pointer; } if (exc != NULL) goto cleanup; js_ret = seed_object_call (sexten->js_context, js_method, sexten->js_object, n_in_args, js_in_args, &exc); if (exc != NULL) goto cleanup; if (n_out_args == 1) { if (seed_value_to_gi_argument (sexten->js_context, js_ret, &out_args[0].type_info, &argument, &exc)) { peas_gi_argument_to_pointer (&out_args[0].type_info, &argument, out_args[0].ptr); } } else if (n_out_args > 0 && seed_value_is_object (sexten->js_context, js_ret)) { for (i = 0; i < n_out_args && exc == NULL; i++) { val = seed_object_get_property_at_index (sexten->js_context, js_ret, i, exc); if (exc == NULL && seed_value_to_gi_argument (sexten->js_context, val, &out_args[i].type_info, &argument, &exc)) { peas_gi_argument_to_pointer (&out_args[i].type_info, &argument, out_args[i].ptr); } } } cleanup: g_base_info_unref ((GIBaseInfo *) func_info); if (exc == NULL) return TRUE; exc_string = seed_exception_to_string (sexten->js_context, exc); g_warning ("Seed Exception: %s", exc_string); g_free (exc_string); return FALSE; }
/* returns an error message or NULL */ static DBusMessage * invoke_js_async_from_dbus(SeedContext ctx, DBusBusType bus_type, DBusMessage *method_call, SeedObject this_obj, SeedObject method_obj, SeedException *exception) { DBusMessage *reply; int argc; SeedValue *argv; DBusMessageIter arg_iter; GArray *values; SeedObject callback_object; SeedValue sender_string, signature_string; gboolean thrown; SeedValue ignored; const char *signature; reply = NULL; thrown = FALSE; argc = 0; argv = NULL; if (!seed_js_values_from_dbus(ctx, &arg_iter, &values, exception)) { if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning ("conversion of dbus method arg failed but no exception was set?"); return reply; } /* we will add an argument, the callback */ callback_object = seed_make_function(ctx, async_call_callback, "" /* anonymous */); g_assert(callback_object); g_array_append_val(values, callback_object); /* We attach the DBus sender and serial as properties to * callback, so we don't need to bother with memory managing them * if the callback is never called and just discarded.*/ sender_string = seed_value_from_string (ctx, dbus_message_get_sender (method_call), exception); if (!sender_string) { thrown = TRUE; goto out; } seed_object_set_property (ctx, callback_object, "_dbusSender", sender_string); seed_object_set_property (ctx, callback_object, "_dbusSerial", seed_value_from_int (ctx, dbus_message_get_serial (method_call), exception)); seed_object_set_property (ctx, callback_object, "_dbusBusType", seed_value_from_int (ctx, bus_type, exception)); if (!signature_from_method(ctx, method_obj, &signature, exception)) { thrown = TRUE; goto out; } signature_string = seed_value_from_string (ctx, signature, exception); if (!signature_string) { thrown = TRUE; goto out; } seed_object_set_property (ctx, callback_object, "_dbusOutSignature", signature_string); argc = values->len; argv = (SeedValue *)values->data; seed_object_call (ctx, method_obj, this_obj, argc, argv, &ignored); out: if (thrown) { if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning("conversion of dbus method arg failed but no exception was set?"); } g_array_free (values, TRUE); return reply; }
static DBusMessage* invoke_js_from_dbus(SeedContext ctx, DBusMessage *method_call, SeedObject this_obj, SeedObject method_obj, SeedException *exception) { DBusMessage *reply; int argc; SeedValue *argv; SeedValue rval; DBusMessageIter arg_iter; GArray *values; const char *signature; reply = NULL; dbus_message_iter_init(method_call, &arg_iter); if (!seed_js_values_from_dbus(ctx, &arg_iter, &values, exception)) { if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning("conversion of dbus method arg failed but no exception was set?"); return reply; } argc = values->len; argv = (SeedValue *)values->data; seed_js_add_dbus_props(ctx, method_call, argv[0], exception); rval = seed_object_call (ctx, method_obj, NULL, argc, argv, exception); if (!seed_value_is_null (ctx, *exception) && seed_value_is_object (ctx, *exception)) { g_warning("dbus method invocation failed"); if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning("dbus method invocation failed but no exception was set?"); goto out; } if (dbus_reply_from_exception(ctx, method_call, &reply, exception)) { g_warning("Closure invocation succeeded but an exception was set?"); goto out; } if (!signature_from_method(ctx, method_obj, &signature, exception)) { if (!dbus_reply_from_exception(ctx, method_call, &reply, exception)) g_warning("dbus method invocation failed but no exception was set?"); goto out; } reply = build_reply_from_jsval(ctx, signature, dbus_message_get_sender(method_call), dbus_message_get_serial(method_call), rval, exception); out: g_array_free(values, TRUE); if (reply) g_warning ("Sending %s reply to dbus method %s", dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN ? "normal" : "error", dbus_message_get_member(method_call)); else g_warning ("Failed to create reply to dbus method %s", dbus_message_get_member(method_call)); return reply; }