コード例 #1
0
ファイル: boxed.c プロジェクト: Katyunechka/gjs
static void
boxed_finalize(JSContext *context,
               JSObject  *obj)
{
    Boxed *priv;

    priv = priv_from_js(context, obj);
    gjs_debug_lifecycle(GJS_DEBUG_GBOXED,
                        "finalize, obj %p priv %p", obj, priv);
    if (priv == NULL)
        return; /* wrong class? */

    if (priv->gboxed && !priv->not_owning_gboxed) {
        if (priv->allocated_directly) {
            g_slice_free1(g_struct_info_get_size (priv->info), priv->gboxed);
        } else {
            if (g_type_is_a (priv->gtype, G_TYPE_BOXED))
                g_boxed_free (priv->gtype,  priv->gboxed);
            else if (g_type_is_a (priv->gtype, G_TYPE_VARIANT))
                g_variant_unref (priv->gboxed);
            else
                g_assert_not_reached ();
        }

        priv->gboxed = NULL;
    }

    if (priv->info) {
        g_base_info_unref( (GIBaseInfo*) priv->info);
        priv->info = NULL;
    }

    GJS_DEC_COUNTER(boxed);
    g_slice_free(Boxed, priv);
}
コード例 #2
0
ファイル: keep-alive.c プロジェクト: KNOPOChKA2/gjs
static void
keep_alive_finalize(JSContext *context,
                    JSObject  *obj)
{
    KeepAlive *priv;
    void *key;
    void *value;

    priv = priv_from_js(context, obj);

    gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE,
                        "keep_alive finalizing, obj %p priv %p", obj, priv);

    if (priv == NULL)
        return; /* we are the prototype, not a real instance, so constructor never called */

    priv->inside_finalize = TRUE;

    while (gjs_g_hash_table_steal_one(priv->children,
                                      &key, &value)) {
        Child *child = value;
        if (child->notify)
            (* child->notify) (child->child, child->data);

        child_free(child);
    }

    g_hash_table_destroy(priv->children);
    g_slice_free(KeepAlive, priv);
}
コード例 #3
0
ファイル: keep-alive.cpp プロジェクト: GNOME/gjs
static void
keep_alive_finalize(JSFreeOp *fop,
                    JSObject *obj)
{
    KeepAlive *priv;
    void *key;
    void *value;

    priv = (KeepAlive *) JS_GetPrivate(obj);

    gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE,
                        "keep_alive finalizing, obj %p priv %p", obj, priv);

    if (priv == NULL)
        return; /* we are the prototype, not a real instance */

    priv->inside_finalize = true;

    while (gjs_g_hash_table_steal_one(priv->children,
                                      &key, &value)) {
        Child *child = (Child *) value;
        if (child->notify)
            (* child->notify) (child->child, child->data);

        child_free(child);
    }

    g_hash_table_destroy(priv->children);
    g_slice_free(KeepAlive, priv);
}
コード例 #4
0
ファイル: fundamental.cpp プロジェクト: victoryang/gjs
static FundamentalInstance *
init_fundamental_instance(JSContext *context,
                          JSObject  *object)
{
    Fundamental *proto_priv;
    FundamentalInstance *priv;

    JS_BeginRequest(context);

    priv = g_slice_new0(FundamentalInstance);

    GJS_INC_COUNTER(fundamental);

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

    gjs_debug_lifecycle(GJS_DEBUG_GFUNDAMENTAL,
                        "fundamental instance constructor, obj %p priv %p proto %p ",
                        object, priv, JS_GetPrototype (object));

    proto_priv = proto_priv_from_js(context, object);
    g_assert(proto_priv != NULL);

    priv->prototype = proto_priv;

    JS_EndRequest(context);

    return priv;
}
コード例 #5
0
ファイル: jsapi-util.c プロジェクト: sjokkis/gjs
JSObject*
gjs_construct_object_dynamic(JSContext      *context,
                             JSObject       *proto,
                             uintN           argc,
                             jsval          *argv)
{
    RuntimeData *rd;
    JSClass *proto_class;
    JSContext *load_context;
    JSObject *result;

    JS_BeginRequest(context);

    /* We replace the passed-in context and global object with our
     * runtime-global permanent load context. Otherwise, JS_ConstructObject
     * can't find the constructor in whatever random global object is set
     * on the passed-in context.
     */
    load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
    JS_BeginRequest(load_context);

    proto_class = JS_GET_CLASS(load_context, proto);

    rd = get_data_from_context(load_context);

    /* Check that it's safe to cast to DynamicJSClass */
    if (g_hash_table_lookup(rd->dynamic_classes, proto_class) == NULL) {
        gjs_throw(load_context, "Prototype is not for a dynamically-registered class");
        goto error;
    }

    gjs_debug_lifecycle(GJS_DEBUG_GREPO,
                        "Constructing instance of dynamic class %s %p from proto %p",
                        proto_class->name, proto_class, proto);

    if (argc > 0)
        result = JS_ConstructObjectWithArguments(load_context, proto_class, proto, NULL, argc, argv);
    else
        result = JS_ConstructObject(load_context, proto_class, proto, NULL);

    if (!result)
        goto error;

    JS_EndRequest(load_context);
    JS_EndRequest(context);
    return result;

 error:
    /* Move the exception to the calling context from load context.
     */
    if (!gjs_move_exception(load_context, context)) {
        /* set an exception since none was set */
        gjs_throw(context, "No exception was set, but object construction failed somehow");
    }

    JS_EndRequest(load_context);
    JS_EndRequest(context);
    return NULL;
}
コード例 #6
0
ファイル: importer.c プロジェクト: darkxst/gjs-js188
static JSObject*
importer_new(JSContext    *context)
{
    JSObject *importer;
    Importer *priv;
    JSObject *global;
    (void) priv;

    global = gjs_get_import_global(context);

    if (!gjs_object_has_property(context, global, gjs_importer_class.name)) {
        JSObject *prototype;
        prototype = JS_InitClass(context, global,
                                 /* parent prototype JSObject* for
                                  * prototype; NULL for
                                  * Object.prototype
                                  */
                                 NULL,
                                 &gjs_importer_class,
                                 /* constructor for instances (NULL for
                                  * none - just name the prototype like
                                  * Math - rarely correct)
                                  */
                                 gjs_importer_constructor,
                                 /* number of constructor args */
                                 0,
                                 /* props of prototype */
                                 &gjs_importer_proto_props[0],
                                 /* funcs of prototype */
                                 &gjs_importer_proto_funcs[0],
                                 /* props of constructor, MyConstructor.myprop */
                                 NULL,
                                 /* funcs of constructor, MyConstructor.myfunc() */
                                 NULL);
        if (prototype == NULL)
            gjs_fatal("Can't init class %s", gjs_importer_class.name);

        g_assert(gjs_object_has_property(context, global, gjs_importer_class.name));

        gjs_debug(GJS_DEBUG_IMPORTER, "Initialized class %s prototype %p",
                  gjs_importer_class.name, prototype);
    }

    importer = JS_NewObject(context, &gjs_importer_class, NULL, global);
    if (importer == NULL)
        gjs_fatal("No memory to create importer importer");

    priv = g_slice_new0(Importer);

    GJS_INC_COUNTER(importer);

    g_assert(priv_from_js(context, importer) == NULL);
    JS_SetPrivate(importer, priv);

    gjs_debug_lifecycle(GJS_DEBUG_IMPORTER,
                        "importer constructor, obj %p priv %p", importer, priv);

    return importer;
}
コード例 #7
0
ファイル: boxed.c プロジェクト: Katyunechka/gjs
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));
}
コード例 #8
0
ファイル: importer.c プロジェクト: PofigNaNik/gjs
static void
importer_finalize(JSFreeOp *fop,
                  JSObject *obj)
{
    Importer *priv;

    priv = JS_GetPrivate(obj);
    gjs_debug_lifecycle(GJS_DEBUG_IMPORTER,
                        "finalize, obj %p priv %p", obj, priv);
    if (priv == NULL)
        return; /* we are the prototype, not a real instance */

    GJS_DEC_COUNTER(importer);
    g_slice_free(Importer, priv);
}
コード例 #9
0
ファイル: importer.c プロジェクト: KNOPOChKA2/gjs
static void
importer_finalize(JSContext *context,
                  JSObject  *obj)
{
    Importer *priv;

    priv = priv_from_js(context, obj);
    gjs_debug_lifecycle(GJS_DEBUG_IMPORTER,
                        "finalize, obj %p priv %p", obj, priv);
    if (priv == NULL)
        return; /* we are the prototype, not a real instance, so constructor never called */

    GJS_DEC_COUNTER(importer);
    g_slice_free(Importer, priv);
}
コード例 #10
0
ファイル: ns.cpp プロジェクト: dreamsxin/gjs
static void
ns_finalize(JSFreeOp *fop,
            JSObject *obj)
{
    Ns *priv;

    priv = (Ns *)JS_GetPrivate(obj);
    gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE,
                        "finalize, obj %p priv %p", obj, priv);
    if (priv == NULL)
        return; /* we are the prototype, not a real instance */

    if (priv->gi_namespace)
        g_free(priv->gi_namespace);

    GJS_DEC_COUNTER(ns);
    g_slice_free(Ns, priv);
}
コード例 #11
0
ファイル: param.c プロジェクト: goizueta/gjs
static void
param_finalize(JSContext *context,
               JSObject  *obj)
{
    Param *priv;

    priv = priv_from_js(context, obj);
    gjs_debug_lifecycle(GJS_DEBUG_GPARAM,
                        "finalize, obj %p priv %p", obj, priv);
    if (priv == NULL)
        return; /* wrong class? */

    if (priv->gparam) {
        g_param_spec_unref(priv->gparam);
        priv->gparam = NULL;
    }

    GJS_DEC_COUNTER(param);
    g_slice_free(Param, priv);
}
コード例 #12
0
ファイル: keep-alive.c プロジェクト: sjokkis/gjs
/* If we set JSCLASS_CONSTRUCT_PROTOTYPE flag, then this is called on
 * the prototype in addition to on each instance. When called on the
 * prototype, "obj" is the prototype, and "retval" is the prototype
 * also, but can be replaced with another object to use instead as the
 * prototype. If we don't set JSCLASS_CONSTRUCT_PROTOTYPE we can
 * identify the prototype as an object of our class with NULL private
 * data.
 */
