static void peas_extension_seed_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { PeasExtensionSeed *sexten = PEAS_EXTENSION_SEED (object); SeedValue seed_value; SeedException exc = NULL; gchar *prop_name; /* Don't add properties as they could shadow the instance's */ seed_value = seed_value_from_gvalue (sexten->js_context, (GValue *) value, &exc); if (exc != NULL) { gchar *exc_string; exc_string = seed_exception_to_string (sexten->js_context, exc); g_warning ("Seed Exception: %s", exc_string); g_free (exc_string); return; } prop_name = convert_property_name (pspec->name); seed_object_set_property (sexten->js_context, sexten->js_object, prop_name, seed_value); g_free (prop_name); }
static gboolean dbus_reply_from_exception_and_sender(SeedContext ctx, const gchar *sender, dbus_uint32_t serial, DBusMessage **reply_p, SeedException *exception) { SeedValue name_val; gchar *s; const gchar *name = NULL; *reply_p = NULL; if (seed_value_is_undefined (ctx, *exception) || seed_value_is_null (ctx, *exception) || !seed_value_is_object (ctx, *exception)) return FALSE; name_val = seed_object_get_property(ctx, *exception, "dbusErrorName"); name = seed_value_to_string (ctx, name_val, NULL); s = seed_exception_to_string (ctx, *exception); g_warning("JS exception we will send as dbus reply to %s: %s", sender, s); *reply_p = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); dbus_message_set_destination(*reply_p, sender); dbus_message_set_reply_serial(*reply_p, serial); dbus_message_set_no_reply(*reply_p, TRUE); dbus_message_set_error_name(*reply_p, name ? name : DBUS_ERROR_FAILED); if (s != NULL) { DBusMessageIter iter; dbus_message_iter_init_append(*reply_p, &iter); if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &s)) { dbus_message_unref(*reply_p); g_free(s); return FALSE; } g_free(s); } return TRUE; }
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 peas_plugin_loader_seed_load (PeasPluginLoader *loader, PeasPluginInfo *info) { PeasPluginLoaderSeed *sloader = PEAS_PLUGIN_LOADER_SEED (loader); SeedContext context; gchar *script; SeedException exc = NULL; SeedObject global, extensions; SeedInfo *sinfo; context = seed_context_create (seed->group, NULL); seed_prepare_global_context (context); script = get_script_for_plugin_info (info, context); seed_simple_evaluate (context, script, &exc); g_free (script); if (exc) { gchar *exc_string = seed_exception_to_string (context, exc); g_warning ("Seed Exception: %s", exc_string); g_free (exc_string); seed_context_unref (context); return FALSE; } global = seed_context_get_global_object (context); extensions = seed_object_get_property (context, global, "extensions"); if (seed_value_is_object (context, extensions)) { sinfo = (SeedInfo *) g_slice_new (SeedInfo); sinfo->context = context; sinfo->extensions = extensions; seed_context_ref (context); seed_value_protect (context, extensions); g_hash_table_insert (sloader->loaded_plugins, info, sinfo); } seed_context_unref (context); return TRUE; }
static gboolean peas_plugin_loader_seed_load (PeasPluginLoader *loader, PeasPluginInfo *info) { PeasPluginLoaderSeed *sloader = PEAS_PLUGIN_LOADER_SEED (loader); gchar *filename; gchar *content; GError *error = NULL; SeedContext context; SeedScript *script; SeedException exc = NULL; SeedObject global, extensions; SeedInfo *sinfo; filename = get_script_filename_for_plugin_info (info); g_debug ("Seed script filename is '%s'", filename); if (!g_file_get_contents (filename, &content, NULL, &error)) { g_warning ("Error: %s", error->message); g_error_free (error); g_free (filename); return FALSE; } context = seed_context_create (seed->group, NULL); seed_prepare_global_context (context); script = seed_make_script (context, content, filename, 0); seed_evaluate (context, script, NULL); exc = seed_script_exception (script); seed_script_destroy (script); g_free (content); g_free (filename); if (exc) { gchar *exc_string = seed_exception_to_string (context, exc); g_warning ("Seed Exception: %s", exc_string); g_free (exc_string); seed_context_unref (context); return FALSE; } global = seed_context_get_global_object (context); extensions = seed_object_get_property (context, global, "extensions"); if (seed_value_is_object (context, extensions)) { sinfo = (SeedInfo *) g_slice_new (SeedInfo); sinfo->context = context; sinfo->extensions = extensions; seed_value_protect (context, extensions); g_hash_table_insert (sloader->loaded_plugins, info, sinfo); return TRUE; } else { g_warning ("extensions is not an object in plugin '%s'", peas_plugin_info_get_module_name (info)); seed_context_unref (context); return FALSE; } }
void seed_signal_marshal_func (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) { SeedClosure *seed_closure = (SeedClosure *) closure; JSValueRef *args, exception = 0; JSValueRef ret = 0; guint i; gchar *mes; GSignalQuery signal_query = { 0, }; if (marshal_data) { /* Inspired from gjs/gi/value.c:closure_marshal() */ /* 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) g_error("Signal handler being called on invalid signal"); if (signal_query.n_params + 1 != n_param_values) g_error("Signal handler being called with wrong number of parameters"); } JSContextRef ctx = JSGlobalContextCreateInGroup (context_group, 0); seed_prepare_global_context (ctx); SEED_NOTE (INVOCATION, "Signal Marshal: "); args = g_newa (JSValueRef, n_param_values + 1); for (i = 0; i < n_param_values; i++) { args[i] = seed_value_from_gvalue_for_signal (ctx, (GValue *) & param_values[i], 0, &signal_query, i); if (!args[i]) g_error ("Error in signal marshal. " "Unable to convert argument of type: %s \n", g_type_name (param_values[i].g_type)); } if (seed_closure->user_data) args[i] = seed_closure->user_data; else args[i] = JSValueMakeNull (ctx); ret = JSObjectCallAsFunction (ctx, seed_closure->function, NULL, n_param_values + 1, args, &exception); if (exception) { seed_closure_warn_exception (closure, ctx, exception); exception = NULL; } if (ret && !JSValueIsNull (ctx, ret) && (seed_closure->return_type != G_TYPE_NONE)) { seed_value_to_gvalue (ctx, ret, seed_closure->return_type, return_value, &exception); } if (exception) { mes = seed_exception_to_string (ctx, exception); g_warning ("Exception in signal handler return value. %s \n", mes); g_free (mes); } JSGlobalContextRelease ((JSGlobalContextRef) ctx); JSGarbageCollect(ctx); }
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; }