Exemplo n.º 1
0
/* Find the first constructor */
static GIFunctionInfo *
find_fundamental_constructor(JSContext    *context,
                             GIObjectInfo *info,
                             jsid         *constructor_name)
{
    int i, n_methods;

    n_methods = g_object_info_get_n_methods(info);

    for (i = 0; i < n_methods; ++i) {
        GIFunctionInfo *func_info;
        GIFunctionInfoFlags flags;

        func_info = g_object_info_get_method(info, i);

        flags = g_function_info_get_flags(func_info);
        if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0) {
            const char *name;

            name = g_base_info_get_name((GIBaseInfo *) func_info);
            *constructor_name = gjs_intern_string_to_id(context, name);

            return func_info;
        }

        g_base_info_unref((GIBaseInfo *) func_info);
    }

    return NULL;
}
Exemplo n.º 2
0
PyObject *
_wrap_g_callable_info_invoke (PyGIBaseInfo *self, PyObject *py_args,
                              PyObject *kwargs)
{
    if (self->cache == NULL) {
        PyGIFunctionCache *function_cache;
        GIInfoType type = g_base_info_get_type (self->info);

        if (type == GI_INFO_TYPE_FUNCTION) {
            GIFunctionInfoFlags flags;

            flags = g_function_info_get_flags ( (GIFunctionInfo *)self->info);

            if (flags & GI_FUNCTION_IS_CONSTRUCTOR) {
                function_cache = pygi_constructor_cache_new (self->info);
            } else if (flags & GI_FUNCTION_IS_METHOD) {
                function_cache = pygi_method_cache_new (self->info);
            } else {
                function_cache = pygi_function_cache_new (self->info);
            }
        } else if (type == GI_INFO_TYPE_VFUNC) {
            function_cache = pygi_vfunc_cache_new (self->info);
        } else if (type == GI_INFO_TYPE_CALLBACK) {
            g_error ("Cannot invoke callback types");
        } else {
            function_cache = pygi_method_cache_new (self->info);
        }

        self->cache = (PyGICallableCache *)function_cache;
        if (self->cache == NULL)
            return NULL;
    }

    return pygi_callable_info_invoke (self->info, py_args, kwargs, self->cache, NULL);
}
Exemplo n.º 3
0
static JSBool
gjs_define_static_methods(JSContext    *context,
                          JSObject     *constructor,
                          GType         gtype,
                          GIStructInfo *boxed_info)
{
    int i;
    int n_methods;

    n_methods = g_struct_info_get_n_methods(boxed_info);

    for (i = 0; i < n_methods; i++) {
        GIFunctionInfo *meth_info;
        GIFunctionInfoFlags flags;

        meth_info = g_struct_info_get_method (boxed_info, i);
        flags = g_function_info_get_flags (meth_info);

        /* Anything that isn't a method we put on the prototype of the
         * constructor.  This includes <constructor> introspection
         * methods, as well as the forthcoming "static methods"
         * support.  We may want to change this to use
         * GI_FUNCTION_IS_CONSTRUCTOR and GI_FUNCTION_IS_STATIC or the
         * like in the near future.
         */
        if (!(flags & GI_FUNCTION_IS_METHOD)) {
            gjs_define_function(context, constructor, gtype,
                                (GICallableInfo *)meth_info);
        }

        g_base_info_unref((GIBaseInfo*) meth_info);
    }
    return JS_TRUE;
}
Exemplo n.º 4
0
static VALUE
rg_flags(VALUE self)
{
    GIFunctionInfo *info;

    info = SELF(self);
    return GI_FUNCTION_INFO_FLAGS2RVAL(g_function_info_get_flags(info));
}
Exemplo n.º 5
0
/*
 * The *resolved out parameter, on success, should be false to indicate that id
 * was not resolved; and true if id was resolved.
 */
