示例#1
0
static bool
bootstrap_coverage(GjsCoverage *coverage)
{
    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);

    JSContext *context = (JSContext *) gjs_context_get_native_context(priv->context);
    JSAutoRequest ar(context);

    JSObject *debuggee = gjs_get_import_global(context);
    JS::RootedObject debugger_compartment(context,
                                          gjs_create_global_object(context));
    {
        JSAutoCompartment compartment(context, debugger_compartment);
        JS::RootedObject debuggeeWrapper(context, debuggee);
        if (!JS_WrapObject(context, &debuggeeWrapper))
            return false;

        JS::RootedValue debuggeeWrapperValue(context, JS::ObjectValue(*debuggeeWrapper));
        if (!JS_SetProperty(context, debugger_compartment, "debuggee",
                            debuggeeWrapperValue) ||
            !gjs_define_global_properties(context, debugger_compartment,
                                          "coverage"))
            return false;

        /* Add a tracer, as suggested by jdm on #jsapi */
        JS_AddExtraGCRootsTracer(context, coverage_tracer, coverage);

        priv->compartment = debugger_compartment;
    }

    return true;
}
示例#2
0
文件: param.c 项目: goizueta/gjs
JSObject*
gjs_param_from_g_param(JSContext    *context,
                       GParamSpec   *gparam)
{
    JSObject *obj;
    JSObject *proto;
    Param *priv;

    if (gparam == NULL)
        return NULL;

    gjs_debug(GJS_DEBUG_GPARAM,
              "Wrapping %s '%s' on %s with JSObject",
              g_type_name(G_TYPE_FROM_INSTANCE((GTypeInstance*) gparam)),
              gparam->name,
              g_type_name(gparam->owner_type));

    proto = gjs_lookup_param_prototype(context);

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

    priv = g_slice_new0(Param);
    JS_SetPrivate(context, obj, priv);
    priv->gparam = gparam;
    g_param_spec_ref (gparam);

    gjs_debug(GJS_DEBUG_GPARAM,
              "JSObject created with param instance %p type %s",
              priv->gparam, g_type_name(G_TYPE_FROM_INSTANCE((GTypeInstance*) priv->gparam)));

    return obj;
}
示例#3
0
文件: importer.c 项目: KNOPOChKA2/gjs
JSBool
gjs_define_root_importer(JSContext   *context,
                         JSObject    *in_object,
                         const char  *importer_name)
{
    JSObject *global;
    jsval value;
    JSBool success;

    success = JS_FALSE;
    global = gjs_get_import_global(context);
    JS_BeginRequest(context);

    if (!gjs_object_require_property(context,
                                     global, "global object",
                                     "imports", &value) ||
            !JSVAL_IS_OBJECT(value)) {
        gjs_debug(GJS_DEBUG_IMPORTER, "Root importer did not exist, couldn't get from load context; must create it");
        goto fail;
    }

    if (!JS_DefineProperty(context, in_object,
                           importer_name, value,
                           NULL, NULL,
                           GJS_MODULE_PROP_FLAGS)) {
        gjs_debug(GJS_DEBUG_IMPORTER, "DefineProperty %s on %p failed",
                  importer_name, in_object);
        goto fail;
    }

    success = JS_TRUE;
fail:
    JS_EndRequest(context);
    return success;
}
示例#4
0
文件: importer.c 项目: KNOPOChKA2/gjs
/* If this were called twice for the same runtime with different args it
 * would basically be a bug, but checking for that is a lot of code so
 * we just ignore all calls after the first and hope the args are the same.
 */
