コード例 #1
0
ファイル: boxed.c プロジェクト: Katyunechka/gjs
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;
}
コード例 #2
0
ファイル: boxed.c プロジェクト: Katyunechka/gjs
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;
}
コード例 #3
0
ファイル: boxed.c プロジェクト: Katyunechka/gjs
JSClass*
gjs_lookup_boxed_class(JSContext    *context,
                          GIBoxedInfo  *info)
{
    JSObject *prototype;

    prototype = gjs_lookup_boxed_prototype(context, info);

    return JS_GET_CLASS(context, prototype);
}
コード例 #4
0
ファイル: boxed.c プロジェクト: Katyunechka/gjs
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;
}
コード例 #5
0
ファイル: gerror.c プロジェクト: Cobinja/cjs
JSBool
gjs_define_error_class(JSContext    *context,
                       JSObject     *in_object,
                       GIEnumInfo   *info,
                       JSObject    **constructor_p,
                       JSObject    **prototype_p)
{
    const char *constructor_name;
    GIBoxedInfo *glib_error_info;
    JSObject *prototype, *parent_proto;
    JSObject *constructor;
    jsval value;
    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);

    if (gjs_object_get_property(context, in_object, constructor_name, &value)) {
        JSObject *constructor;

        if (!JSVAL_IS_OBJECT(value)) {
            gjs_throw(context, "Existing property '%s' does not look like a constructor",
                         constructor_name);
            return JS_FALSE;
        }

        constructor = JSVAL_TO_OBJECT(value);

        gjs_object_get_property(context, constructor, "prototype", &value);
        if (!JSVAL_IS_OBJECT(value)) {
            gjs_throw(context, "error %s prototype property does not appear to exist or has wrong type", constructor_name);
            return JS_FALSE;
        } else {
            if (prototype_p)
                *prototype_p = JSVAL_TO_OBJECT(value);
            if (constructor_p)
                *constructor_p = constructor;

            return JS_TRUE;
        }
    }

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

    prototype = gjs_init_class_dynamic(context, in_object,
                                          parent_proto,
                                          g_base_info_get_namespace( (GIBaseInfo*) info),
                                          constructor_name,
                                          &gjs_error_class,
                                          gjs_error_constructor,
                                          /* number of constructor args (less can be passed) */
                                          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]);
    if (prototype == NULL) {
        gjs_log_exception(context, NULL);
        gjs_fatal("Can't init class %s", constructor_name);
    }

    g_assert(gjs_object_has_property(context, in_object, 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(context, prototype, priv);

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

    constructor = NULL;
    gjs_object_get_property(context, in_object, constructor_name, &value);
    if (!JSVAL_IS_VOID(value)) {
        if (!JSVAL_IS_OBJECT(value)) {
            gjs_throw(context, "Property '%s' does not look like a constructor",
                      constructor_name);
            return JS_FALSE;
        }
    }

    constructor = JSVAL_TO_OBJECT(value);

    gjs_define_enum_values(context, constructor, priv->info);

    if (constructor_p)
        *constructor_p = constructor;

    if (prototype_p)
        *prototype_p = prototype;

    return JS_TRUE;
}