Exemple #1
0
static JSBool
boxed_field_setter (JSContext *context,
                    JSObject  *obj,
                    jsid       id,
                    JSBool     strict,
                    jsval     *value)
{
    Boxed *priv;
    GIFieldInfo *field_info;
    gboolean success = FALSE;

    priv = priv_from_js(context, obj);
    if (!priv)
        return JS_FALSE;

    field_info = get_field_info(context, priv, id);
    if (!field_info)
        return JS_FALSE;

    if (priv->gboxed == NULL) { /* direct access to proto field */
        gjs_throw(context, "Can't set field %s.%s on prototype",
                  g_base_info_get_name ((GIBaseInfo *)priv->info),
                  g_base_info_get_name ((GIBaseInfo *)field_info));
        goto out;
    }

    success = boxed_set_field_from_value (context, priv, field_info, *value);

out:
    g_base_info_unref ((GIBaseInfo *)field_info);

    return success;
}
Exemple #2
0
static GIFieldInfo *
get_field_info (JSContext *context,
                Boxed     *priv,
                jsid       id)
{
    int field_index;
    jsval id_val;

    if (!JS_IdToValue(context, id, &id_val))
        return JS_FALSE;

    if (!JSVAL_IS_INT (id_val)) {
        gjs_throw(context, "Field index for %s is not an integer",
                  g_base_info_get_name ((GIBaseInfo *)priv->info));
        return NULL;
    }

    field_index = JSVAL_TO_INT(id_val);
    if (field_index < 0 || field_index >= g_struct_info_get_n_fields (priv->info)) {
        gjs_throw(context, "Bad field index %d for %s", field_index,
                  g_base_info_get_name ((GIBaseInfo *)priv->info));
        return NULL;
    }

    return g_struct_info_get_field (priv->info, field_index);
}
Exemple #3
0
static GjsForeignInfo *
gjs_struct_foreign_lookup(JSContext  *context,
                          GIBaseInfo *interface_info)
{
    GjsForeignInfo *retval = NULL;
    GHashTable *hash_table;
    char *key;

    key = g_strdup_printf("%s.%s",
                          g_base_info_get_namespace(interface_info),
                          g_base_info_get_name(interface_info));
    hash_table = get_foreign_structs();
    retval = (GjsForeignInfo*)g_hash_table_lookup(hash_table, key);
    if (!retval) {
        if (gjs_foreign_load_foreign_module(context, g_base_info_get_namespace(interface_info))) {
            retval = (GjsForeignInfo*)g_hash_table_lookup(hash_table, key);
        }
    }

    if (!retval) {
        gjs_throw(context, "Unable to find module implementing foreign type %s.%s",
                  g_base_info_get_namespace(interface_info),
                  g_base_info_get_name(interface_info));
    }

    g_free(key);

    return retval;
}
Exemple #4
0
JSObject*
gjs_boxed_from_c_struct(JSContext             *context,
                        GIStructInfo          *info,
                        void                  *gboxed,
                        GjsBoxedCreationFlags  flags)
{
    JSObject *obj;
    JSObject *proto;
    Boxed *priv;
    Boxed *proto_priv;

    if (gboxed == NULL)
        return NULL;

    gjs_debug_marshal(GJS_DEBUG_GBOXED,
                      "Wrapping struct %s %p with JSObject",
                      g_base_info_get_name((GIBaseInfo *)info), gboxed);

    proto = gjs_lookup_boxed_prototype(context, info);
    proto_priv = priv_from_js(context, proto);

    obj = JS_NewObjectWithGivenProto(context,
                                     JS_GET_CLASS(context, proto), proto,
                                     gjs_get_import_global (context));

    GJS_INC_COUNTER(boxed);
    priv = g_slice_new0(Boxed);

    *priv = *proto_priv;
    g_base_info_ref( (GIBaseInfo*) priv->info);

    JS_SetPrivate(context, obj, priv);

    if ((flags & GJS_BOXED_CREATION_NO_COPY) != 0) {
        /* we need to create a JS Boxed which references the
         * original C struct, not a copy of it. Used for
         * G_SIGNAL_TYPE_STATIC_SCOPE
         */
        priv->gboxed = gboxed;
        priv->not_owning_gboxed = TRUE;
    } else {
        if (priv->gtype != G_TYPE_NONE && g_type_is_a (priv->gtype, G_TYPE_BOXED)) {
            priv->gboxed = g_boxed_copy(priv->gtype, gboxed);
        } else if (priv->gtype == G_TYPE_VARIANT) {
            priv->gboxed = g_variant_ref_sink (gboxed);
        } else if (priv->can_allocate_directly) {
            boxed_new_direct(priv);
            memcpy(priv->gboxed, gboxed, g_struct_info_get_size (priv->info));
        } else {
            gjs_throw(context,
                      "Can't create a Javascript object for %s; no way to copy",
                      g_base_info_get_name( (GIBaseInfo*) priv->info));
        }
    }

    return obj;
}
Exemple #5
0
static JSBool
get_nested_interface_object (JSContext   *context,
                             JSObject    *parent_obj,
                             Boxed       *parent_priv,
                             GIFieldInfo *field_info,
                             GITypeInfo  *type_info,
                             GIBaseInfo  *interface_info,
                             jsval       *value)
{
    JSObject *obj;
    JSObject *proto;
    int offset;
    Boxed *priv;
    Boxed *proto_priv;

    if (!struct_is_simple ((GIStructInfo *)interface_info)) {
        gjs_throw(context, "Reading field %s.%s is not supported",
                  g_base_info_get_name ((GIBaseInfo *)parent_priv->info),
                  g_base_info_get_name ((GIBaseInfo *)field_info));

        return JS_FALSE;
    }

    proto = gjs_lookup_boxed_prototype(context, (GIBoxedInfo*) interface_info);
    proto_priv = priv_from_js(context, proto);

    offset = g_field_info_get_offset (field_info);

    obj = JS_NewObjectWithGivenProto(context,
                                     JS_GET_CLASS(context, proto), proto,
                                     gjs_get_import_global (context));

    if (obj == NULL)
        return JS_FALSE;

    GJS_INC_COUNTER(boxed);
    priv = g_slice_new0(Boxed);
    JS_SetPrivate(context, obj, priv);
    priv->info = (GIBoxedInfo*) interface_info;
    g_base_info_ref( (GIBaseInfo*) priv->info);
    priv->gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*) interface_info);
    priv->can_allocate_directly = proto_priv->can_allocate_directly;

    /* A structure nested inside a parent object; doesn't have an independent allocation */
    priv->gboxed = ((char *)parent_priv->gboxed) + offset;
    priv->not_owning_gboxed = TRUE;

    /* We never actually read the reserved slot, but we put the parent object
     * into it to hold onto the parent object.
     */
    JS_SetReservedSlot(context, obj, 0,
                       OBJECT_TO_JSVAL (parent_obj));

    *value = OBJECT_TO_JSVAL(obj);
    return JS_TRUE;
}
Exemple #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);
}
Exemple #7
0
static JSBool
error_to_string(JSContext *context, uintN argc, jsval *vp)
{
    jsval v_self;
    JSObject *self;
    Error *priv;
    jsval v_out;
    gchar *descr;
    JSBool retval;

    v_self = JS_THIS(context, vp);
    if (!JSVAL_IS_OBJECT(v_self)) {
        /* Lie a bit here... */
        gjs_throw(context, "GLib.Error.prototype.toString() called on a non object");
        return JS_FALSE;
    }

    self = JSVAL_TO_OBJECT(v_self);
    priv = priv_from_js(context, self);

    if (priv == NULL)
        return JS_FALSE;

    v_out = JSVAL_VOID;
    retval = JS_FALSE;

    /* We follow the same pattern as standard JS errors, at the expense of
       hiding some useful information */

    if (priv->gerror == NULL) {
        descr = g_strdup_printf("%s.%s",
                                g_base_info_get_namespace(priv->info),
                                g_base_info_get_name(priv->info));

        if (!gjs_string_from_utf8(context, descr, -1, &v_out))
            goto out;
    } else {
        descr = g_strdup_printf("%s.%s: %s",
                                g_base_info_get_namespace(priv->info),
                                g_base_info_get_name(priv->info),
                                priv->gerror->message);

        if (!gjs_string_from_utf8(context, descr, -1, &v_out))
            goto out;
    }

    JS_SET_RVAL(context, vp, v_out);
    retval = JS_TRUE;

 out:
    g_free(descr);
    return retval;
}
Exemple #8
0
static JSBool
define_boxed_class_fields (JSContext *context,
                           Boxed     *priv,
                           JSObject  *proto)
{
    int n_fields = g_struct_info_get_n_fields (priv->info);
    int i;

    /* We identify properties with a 'TinyId': a 8-bit numeric value
     * that can be retrieved in the property getter/setter. Using it
     * allows us to avoid a hash-table lookup or linear search.
     * It does restrict us to a maximum of 256 fields per type.
     *
     * We define all fields as read/write so that the user gets an
     * error message. If we omitted fields or defined them read-only
     * we'd:
     *
     *  - Storing a new property for a non-accessible field
     *  - Silently do nothing when writing a read-only field
     *
     * Which is pretty confusing if the only reason a field isn't
     * writable is language binding or memory-management restrictions.
     *
     * We just go ahead and define the fields immediately for the
     * class; doing it lazily in boxed_new_resolve() would be possible
     * as well if doing it ahead of time caused to much start-up
     * memory overhead.
     */
    if (n_fields > 256) {
        gjs_debug(GJS_DEBUG_ERROR,
                  "Only defining the first 256 fields in boxed type '%s'",
                  g_base_info_get_name ((GIBaseInfo *)priv->info));
        n_fields = 256;
    }

    for (i = 0; i < n_fields; i++) {
        GIFieldInfo *field = g_struct_info_get_field (priv->info, i);
        const char *field_name = g_base_info_get_name ((GIBaseInfo *)field);
        gboolean result;

        result = JS_DefinePropertyWithTinyId(context, proto, field_name, i,
                                             JSVAL_NULL,
                                             boxed_field_getter, boxed_field_setter,
                                             JSPROP_PERMANENT | JSPROP_SHARED);

        g_base_info_unref ((GIBaseInfo *)field);

        if (!result)
            return JS_FALSE;
    }

    return JS_TRUE;
}
static void
in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args)
{
    gpointer callback;
    GIArgInfo *arg_info;
    GIArgument *callback_argument;

    arg_info = &(metadata->arg_info);
    callback = find_callback_function(arg_info);
    if (!callback) {
        GITypeInfo type_info;
        GIBaseInfo *interface_info;
        VALUE rb_type_name;
        g_arg_info_load_type(arg_info, &type_info);
        interface_info = g_type_info_get_interface(&type_info);
        rb_type_name = CSTR2RVAL(g_base_info_get_name(interface_info));
        g_base_info_unref(interface_info);
        rb_raise(rb_eNotImpError,
                 "TODO: <%s>(%s) callback is not supported yet.",
                 RVAL2CSTR(rb_type_name),
                 g_base_info_get_name(arg_info));
    }

    callback_argument = &(g_array_index(in_args,
                                        GIArgument,
                                        metadata->in_arg_index));
    callback_argument->v_pointer = callback;

    if (metadata->closure_in_arg_index != -1) {
        RBGICallbackData *callback_data;
        GIArgument *closure_argument;

        callback_data = ALLOC(RBGICallbackData);
        callback_data->metadata = metadata;
        callback_data->rb_callback = rb_block_proc();
        callback_data_guard_from_gc(callback_data);
        closure_argument = &(g_array_index(in_args,
                                           GIArgument,
                                           metadata->closure_in_arg_index));
        closure_argument->v_pointer = callback_data;
    }

    if (metadata->destroy_in_arg_index != -1) {
        GIArgument *destroy_argument;
        destroy_argument = &(g_array_index(in_args,
                                           GIArgument,
                                           metadata->destroy_in_arg_index));
        destroy_argument->v_pointer = destroy_notify;
    }
}
Exemple #10
0
JSBool
gjs_typecheck_fundamental(JSContext *context,
                          JSObject  *object,
                          GType      expected_gtype,
                          JSBool     throw_error)
{
    FundamentalInstance *priv;
    JSBool result;

    if (!do_base_typecheck(context, object, throw_error))
        return JS_FALSE;

    priv = priv_from_js(context, object);
    g_assert(priv != NULL);

    if (priv->gfundamental == NULL) {
        if (throw_error) {
            Fundamental *proto_priv = (Fundamental *) priv;
            gjs_throw(context,
                      "Object is %s.%s.prototype, not an fundamental instance - cannot convert to void*",
                      proto_priv->info ? g_base_info_get_namespace((GIBaseInfo *) proto_priv->info) : "",
                      proto_priv->info ? g_base_info_get_name((GIBaseInfo *) proto_priv->info) : g_type_name(proto_priv->gtype));
        }

        return JS_FALSE;
    }

    if (expected_gtype != G_TYPE_NONE)
        result = g_type_is_a(priv->prototype->gtype, expected_gtype);
    else
        result = JS_TRUE;

    if (!result && throw_error) {
        if (priv->prototype->info) {
            gjs_throw_custom(context, "TypeError",
                             "Object is of type %s.%s - cannot convert to %s",
                             g_base_info_get_namespace((GIBaseInfo *) priv->prototype->info),
                             g_base_info_get_name((GIBaseInfo *) priv->prototype->info),
                             g_type_name(expected_gtype));
        } else {
            gjs_throw_custom(context, "TypeError",
                             "Object is of type %s - cannot convert to %s",
                             g_type_name(priv->prototype->gtype),
                             g_type_name(expected_gtype));
        }
    }

    return result;
}
Exemple #11
0
GError*
gjs_gerror_from_error(JSContext    *context,
                      JSObject     *obj)
{
    Error *priv;

    if (obj == NULL)
        return NULL;

    /* If this is a plain GBoxed (i.e. a GError without metadata),
       delegate marshalling.
    */
    if (gjs_typecheck_boxed (context, obj, NULL, G_TYPE_ERROR, JS_FALSE))
        return gjs_c_struct_from_boxed (context, obj);

    priv = priv_from_js(context, obj);

    if (priv == NULL)
        return NULL;

    if (priv->gerror == NULL) {
        gjs_throw(context,
                  "Object is %s.%s.prototype, not an object instance - cannot convert to a boxed instance",
                  g_base_info_get_namespace( (GIBaseInfo*) priv->info),
                  g_base_info_get_name( (GIBaseInfo*) priv->info));
        return NULL;
    }

    return priv->gerror;
}
Exemple #12
0
int
lgi_type_get_name (lua_State *L, GIBaseInfo *info)
{
  GSList *list = NULL, *i;
  int n = 1;
  lua_pushstring (L, g_base_info_get_namespace (info));

  if (g_base_info_get_type (info) == GI_INFO_TYPE_CALLBACK)
    /* Avoid duplicate name for callbacks. */
    info = g_base_info_get_container (info);

  /* Add names on the whole path, but in reverse order. */
  for (; info != NULL; info = g_base_info_get_container (info))
    if (!GI_IS_TYPE_INFO (info))
      list = g_slist_prepend (list, info);

  for (i = list; i != NULL; i = g_slist_next (i))
    {
      if (g_base_info_get_type (i->data) != GI_INFO_TYPE_TYPE)
	{
	  lua_pushstring (L, ".");
	  lua_pushstring (L, g_base_info_get_name (i->data));
	  n += 2;
	}
    }

  g_slist_free (list);
  return n;
}
Exemple #13
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;
}
static void
fill_metadata_inout_argv(GPtrArray *args_metadata)
{
    guint i;
    gint inout_argc_arg_index = -1;

    for (i = 0; i < args_metadata->len; i++) {
        RBGIArgMetadata *metadata;
        GIArgInfo *arg_info;
        const gchar *name;

        metadata = g_ptr_array_index(args_metadata, i);
        if (metadata->direction != GI_DIRECTION_INOUT) {
            continue;
        }
        arg_info = &(metadata->arg_info);
        name = g_base_info_get_name(arg_info);
        if (strcmp(name, "argc") == 0) {
            inout_argc_arg_index = i;
        } else if (strcmp(name, "argv") == 0) {
            metadata->inout_argv_p = TRUE;
            metadata->inout_argc_arg_index = inout_argc_arg_index;
        }
    }
}
Exemple #15
0
void*
gjs_g_fundamental_from_object(JSContext *context,
                              JSObject  *obj)
{
    FundamentalInstance *priv;

    if (obj == NULL)
        return NULL;

    priv = priv_from_js(context, obj);

    if (priv == NULL) {
        gjs_throw(context,
                  "No introspection information for %p", obj);
        return NULL;
    }

    if (priv->gfundamental == NULL) {
        gjs_throw(context,
                  "Object is %s.%s.prototype, not an object instance - cannot convert to a fundamental instance",
                  g_base_info_get_namespace((GIBaseInfo *) priv->prototype->info),
                  g_base_info_get_name((GIBaseInfo *) priv->prototype->info));
        return NULL;
    }

    return priv->gfundamental;
}
static void
store_objects_with_vfuncs (AV *objects_with_vfuncs, GIObjectInfo *info)
{
	if (g_object_info_get_n_vfuncs (info) <= 0)
		return;
	av_push (objects_with_vfuncs,
	         newSVpv (g_base_info_get_name (info), 0));
}
static PyObject *
_base_info_repr (PyGIBaseInfo *self)
{
    return PYGLIB_PyUnicode_FromFormat ("<%s object (%s) at 0x%p>",
                                        Py_TYPE( (PyObject *) self)->tp_name, 
                                        g_base_info_get_name (self->info), 
                                        (void *) self);
}
Exemple #18
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;
}
static gpointer
sv_to_callback (GIArgInfo * arg_info,
                GITypeInfo * type_info,
                SV * sv,
                GPerlI11nInvocationInfo * invocation_info)
{
	GIBaseInfo *callback_interface_info;
	GPerlI11nPerlCallbackInfo *callback_info;
	GIScopeType scope;

	/* the destroy notify func is handled by _handle_automatic_arg */

	dwarn ("      Perl callback at %d (%s)\n",
	       invocation_info->current_pos,
	       g_base_info_get_name (arg_info));

	callback_interface_info = g_type_info_get_interface (type_info);
	callback_info = create_perl_callback_closure (callback_interface_info, sv);
	callback_info->data_pos = g_arg_info_get_closure (arg_info);
	callback_info->destroy_pos = g_arg_info_get_destroy (arg_info);
	callback_info->free_after_use = FALSE;
	g_base_info_unref (callback_interface_info);

	dwarn ("      Perl callback data at %d, destroy at %d\n",
	       callback_info->data_pos, callback_info->destroy_pos);

	scope = (!gperl_sv_is_defined (sv))
		? GI_SCOPE_TYPE_CALL
		: g_arg_info_get_scope (arg_info);
	switch (scope) {
	    case GI_SCOPE_TYPE_CALL:
		dwarn ("      Perl callback has scope 'call'\n");
		free_after_call (invocation_info,
		                 (GFunc) release_perl_callback, callback_info);
		break;
	    case GI_SCOPE_TYPE_NOTIFIED:
		dwarn ("      Perl callback has scope 'notified'\n");
		/* This case is already taken care of by the notify
		 * stuff above */
		break;
	    case GI_SCOPE_TYPE_ASYNC:
		dwarn ("      Perl callback has scope 'async'\n");
		/* FIXME: callback_info->free_after_use = TRUE; */
		break;
	    default:
		ccroak ("unhandled scope type %d encountered",
		       g_arg_info_get_scope (arg_info));
	}

	invocation_info->callback_infos =
		g_slist_prepend (invocation_info->callback_infos,
		                 callback_info);

	dwarn ("      returning Perl closure %p from info %p\n",
	       callback_info->closure, callback_info);
	return callback_info->closure;
}
Exemple #20
0
void
gjs_define_error_class(JSContext    *context,
                       JSObject     *in_object,
                       GIEnumInfo   *info)
{
    const char *constructor_name;
    GIBoxedInfo *glib_error_info;
    JSObject *prototype, *parent_proto;
    JSObject *constructor;
    Error *priv;

    /* See the comment in gjs_define_boxed_class() for an
     * explanation of how this all works; Error is pretty much the
     * same as Boxed (except that we inherit from GLib.Error).
     */

    constructor_name = g_base_info_get_name( (GIBaseInfo*) info);

    g_irepository_require(NULL, "GLib", "2.0", (GIRepositoryLoadFlags) 0, NULL);
    glib_error_info = (GIBoxedInfo*) g_irepository_find_by_name(NULL, "GLib", "Error");
    parent_proto = gjs_lookup_generic_prototype(context, glib_error_info);
    g_base_info_unref((GIBaseInfo*)glib_error_info);

    if (!gjs_init_class_dynamic(context, in_object,
                                parent_proto,
                                g_base_info_get_namespace( (GIBaseInfo*) info),
                                constructor_name,
                                &gjs_error_class,
                                gjs_error_constructor, 1,
                                /* props of prototype */
                                &gjs_error_proto_props[0],
                                /* funcs of prototype */
                                &gjs_error_proto_funcs[0],
                                /* props of constructor, MyConstructor.myprop */
                                NULL,
                                /* funcs of constructor, MyConstructor.myfunc() */
                                &gjs_error_constructor_funcs[0],
                                &prototype,
                                &constructor)) {
        gjs_log_exception(context);
        g_error("Can't init class %s", constructor_name);
    }

    GJS_INC_COUNTER(gerror);
    priv = g_slice_new0(Error);
    priv->info = info;
    g_base_info_ref( (GIBaseInfo*) priv->info);
    priv->domain = g_quark_from_string (g_enum_info_get_error_domain(priv->info));

    JS_SetPrivate(prototype, priv);

    gjs_debug(GJS_DEBUG_GBOXED, "Defined class %s prototype is %p class %p in object %p",
              constructor_name, prototype, JS_GetClass(prototype), in_object);

    gjs_define_enum_values(context, constructor, priv->info);
    gjs_define_enum_static_methods(context, constructor, priv->info);
}
Exemple #21
0
static JSBool
set_nested_interface_object (JSContext   *context,
                             Boxed       *parent_priv,
                             GIFieldInfo *field_info,
                             GITypeInfo  *type_info,
                             GIBaseInfo  *interface_info,
                             jsval        value)
{
    JSObject *proto;
    int offset;
    Boxed *proto_priv;
    Boxed *source_priv;

    if (!struct_is_simple ((GIStructInfo *)interface_info)) {
        gjs_throw(context, "Writing field %s.%s is not supported",
                  g_base_info_get_name ((GIBaseInfo *)parent_priv->info),
                  g_base_info_get_name ((GIBaseInfo *)field_info));

        return JS_FALSE;
    }

    proto = gjs_lookup_boxed_prototype(context, (GIBoxedInfo*) interface_info);
    proto_priv = priv_from_js(context, proto);

    /* If we can't directly copy from the source object we need
     * to construct a new temporary object.
     */
    if (!boxed_get_copy_source(context, proto_priv, value, &source_priv)) {
        JSObject *tmp_object = gjs_construct_object_dynamic(context, proto, 1, &value);
        if (!tmp_object)
            return JS_FALSE;

        source_priv = priv_from_js(context, tmp_object);
        if (!source_priv)
            return JS_FALSE;
    }

    offset = g_field_info_get_offset (field_info);
    memcpy(((char *)parent_priv->gboxed) + offset,
           source_priv->gboxed,
           g_struct_info_get_size (source_priv->info));

    return JS_TRUE;
}
Exemple #22
0
void
lgi_type_get_repotype (lua_State *L, GType gtype, GIBaseInfo *info)
{
  luaL_checkstack (L, 4, "");

  /* Get repo-index table. */
  lua_pushlightuserdata (L, &repo_index);
  lua_rawget (L, LUA_REGISTRYINDEX);

  /* Prepare gtype, if not given directly. */
  if (gtype == G_TYPE_INVALID && info && GI_IS_REGISTERED_TYPE_INFO (info))
    {
      gtype = g_registered_type_info_get_g_type (info);
      if (gtype == G_TYPE_NONE)
	gtype = G_TYPE_INVALID;
    }

  /* First of all, check direct indexing of repo-index by gtype,
     should be fastest. */
  if (gtype != G_TYPE_INVALID)
    {
      lua_pushlightuserdata (L, (gpointer) gtype);
      lua_rawget (L, -2);
    }
  else
    lua_pushnil (L);

  if (lua_isnil (L, -1))
    {
      /* Not indexed yet.  Try to lookup by name - this works when
	 lazy-loaded repo tables are not loaded yet. */
      if (!info && gtype != G_TYPE_INVALID)
	{
	  info = g_irepository_find_by_gtype (NULL, gtype);
	  lgi_gi_info_new (L, info);
	}
      else
	/* Keep stack balanced as in the previous 'if' branch. */
	lua_pushnil (L);

      if (info)
	{
	  lua_pushlightuserdata (L, &repo);
	  lua_rawget (L, LUA_REGISTRYINDEX);
	  lua_getfield (L, -1, g_base_info_get_namespace (info));
	  lua_getfield (L, -1, g_base_info_get_name (info));
	  lua_replace (L, -5);
	  lua_pop (L, 3);
	}
      else
	lua_pop (L, 1);
    }
  lua_replace (L, -2);
}
Exemple #23
0
static gboolean
seed_gi_importer_is_init(GIFunctionInfo* info)
{
    if (g_strcmp0(g_base_info_get_name((GIBaseInfo*) info), "init")) {
        return FALSE;
    }
    if (g_callable_info_get_n_args((GICallableInfo*) info) != 2)
        return FALSE;

    return TRUE;
}
Exemple #24
0
static gchar *
get_struct_package (GIBaseInfo* info)
{
	const gchar *basename, *package, *name;
	basename = g_base_info_get_namespace (info);
	package = get_package_for_basename (basename);
	if (!package)
		return NULL;
	name = g_base_info_get_name (info);
	return g_strconcat (package, "::", name, NULL);
}
Exemple #25
0
static void
seed_gi_importer_handle_callback(JSContextRef ctx,
                                 JSObjectRef namespace_ref,
                                 GICallbackInfo* info,
                                 JSValueRef* exception)
{
    JSObjectRef callback_ref = JSObjectMake(ctx, seed_callback_class, info);
    seed_object_set_property(ctx, namespace_ref,
                             g_base_info_get_name((GIBaseInfo*) info),
                             (JSValueRef) callback_ref);
}
Exemple #26
0
/*
 * Handle definition of enums in a namespace.
 * Each enum class gets an object containing
 * a value for each member, all in uppercase
 * i.e. Gtk.WindowType.NORMAL
 */