JSBool
gjs_create_root_importer(JSContext   *context,
                         const char **initial_search_path,
                         gboolean     add_standard_search_path)
{
    JSObject *global;

    global = gjs_get_import_global(context);

    JS_BeginRequest(context);

    if (!gjs_object_has_property(context,
                                 global,
                                 "imports")) {
        if (gjs_define_importer(context, global,
                                "imports",
                                initial_search_path, add_standard_search_path) == NULL) {
            JS_EndRequest(context);
            return JS_FALSE;
        }
    } else {
        gjs_debug(GJS_DEBUG_IMPORTER,
                  "Someone else already created root importer, ignoring second request");
        JS_EndRequest(context);
        return JS_TRUE;
    }

    JS_EndRequest(context);
    return JS_TRUE;
}
示例#5
0
文件: gtype.c 项目: Cobinja/cjs
JSObject *
gjs_gtype_create_gtype_wrapper (JSContext *context,
                                GType      gtype)
{
    JSObject *object;
    JSObject *global;

    JS_BeginRequest(context);

    /* put constructor for GIRepositoryGType() in the global namespace */
    global = gjs_get_import_global(context);
    gjs_gtype_create_proto(context, global, "GIRepositoryGType", NULL);

    object = g_type_get_qdata(gtype, gjs_get_gtype_wrapper_quark());
    if (object != NULL)
        goto out;

    object = JS_NewObject(context, &gjs_gtype_class, NULL, NULL);
    if (object == NULL)
        goto out;

    JS_SetPrivate(context, object, GSIZE_TO_POINTER(gtype));
    g_type_set_qdata(gtype, gjs_get_gtype_wrapper_quark(), object);

 out:
    JS_EndRequest(context);
    return object;
}
示例#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;
}
示例#7
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;
}
示例#8
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;
}
示例#9
0
文件: gerror.c 项目: Cobinja/cjs
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;
}
示例#10
0
static void
gjs_coverage_constructed(GObject *object)
{
    G_OBJECT_CLASS(gjs_coverage_parent_class)->constructed(object);

    GjsCoverage *coverage = GJS_COVERAGE(object);
    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
    new (&priv->compartment) JS::Heap<JSObject *>();

    if (!bootstrap_coverage(coverage)) {
        JSContext *context = static_cast<JSContext *>(gjs_context_get_native_context(priv->context));
        JSAutoCompartment compartment(context, gjs_get_import_global(context));
        gjs_log_exception(context);
    }
}
示例#11
0
/**
 * gjs_coverage_write_statistics:
 * @coverage: A #GjsCoverage
 * @output_directory: A directory to write coverage information to.
 *
 * Scripts which were provided as part of the #GjsCoverage:prefixes
 * construction property will be written out to @output_directory, in the same
 * directory structure relative to the source dir where the tests were run.
 *
 * This function takes all available statistics and writes them out to either
 * the file provided or to files of the pattern (filename).info in the same
 * directory as the scanned files. It will provide coverage data for all files
 * ending with ".js" in the coverage directories.
 */