static bool
param_resolve(JSContext       *context,
              JS::HandleObject obj,
              JS::HandleId     id,
              bool            *resolved)
{
    GIObjectInfo *info = NULL;
    GIFunctionInfo *method_info;
    Param *priv;
    bool ret = false;

    priv = priv_from_js(context, obj);
    if (priv != NULL) {
        /* instance, not prototype */
        *resolved = false;
        return true;
    }

    GjsAutoJSChar name;
    if (!gjs_get_string_id(context, id, &name)) {
        *resolved = false;
        return true; /* not resolved, but no error */
    }

    info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), G_TYPE_PARAM);
    method_info = g_object_info_find_method(info, name);

    if (method_info == NULL) {
        *resolved = false;
        ret = true;
        goto out;
    }
#if GJS_VERBOSE_ENABLE_GI_USAGE
    _gjs_log_info_usage((GIBaseInfo*) method_info);
#endif

    if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
        gjs_debug(GJS_DEBUG_GOBJECT,
                  "Defining method %s in prototype for GObject.ParamSpec",
                  g_base_info_get_name( (GIBaseInfo*) method_info));

        if (gjs_define_function(context, obj, G_TYPE_PARAM, method_info) == NULL) {
            g_base_info_unref( (GIBaseInfo*) method_info);
            goto out;
        }

        *resolved = true; /* we defined the prop in obj */
    }

    g_base_info_unref( (GIBaseInfo*) method_info);

    ret = true;
 out:
    if (info != NULL)
        g_base_info_unref( (GIBaseInfo*)info);

    return ret;
}
Exemplo n.º 6
0
/*
 * Set up prototype and constructor for structs. Same semantics as objects
 * except
 * for the type.
 */
static void
seed_gi_importer_handle_struct(JSContextRef ctx,
                               JSObjectRef namespace_ref,
                               GIStructInfo* info,
                               JSValueRef* exception)
{
    JSObjectRef struct_ref;
    JSObjectRef proto;
    gint i, n_methods;
    GIFunctionInfo* finfo;

    struct_ref = JSObjectMake(ctx, seed_struct_constructor_class, info);
    g_base_info_ref(info);

    n_methods = g_struct_info_get_n_methods(info);

    for (i = 0; i < n_methods; i++) {
        GIFunctionInfoFlags flags;
        finfo = g_struct_info_get_method(info, i);

        flags = g_function_info_get_flags(finfo);

        if (flags & GI_FUNCTION_IS_CONSTRUCTOR) {
            JSObjectRef constructor
              = JSObjectMake(ctx, gobject_named_constructor_class, finfo);
            const gchar* fname = g_base_info_get_name((GIBaseInfo*) finfo);
            if (g_strrstr(fname, "new_") == fname) {
                // To be compatible with gjs, we need to have a method with
                // new_, too.
                seed_object_set_property(ctx, struct_ref, fname, constructor);
                fname += 4;
            }

            else if (!g_strcmp0(fname, "new")) {
                // To be compatible with gjs, we need to have new as function,
                // too.
                seed_object_set_property(ctx, struct_ref, fname, constructor);
                fname = "c_new";
            }

            seed_object_set_property(ctx, struct_ref, fname, constructor);
        } else if (flags & GI_FUNCTION_IS_METHOD)
            g_base_info_unref((GIBaseInfo*) finfo);
        else
            seed_gobject_define_property_from_function_info(ctx, finfo,
                                                            struct_ref, FALSE);
    }

    proto = seed_struct_prototype(ctx, (GIBaseInfo*) info);
    seed_object_set_property(ctx, struct_ref, "prototype", proto);

    seed_object_set_property(ctx, namespace_ref,
                             g_base_info_get_name((GIBaseInfo*) info),
                             struct_ref);
}
Exemplo n.º 7
0
/**
 * g_function_info_invoke: (skip)
 * @info: a #GIFunctionInfo describing the function to invoke
 * @in_args: an array of #GIArgument<!-- -->s, one for each in
 *    parameter of @info. If there are no in parameter, @in_args
 *    can be %NULL
 * @n_in_args: the length of the @in_args array
 * @out_args: an array of #GIArgument<!-- -->s, one for each out
 *    parameter of @info. If there are no out parameters, @out_args
 *    may be %NULL
 * @n_out_args: the length of the @out_args array
 * @return_value: return location for the return value of the
 *    function. If the function returns void, @return_value may be
 *    %NULL
 * @error: return location for detailed error information, or %NULL
 *
 * Invokes the function described in @info with the given
 * arguments. Note that inout parameters must appear in both
 * argument lists. This function uses dlsym() to obtain a pointer
 * to the function, so the library or shared object containing the
 * described function must either be linked to the caller, or must
 * have been g_module_symbol()<!-- -->ed before calling this function.
 *
 * Returns: %TRUE if the function has been invoked, %FALSE if an
 *   error occurred.
 */
