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