[gjs] jsapi-util: Split off class stuff into jsapi-class.h



commit aa60fc5df9820dbef2fb0a4d42afd6ac0f612adb
Author: Philip Chimento <philip chimento gmail com>
Date:   Wed Apr 12 22:23:19 2017 -0700

    jsapi-util: Split off class stuff into jsapi-class.h
    
    I've been wishing I had done this for three days now; jsapi-util.h is far
    too long, and it's no fun to recompile the entire program every time one
    of the macros is changed. The class macros plus the dynamic class functions
    make a fairly independent unit, so this seems logical.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=614413

 gi/boxed.cpp                      |    1 +
 gi/function.cpp                   |    1 +
 gi/fundamental.cpp                |    1 +
 gi/gerror.cpp                     |    1 +
 gi/gtype.cpp                      |    1 +
 gi/interface.cpp                  |    1 +
 gi/ns.cpp                         |    1 +
 gi/object.cpp                     |    1 +
 gi/param.cpp                      |    1 +
 gi/repo.cpp                       |    1 +
 gi/union.cpp                      |    1 +
 gjs/byteArray.cpp                 |    1 +
 gjs/importer.cpp                  |    1 +
 gjs/jsapi-class.h                 |  272 +++++++++++++++++++++++++++++++++++++
 gjs/jsapi-dynamic-class.cpp       |    1 +
 gjs/jsapi-util.cpp                |    1 +
 gjs/jsapi-util.h                  |  233 -------------------------------
 modules/cairo-context.cpp         |    1 +
 modules/cairo-gradient.cpp        |    1 +
 modules/cairo-image-surface.cpp   |    1 +
 modules/cairo-linear-gradient.cpp |    1 +
 modules/cairo-path.cpp            |    1 +
 modules/cairo-pattern.cpp         |    1 +
 modules/cairo-pdf-surface.cpp     |    1 +
 modules/cairo-ps-surface.cpp      |    1 +
 modules/cairo-radial-gradient.cpp |    1 +
 modules/cairo-region.cpp          |    1 +
 modules/cairo-solid-pattern.cpp   |    1 +
 modules/cairo-surface-pattern.cpp |    1 +
 modules/cairo-surface.cpp         |    1 +
 modules/cairo-svg-surface.cpp     |    1 +
 31 files changed, 301 insertions(+), 233 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index e212b27..6b2bf8d 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -28,6 +28,7 @@
 #include "boxed.h"
 #include "arg.h"
 #include "object.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/mem.h"
 #include "repo.h"
diff --git a/gi/function.cpp b/gi/function.cpp
index 00cd15b..addb0f3 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -34,6 +34,7 @@
 #include "gtype.h"
 #include "param.h"
 #include "gjs/context-private.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-private.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/mem.h"
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 7a3b5ec..2fac605 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -33,6 +33,7 @@
 #include "gtype.h"
 #include "proxyutils.h"
 #include "repo.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/mem.h"
 
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index cc8875d..c20b6fa 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -27,6 +27,7 @@
 
 #include "boxed.h"
 #include "enumeration.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/mem.h"
 #include "repo.h"
diff --git a/gi/gtype.cpp b/gi/gtype.cpp
index be84ae9..ffeb263 100644
--- a/gi/gtype.cpp
+++ b/gi/gtype.cpp
@@ -27,6 +27,7 @@
 #include <set>
 
 #include "gtype.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-wrapper.h"
 #include <util/log.h>
 #include <girepository.h>
diff --git a/gi/interface.cpp b/gi/interface.cpp
index cd4f9a7..213dda3 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -28,6 +28,7 @@
 #include "gtype.h"
 #include "interface.h"
 #include "repo.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/mem.h"
 
diff --git a/gi/ns.cpp b/gi/ns.cpp
index 124dd7e..848b638 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -26,6 +26,7 @@
 #include "ns.h"
 #include "repo.h"
 #include "param.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/mem.h"
 
diff --git a/gi/object.cpp b/gi/object.cpp
index ca78966..a82595c 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -45,6 +45,7 @@
 #include "value.h"
 #include "closure.h"
 #include "gjs_gi_trace.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-root.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/context-private.h"