gboolean
g_function_info_invoke (GIFunctionInfo *info,
			const GIArgument  *in_args,
			int               n_in_args,
			const GIArgument  *out_args,
			int               n_out_args,
			GIArgument        *return_value,
			GError          **error)
{
  const gchar *symbol;
  gpointer func;
  gboolean is_method;
  gboolean throws;

  symbol = g_function_info_get_symbol (info);

  if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info),
                         symbol, &func))
    {
      g_set_error (error,
                   G_INVOKE_ERROR,
                   G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
                   "Could not locate %s: %s", symbol, g_module_error ());

      return FALSE;
    }

  is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0
    && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0;
  throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS;

  return g_callable_info_invoke ((GICallableInfo*) info,
                                 func,
                                 in_args,
                                 n_in_args,
                                 out_args,
                                 n_out_args,
                                 return_value,
                                 is_method,
                                 throws,
                                 error);
}
Exemplo n.º 8
0
static PyObject *
_wrap_g_function_info_is_method (PyGIBaseInfo *self)
{
    GIFunctionInfoFlags flags;
    gboolean is_method;

    flags = g_function_info_get_flags ( (GIFunctionInfo*) self->info);
    is_method = flags & GI_FUNCTION_IS_METHOD;

    return PyBool_FromLong (is_method);
}
Exemplo n.º 9
0
static PyObject *
_wrap_g_function_info_is_constructor (PyGIBaseInfo *self)
{
    GIFunctionInfoFlags flags;
    gboolean is_constructor;

    flags = g_function_info_get_flags ( (GIFunctionInfo*) self->info);
    is_constructor = flags & GI_FUNCTION_IS_CONSTRUCTOR;

    return PyBool_FromLong (is_constructor);
}
Exemplo n.º 10
0
static JSBool
fundamental_instance_new_resolve_interface(JSContext    *context,
                                           JS::HandleObject obj,
                                           JS::MutableHandleObject objp,
                                           Fundamental  *proto_priv,
                                           char         *name)
{
    GIFunctionInfo *method_info;
    JSBool ret;
    GType *interfaces;
    guint n_interfaces;
    guint i;

    ret = JS_TRUE;
    interfaces = g_type_interfaces(proto_priv->gtype, &n_interfaces);
    for (i = 0; i < n_interfaces; i++) {
        GIBaseInfo *base_info;
        GIInterfaceInfo *iface_info;

        base_info = g_irepository_find_by_gtype(g_irepository_get_default(),
                                                interfaces[i]);

        if (base_info == NULL)
            continue;

        /* An interface GType ought to have interface introspection info */
        g_assert(g_base_info_get_type(base_info) == GI_INFO_TYPE_INTERFACE);

        iface_info = (GIInterfaceInfo *) base_info;

        method_info = g_interface_info_find_method(iface_info, name);

        g_base_info_unref(base_info);


        if (method_info != NULL) {
            if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
                if (gjs_define_function(context, obj,
                                        proto_priv->gtype,
                                        (GICallableInfo *) method_info)) {
                    objp.set(obj);
                } else {
                    ret = JS_FALSE;
                }
            }

            g_base_info_unref((GIBaseInfo *) method_info);
        }
    }

    g_free(interfaces);
    return ret;
}
Exemplo n.º 11
0
static bool
interface_new_resolve(JSContext *context,
                      JS::HandleObject obj,
                      JS::HandleId id,
                      JS::MutableHandleObject objp)
{
    Interface *priv;
    char *name;
    bool ret = false;
    GIFunctionInfo *method_info;

    if (!gjs_get_string_id(context, id, &name))
        return true;

    priv = priv_from_js(context, obj);

    if (priv == NULL)
        goto out;

    /* If we have no GIRepository information then this interface was defined
     * from within GJS. In that case, it has no properties that need to be
     * resolved from within C code, as interfaces cannot inherit. */
    if (priv->info == NULL) {
        ret = true;
        goto out;
    }

    method_info = g_interface_info_find_method((GIInterfaceInfo*) priv->info, name);

    if (method_info != NULL) {
        if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
            if (gjs_define_function(context, obj,
                                    priv->gtype,
                                    (GICallableInfo*)method_info) == NULL) {
                g_base_info_unref((GIBaseInfo*)method_info);
                goto out;
            }

            objp.set(obj);
        }

        g_base_info_unref((GIBaseInfo*)method_info);
    }

    ret = true;

 out:
    g_free (name);
    return ret;
}
Exemplo n.º 12
0
static void*
union_new(JSContext   *context,
          JSObject    *obj, /* "this" for constructor */
          GIUnionInfo *info)
{
    int n_methods;
    int i;

    /* Find a zero-args constructor and call it */

    n_methods = g_union_info_get_n_methods(info);

    for (i = 0; i < n_methods; ++i) {
        GIFunctionInfo *func_info;
        GIFunctionInfoFlags flags;

        func_info = g_union_info_get_method(info, i);

        flags = g_function_info_get_flags(func_info);
        if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0 &&
            g_callable_info_get_n_args((GICallableInfo*) func_info) == 0) {

            jsval rval;

            rval = JSVAL_NULL;
            gjs_invoke_c_function_uncached(context, func_info, obj,
                                           0, NULL, &rval);

            g_base_info_unref((GIBaseInfo*) func_info);

            /* We are somewhat wasteful here; invoke_c_function() above
             * creates a JSObject wrapper for the union that we immediately
             * discard.
             */
            if (JSVAL_IS_NULL(rval))
                return NULL;
            else
                return gjs_c_union_from_union(context, JSVAL_TO_OBJECT(rval));
        }

        g_base_info_unref((GIBaseInfo*) func_info);
    }

    gjs_throw(context, "Unable to construct union type %s since it has no zero-args <constructor>, can only wrap an existing one",
              g_base_info_get_name((GIBaseInfo*) info));

    return NULL;
}
Exemplo n.º 13
0
static void
boxed_fill_prototype_info(Boxed *priv)
{
    int i, n_methods;
    int first_constructor = -1;

    priv->gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
    priv->zero_args_constructor = -1;
    priv->default_constructor = -1;

    if (priv->gtype != G_TYPE_NONE) {
        /* If the structure is registered as a boxed, we can create a new instance by
         * looking for a zero-args constructor and calling it; constructors don't
         * really make sense for non-boxed types, since there is no memory management
         * for the return value.
         */
        n_methods = g_struct_info_get_n_methods(priv->info);

        for (i = 0; i < n_methods; ++i) {
            GIFunctionInfo *func_info;
            GIFunctionInfoFlags flags;

            func_info = g_struct_info_get_method(priv->info, i);

            flags = g_function_info_get_flags(func_info);
            if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0) {
                if (first_constructor < 0)
                    first_constructor = i;

                if (priv->zero_args_constructor < 0 &&
                    g_callable_info_get_n_args((GICallableInfo*) func_info) == 0)
                    priv->zero_args_constructor = i;

                if (priv->default_constructor < 0 &&
                    strcmp(g_base_info_get_name ((GIBaseInfo*) func_info), "new") == 0)
                    priv->default_constructor = i;
            }

            g_base_info_unref((GIBaseInfo*) func_info);
        }

        if (priv->default_constructor < 0)
            priv->default_constructor = priv->zero_args_constructor;
        if (priv->default_constructor < 0)
            priv->default_constructor = first_constructor;
    }
}
Exemplo n.º 14
0
int
main(int argc, char **argv)
{
  GIRepository *repo;
  GITypelib *ret;
  GIBaseInfo *info;
  GIArgument in_arg[1];
  GIArgument ret_arg;
  GError *error;
  gboolean invoke_return;

  repo = g_irepository_get_default ();

  error = NULL;
  ret = g_irepository_require (repo, "GLib", NULL, 0, &error);
  g_assert (ret != NULL);
  g_assert (error == NULL);

  info = g_irepository_find_by_name (repo, "GLib", "file_read_link");
  g_assert (info != NULL);
  g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
  g_assert (g_function_info_get_flags ((GIFunctionInfo *)info) & GI_FUNCTION_THROWS);

  in_arg[0].v_string = g_strdup ("non-existent-file/hope");
  error = NULL;
  invoke_return = g_function_info_invoke ((GIFunctionInfo *)info,
                                          in_arg,
                                          1,
                                          NULL,
                                          0,
                                          &ret_arg,
                                          &error);
  g_free(in_arg[0].v_string);

  g_assert (invoke_return == FALSE);
  g_assert (error != NULL);
  g_assert (error->domain == G_FILE_ERROR);
  g_assert (error->code == G_FILE_ERROR_NOENT);

  exit(0);
}
Exemplo n.º 15
0
static void
seed_gi_importer_handle_iface(JSContextRef ctx,
                              JSObjectRef namespace_ref,
                              GIObjectInfo* info,
                              JSValueRef* exception)
{
    GType type;

    type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*) info);

    if (type != 0) {
        GIFunctionInfo* finfo;
        GIFunctionInfoFlags flags;
        JSObjectRef constructor_ref;
        guint i, n_methods;

        constructor_ref
          = JSObjectMake(ctx, gobject_constructor_class, (gpointer) type);

        seed_object_set_property(ctx, constructor_ref, "type",
                                 seed_value_from_long(ctx, type, exception));
        n_methods = g_interface_info_get_n_methods(info);
        for (i = 0; i < n_methods; i++) {
            finfo = g_interface_info_get_method(info, i);
            flags = g_function_info_get_flags(finfo);
            if (!(flags & GI_FUNCTION_IS_METHOD)) {
                seed_gobject_define_property_from_function_info(ctx, finfo,
                                                                constructor_ref,
                                                                FALSE);
            } else {
                g_base_info_unref((GIBaseInfo*) finfo);
            }
        }

        seed_object_set_property(ctx, namespace_ref,
                                 g_base_info_get_name((GIBaseInfo*) info),
                                 constructor_ref);
        seed_object_set_property(ctx, constructor_ref, "prototype",
                                 seed_gobject_get_prototype_for_gtype(type));
    }
}
Exemplo n.º 16
0
static void
seed_gi_importer_handle_union(JSContextRef ctx,
                              JSObjectRef namespace_ref,
                              GIUnionInfo* info,
                              JSValueRef* exception)
{
    JSObjectRef union_ref;
    JSObjectRef proto;
    guint i, n_methods;
    GIFunctionInfo* finfo;

    union_ref = JSObjectMake(ctx, seed_struct_constructor_class, info);
    g_base_info_ref(info);

    n_methods = g_union_info_get_n_methods(info);

    for (i = 0; i < n_methods; i++) {
        GIFunctionInfoFlags flags;
        finfo = g_union_info_get_method(info, i);

        flags = g_function_info_get_flags(finfo);

        if (flags & GI_FUNCTION_IS_METHOD)
            g_base_info_unref((GIBaseInfo*) finfo);
        else
            seed_gobject_define_property_from_function_info(ctx, finfo,
                                                            union_ref, FALSE);
    }

    proto = seed_union_prototype(ctx, (GIBaseInfo*) info);
    seed_object_set_property(ctx, union_ref, "prototype", proto);

    seed_object_set_property(ctx, namespace_ref,
                             g_base_info_get_name((GIBaseInfo*) info),
                             union_ref);
}
Exemplo n.º 17
0
/*
 * Like JSResolveOp, but flags provide contextual information as follows:
 *
 *  JSRESOLVE_QUALIFIED   a qualified property id: obj.id or obj[id], not id
 *  JSRESOLVE_ASSIGNING   obj[id] is on the left-hand side of an assignment
 *  JSRESOLVE_DETECTING   'if (o.p)...' or similar detection opcode sequence
 *  JSRESOLVE_DECLARING   var, const, or boxed prolog declaration opcode
 *  JSRESOLVE_CLASSNAME   class name used when constructing
 *
 * The *objp out parameter, on success, should be null to indicate that id
 * was not resolved; and non-null, referring to obj or one of its prototypes,
 * if id was resolved.
 */
