示例#1
0
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;
}
示例#2
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);
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
/* 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;
}
示例#6
0
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;
}