diff --git a/gi/param.cpp b/gi/param.cpp
index c80822a..80fecd5 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -31,6 +31,7 @@
 #include "repo.h"
 #include "gtype.h"
 #include "function.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/mem.h"
 
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 1fc12cf..cb1e876 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -36,6 +36,7 @@
 #include "fundamental.h"
 #include "interface.h"
 #include "gerror.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/jsapi-private.h"
 #include "gjs/mem.h"
diff --git a/gi/union.cpp b/gi/union.cpp
index de708da..aadeb84 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -31,6 +31,7 @@
 #include "union.h"
 #include "arg.h"
 #include "object.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-wrapper.h"
 #include "gjs/mem.h"
 #include "repo.h"
diff --git a/gjs/byteArray.cpp b/gjs/byteArray.cpp
index d385ad6..33ad4f6 100644
--- a/gjs/byteArray.cpp
+++ b/gjs/byteArray.cpp
@@ -26,6 +26,7 @@
 #include <glib.h>
 #include "byteArray.h"
 #include "gi/boxed.h"
+#include "jsapi-class.h"
 #include "jsapi-wrapper.h"
 #include "jsapi-util-args.h"
 #include <girepository.h>
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 61f90e9..4ed8b18 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -27,6 +27,7 @@
 #include <util/glib.h>
 
 #include "importer.h"
+#include "jsapi-class.h"
 #include "jsapi-wrapper.h"
 #include "mem.h"
 #include "native.h"