static JSBool
union_new_resolve(JSContext *context,
                  JS::HandleObject obj,
                  JS::HandleId id,
                  unsigned flags,
                  JS::MutableHandleObject objp)
{
    Union *priv;
    char *name;
    JSBool ret = JS_TRUE;

    if (!gjs_get_string_id(context, id, &name))
        return JS_TRUE; /* not resolved, but no error */

    priv = priv_from_js(context, obj);
    gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv);

    if (priv == NULL) {
        ret = JS_FALSE; /* wrong class */
        goto out;
    }

    if (priv->gboxed == NULL) {
        /* We are the prototype, so look for methods and other class properties */
        GIFunctionInfo *method_info;

        method_info = g_union_info_find_method((GIUnionInfo*) priv->info,
                                               name);

        if (method_info != NULL) {
            JSObject *union_proto;
            const char *method_name;

#if GJS_VERBOSE_ENABLE_GI_USAGE
            _gjs_log_info_usage((GIBaseInfo*) method_info);
#endif
            if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
                method_name = g_base_info_get_name( (GIBaseInfo*) method_info);

                gjs_debug(GJS_DEBUG_GBOXED,
                          "Defining method %s in prototype for %s.%s",
                          method_name,
                          g_base_info_get_namespace( (GIBaseInfo*) priv->info),
                          g_base_info_get_name( (GIBaseInfo*) priv->info));

                union_proto = obj;

                if (gjs_define_function(context, union_proto,
                                        g_registered_type_info_get_g_type(priv->info),
                                        method_info) == NULL) {
                    g_base_info_unref( (GIBaseInfo*) method_info);
                    ret = JS_FALSE;
                    goto out;
                }

                objp.set(union_proto); /* we defined the prop in object_proto */
            }

            g_base_info_unref( (GIBaseInfo*) method_info);
        }
    } else {
        /* We are an instance, not a prototype, so look for
         * per-instance props that we want to define on the
         * JSObject. Generally we do not want to cache these in JS, we
         * want to always pull them from the C object, or JS would not
         * see any changes made from C. So we use the get/set prop
         * hooks, not this resolve hook.
         */
    }

 out:
    g_free(name);
    return ret;
}
/**
 * g_function_info_prep_invoker:
 * @info: A #GIFunctionInfo
 * @invoker: Output invoker structure
 * @error: A #GError
 *
 * Initialize the caller-allocated @invoker structure with a cache
 * of information needed to invoke the C function corresponding to
 * @info with the platform's default ABI.
 *
 * A primary intent of this function is that a dynamic structure allocated
 * by a language binding could contain a #GIFunctionInvoker structure
 * inside the binding's function mapping.
 *
 * Returns: %TRUE on success, %FALSE otherwise with @error set.
 */