void
gjs_coverage_write_statistics(GjsCoverage *coverage)
{
    auto priv = static_cast<GjsCoveragePrivate *>(gjs_coverage_get_instance_private(coverage));
    GError *error = nullptr;

    auto cx = static_cast<JSContext *>(gjs_context_get_native_context(priv->context));
    JSAutoCompartment ac(cx, gjs_get_import_global(cx));
    JSAutoRequest ar(cx);

    GjsAutoUnref<GFile> output_file = write_statistics_internal(coverage, cx, &error);
    if (!output_file) {
        g_critical("Error writing coverage data: %s", error->message);
        g_error_free(error);
        return;
    }

    GjsAutoChar output_file_path = g_file_get_path(output_file);
    g_message("Wrote coverage statistics to %s", output_file_path.get());
}
示例#12
0
JSObject*
gjs_object_from_g_fundamental(JSContext    *context,
                              GIObjectInfo *info,
                              void         *gfundamental)
{
    JSObject *proto;
    JSObject *object;

    if (gfundamental == NULL)
        return NULL;

    object = _fundamental_lookup_object(gfundamental);
    if (object)
        return object;

    gjs_debug_marshal(GJS_DEBUG_GFUNDAMENTAL,
                      "Wrapping fundamental %s.%s %p with JSObject",
                      g_base_info_get_namespace((GIBaseInfo *) info),
                      g_base_info_get_name((GIBaseInfo *) info),
                      gfundamental);

    proto = gjs_lookup_fundamental_prototype_from_gtype(context,
                                                        G_TYPE_FROM_INSTANCE(gfundamental));

    object = JS_NewObjectWithGivenProto(context,
                                        JS_GetClass(proto), proto,
                                        gjs_get_import_global(context));

    if (object == NULL)
        goto out;

    init_fundamental_instance(context, object);

    associate_js_instance_to_fundamental(context, object, gfundamental, FALSE);

 out:
    return object;
}
示例#13
0
JSObject*
gjs_keep_alive_get_for_import_global(JSContext *context)
{
    JSObject *global;
    JSObject *keep_alive;

    global = gjs_get_import_global(context);

    g_assert(global != NULL);

    JS_BeginRequest(context);

    keep_alive = gjs_keep_alive_get_from_parent(context, global);

    if (!keep_alive)
        keep_alive = gjs_keep_alive_create_in_parent(context, global);

    if (!keep_alive)
        gjs_fatal("could not create keep_alive on global object, no memory?");

    JS_EndRequest(context);

    return keep_alive;
}
示例#14
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;
}
示例#15
0
JSObject*
gjs_keep_alive_new(JSContext *context)
{
    JSObject *keep_alive;
    JSObject *global;

    /* 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);

    JS_BeginRequest(context);

    global = gjs_get_import_global(context);

    g_assert(global != NULL);

    if (!gjs_object_has_property(context, global, gjs_keep_alive_class.name)) {
        JSObject *prototype;

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

        prototype = JS_InitClass(context, global,
                                 /* parent prototype JSObject* for
                                  * prototype; NULL for
                                  * Object.prototype
                                  */
                                 NULL,
                                 &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)
            gjs_fatal("Can't init class %s", gjs_keep_alive_class.name);

        g_assert(gjs_object_has_property(context, global, 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);

    keep_alive = JS_ConstructObject(context, &gjs_keep_alive_class, NULL, global);
    if (keep_alive == NULL) {
        gjs_log_exception(context, NULL);
        gjs_fatal("Failed to create keep_alive object");
    }

    JS_EndRequest(context);

    return keep_alive;
}
示例#16
0
JSObject*
gjs_init_class_dynamic(JSContext      *context,
                       JSObject       *in_object,
                       JSObject       *parent_proto,
                       const char     *ns_name,
                       const char     *class_name,
                       JSClass        *clasp,
                       JSNative        constructor,
                       uintN           nargs,
                       JSPropertySpec *ps,
                       JSFunctionSpec *fs,
                       JSPropertySpec *static_ps,
                       JSFunctionSpec *static_fs)
{
    jsval value;
    char *private_name;
    JSObject *global;
    JSObject *prototype;

    if (clasp->name != NULL) {
        g_warning("Dynamic class should not have a name in the JSClass struct");
        return NULL;
    }

    JS_BeginRequest(context);

    /* We use a special "fake" global object to store our constructors
     * in for future use. Using the actual global object of the context would
     * result in different contexts having different class definitions for
     * the same GObject class; since the proxies are shared between all
     * contexts, this would produce confusing results.
     */
    global = gjs_get_import_global(context);

    /* JS_InitClass() wants to define the constructor in the global object, so
     * we give it a private and namespaced name... passing in the namespace
     * object instead of global object seems to break JS_ConstructObject()
     * which then can't find the constructor for the class. I am probably
     * missing something.
     */
    private_name = g_strdup_printf("_private_%s_%s", ns_name, class_name);

    prototype = NULL;
    if (gjs_object_get_property(context, global,
                                private_name, &value) &&
        JSVAL_IS_OBJECT(value)) {
        jsval proto_val;

        g_free(private_name); /* don't need it anymore */

        if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(value), NULL,
                                         "prototype", &proto_val) ||
            !JSVAL_IS_OBJECT(proto_val)) {
            gjs_throw(context, "prototype was not defined or not an object?");
            goto error;
        }
        prototype = JSVAL_TO_OBJECT(proto_val);
    } else {
        DynamicJSClass *class_copy;
        RuntimeData *rd;

        rd = get_data_from_context(context);

        class_copy = g_slice_new0(DynamicJSClass);
        class_copy->base = *clasp;

        class_copy->base.name = private_name; /* Pass ownership of memory */
        class_copy->static_class = clasp;

        /* record the allocated class to be destroyed with the runtime and so
         * we can do an IS_DYNAMIC_CLASS check
         */
        g_hash_table_replace(rd->dynamic_classes,
                             class_copy, class_copy);

        gjs_debug(GJS_DEBUG_GREPO,
                  "Initializing dynamic class %s %p",
                  class_name, class_copy);

        prototype = JS_InitClass(context, global,
                                 parent_proto, &class_copy->base,
                                 constructor, nargs,
                                 ps, fs,
                                 static_ps, static_fs);
        if (prototype == NULL)
            goto error;

        /* Retrieve the property again so we can define it in
         * in_object
         */
        if (!gjs_object_require_property(context, global, NULL,
                                         class_copy->base.name, &value))
            goto error;
    }
    g_assert(!JSVAL_IS_VOID(value));
    g_assert(prototype != NULL);

    /* Now manually define our constructor with a sane name, in the
     * namespace object.
     */
    if (!JS_DefineProperty(context, in_object,
                           class_name,
                           value,
                           NULL, NULL,
                           GJS_MODULE_PROP_FLAGS))
        goto error;

    JS_EndRequest(context);
    return prototype;

 error:
    JS_EndRequest(context);
    return NULL;
}
示例#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
文件: importer.c 项目: PofigNaNik/gjs
static JSObject *
load_module_init(JSContext  *context,
                 JSObject   *in_object,
                 const char *full_path)
{
    char *script;
    gsize script_len;
    jsval script_retval;
    JSObject *module_obj;
    GError *error;
    JSBool found;
    jsid module_init_name;

    /* First we check if js module has already been loaded  */
    module_init_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
                                                    GJS_STRING_MODULE_INIT);
    if (JS_HasPropertyById(context, in_object, module_init_name, &found) && found) {
        jsval module_obj_val;

        if (JS_GetPropertyById(context,
                               in_object,
                               module_init_name,
                               &module_obj_val)) {
            return JSVAL_TO_OBJECT(module_obj_val);
        }
    }

    module_obj = JS_NewObject(context, NULL, NULL, NULL);
    if (module_obj == NULL) {
        return JS_FALSE;
    }

    /* https://bugzilla.mozilla.org/show_bug.cgi?id=599651 means we
     * can't just pass in the global as the parent */
    JS_SetParent(context, module_obj,
                 gjs_get_import_global (context));

    /* Define module in importer for future use and to avoid module_obj
     * object to be garbage collected during the evaluation of the script */
    JS_DefinePropertyById(context, in_object,
                          module_init_name, OBJECT_TO_JSVAL(module_obj),
                          NULL, NULL,
                          GJS_MODULE_PROP_FLAGS & ~JSPROP_PERMANENT);

    script_len = 0;
    error = NULL;

    if (!g_file_get_contents(full_path, &script, &script_len, &error)) {
        if (!g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_ISDIR) &&
            !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR) &&
            !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
            gjs_throw_g_error(context, error);
        else
            g_error_free(error);

        return NULL;
    }

    g_assert(script != NULL);

    gjs_debug(GJS_DEBUG_IMPORTER, "Importing %s", full_path);

    if (!JS_EvaluateScript(context,
                           module_obj,
                           script,
                           script_len,
                           full_path,
                           1, /* line number */
                           &script_retval)) {
        g_free(script);

        /* If JSOPTION_DONT_REPORT_UNCAUGHT is set then the exception
         * would be left set after the evaluate and not go to the error
         * reporter function.
         */
        if (JS_IsExceptionPending(context)) {
            gjs_debug(GJS_DEBUG_IMPORTER,
                      "Module " MODULE_INIT_FILENAME " left an exception set");
            gjs_log_and_keep_exception(context);
        } else {
            gjs_throw(context,
                      "JS_EvaluateScript() returned FALSE but did not set exception");
        }

        return NULL;
    }

    g_free(script);

    return module_obj;
}
示例#19
0
文件: importer.cpp 项目: invy/xpjs
static JSObject*
importer_new(JSContext *context,
             bool   is_root)
{
    JSObject *importer;
    Importer *priv;
    JSObject *global;
    JSBool found;

    global = gjs_get_import_global(context);

    if (!JS_HasProperty(context, global, gjs_importer_class.name, &found))
        g_error("HasProperty call failed creating importer class");

    if (!found) {
        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)
            g_error("Can't init class %s", 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)
        g_error("No memory to create importer importer");

    priv = new Importer;
    priv->is_root = is_root;

//    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;
}