static void
seed_gi_importer_handle_enum(JSContextRef ctx,
                             JSObjectRef namespace_ref,
                             GIEnumInfo* info,
                             JSValueRef* exception)
{
    JSObjectRef enum_class;
    guint num_vals, i, j;
    gsize name_len;
    gint value; // TODO: investigate what's up with the glong/gint mystery here
    gchar* name;
    GIValueInfo* val;

    enum_class = JSObjectMake(ctx, 0, 0);
    num_vals = g_enum_info_get_n_values(info);
    seed_object_set_property(ctx, namespace_ref,
                             g_base_info_get_name((GIBaseInfo*) info),
                             enum_class);

    for (i = 0; i < num_vals; i++) {
        val = g_enum_info_get_value((GIEnumInfo*) info, i);
        value = g_value_info_get_value(val);
        name = g_strdup(g_base_info_get_name((GIBaseInfo*) val));
        name_len = strlen(name);
        JSValueRef value_ref;

        value_ref = JSValueMakeNumber(ctx, value);
        JSValueProtect(ctx, (JSValueRef) value_ref);

        for (j = 0; j < name_len; j++) {
            if (name[j] == '-')
                name[j] = '_';
            name[j] = g_ascii_toupper(name[j]);
        }

        seed_object_set_property(ctx, enum_class, name, value_ref);

        g_free(name);
        g_base_info_unref((GIBaseInfo*) val);
    }
}
Exemple #27
0
static void
boxed_new_direct(Boxed       *priv)
{
    g_assert(priv->can_allocate_directly);

    priv->gboxed = g_slice_alloc0(g_struct_info_get_size (priv->info));
    priv->allocated_directly = TRUE;

    gjs_debug_lifecycle(GJS_DEBUG_GBOXED,
                        "JSObject created by directly allocating %s",
                        g_base_info_get_name ((GIBaseInfo *)priv->info));
}
Exemple #28
0
JSObject*
gjs_error_from_gerror(JSContext             *context,
                      GError                *gerror,
                      gboolean               add_stack)
{
    JSObject *obj;
    JSObject *proto;
    Error *priv;
    Error *proto_priv;
    GIEnumInfo *info;

    if (gerror == NULL)
        return NULL;

    info = find_error_domain_info(gerror->domain);

    if (!info) {
        /* We don't have error domain metadata */
        /* Marshal the error as a plain GError */
        GIBaseInfo *glib_boxed;
        JSObject *retval;

        glib_boxed = g_irepository_find_by_name(NULL, "GLib", "Error");
        retval = gjs_boxed_from_c_struct(context, glib_boxed, gerror, 0);

        g_base_info_unref(glib_boxed);
        return retval;
    }

    gjs_debug_marshal(GJS_DEBUG_GBOXED,
                      "Wrapping struct %s %p with JSObject",
                      g_base_info_get_name((GIBaseInfo *)info), gboxed);

    proto = gjs_lookup_error_prototype(context, info);
    proto_priv = priv_from_js(context, proto);

    obj = JS_NewObjectWithGivenProto(context,
                                     JS_GET_CLASS(context, proto), proto,
                                     gjs_get_import_global (context));

    GJS_INC_COUNTER(gerror);
    priv = g_slice_new0(Error);
    JS_SetPrivate(context, obj, priv);
    priv->info = info;
    priv->domain = proto_priv->domain;
    g_base_info_ref( (GIBaseInfo*) priv->info);
    priv->gerror = g_error_copy(gerror);

    if (add_stack)
        define_error_properties(context, obj);

    return obj;
}
static void
prepare_invocation_info (GPerlI11nInvocationInfo *iinfo,
                         GICallableInfo *info)
{
	gint orig_n_args;
	guint i;

	dwarn ("invoke: %s\n"
	       "  n_args: %d\n",
	       g_base_info_get_name (info),
	       g_callable_info_get_n_args (info));

	iinfo->interface = info;

	iinfo->is_function = GI_IS_FUNCTION_INFO (info);
	iinfo->is_vfunc = GI_IS_VFUNC_INFO (info);
	iinfo->is_callback = (g_base_info_get_type (info) == GI_INFO_TYPE_CALLBACK);
	iinfo->is_signal = GI_IS_SIGNAL_INFO (info);
	dwarn ("  is_function = %d, is_vfunc = %d, is_callback = %d\n",
	       iinfo->is_function, iinfo->is_vfunc, iinfo->is_callback);

	orig_n_args = g_callable_info_get_n_args (info);
	g_assert (orig_n_args >= 0);
	iinfo->n_args = (guint) orig_n_args;

	if (iinfo->n_args) {
		iinfo->arg_infos = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args);
		iinfo->arg_types = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args);
		iinfo->aux_args = gperl_alloc_temp (sizeof (GIArgument) * iinfo->n_args);
	} else {
		iinfo->arg_infos = NULL;
		iinfo->arg_types = NULL;
		iinfo->aux_args = NULL;
	}

	for (i = 0 ; i < iinfo->n_args ; i++) {
		iinfo->arg_infos[i] = g_callable_info_get_arg (info, (gint) i);
		iinfo->arg_types[i] = g_arg_info_get_type (iinfo->arg_infos[i]);
	}

	iinfo->return_type_info = g_callable_info_get_return_type (info);
	iinfo->has_return_value =
		GI_TYPE_TAG_VOID != g_type_info_get_tag (iinfo->return_type_info);
	iinfo->return_type_ffi = g_type_info_get_ffi_type (iinfo->return_type_info);
	iinfo->return_type_transfer = g_callable_info_get_caller_owns (info);

	iinfo->callback_infos = NULL;
	iinfo->array_infos = NULL;

	iinfo->free_after_call = NULL;
}
Exemple #30
0
static JSBool
fundamental_invoke_constructor(FundamentalInstance *priv,
                               JSContext           *context,
                               JSObject            *obj,
                               unsigned             argc,
                               jsval               *argv,
                               GArgument           *rvalue)
{
    jsval js_constructor, js_constructor_func;
    jsid constructor_const;
    JSBool ret = JS_FALSE;

    constructor_const = gjs_context_get_const_string(context, GJS_STRING_CONSTRUCTOR);
    if (!gjs_object_require_property(context, obj, NULL,
                                     constructor_const, &js_constructor) ||
        priv->prototype->constructor_name == JSID_VOID) {
        gjs_throw (context,
                   "Couldn't find a constructor for type %s.%s",
                   g_base_info_get_namespace((GIBaseInfo*) priv->prototype->info),
                   g_base_info_get_name((GIBaseInfo*) priv->prototype->info));
        goto end;
    }

    if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(js_constructor), NULL,
                                     priv->prototype->constructor_name, &js_constructor_func)) {
        gjs_throw (context,
                   "Couldn't find a constructor for type %s.%s",
                   g_base_info_get_namespace((GIBaseInfo*) priv->prototype->info),
                   g_base_info_get_name((GIBaseInfo*) priv->prototype->info));
        goto end;
    }

    ret = gjs_invoke_constructor_from_c(context, JSVAL_TO_OBJECT(js_constructor_func), obj, argc, argv, rvalue);

 end:
    return ret;
}