[gjs/wip/ptomato/mozjs45prep: 38/39] WIP - create all native objects with JS_NewObjectWithGivenProto
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/ptomato/mozjs45prep: 38/39] WIP - create all native objects with JS_NewObjectWithGivenProto
- Date: Wed, 12 Apr 2017 06:47:52 +0000 (UTC)
commit 83d311e070bd44d784750d9658278ddadc811bc3
Author: Philip Chimento <philip chimento gmail com>
Date: Tue Apr 11 23:44:52 2017 -0700
WIP - create all native objects with JS_NewObjectWithGivenProto
gi/function.cpp | 57 +++++++++++++++++----------------------------------
gi/ns.cpp | 53 +++++++++-------------------------------------
gjs/importer.cpp | 60 +++++++++++++----------------------------------------
gjs/jsapi-util.h | 25 +++++++++++++++++++--
4 files changed, 67 insertions(+), 128 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index 5f7068a..f8bfc25 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -1497,18 +1497,20 @@ struct JSClass gjs_function_class = {
function_call
};
-JSPropertySpec gjs_function_proto_props[] = {
+static JSPropertySpec gjs_function_proto_props[] = {
JS_PSG("length", get_num_arguments, JSPROP_PERMANENT),
JS_PS_END
};
/* The original Function.prototype.toString complains when
given a GIRepository function as an argument */
-JSFunctionSpec gjs_function_proto_funcs[] = {
+static JSFunctionSpec gjs_function_proto_funcs[] = {
JS_FN("toString", function_to_string, 0, 0),
JS_FS_END
};
+static JSFunctionSpec *gjs_function_static_funcs = nullptr;
+
static bool
init_cached_function_data (JSContext *context,
Function *function,
@@ -1657,51 +1659,30 @@ init_cached_function_data (JSContext *context,
return true;
}
+static bool
+gjs_builtin_function_ensure_proto(JSContext *cx,
+ JS::MutableHandleObject proto)
+{
+ JS::RootedObject global(cx, gjs_get_import_global(cx));
+ proto.set(JS_GetFunctionPrototype(cx, global));
+ return true;
+}
+
+GJS_DEFINE_ENSURE_PROTO_WITH_PARENT(function, builtin_function)
+
static JSObject*
function_new(JSContext *context,
GType gtype,
GICallableInfo *info)
{
Function *priv;
- bool found;
-
- /* put constructor for GIRepositoryFunction() in the global namespace */
- JS::RootedObject global(context, gjs_get_import_global(context));
- if (!JS_HasProperty(context, global, gjs_function_class.name, &found))
- return NULL;
-
- if (!found) {
- JSObject *prototype;
- JS::RootedObject function_proto(context,
- JS_GetFunctionPrototype(context, global));
-
- prototype = JS_InitClass(context, global, function_proto,
- &gjs_function_class,
- /* constructor for instances (NULL for
- * none - just name the prototype like
- * Math - rarely correct)
- */
- gjs_function_constructor,
- /* number of constructor args */
- 0,
- /* props of prototype */
- &gjs_function_proto_props[0],
- /* funcs of prototype */
- &gjs_function_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_function_class.name);
-
- gjs_debug(GJS_DEBUG_GFUNCTION, "Initialized class %s prototype %p",
- gjs_function_class.name, prototype);
- }
+ JS::RootedObject prototype(context);
+ if (!gjs_function_ensure_proto(context, &prototype))
+ return nullptr;
JS::RootedObject function(context,
- JS_NewObject(context, &gjs_function_class));
+ JS_NewObjectWithGivenProto(context, &gjs_function_class, prototype));
if (function == NULL) {
gjs_debug(GJS_DEBUG_GFUNCTION, "Failed to construct function");
return NULL;
diff --git a/gi/ns.cpp b/gi/ns.cpp
index f758e2c..d4eef29 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -168,59 +168,28 @@ struct JSClass gjs_ns_class = {
ns_finalize
};
-JSPropertySpec gjs_ns_proto_props[] = {
+static JSPropertySpec gjs_ns_proto_props[] = {
JS_PSG("__name__", get_name, GJS_MODULE_PROP_FLAGS),
JS_PS_END
};
-JSFunctionSpec gjs_ns_proto_funcs[] = {
- JS_FS_END
-};
+static JSFunctionSpec *gjs_ns_proto_funcs = nullptr;
+static JSFunctionSpec *gjs_ns_static_funcs = nullptr;
+
+GJS_DEFINE_ENSURE_PROTO(ns)
static JSObject*
ns_new(JSContext *context,
const char *ns_name)
{
Ns *priv;
- bool found;
-
- /* put constructor in the global namespace */
- JS::RootedObject global(context, 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
- */
- nullptr,
- &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);
- }
- JS::RootedObject ns(context, JS_NewObject(context, &gjs_ns_class));
+ JS::RootedObject prototype(context);
+ if (!gjs_ns_ensure_proto(context, &prototype))
+ return nullptr;
+
+ JS::RootedObject ns(context,
+ JS_NewObjectWithGivenProto(context, &gjs_ns_class, prototype));
if (ns == NULL)
g_error("No memory to create ns object");
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 1c8607c..97949d0 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -53,11 +53,13 @@ typedef struct {
unsigned int index;
} ImporterIterator;
-extern const js::Class gjs_importer_class;
+extern const js::Class gjs_importer_real_class;
/* Bizarrely, the API for safely casting const js::Class * to const JSClass *
* is called "js::Jsvalify" */
-GJS_DEFINE_PRIV_FROM_JS(Importer, (*js::Jsvalify(&gjs_importer_class)))
+static const JSClass gjs_importer_class = *js::Jsvalify(&gjs_importer_real_class);
+
+GJS_DEFINE_PRIV_FROM_JS(Importer, gjs_importer_class)
static bool
importer_to_string(JSContext *cx,
@@ -107,7 +109,7 @@ define_meta_properties(JSContext *context,
* on the root importer
*/
parent_is_module = parent && JS_InstanceOf(context, parent,
- js::Jsvalify(&gjs_importer_class), NULL);
+ &gjs_importer_class, nullptr);
gjs_debug(GJS_DEBUG_IMPORTER, "Defining parent %p of %p '%s' is mod %d",
parent.get(), module_obj.get(),
@@ -857,7 +859,7 @@ importer_finalize(js::FreeOp *fop,
* instances of the object, and to the prototype that instances of the
* class have.
*/
-const js::Class gjs_importer_class = {
+const js::Class gjs_importer_real_class = {
"GjsFileImporter",
JSCLASS_HAS_PRIVATE,
NULL, /* addProperty */
@@ -890,62 +892,30 @@ const js::Class gjs_importer_class = {
}
};
-JSPropertySpec gjs_importer_proto_props[] = {
- JS_PS_END
-};
+static JSPropertySpec *gjs_importer_proto_props = nullptr;
+static JSFunctionSpec *gjs_importer_static_funcs = nullptr;
JSFunctionSpec gjs_importer_proto_funcs[] = {
JS_FS("toString", importer_to_string, 0, 0),
JS_FS_END
};
+GJS_DEFINE_ENSURE_PROTO(importer)
+
static JSObject*
importer_new(JSContext *context,
bool is_root)
{
Importer *priv;
- bool found;
- JS::RootedObject global(context, 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
- */
- nullptr,
- js::Jsvalify(&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);
- }
+ JS::RootedObject prototype(context);
+ if (!gjs_importer_ensure_proto(context, &prototype))
+ g_error("Error creating importer prototype");
JS::RootedObject importer(context,
- JS_NewObject(context, js::Jsvalify(&gjs_importer_class)));
+ JS_NewObjectWithGivenProto(context, &gjs_importer_class, prototype));
if (importer == NULL)
- g_error("No memory to create importer importer");
+ g_error("No memory to create importer");
priv = g_slice_new0(Importer);
priv->is_root = is_root;
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 5014491..f19ddfb 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -32,6 +32,7 @@
#include "jsapi-wrapper.h"
#include "gjs/runtime.h"
#include "gi/gtype.h"
+#include "util/log.h"
class GjsAutoChar : public std::unique_ptr<char, decltype(&g_free)> {
public:
@@ -75,7 +76,10 @@ enum {
typedef enum {
GJS_GLOBAL_SLOT_IMPORTS,
GJS_GLOBAL_SLOT_PROTOTYPE_gtype,
- GJS_GLOBAL_SLOT_BYTE_ARRAY_PROTOTYPE,
+ GJS_GLOBAL_SLOT_PROTOTYPE_function,
+ GJS_GLOBAL_SLOT_PROTOTYPE_ns,
+ GJS_GLOBAL_SLOT_PROTOTYPE_byte_array,
+ GJS_GLOBAL_SLOT_PROTOTYPE_importer,
GJS_GLOBAL_SLOT_PROTOTYPE_cairo_context,
GJS_GLOBAL_SLOT_PROTOTYPE_cairo_gradient,
GJS_GLOBAL_SLOT_PROTOTYPE_cairo_image_surface,
@@ -247,6 +251,18 @@ static struct JSClass gjs_##cname##_class = { \
NULL, /* convert */ \
gjs_##cname##_finalize \
}; \
+_GJS_DEFINE_ENSURE_PROTO_FULL(cname, parent_cname, ctor, gtype)
+
+#define GJS_DEFINE_ENSURE_PROTO_WITH_PARENT(cname, parent_cname) \
+static \
+_GJS_DEFINE_ENSURE_PROTO_FULL(cname, parent_cname, \
+ gjs_##cname##_constructor, \
+ G_TYPE_NONE)
+
+#define GJS_DEFINE_ENSURE_PROTO(cname) \
+GJS_DEFINE_ENSURE_PROTO_WITH_PARENT(cname, no_parent)
+
+#define _GJS_DEFINE_ENSURE_PROTO_FULL(cname, parent_cname, ctor, gtype) \
bool \
gjs_##cname##_ensure_proto(JSContext *cx, \
JS::MutableHandleObject proto) \
@@ -268,11 +284,14 @@ gjs_##cname##_ensure_proto(JSContext *cx, \
gjs_##cname##_proto_funcs, nullptr, \
gjs_##cname##_static_funcs)); \
if (!proto) \
- return false; \
+ g_error("Can't init class %s", gjs_##cname##_class.name); \
gjs_set_global_slot(cx, GJS_GLOBAL_SLOT_PROTOTYPE_##cname, \
JS::ObjectValue(*proto)); \
+ gjs_debug(GJS_DEBUG_CONTEXT, "Initialized class %s prototype %p", \
+ gjs_##cname##_class.name, proto.get()); \
if (gtype != G_TYPE_NONE) { \
- JS::RootedId type_id(cx, gjs_intern_string_to_id(cx, type_name)); \
+ JS::RootedId type_id(cx, \
+ gjs_intern_string_to_id(cx, gjs_##cname##_class.name)); \
JS::RootedObject ctor_obj(cx); \
if (!gjs_object_require_property(cx, global, #cname " constructor", \
type_id, &ctor_obj)) \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]