gboolean
g_function_info_prep_invoker (GIFunctionInfo       *info,
                              GIFunctionInvoker    *invoker,
                              GError              **error)
{
  const char *symbol;
  ffi_type *rtype;
  ffi_type **atypes;
  GITypeInfo *tinfo;
  GIArgInfo *ainfo;
  gboolean is_method;
  gboolean throws;
  gint n_args, n_invoke_args, i;

  g_return_val_if_fail (info != NULL, FALSE);
  g_return_val_if_fail (invoker != NULL, FALSE);

  symbol = g_function_info_get_symbol ((GIFunctionInfo*) info);

  if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info),
                         symbol, &(invoker->native_address)))
    {
      g_set_error (error,
                   G_INVOKE_ERROR,
                   G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
                   "Could not locate %s: %s", symbol, g_module_error ());

      return FALSE;
    }

  is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0
    && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0;
  throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS;

  tinfo = g_callable_info_get_return_type ((GICallableInfo *)info);
  rtype = g_type_info_get_ffi_type (tinfo);
  g_base_info_unref ((GIBaseInfo *)tinfo);

  n_args = g_callable_info_get_n_args ((GICallableInfo *)info);
  if (is_method)
    n_invoke_args = n_args+1;
  else
    n_invoke_args = n_args;

  if (throws)
    /* Add an argument for the GError */
    n_invoke_args ++;

  /* TODO: avoid malloc here? */
  atypes = g_malloc0 (sizeof (ffi_type*) * n_invoke_args);

  if (is_method)
    {
      atypes[0] = &ffi_type_pointer;
    }
  for (i = 0; i < n_args; i++)
    {
      int offset = (is_method ? 1 : 0);
      ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i);
      switch (g_arg_info_get_direction (ainfo))
        {
          case GI_DIRECTION_IN:
            tinfo = g_arg_info_get_type (ainfo);
            atypes[i+offset] = g_type_info_get_ffi_type (tinfo);
            g_base_info_unref ((GIBaseInfo *)tinfo);
            break;
          case GI_DIRECTION_OUT:
          case GI_DIRECTION_INOUT:
            atypes[i+offset] = &ffi_type_pointer;
    	    break;
          default:
            g_assert_not_reached ();
        }
      g_base_info_unref ((GIBaseInfo *)ainfo);
    }

  if (throws)
    {
      atypes[n_invoke_args - 1] = &ffi_type_pointer;
    }

  return ffi_prep_cif (&(invoker->cif), FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) == FFI_OK;
}
Exemplo n.º 19
0
/*
 * Like JSResolveOp, but flags provide contextual information as follows:
 *
 *  JSRESOLVE_QUALIFIED   a qualified property id: obj.id or obj[id], not id
 *  JSRESOLVE_ASSIGNING   obj[id] is on the left-hand side of an assignment
 *  JSRESOLVE_DETECTING   'if (o.p)...' or similar detection opcode sequence
 *  JSRESOLVE_DECLARING   var, const, or fundamental prolog declaration opcode
 *  JSRESOLVE_CLASSNAME   class name used when constructing
 *
 * The *objp out parameter, on success, should be null to indicate that id
 * was not resolved; and non-null, referring to obj or one of its prototypes,
 * if id was resolved.
 */
