[gjs/wip/gdbus-2: 7/13] Don't use JS_ConstructObject
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/gdbus-2: 7/13] Don't use JS_ConstructObject
- Date: Fri, 2 Nov 2012 13:10:35 +0000 (UTC)
commit 9d3ba85b718b25c96f33f46d1ecaf9bf1c8caee0
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Sat Jul 21 16:22:08 2012 +0200
Don't use JS_ConstructObject
JS_ConstructObject is deprecated with modern JSAPI, and should be
replaced by JS_NewObject and JS_New. Also, while we're there,
replace constructors with functions that throw, as it is generally
an error to call them from JS anyway.
https://bugzilla.gnome.org/show_bug.cgi?id=679688
gi/enumeration.c | 2 +-
gi/function.c | 36 ++++++++++++----------------------
gi/interface.c | 19 +-----------------
gi/keep-alive.c | 35 ++++++++++++---------------------
gi/ns.c | 34 +++++++++++---------------------
gi/repo.c | 42 ++++++++++++++-------------------------
gjs/compat.h | 13 ++++++++++++
gjs/importer.c | 50 +++++++++++++++--------------------------------
gjs/jsapi-util.c | 22 +++++++++++++++++++++
gjs/jsapi-util.h | 2 +
modules/dbus-exports.c | 50 +++++++++++++++--------------------------------
modules/dbus-values.c | 2 +-
modules/dbus.c | 13 ++---------
13 files changed, 128 insertions(+), 192 deletions(-)
---
diff --git a/gi/enumeration.c b/gi/enumeration.c
index d4d96a3..15797c9 100644
--- a/gi/enumeration.c
+++ b/gi/enumeration.c
@@ -174,7 +174,7 @@ gjs_define_enumeration(JSContext *context,
return JS_TRUE;
}
- enum_obj = JS_ConstructObject(context, NULL, NULL, NULL);
+ enum_obj = JS_NewObject(context, NULL, NULL, gjs_get_import_global (context));
if (enum_obj == NULL)
return JS_FALSE;
diff --git a/gi/function.c b/gi/function.c
index a243791..0dba4c7 100644
--- a/gi/function.c
+++ b/gi/function.c
@@ -1219,27 +1219,7 @@ function_call(JSContext *context,
return success;
}
-GJS_NATIVE_CONSTRUCTOR_DECLARE(function)
-{
- GJS_NATIVE_CONSTRUCTOR_VARIABLES(function)
- Function *priv;
-
- GJS_NATIVE_CONSTRUCTOR_PRELUDE(name);
-
- priv = g_slice_new0(Function);
-
- GJS_INC_COUNTER(function);
-
- g_assert(priv_from_js(context, object) == NULL);
- JS_SetPrivate(context, object, priv);
-
- gjs_debug_lifecycle(GJS_DEBUG_GFUNCTION,
- "function constructor, obj %p priv %p", object, priv);
-
- GJS_NATIVE_CONSTRUCTOR_FINISH(name);
-
- return JS_TRUE;
-}
+GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(function)
/* Does not actually free storage for structure, just
* reverses init_cached_function_data
@@ -1615,13 +1595,23 @@ function_new(JSContext *context,
gjs_function_class.name, prototype);
}
- function = JS_ConstructObject(context, &gjs_function_class, NULL, global);
+ function = JS_NewObject(context, &gjs_function_class, NULL, global);
if (function == NULL) {
gjs_debug(GJS_DEBUG_GFUNCTION, "Failed to construct function");
return NULL;
}
- priv = priv_from_js(context, function);
+
+ priv = g_slice_new0(Function);
+
+ GJS_INC_COUNTER(function);
+
+ g_assert(priv_from_js(context, function) == NULL);
+ JS_SetPrivate(context, function, priv);
+
+ gjs_debug_lifecycle(GJS_DEBUG_GFUNCTION,
+ "function constructor, obj %p priv %p", function, priv);
+
if (!init_cached_function_data(context, priv, gtype, (GICallableInfo *)info))
return NULL;
diff --git a/gi/interface.c b/gi/interface.c
index c8147b2..7de8839 100644
--- a/gi/interface.c
+++ b/gi/interface.c
@@ -44,24 +44,7 @@ static struct JSClass gjs_interface_class;
GJS_DEFINE_DYNAMIC_PRIV_FROM_JS(Interface, gjs_interface_class)
-GJS_NATIVE_CONSTRUCTOR_DECLARE(interface)
-{
- jsval obj;
- JSObject *proto;
- JSObject *constructor;
- Interface *priv;
-
- constructor = JSVAL_TO_OBJECT(JS_CALLEE(context, vp));
- gjs_object_get_property(context, constructor, "prototype", &obj);
- proto = JSVAL_TO_OBJECT(obj);
- priv = priv_from_js(context, proto);
-
- gjs_throw(context, "You cannot construct new instances of '%s.%s'",
- g_base_info_get_namespace(priv->info),
- g_base_info_get_name(priv->info));
-
- return JS_TRUE;
-}
+GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(interface)
static void
interface_finalize(JSContext *context,
diff --git a/gi/keep-alive.c b/gi/keep-alive.c
index 69c1549..ad3e089 100644
--- a/gi/keep-alive.c
+++ b/gi/keep-alive.c
@@ -80,26 +80,7 @@ child_free(void *data)
g_slice_free(Child, child);
}
-GJS_NATIVE_CONSTRUCTOR_DECLARE(keep_alive)
-{
- GJS_NATIVE_CONSTRUCTOR_VARIABLES(keep_alive)
- KeepAlive *priv;
-
- GJS_NATIVE_CONSTRUCTOR_PRELUDE(keep_alive);
-
- 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, object) == NULL);
- JS_SetPrivate(context, object, priv);
-
- gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE,
- "keep_alive constructor, obj %p priv %p", object, priv);
-
- GJS_NATIVE_CONSTRUCTOR_FINISH(keep_alive);
-
- return JS_TRUE;
-}
+GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(keep_alive)
static void
keep_alive_finalize(JSContext *context,
@@ -115,7 +96,7 @@ keep_alive_finalize(JSContext *context,
"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 */
+ return; /* we are the prototype, not a real instance */
priv->inside_finalize = TRUE;
@@ -271,6 +252,7 @@ static JSFunctionSpec gjs_keep_alive_proto_funcs[] = {
JSObject*
gjs_keep_alive_new(JSContext *context)
{
+ KeepAlive *priv;
JSObject *keep_alive;
JSObject *global;
@@ -330,12 +312,21 @@ gjs_keep_alive_new(JSContext *context)
"Creating new keep-alive object for context %p global %p",
context, global);
- keep_alive = JS_ConstructObject(context, &gjs_keep_alive_class, NULL, global);
+ keep_alive = JS_NewObject(context, &gjs_keep_alive_class, NULL, global);
if (keep_alive == NULL) {
gjs_log_exception(context, NULL);
gjs_fatal("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(context, keep_alive, priv);
+
+ gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE,
+ "keep_alive constructor, obj %p priv %p", keep_alive, priv);
+
JS_EndRequest(context);
return keep_alive;
diff --git a/gi/ns.c b/gi/ns.c
index 31cea6d..ce25da3 100644
--- a/gi/ns.c
+++ b/gi/ns.c
@@ -129,26 +129,7 @@ ns_new_resolve(JSContext *context,
return ret;
}
-GJS_NATIVE_CONSTRUCTOR_DECLARE(ns)
-{
- GJS_NATIVE_CONSTRUCTOR_VARIABLES(ns)
- Ns *priv;
-
- GJS_NATIVE_CONSTRUCTOR_PRELUDE(ns);
-
- priv = g_slice_new0(Ns);
-
- GJS_INC_COUNTER(ns);
-
- g_assert(priv_from_js(context, object) == NULL);
- JS_SetPrivate(context, object, priv);
-
- gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE, "ns constructor, obj %p priv %p", object, priv);
-
- GJS_NATIVE_CONSTRUCTOR_FINISH(ns);
-
- return JS_TRUE;
-}
+GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(ns)
static void
ns_finalize(JSContext *context,
@@ -160,7 +141,7 @@ ns_finalize(JSContext *context,
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, so constructor never called */
+ return; /* we are the prototype, not a real instance */
if (priv->namespace)
g_free(priv->namespace);
@@ -244,10 +225,19 @@ ns_new(JSContext *context,
gjs_ns_class.name, prototype);
}
- ns = JS_ConstructObject(context, &gjs_ns_class, NULL, global);
+ ns = JS_NewObject(context, &gjs_ns_class, NULL, global);
if (ns == NULL)
gjs_fatal("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(context, ns, priv);
+
+ gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE, "ns constructor, obj %p priv %p", ns, priv);
+
priv = priv_from_js(context, ns);
priv->repo = g_object_ref(repo);
priv->namespace = g_strdup(ns_name);
diff --git a/gi/repo.c b/gi/repo.c
index 4ecdf05..3b4502e 100644
--- a/gi/repo.c
+++ b/gi/repo.c
@@ -194,27 +194,7 @@ repo_new_resolve(JSContext *context,
return ret;
}
-GJS_NATIVE_CONSTRUCTOR_DECLARE(repo)
-{
- GJS_NATIVE_CONSTRUCTOR_VARIABLES(repo)
- Repo *priv;
-
- GJS_NATIVE_CONSTRUCTOR_PRELUDE(repo);
-
- priv = g_slice_new0(Repo);
-
- GJS_INC_COUNTER(repo);
-
- g_assert(priv_from_js(context, object) == NULL);
- JS_SetPrivate(context, object, priv);
-
- gjs_debug_lifecycle(GJS_DEBUG_GREPO,
- "repo constructor, obj %p priv %p", object, priv);
-
- GJS_NATIVE_CONSTRUCTOR_FINISH(repo);
-
- return JS_TRUE;
-}
+GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(repo)
static void
repo_finalize(JSContext *context,
@@ -226,7 +206,7 @@ repo_finalize(JSContext *context,
gjs_debug_lifecycle(GJS_DEBUG_GREPO,
"finalize, obj %p priv %p", obj, priv);
if (priv == NULL)
- return; /* we are the prototype, not a real instance, so constructor never called */
+ return; /* we are the prototype, not a real instance */
GJS_DEC_COUNTER(repo);
g_slice_free(Repo, priv);
@@ -263,6 +243,7 @@ static JSFunctionSpec gjs_repo_proto_funcs[] = {
static JSObject*
repo_new(JSContext *context)
{
+ Repo *priv;
JSObject *repo;
JSObject *global;
JSObject *versions;
@@ -302,16 +283,23 @@ repo_new(JSContext *context)
gjs_repo_class.name, prototype);
}
- repo = JS_ConstructObject(context, &gjs_repo_class, NULL, global);
+ repo = JS_NewObject(context, &gjs_repo_class, NULL, global);
if (repo == NULL) {
gjs_throw(context, "No memory to create repo object");
return JS_FALSE;
}
- versions = JS_ConstructObject(context, NULL, NULL, NULL);
- /* https://bugzilla.mozilla.org/show_bug.cgi?id=599651 means we
- * can't just pass in the global as the parent */
- JS_SetParent(context, versions, global);
+ priv = g_slice_new0(Repo);
+
+ GJS_INC_COUNTER(repo);
+
+ g_assert(priv_from_js(context, repo) == NULL);
+ JS_SetPrivate(context, repo, priv);
+
+ gjs_debug_lifecycle(GJS_DEBUG_GREPO,
+ "repo constructor, obj %p priv %p", repo, priv);
+
+ versions = JS_NewObject(context, NULL, NULL, global);
JS_DefineProperty(context, repo,
"versions",
diff --git a/gjs/compat.h b/gjs/compat.h
index 8582e74..96f2761 100644
--- a/gjs/compat.h
+++ b/gjs/compat.h
@@ -81,6 +81,19 @@ gjs_##name##_constructor(JSContext *context, \
#define GJS_NATIVE_CONSTRUCTOR_FINISH(name) \
JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(object));
+/**
+ * GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT:
+ * Defines a constructor whose only purpose is to throw an error
+ * and fail. To be used with classes that require a constructor (because they have
+ * instances), but whose constructor cannot be used from JS code.
+ */
+#define GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(name) \
+ GJS_NATIVE_CONSTRUCTOR_DECLARE(name) \
+ { \
+ gjs_throw_abstract_constructor_error(context, vp); \
+ return JS_FALSE; \
+ }
+
G_END_DECLS
#endif /* __GJS_COMPAT_H__ */
diff --git a/gjs/importer.c b/gjs/importer.c
index ddbc985..63ee1f3 100644
--- a/gjs/importer.c
+++ b/gjs/importer.c
@@ -228,7 +228,7 @@ import_native_file(JSContext *context,
gjs_debug(GJS_DEBUG_IMPORTER,
"Importing '%s' from '%s'", name, full_path ? full_path : "<internal>");
- module_obj = JS_ConstructObject(context, NULL, NULL, NULL);
+ module_obj = JS_NewObject(context, NULL, NULL, NULL);
if (module_obj == NULL) {
return JS_FALSE;
}
@@ -398,7 +398,7 @@ import_file(JSContext *context,
gjs_debug(GJS_DEBUG_IMPORTER,
"Importing '%s'", full_path);
- module_obj = JS_ConstructObject(context, NULL, NULL, NULL);
+ module_obj = JS_NewObject(context, NULL, NULL, NULL);
if (module_obj == NULL) {
return JS_FALSE;
}
@@ -955,35 +955,7 @@ importer_new_resolve(JSContext *context,
return ret;
}
-/* 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.
- */
-GJS_NATIVE_CONSTRUCTOR_DECLARE(importer)
-{
- GJS_NATIVE_CONSTRUCTOR_VARIABLES(importer)
- Importer *priv;
-
- GJS_NATIVE_CONSTRUCTOR_PRELUDE(importer);
-
- priv = g_slice_new0(Importer);
-
- GJS_INC_COUNTER(importer);
-
- g_assert(priv_from_js(context, object) == NULL);
- JS_SetPrivate(context, object, priv);
-
- gjs_debug_lifecycle(GJS_DEBUG_IMPORTER,
- "importer constructor, obj %p priv %p", object, priv);
-
- GJS_NATIVE_CONSTRUCTOR_FINISH(importer);
-
- return JS_TRUE;
-}
+GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(importer)
static void
importer_finalize(JSContext *context,
@@ -995,7 +967,7 @@ importer_finalize(JSContext *context,
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 */
+ return; /* we are the prototype, not a real instance */
GJS_DEC_COUNTER(importer);
g_slice_free(Importer, priv);
@@ -1073,9 +1045,19 @@ importer_new(JSContext *context)
gjs_importer_class.name, prototype);
}
- importer = JS_ConstructObject(context, &gjs_importer_class, NULL, global);
+ importer = JS_NewObject(context, &gjs_importer_class, NULL, global);
if (importer == NULL)
- gjs_fatal("No memory to create ns object");
+ 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(context, importer, priv);
+
+ gjs_debug_lifecycle(GJS_DEBUG_IMPORTER,
+ "importer constructor, obj %p priv %p", importer, priv);
return importer;
}
diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c
index 59df435..394ac3c 100644
--- a/gjs/jsapi-util.c
+++ b/gjs/jsapi-util.c
@@ -567,6 +567,28 @@ gjs_throw_constructor_error(JSContext *context)
"Constructor called as normal method. Use 'new SomeObject()' not 'SomeObject()'");
}
+void
+gjs_throw_abstract_constructor_error(JSContext *context,
+ jsval *vp)
+{
+ jsval callee;
+ jsval prototype;
+ JSClass *proto_class;
+ const char *name = "anonymous";
+
+ callee = JS_CALLEE(context, vp);
+
+ if (JSVAL_IS_OBJECT(callee)) {
+ if (gjs_object_get_property(context, JSVAL_TO_OBJECT(callee),
+ "prototype", &prototype)) {
+ proto_class = JS_GetClass(context, JSVAL_TO_OBJECT(prototype));
+ name = proto_class->name;
+ }
+ }
+
+ gjs_throw(context, "You cannot construct new instances of '%s'", name);
+}
+
static const char*
format_dynamic_class_name (const char *name)
{
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 191dfd8..410fa40 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -239,6 +239,8 @@ JSObject * gjs_init_class_dynamic (JSContext *context,
JSPropertySpec *static_ps,
JSFunctionSpec *static_fs);
void gjs_throw_constructor_error (JSContext *context);
+void gjs_throw_abstract_constructor_error (JSContext *context,
+ jsval *vp);
JSBool gjs_typecheck_static_instance (JSContext *context,
JSObject *obj,
diff --git a/modules/dbus-exports.c b/modules/dbus-exports.c
index a715771..06b674e 100644
--- a/modules/dbus-exports.c
+++ b/modules/dbus-exports.c
@@ -1699,38 +1699,7 @@ exports_new_resolve(JSContext *context,
return JS_TRUE;
}
-/* 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.
- */
-GJS_NATIVE_CONSTRUCTOR_DECLARE(js_exports)
-{
- GJS_NATIVE_CONSTRUCTOR_VARIABLES(js_exports)
- Exports *priv;
-
- GJS_NATIVE_CONSTRUCTOR_PRELUDE(js_exports);
-
- priv = g_slice_new0(Exports);
-
- GJS_INC_COUNTER(dbus_exports);
-
- g_assert(priv_from_js(context, object) == NULL);
- JS_SetPrivate(context, object, priv);
-
- gjs_debug_lifecycle(GJS_DEBUG_DBUS,
- "exports constructor, obj %p priv %p", object, priv);
-
- priv->runtime = JS_GetRuntime(context);
- priv->object = object;
-
- GJS_NATIVE_CONSTRUCTOR_FINISH(js_exports);
-
- return JS_TRUE;
-}
+GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(js_exports)
static JSBool
add_connect_funcs(JSContext *context,
@@ -1822,6 +1791,7 @@ static JSObject*
exports_new(JSContext *context,
DBusBusType which_bus)
{
+ Exports *priv;
JSObject *exports;
JSObject *global;
@@ -1862,8 +1832,20 @@ exports_new(JSContext *context,
gjs_js_exports_class.name, prototype);
}
- exports = JS_ConstructObject(context, &gjs_js_exports_class, NULL, global);
- /* may be NULL */
+ exports = JS_NewObject(context, &gjs_js_exports_class, NULL, global);
+
+ priv = g_slice_new0(Exports);
+
+ GJS_INC_COUNTER(dbus_exports);
+
+ g_assert(priv_from_js(context, exports) == NULL);
+ JS_SetPrivate(context, exports, priv);
+
+ gjs_debug_lifecycle(GJS_DEBUG_DBUS,
+ "exports constructor, obj %p priv %p", exports, priv);
+
+ priv->runtime = JS_GetRuntime(context);
+ priv->object = exports;
return exports;
}
diff --git a/modules/dbus-values.c b/modules/dbus-values.c
index 98e0c66..fe9c1c0 100644
--- a/modules/dbus-values.c
+++ b/modules/dbus-values.c
@@ -44,7 +44,7 @@ _gjs_js_one_value_from_dbus_array_dict_entry(JSContext *context,
char *key;
JSBool retval = JS_FALSE;
- obj = JS_ConstructObject(context, NULL, NULL, NULL);
+ obj = JS_NewObject(context, NULL, NULL, NULL);
if (obj == NULL)
return JS_FALSE;
diff --git a/modules/dbus.c b/modules/dbus.c
index 6baf085..c9bbebe 100644
--- a/modules/dbus.c
+++ b/modules/dbus.c
@@ -1645,7 +1645,7 @@ gjs_js_dbus_get_current_message_context(JSContext *context,
current_message = _gjs_current_dbus_messages->data;
- context_obj = JS_ConstructObject(context, NULL, NULL, NULL);
+ context_obj = JS_NewObject(context, NULL, NULL, NULL);
if (context_obj == NULL)
return JS_FALSE;
@@ -1694,7 +1694,7 @@ define_bus_proto(JSContext *context,
bus_proto_val = JSVAL_VOID;
JS_AddValueRoot(context, &bus_proto_val);
- bus_proto_obj = JS_ConstructObject(context, NULL, NULL, NULL);
+ bus_proto_obj = JS_NewObject(context, NULL, NULL, NULL);
if (bus_proto_obj == NULL)
goto out;
@@ -1813,16 +1813,9 @@ define_bus_object(JSContext *context,
bus_val = JSVAL_VOID;
JS_AddValueRoot(context, &bus_val);
- bus_obj = JS_ConstructObject(context, NULL, NULL, NULL);
+ bus_obj = JS_NewObject(context, NULL, proto_obj, NULL);
if (bus_obj == NULL)
goto out;
- /* We need to use a separate call to SetPrototype to work
- * around a SpiderMonkey bug where with clasp=NULL, the
- * parent and proto arguments to JS_ConstructObject are
- * lost.
- * https://bugzilla.mozilla.org/show_bug.cgi?id=599651
- */
- JS_SetPrototype(context, bus_obj, proto_obj);
bus_val = OBJECT_TO_JSVAL(bus_obj);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]