diff --git a/gjs/jsapi-class.h b/gjs/jsapi-class.h
new file mode 100644
index 0000000..2e6262a
--- /dev/null
+++ b/gjs/jsapi-class.h
@@ -0,0 +1,272 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (c) 2017  Philip Chimento
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef GJS_JSAPI_CLASS_H
+#define GJS_JSAPI_CLASS_H
+
+#include "jsapi-util.h"
+#include "jsapi-wrapper.h"
+
+G_BEGIN_DECLS
+
+bool gjs_init_class_dynamic(JSContext              *cx,
+                            JS::HandleObject        in_object,
+                            JS::HandleObject        parent_proto,
+                            const char             *ns_name,
+                            const char             *class_name,
+                            JSClass                *clasp,
+                            JSNative                constructor_native,
+                            unsigned                nargs,
+                            JSPropertySpec         *ps,
+                            JSFunctionSpec         *fs,
+                            JSPropertySpec         *static_ps,
+                            JSFunctionSpec         *static_fs,
+                            JS::MutableHandleObject prototype,
+                            JS::MutableHandleObject constructor);
+
+bool gjs_typecheck_instance(JSContext       *cx,
+                            JS::HandleObject obj,
+                            const JSClass   *static_clasp,
+                            bool             throw_error);
+
+JSObject *gjs_construct_object_dynamic(JSContext                  *cx,
+                                       JS::HandleObject            proto,
+                                       const JS::HandleValueArray& args);
+
+/*
+ * Helper methods to access private data:
+ *
+ * do_base_typecheck: checks that object has the right JSClass, and possibly
+ *                    throw a TypeError exception if the check fails
+ * priv_from_js: accesses the object private field; as a debug measure,
+ *               it also checks that the object is of a compatible
+ *               JSClass, but it doesn't raise an exception (it
+ *               wouldn't be of much use, if subsequent code crashes on
+ *               NULL)
+ * priv_from_js_with_typecheck: a convenience function to call
+ *                              do_base_typecheck and priv_from_js
+ */
+#define GJS_DEFINE_PRIV_FROM_JS(type, klass)                          \
+    G_GNUC_UNUSED static inline bool                                    \
+    do_base_typecheck(JSContext       *context,                         \
+                      JS::HandleObject object,                          \
+                      bool             throw_error)                     \
+    {                                                                   \
+        return gjs_typecheck_instance(context, object, &klass, throw_error);  \
+    }                                                                   \
+    static inline type *                                                \
+    priv_from_js(JSContext       *context,                              \
+                 JS::HandleObject object)                               \
+    {                                                                   \
+        type *priv;                                                     \
+        JS_BeginRequest(context);                                       \
+        priv = (type*) JS_GetInstancePrivate(context, object, &klass, NULL);  \
+        JS_EndRequest(context);                                         \
+        return priv;                                                    \
+    }                                                                   \
+    G_GNUC_UNUSED static bool                                           \
+    priv_from_js_with_typecheck(JSContext       *context,               \
+                                JS::HandleObject object,                \
+                                type           **out)                   \
+    {                                                                   \
+        if (!do_base_typecheck(context, object, false))                 \
+            return false;                                               \
+        *out = priv_from_js(context, object);                           \
+        return true;                                                    \
+    }
+
+/*
+ * GJS_GET_PRIV:
+ * @cx: JSContext pointer passed into JSNative function
+ * @argc: Number of arguments passed into JSNative function
+ * @vp: Argument value array passed into JSNative function
+ * @args: Name for JS::CallArgs variable defined by this code snippet
+ * @to: Name for JS::RootedObject variable referring to function's this
+ * @type: Type of private data
+ * @priv: Name for private data variable defined by this code snippet
+ *
+ * A convenience macro for getting the private data from GJS classes using
+ * priv_from_js().
+ * Throws an error if the 'this' object is not the right type.
+ * Use in any JSNative function.
+ */
+#define GJS_GET_PRIV(cx, argc, vp, args, to, type, priv)  \
+    GJS_GET_THIS(cx, argc, vp, args, to);                 \
+    if (!do_base_typecheck(cx, to, true))                 \
+        return false;                                     \
+    type *priv = priv_from_js(cx, to)
+
+/**
+ * GJS_DEFINE_PROTO:
+ * @tn: The name of the prototype, as a string
+ * @cn: The name of the prototype, separated by _
+ * @flags: additional JSClass flags, such as JSCLASS_BACKGROUND_FINALIZE
+ *
+ * A convenience macro for prototype implementations.
+ */
+#define GJS_DEFINE_PROTO(tn, cn, flags)                            \
+GJS_NATIVE_CONSTRUCTOR_DECLARE(cn);                                \
+_GJS_DEFINE_PROTO_FULL(tn, cn, gjs_##cn##_constructor, G_TYPE_NONE, flags)
+
+/**
+ * GJS_DEFINE_PROTO_ABSTRACT:
+ * @tn: The name of the prototype, as a string
+ * @cn: The name of the prototype, separated by _
+ *
+ * A convenience macro for prototype implementations.
+ * Similar to GJS_DEFINE_PROTO but marks the prototype as abstract,
+ * you won't be able to instantiate it using the new keyword
+ */
+#define GJS_DEFINE_PROTO_ABSTRACT(tn, cn, flags)                 \
+_GJS_DEFINE_PROTO_FULL(tn, cn, nullptr, G_TYPE_NONE, flags)
+
+#define GJS_DEFINE_PROTO_WITH_GTYPE(tn, cn, gtype, flags)          \
+GJS_NATIVE_CONSTRUCTOR_DECLARE(cn);                                \
+_GJS_DEFINE_PROTO_FULL(tn, cn, gjs_##cn##_constructor, gtype, flags)
+
+#define GJS_DEFINE_PROTO_ABSTRACT_WITH_GTYPE(tn, cn, gtype, flags)  \
+_GJS_DEFINE_PROTO_FULL(tn, cn, nullptr, gtype, flags)
+
+#define GJS_DEFINE_PROTO_WITH_PARENT(tn, cn, flags)     \
+GJS_NATIVE_CONSTRUCTOR_DECLARE(cn);                     \
+_GJS_DEFINE_PROTO_FULL(tn, cn, gjs_##cn##_constructor, G_TYPE_NONE, flags)
+
+#define GJS_DEFINE_PROTO_ABSTRACT_WITH_PARENT(tn, cn, flags)  \
+_GJS_DEFINE_PROTO_FULL(tn, cn, nullptr, G_TYPE_NONE, flags)
+
+#define _GJS_DEFINE_PROTO_FULL(type_name, cname, ctor, gtype, jsclass_flags) \
+extern JSPropertySpec gjs_##cname##_proto_props[];                           \
+extern JSFunctionSpec gjs_##cname##_proto_funcs[];                           \
+static void gjs_##cname##_finalize(JSFreeOp *fop, JSObject *obj);            \
+static JS::PersistentRootedObject gjs_##cname##_prototype;                   \
+static struct JSClass gjs_##cname##_class = {                                \
+    type_name,                                                               \
+    JSCLASS_HAS_PRIVATE | jsclass_flags,                                     \
+    nullptr,  /* addProperty */                                              \
+    nullptr,  /* deleteProperty */                                           \
+    nullptr,  /* getProperty */                                              \
+    nullptr,  /* setProperty */                                              \
+    nullptr,  /* enumerate */                                                \
+    nullptr,  /* resolve */                                                  \
+    nullptr,  /* convert */                                                  \
+    gjs_##cname##_finalize                                                   \
+};                                                                           \
+JSObject *                                                                   \
+gjs_##cname##_create_proto(JSContext       *cx,                              \
+                           JS::HandleObject module,                          \
+                           const char      *proto_name,                      \
+                           JS::HandleObject parent)                          \
+{                                                                            \
+    JS::RootedObject rval(cx);                                               \
+    JS::RootedObject global(cx, gjs_get_import_global(cx));                  \
+    JS::RootedId class_name(cx,                                              \
+        gjs_intern_string_to_id(cx, gjs_##cname##_class.name));              \
+    bool found = false;                                                      \
+    if (!JS_AlreadyHasOwnPropertyById(cx, global, class_name, &found))       \
+        return nullptr;                                                      \
+    if (!found) {                                                            \
+        gjs_##cname##_prototype.init(cx);                                    \
+        gjs_##cname##_prototype =                                            \
+            JS_InitClass(cx, global, parent, &gjs_##cname##_class, ctor,     \
+                         0, &gjs_##cname##_proto_props[0],                   \
+                         &gjs_##cname##_proto_funcs[0],                      \
+                         nullptr, nullptr);                                  \
+        if (!gjs_##cname##_prototype)                                        \
+            return nullptr;                                                  \
+    }                                                                        \
+    if (!gjs_object_require_property(cx, global, nullptr,                    \
+                                     class_name, &rval))                     \
+        return nullptr;                                                      \
+    if (found)                                                               \
+        return rval;                                                         \
+    if (!JS_DefineProperty(cx, module, proto_name,                           \
+                           rval, GJS_MODULE_PROP_FLAGS))                     \
+        return nullptr;                                                      \
+    if (gtype != G_TYPE_NONE) {                                              \
+        JS::RootedObject gtype_obj(cx,                                       \
+            gjs_gtype_create_gtype_wrapper(cx, gtype));                      \
+        JS_DefineProperty(cx, rval, "$gtype", gtype_obj,                     \
+                          JSPROP_PERMANENT);                                 \
+    }                                                                        \
+    return rval;                                                             \
+}
+
+/**
+ * GJS_NATIVE_CONSTRUCTOR_DECLARE:
+ * Prototype a constructor.
+ */
+#define GJS_NATIVE_CONSTRUCTOR_DECLARE(name)            \
+static bool                                             \
+gjs_##name##_constructor(JSContext  *context,           \
+                         unsigned    argc,              \
+                         JS::Value  *vp)
+
+/**
+ * GJS_NATIVE_CONSTRUCTOR_VARIABLES:
+ * Declare variables necessary for the constructor; should
+ * be at the very top.
+ */
+#define GJS_NATIVE_CONSTRUCTOR_VARIABLES(name)                      \
+    JS::RootedObject object(context, NULL);                         \
+    JS::CallArgs argv G_GNUC_UNUSED = JS::CallArgsFromVp(argc, vp);
+
+/**
+ * GJS_NATIVE_CONSTRUCTOR_PRELUDE:
+ * Call after the initial variable declaration.
+ */
+#define GJS_NATIVE_CONSTRUCTOR_PRELUDE(name)                                  \
+{                                                                             \
+    if (!argv.isConstructing()) {                                             \
+        gjs_throw_constructor_error(context);                                 \
+        return false;                                                         \
+    }                                                                         \
+    object = JS_NewObjectForConstructor(context, &gjs_##name##_class, argv);  \
+    if (object == NULL)                                                       \
+        return false;                                                         \
+}
+
+/**
+ * GJS_NATIVE_CONSTRUCTOR_FINISH:
+ * Call this at the end of a constructor when it's completed
+ * successfully.
+ */
+#define GJS_NATIVE_CONSTRUCTOR_FINISH(name)             \
+    argv.rval().setObject(*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)                        \
+    {                                                           \
+        JS::CallArgs args = JS::CallArgsFromVp(argc, vp);       \
+        gjs_throw_abstract_constructor_error(context, args);    \
+        return false;                                           \
+    }
+
+G_END_DECLS
+
+#endif /* GJS_JSAPI_CLASS_H */
diff --git a/gjs/jsapi-dynamic-class.cpp b/gjs/jsapi-dynamic-class.cpp
index 1205a65..82d34cd 100644
--- a/gjs/jsapi-dynamic-class.cpp
+++ b/gjs/jsapi-dynamic-class.cpp
@@ -28,6 +28,7 @@
 #include <util/glib.h>
 #include <util/misc.h>
 
+#include "jsapi-class.h"
 #include "jsapi-util.h"
 #include "jsapi-wrapper.h"
 #include "jsapi-private.h"
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index f0bcd75..07d895b 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -29,6 +29,7 @@
 #include <util/misc.h>
 #include <util/error.h>
 
+#include "jsapi-class.h"
 #include "jsapi-util.h"
 #include "jsapi-wrapper.h"
 #include "context-private.h"
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 0e537c7..f00067e 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -90,48 +90,6 @@ typedef struct GjsRootedArray GjsRootedArray;
 #define GJS_MODULE_PROP_FLAGS (JSPROP_PERMANENT | JSPROP_ENUMERATE)
 
 /*
- * Helper methods to access private data:
- *
- * do_base_typecheck: checks that object has the right JSClass, and possibly
- *                    throw a TypeError exception if the check fails
- * priv_from_js: accesses the object private field; as a debug measure,
- *               it also checks that the object is of a compatible
- *               JSClass, but it doesn't raise an exception (it
- *               wouldn't be of much use, if subsequent code crashes on
- *               NULL)
- * priv_from_js_with_typecheck: a convenience function to call
- *                              do_base_typecheck and priv_from_js
- */
-#define GJS_DEFINE_PRIV_FROM_JS(type, klass)                          \
-    G_GNUC_UNUSED static inline bool                                    \
-    do_base_typecheck(JSContext       *context,                         \
-                      JS::HandleObject object,                          \
-                      bool             throw_error)                     \
-    {                                                                   \
-        return gjs_typecheck_instance(context, object, &klass, throw_error);  \
-    }                                                                   \
-    static inline type *                                                \
-    priv_from_js(JSContext       *context,                              \
-                 JS::HandleObject object)                               \
-    {                                                                   \
-        type *priv;                                                     \
-        JS_BeginRequest(context);                                       \
-        priv = (type*) JS_GetInstancePrivate(context, object, &klass, NULL);  \
-        JS_EndRequest(context);                                         \
-        return priv;                                                    \
-    }                                                                   \
-    G_GNUC_UNUSED static bool                                           \
-    priv_from_js_with_typecheck(JSContext       *context,               \
-                                JS::HandleObject object,                \
-                                type           **out)                   \
-    {                                                                   \
-        if (!do_base_typecheck(context, object, false))                 \
-            return false;                                               \
-        *out = priv_from_js(context, object);                           \
-        return true;                                                    \
-    }
-
-/*
  * GJS_GET_THIS:
  * @cx: JSContext pointer passed into JSNative function
  * @argc: Number of arguments passed into JSNative function
@@ -146,173 +104,6 @@ typedef struct GjsRootedArray GjsRootedArray;
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);          \
     JS::RootedObject to(cx, &args.computeThis(cx).toObject())
 
-/*
- * GJS_GET_PRIV:
- * @cx: JSContext pointer passed into JSNative function
- * @argc: Number of arguments passed into JSNative function
- * @vp: Argument value array passed into JSNative function
- * @args: Name for JS::CallArgs variable defined by this code snippet
- * @to: Name for JS::RootedObject variable referring to function's this
- * @type: Type of private data
- * @priv: Name for private data variable defined by this code snippet
- *
- * A convenience macro for getting the private data from GJS classes using
- * priv_from_js().
- * Throws an error if the 'this' object is not the right type.
- * Use in any JSNative function.
- */
-#define GJS_GET_PRIV(cx, argc, vp, args, to, type, priv)  \
-    GJS_GET_THIS(cx, argc, vp, args, to);                 \
-    if (!do_base_typecheck(cx, to, true))                 \
-        return false;                                     \
-    type *priv = priv_from_js(cx, to)
-
-/**
- * GJS_DEFINE_PROTO:
- * @tn: The name of the prototype, as a string
- * @cn: The name of the prototype, separated by _
- * @flags: additional JSClass flags, such as JSCLASS_BACKGROUND_FINALIZE
- *
- * A convenience macro for prototype implementations.
- */
-#define GJS_DEFINE_PROTO(tn, cn, flags) \
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cn); \
-_GJS_DEFINE_PROTO_FULL(tn, cn, gjs_##cn##_constructor, G_TYPE_NONE, flags)
-
-/**
- * GJS_DEFINE_PROTO_ABSTRACT:
- * @tn: The name of the prototype, as a string
- * @cn: The name of the prototype, separated by _
- *
- * A convenience macro for prototype implementations.
- * Similar to GJS_DEFINE_PROTO but marks the prototype as abstract,
- * you won't be able to instantiate it using the new keyword
- */
-#define GJS_DEFINE_PROTO_ABSTRACT(tn, cn, flags) \
-_GJS_DEFINE_PROTO_FULL(tn, cn, NULL, G_TYPE_NONE, flags)
-
-#define GJS_DEFINE_PROTO_WITH_GTYPE(tn, cn, gtype, flags)   \
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cn); \
-_GJS_DEFINE_PROTO_FULL(tn, cn, gjs_##cn##_constructor, gtype, flags)
-
-#define GJS_DEFINE_PROTO_ABSTRACT_WITH_GTYPE(tn, cn, gtype, flags)   \
-_GJS_DEFINE_PROTO_FULL(tn, cn, NULL, gtype, flags)
-
-#define _GJS_DEFINE_PROTO_FULL(type_name, cname, ctor, gtype, jsclass_flags)     \
-extern JSPropertySpec gjs_##cname##_proto_props[]; \
-extern JSFunctionSpec gjs_##cname##_proto_funcs[]; \
-static void gjs_##cname##_finalize(JSFreeOp *fop, JSObject *obj); \
-static JS::PersistentRootedObject gjs_##cname##_prototype;                     \
-static struct JSClass gjs_##cname##_class = { \
-    type_name, \
-    JSCLASS_HAS_PRIVATE | jsclass_flags,                                       \
-    NULL,  /* addProperty */                                                   \
-    NULL,  /* deleteProperty */                                                \
-    NULL,  /* getProperty */                                                   \
-    NULL,  /* setProperty */                                                   \
-    NULL,  /* enumerate */                                                     \
-    NULL,  /* resolve */                                                       \
-    NULL,  /* convert */                                                       \
-    gjs_##cname##_finalize                                                     \
-}; \
-JSObject *                                                                     \
-gjs_##cname##_create_proto(JSContext *context,                                 \
-                           JS::HandleObject module,                            \
-                           const char      *proto_name,                        \
-                           JS::HandleObject parent)                            \
-{ \
-    JS::RootedObject rval(context);                                            \
-    JS::RootedObject global(context, gjs_get_import_global(context));          \
-    JS::RootedId class_name(context,                                           \
-        gjs_intern_string_to_id(context, gjs_##cname##_class.name));           \
-    bool found = false;                                                        \
-    if (!JS_AlreadyHasOwnPropertyById(context, global, class_name, &found))    \
-        return nullptr;                                                        \
-    if (!found) {                                                              \
-        gjs_##cname##_prototype.init(context);                                 \
-        gjs_##cname##_prototype =                                              \
-            JS_InitClass(context, global, parent, &gjs_##cname##_class, ctor,  \
-                         0, &gjs_##cname##_proto_props[0],                     \
-                         &gjs_##cname##_proto_funcs[0],                        \
-                         nullptr, nullptr);                                    \
-        if (!gjs_##cname##_prototype)                                          \
-            return nullptr;                                                    \
-    } \
-    if (!gjs_object_require_property( \
-            context, global, NULL, \
-            class_name, &rval)) { \
-        return nullptr;                                                        \
-    } \
-    if (found)                                                                 \
-        return rval;                                                           \
-    if (!JS_DefineProperty(context, module, proto_name,                        \
-                           rval, GJS_MODULE_PROP_FLAGS))                       \
-        return nullptr;                                                        \
-    if (gtype != G_TYPE_NONE) { \
-        JS::RootedObject gtype_obj(context,                                    \
-            gjs_gtype_create_gtype_wrapper(context, gtype));                   \
-        JS_DefineProperty(context, rval, "$gtype", gtype_obj,                  \
-                          JSPROP_PERMANENT);                                   \
-    } \
-    return rval; \
-}
-
-/**
- * GJS_NATIVE_CONSTRUCTOR_DECLARE:
- * Prototype a constructor.
- */
-#define GJS_NATIVE_CONSTRUCTOR_DECLARE(name)            \
-static bool                                             \
-gjs_##name##_constructor(JSContext  *context,           \
-                         unsigned    argc,              \
-                         JS::Value  *vp)
-
-/**
- * GJS_NATIVE_CONSTRUCTOR_VARIABLES:
- * Declare variables necessary for the constructor; should
- * be at the very top.
- */
-#define GJS_NATIVE_CONSTRUCTOR_VARIABLES(name)          \
-    JS::RootedObject object(context, NULL);                         \
-    JS::CallArgs argv G_GNUC_UNUSED = JS::CallArgsFromVp(argc, vp);
-
-/**
- * GJS_NATIVE_CONSTRUCTOR_PRELUDE:
- * Call after the initial variable declaration.
- */
-#define GJS_NATIVE_CONSTRUCTOR_PRELUDE(name)                                   \
-    {                                                                          \
-        if (!argv.isConstructing()) {                                          \
-            gjs_throw_constructor_error(context);                              \
-            return false;                                                      \
-        }                                                                      \
-        object = JS_NewObjectForConstructor(context, &gjs_##name##_class, argv); \
-        if (object == NULL)                                                    \
-            return false;                                                      \
-    }
-
-/**
- * GJS_NATIVE_CONSTRUCTOR_FINISH:
- * Call this at the end of a constructor when it's completed
- * successfully.
- */
-#define GJS_NATIVE_CONSTRUCTOR_FINISH(name)             \
-    argv.rval().setObject(*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)                        \
-    {                                                           \
-        JS::CallArgs args = JS::CallArgsFromVp(argc, vp);       \
-        gjs_throw_abstract_constructor_error(context, args);    \
-        return false;                                           \
-    }
-
 bool gjs_init_context_standard(JSContext              *context,
                                JS::MutableHandleObject global);
 
@@ -324,35 +115,11 @@ void        gjs_set_global_slot              (JSContext       *context,
                                               GjsGlobalSlot    slot,
                                               JS::Value        value);
 
-bool gjs_init_class_dynamic(JSContext              *context,
-                            JS::HandleObject        in_object,
-                            JS::HandleObject        parent_proto,
-                            const char             *ns_name,
-                            const char             *class_name,
-                            JSClass                *clasp,
-                            JSNative                constructor_native,
-                            unsigned                nargs,
-                            JSPropertySpec         *ps,
-                            JSFunctionSpec         *fs,
-                            JSPropertySpec         *static_ps,
-                            JSFunctionSpec         *static_fs,
-                            JS::MutableHandleObject prototype,
-                            JS::MutableHandleObject constructor);
-
 void gjs_throw_constructor_error             (JSContext       *context);
 
 void gjs_throw_abstract_constructor_error(JSContext    *context,
                                           JS::CallArgs& args);
 
-bool gjs_typecheck_instance(JSContext       *context,
-                            JS::HandleObject obj,
-                            const JSClass   *static_clasp,
-                            bool             throw_error);
-
-JSObject *gjs_construct_object_dynamic(JSContext                  *context,
-                                       JS::HandleObject            proto,
-                                       const JS::HandleValueArray& args);
-
 JSObject*   gjs_build_string_array           (JSContext       *context,
                                               gssize           array_length,
                                               char           **array_values);
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index cb01bf7..2a1e225 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -25,6 +25,7 @@
 #include <vector>
 
 #include "gi/foreign.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 
diff --git a/modules/cairo-gradient.cpp b/modules/cairo-gradient.cpp
index 7bd6999..c824eb5 100644
--- a/modules/cairo-gradient.cpp
+++ b/modules/cairo-gradient.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-image-surface.cpp b/modules/cairo-image-surface.cpp
index f2253ae..b01bda2 100644
--- a/modules/cairo-image-surface.cpp
+++ b/modules/cairo-image-surface.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
diff --git a/modules/cairo-linear-gradient.cpp b/modules/cairo-linear-gradient.cpp
index 27d5854..a7104c1 100644
--- a/modules/cairo-linear-gradient.cpp
+++ b/modules/cairo-linear-gradient.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-path.cpp b/modules/cairo-path.cpp
index c08a14a..57a1435 100644
--- a/modules/cairo-path.cpp
+++ b/modules/cairo-path.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-pattern.cpp b/modules/cairo-pattern.cpp
index 5c3ef12..0c44328 100644
--- a/modules/cairo-pattern.cpp
+++ b/modules/cairo-pattern.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-pdf-surface.cpp b/modules/cairo-pdf-surface.cpp
index d8d399e..a2469be 100644
--- a/modules/cairo-pdf-surface.cpp
+++ b/modules/cairo-pdf-surface.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-ps-surface.cpp b/modules/cairo-ps-surface.cpp
index d9aa54d..a26be4e 100644
--- a/modules/cairo-ps-surface.cpp
+++ b/modules/cairo-ps-surface.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-radial-gradient.cpp b/modules/cairo-radial-gradient.cpp
index 8dc87cd..3c222a2 100644
--- a/modules/cairo-radial-gradient.cpp
+++ b/modules/cairo-radial-gradient.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-region.cpp b/modules/cairo-region.cpp
index 6de92b2..324ec30 100644
--- a/modules/cairo-region.cpp
+++ b/modules/cairo-region.cpp
@@ -23,6 +23,7 @@
 #include <config.h>
 
 #include "gi/foreign.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 
diff --git a/modules/cairo-solid-pattern.cpp b/modules/cairo-solid-pattern.cpp
index f6a3d19..0651dc5 100644
--- a/modules/cairo-solid-pattern.cpp
+++ b/modules/cairo-solid-pattern.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-surface-pattern.cpp b/modules/cairo-surface-pattern.cpp
index a6ddc76..ae1a6b3 100644
--- a/modules/cairo-surface-pattern.cpp
+++ b/modules/cairo-surface-pattern.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-surface.cpp b/modules/cairo-surface.cpp
index 9d2d0f7..d55030b 100644
--- a/modules/cairo-surface.cpp
+++ b/modules/cairo-surface.cpp
@@ -23,6 +23,7 @@
 #include <config.h>
 
 #include "gi/foreign.h"
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>
diff --git a/modules/cairo-svg-surface.cpp b/modules/cairo-svg-surface.cpp
index 5a1af1f..cb9f15d 100644
--- a/modules/cairo-svg-surface.cpp
+++ b/modules/cairo-svg-surface.cpp
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
 #include <cairo.h>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]