static JSBool
fundamental_instance_new_resolve(JSContext  *context,
                                 JS::HandleObject obj,
                                 JS::HandleId id,
                                 unsigned flags,
                                 JS::MutableHandleObject objp)
{
    FundamentalInstance *priv;
    char *name;
    JSBool ret = JS_FALSE;

    if (!gjs_get_string_id(context, id, &name))
        return JS_TRUE; /* not resolved, but no error */

    priv = priv_from_js(context, obj);
    gjs_debug_jsprop(GJS_DEBUG_GFUNDAMENTAL, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv);

    if (priv == NULL)
        goto out; /* wrong class */

    if (priv->prototype == NULL) {
        /* We are the prototype, so look for methods and other class properties */
        Fundamental *proto_priv = (Fundamental *) priv;
        GIFunctionInfo *method_info;

        method_info = g_object_info_find_method((GIStructInfo*) proto_priv->info,
                                                name);

        if (method_info != NULL) {
            const char *method_name;

#if GJS_VERBOSE_ENABLE_GI_USAGE
            _gjs_log_info_usage((GIBaseInfo *) method_info);
#endif
            if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
                method_name = g_base_info_get_name((GIBaseInfo *) method_info);

                /* we do not define deprecated methods in the prototype */
                if (g_base_info_is_deprecated((GIBaseInfo *) method_info)) {
                    gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
                              "Ignoring definition of deprecated method %s in prototype %s.%s",
                              method_name,
                              g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
                              g_base_info_get_name((GIBaseInfo *) proto_priv->info));
                    g_base_info_unref((GIBaseInfo *) method_info);
                    ret = JS_TRUE;
                    goto out;
                }

                gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
                          "Defining method %s in prototype for %s.%s",
                          method_name,
                          g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
                          g_base_info_get_name((GIBaseInfo *) proto_priv->info));

                if (gjs_define_function(context, obj, proto_priv->gtype,
                                        method_info) == NULL) {
                    g_base_info_unref((GIBaseInfo *) method_info);
                    goto out;
                }

                objp.set(obj);
            }

            g_base_info_unref((GIBaseInfo *) method_info);
        }

        ret = fundamental_instance_new_resolve_interface(context, obj, objp,
                                                         proto_priv, name);
    } else {
        /* We are an instance, not a prototype, so look for
         * per-instance props that we want to define on the
         * JSObject. Generally we do not want to cache these in JS, we
         * want to always pull them from the C object, or JS would not
         * see any changes made from C. So we use the get/set prop
         * hooks, not this resolve hook.
         */
    }

    ret = JS_TRUE;
 out:
    g_free(name);
    return ret;
}
Exemplo n.º 20
0
/*
 * Handle setting up the prototype and constructor for a GObject type
 * Namespace.Type will be the constructor and Namespace.Type.prototype is
 * the prototype object. Namespace.Type.type will be the GType.
 */
