Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
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));
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
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);
}
Exemplo n.º 10
0
Arquivo: ns.cpp Projeto: 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);
}
Exemplo n.º 11
0
Arquivo: param.c Projeto: 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);
}
Exemplo n.º 12
0
/* 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;
}
Exemplo n.º 13
0
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);
}
Exemplo n.º 14
0
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);
}
Exemplo n.º 15
0
Arquivo: gerror.c Projeto: 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);
}
Exemplo n.º 16
0
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);
    }
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
Arquivo: ns.cpp Projeto: 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;
}
Exemplo n.º 19
0
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]);
}