static JSBool
keep_alive_constructor(JSContext *context,
                       JSObject  *obj,
                       uintN      argc,
                       jsval     *argv,
                       jsval     *retval)
{
    KeepAlive *priv;

    priv = g_slice_new0(KeepAlive);
    priv->children = g_hash_table_new_full(child_hash, child_equal, NULL, child_free);

    g_assert(priv_from_js(context, obj) == NULL);
    JS_SetPrivate(context, obj, priv);

    gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE,
                        "keep_alive constructor, obj %p priv %p", obj, priv);

    return JS_TRUE;
}
コード例 #13
0
ファイル: param.cpp プロジェクト: leigh123linux/cjs
static void
param_finalize(JSFreeOp *fop,
               JSObject *obj)
{
    Param *priv;

    priv = (Param*) JS_GetPrivate(obj);
    gjs_debug_lifecycle(GJS_DEBUG_GPARAM,
                        "finalize, obj %p priv %p", obj, priv);
    if (priv == NULL)
        return; /* wrong class? */

    if (priv->gparam) {
        g_param_spec_unref(priv->gparam);
        priv->gparam = NULL;
    }

    GJS_DEC_COUNTER(param);
    g_slice_free(Param, priv);
}
コード例 #14
0
ファイル: fundamental.cpp プロジェクト: victoryang/gjs
static void
associate_js_instance_to_fundamental(JSContext *context,
                                     JSObject  *object,
                                     void      *gfundamental,
                                     gboolean   owned_ref)
{
    FundamentalInstance *priv;

    priv = priv_from_js(context, object);
    priv->gfundamental = gfundamental;

    g_assert(_fundamental_lookup_object(gfundamental) == NULL);
    _fundamental_add_object(gfundamental, object);

    gjs_debug_lifecycle(GJS_DEBUG_GFUNDAMENTAL,
                        "associated JSObject %p with fundamental %p",
                        object, gfundamental);

    if (!owned_ref)
        priv->prototype->ref_function(gfundamental);
}
コード例 #15
0
ファイル: gerror.c プロジェクト: Cobinja/cjs
static void
error_finalize(JSContext *context,
               JSObject  *obj)
{
    Error *priv;

    priv = priv_from_js(context, obj);
    gjs_debug_lifecycle(GJS_DEBUG_GERROR,
                        "finalize, obj %p priv %p", obj, priv);
    if (priv == NULL)
        return; /* wrong class? */

    g_clear_error (&priv->gerror);

    if (priv->info) {
        g_base_info_unref( (GIBaseInfo*) priv->info);
        priv->info = NULL;
    }

    GJS_DEC_COUNTER(gerror);
    g_slice_free(Error, priv);
}
コード例 #16
0
ファイル: fundamental.cpp プロジェクト: victoryang/gjs
static void
fundamental_finalize(JSFreeOp  *fop,
                     JSObject  *obj)
{
    FundamentalInstance *priv;

    priv = (FundamentalInstance *) JS_GetPrivate(obj);

    gjs_debug_lifecycle(GJS_DEBUG_GFUNDAMENTAL,
                        "finalize, obj %p priv %p", obj, priv);
    if (priv == NULL)
        return; /* wrong class? */

    if (priv->prototype) {
        if (priv->gfundamental) {
            _fundamental_remove_object(priv->gfundamental);
            priv->prototype->unref_function(priv->gfundamental);
            priv->gfundamental = NULL;
        }

        g_slice_free(FundamentalInstance, priv);
        GJS_DEC_COUNTER(fundamental);
    } else {
        Fundamental *proto_priv = (Fundamental *) priv;

        /* Only unref infos when freeing the prototype */
        if (proto_priv->constructor_info)
            g_base_info_unref (proto_priv->constructor_info);
        proto_priv->constructor_info = NULL;
        if (proto_priv->info)
            g_base_info_unref((GIBaseInfo *) proto_priv->info);
        proto_priv->info = NULL;

        g_slice_free(Fundamental, proto_priv);
    }
}
コード例 #17
0
ファイル: keep-alive.cpp プロジェクト: GNOME/gjs
static JSObject *
gjs_keep_alive_new(JSContext *context)
{
    KeepAlive *priv;
    bool found;

    /* This function creates an unattached KeepAlive object; following our
     * general strategy, we have a single KeepAlive class with a constructor
     * stored on our single "load global" pseudo-global object, and we create
     * instances with the load global as parent.
     */

    g_assert(context != NULL);

    JSAutoRequest ar(context);

    JS::RootedObject global(context, gjs_get_import_global(context));

    g_assert(global != NULL);

    if (!JS_HasProperty(context, global, gjs_keep_alive_class.name, &found))
        return NULL;

    if (!found) {
        JSObject *prototype;

        gjs_debug(GJS_DEBUG_KEEP_ALIVE,
                  "Initializing keep-alive class in context %p global %p",
                  context, global.get());

        prototype = JS_InitClass(context, global,
                                 /* parent prototype JSObject* for
                                  * prototype; NULL for
                                  * Object.prototype
                                  */
                                 JS::NullPtr(),
                                 &gjs_keep_alive_class,
                                 /* constructor for instances (NULL for
                                  * none - just name the prototype like
                                  * Math - rarely correct)
                                  */
                                 gjs_keep_alive_constructor,
                                 /* number of constructor args */
                                 0,
                                 /* props of prototype */
                                 &gjs_keep_alive_proto_props[0],
                                 /* funcs of prototype */
                                 &gjs_keep_alive_proto_funcs[0],
                                 /* props of constructor, MyConstructor.myprop */
                                 NULL,
                                 /* funcs of constructor, MyConstructor.myfunc() */
                                 NULL);
        if (prototype == NULL)
            g_error("Can't init class %s", gjs_keep_alive_class.name);

        gjs_debug(GJS_DEBUG_KEEP_ALIVE, "Initialized class %s prototype %p",
                  gjs_keep_alive_class.name, prototype);
    }

    gjs_debug(GJS_DEBUG_KEEP_ALIVE,
              "Creating new keep-alive object for context %p global %p",
              context, global.get());

    JS::RootedObject keep_alive(context,
        JS_NewObject(context, &gjs_keep_alive_class, JS::NullPtr(), global));
    if (keep_alive == NULL) {
        gjs_log_exception(context);
        g_error("Failed to create keep_alive object");
    }

    priv = g_slice_new0(KeepAlive);
    priv->children = g_hash_table_new_full(child_hash, child_equal, NULL, child_free);

    g_assert(priv_from_js(context, keep_alive) == NULL);
    JS_SetPrivate(keep_alive, priv);

    gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE,
                        "keep_alive constructor, obj %p priv %p",
                        keep_alive.get(), priv);

    return keep_alive;
}
コード例 #18
0
ファイル: ns.cpp プロジェクト: dreamsxin/gjs
static JSObject*
ns_new(JSContext    *context,
       const char   *ns_name)
{
    JSObject *ns;
    JSObject *global;
    Ns *priv;
    JSBool found;

    /* put constructor in the global namespace */
    global = gjs_get_import_global(context);

    if (!JS_HasProperty(context, global, gjs_ns_class.name, &found))
        return NULL;
    if (!found) {
        JSObject *prototype;
        prototype = JS_InitClass(context, global,
                                 /* parent prototype JSObject* for
                                  * prototype; NULL for
                                  * Object.prototype
                                  */
                                 NULL,
                                 &gjs_ns_class,
                                 /* constructor for instances (NULL for
                                  * none - just name the prototype like
                                  * Math - rarely correct)
                                  */
                                 gjs_ns_constructor,
                                 /* number of constructor args */
                                 0,
                                 /* props of prototype */
                                 &gjs_ns_proto_props[0],
                                 /* funcs of prototype */
                                 &gjs_ns_proto_funcs[0],
                                 /* props of constructor, MyConstructor.myprop */
                                 NULL,
                                 /* funcs of constructor, MyConstructor.myfunc() */
                                 NULL);
        if (prototype == NULL)
            g_error("Can't init class %s", gjs_ns_class.name);

        gjs_debug(GJS_DEBUG_GNAMESPACE, "Initialized class %s prototype %p",
                  gjs_ns_class.name, prototype);
    }

    ns = JS_NewObject(context, &gjs_ns_class, NULL, global);
    if (ns == NULL)
        g_error("No memory to create ns object");

    priv = g_slice_new0(Ns);

    GJS_INC_COUNTER(ns);

    g_assert(priv_from_js(context, ns) == NULL);
    JS_SetPrivate(ns, priv);

    gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE, "ns constructor, obj %p priv %p", ns, priv);

    priv = priv_from_js(context, ns);
    priv->gi_namespace = g_strdup(ns_name);
    return ns;
}
コード例 #19
0
ファイル: boxed.c プロジェクト: Katyunechka/gjs
static JSBool
boxed_new(JSContext   *context,
          JSObject    *obj, /* "this" for constructor */
          Boxed       *priv,
          unsigned     argc,
          jsval       *argv,
          jsval       *rval)
{
    if (priv->gtype == G_TYPE_VARIANT) {
        /* Short-circuit construction for GVariants by calling into the JS packing
           function */
        return boxed_invoke_constructor (context, obj, "_new_internal", argc, argv, rval);
    }

    /* 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, and zero_args_constructor and
     * default_constructor are always -1 for them.
     *
     * For backward compatibility, we choose the zero args constructor if one
     * exists, otherwise we choose the internal slice allocator if possible;
     * finally, we fallback on the default constructor */
    if (priv->zero_args_constructor >= 0) {
        GIFunctionInfo *func_info = g_struct_info_get_method (priv->info, priv->zero_args_constructor);

        GIArgument rval;
        GError *error = NULL;

        if (!g_function_info_invoke(func_info, NULL, 0, NULL, 0, &rval, &error)) {
            gjs_throw(context, "Failed to invoke boxed constructor: %s", error->message);
            g_clear_error(&error);
            g_base_info_unref((GIBaseInfo*) func_info);
            return JS_FALSE;
        }

        g_base_info_unref((GIBaseInfo*) func_info);

        priv->gboxed = rval.v_pointer;

        gjs_debug_lifecycle(GJS_DEBUG_GBOXED,
                            "JSObject created with boxed instance %p type %s",
                            priv->gboxed, g_type_name(gtype));

    } else if (priv->can_allocate_directly) {
        boxed_new_direct(priv);
    } else if (priv->default_constructor >= 0) {
        GIFunctionInfo *constructor;
        const gchar *constructor_name;
        JSBool retval;

        /* for simplicity, we simply delegate all the work to the actual JS constructor
           function (which we retrieve from the JS constructor, that is, Namespace.BoxedType,
           or object.constructor, given that object was created with the right prototype */

        constructor = g_struct_info_get_method(priv->info, priv->default_constructor);
        constructor_name = g_base_info_get_name((GIBaseInfo*)constructor);

        retval = boxed_invoke_constructor(context, obj, constructor_name, argc, argv, rval);

        g_base_info_unref((GIBaseInfo*)constructor);

        return retval;
    } else {
        gjs_throw(context, "Unable to construct struct type %s since it has no default constructor and cannot be allocated directly",
                  g_base_info_get_name((GIBaseInfo*) priv->info));
        return JS_FALSE;
    }

    /* If we reach this code, we need to init from a map of fields */

    if (argc == 0)
        return JS_TRUE;

    if (argc > 1) {
        gjs_throw(context, "Constructor with multiple arguments not supported for %s",
                  g_base_info_get_name((GIBaseInfo *)priv->info));
        return JS_FALSE;
    }

    return boxed_init_from_props (context, obj, priv, argv[0]);
}