static void
seed_gi_importer_handle_object(JSContextRef ctx,
                               JSObjectRef namespace_ref,
                               GIObjectInfo* info,
                               JSValueRef* exception)
{
    GType type;
    JSClassRef class_ref;

    type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*) info);

    if (type != 0) {
        GIFunctionInfo* finfo;
        GIFunctionInfoFlags flags;
        JSObjectRef constructor_ref;
        guint i, n_methods;

        class_ref = seed_gobject_get_class_for_gtype(ctx, type);

        constructor_ref
          = JSObjectMake(ctx, gobject_constructor_class, (gpointer) type);

        seed_object_set_property(ctx, constructor_ref, "type",
                                 seed_value_from_long(ctx, type, exception));
        n_methods = g_object_info_get_n_methods(info);
        for (i = 0; i < n_methods; i++) {
            finfo = g_object_info_get_method(info, i);
            flags = g_function_info_get_flags(finfo);
            if (flags & GI_FUNCTION_IS_CONSTRUCTOR) {
                JSObjectRef constructor
                  = JSObjectMake(ctx, gobject_named_constructor_class, finfo);
                const gchar* fname = g_base_info_get_name((GIBaseInfo*) finfo);
                if (g_strrstr(fname, "new_") == fname) {
                    // To be compatible with gjs, we need to have a method with
                    // new_, too.
                    seed_object_set_property(ctx, constructor_ref, fname,
                                             constructor);
                    fname += 4;
                }

                else if (!g_strcmp0(fname, "new")) {
                    // To be compatible with gjs, we need to have new as
                    // function, too.
                    seed_object_set_property(ctx, constructor_ref, fname,
                                             constructor);
                    fname = "c_new";
                }

                seed_object_set_property(ctx, constructor_ref, fname,
                                         constructor);
            } else if (!(flags & GI_FUNCTION_IS_METHOD)) {
                seed_gobject_define_property_from_function_info(ctx, finfo,
                                                                constructor_ref,
                                                                FALSE);
            } else {
                g_base_info_unref((GIBaseInfo*) finfo);
            }
        }

        seed_object_set_property(ctx, namespace_ref,
                                 g_base_info_get_name((GIBaseInfo*) info),
                                 constructor_ref);
        seed_object_set_property(ctx, constructor_ref, "prototype",
                                 seed_gobject_get_prototype_for_gtype(type));
    }
}