[gjs: 1/2] modules: Split print functions into native module.



commit 459909a55f2ad77632377907a02e9c7a9a47836f
Author: Evan Welsh <noreply evanwelsh com>
Date:   Thu Jun 4 15:46:49 2020 -0500

    modules: Split print functions into native module.

 gjs/global.cpp                          | 147 -----------------------------
 meson.build                             |   1 +
 modules/modules.cpp                     |   2 +
 modules/print.cpp                       | 159 ++++++++++++++++++++++++++++++++
 modules/print.h                         |  20 ++++
 modules/script/_bootstrap/.eslintrc.yml |   7 ++
 modules/script/_bootstrap/debugger.js   |   2 +
 modules/script/_bootstrap/default.js    |  25 ++++-
 tools/run_iwyu.sh                       |   4 +-
 9 files changed, 216 insertions(+), 151 deletions(-)
---
diff --git a/gjs/global.cpp b/gjs/global.cpp
index dd2ad2a9..846c65f9 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -29,12 +29,9 @@
 
 #include <glib.h>
 
-#include <js/CallArgs.h>
-#include <js/CharacterEncoding.h>
 #include <js/Class.h>
 #include <js/CompilationAndEvaluation.h>
 #include <js/CompileOptions.h>
-#include <js/Conversions.h>
 #include <js/PropertyDescriptor.h>  // for JSPROP_PERMANENT, JSPROP_RE...
 #include <js/PropertySpec.h>
 #include <js/Realm.h>  // for GetObjectRealmOrNull, SetRealmPrivate
@@ -42,7 +39,6 @@
 #include <js/RootingAPI.h>
 #include <js/SourceText.h>
 #include <js/TypeDecls.h>
-#include <js/Utility.h>  // for UniqueChars
 #include <jsapi.h>       // for AutoSaveExceptionState, ...
 
 #include "gjs/atoms.h"
@@ -88,145 +84,6 @@ run_bootstrap(JSContext       *cx,
     return JS::CloneAndExecuteScript(cx, compiled_script, &ignored);
 }
 
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-gjs_log(JSContext *cx,
-        unsigned   argc,
-        JS::Value *vp)
-{
-    JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
-
-    if (argc != 1) {
-        gjs_throw(cx, "Must pass a single argument to log()");
-        return false;
-    }
-
-    /* JS::ToString might throw, in which case we will only log that the value
-     * could not be converted to string */
-    JS::AutoSaveExceptionState exc_state(cx);
-    JS::RootedString jstr(cx, JS::ToString(cx, argv[0]));
-    exc_state.restore();
-
-    if (!jstr) {
-        g_message("JS LOG: <cannot convert value to string>");
-        return true;
-    }
-
-    JS::UniqueChars s(JS_EncodeStringToUTF8(cx, jstr));
-    if (!s)
-        return false;
-
-    g_message("JS LOG: %s", s.get());
-
-    argv.rval().setUndefined();
-    return true;
-}
-
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-gjs_log_error(JSContext *cx,
-              unsigned   argc,
-              JS::Value *vp)
-{
-    JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
-
-    if ((argc != 1 && argc != 2) || !argv[0].isObject()) {
-        gjs_throw(cx, "Must pass an exception and optionally a message to logError()");
-        return false;
-    }
-
-    JS::RootedString jstr(cx);
-
-    if (argc == 2) {
-        /* JS::ToString might throw, in which case we will only log that the
-         * value could not be converted to string */
-        JS::AutoSaveExceptionState exc_state(cx);
-        jstr = JS::ToString(cx, argv[1]);
-        exc_state.restore();
-    }
-
-    gjs_log_exception_full(cx, argv[0], jstr, G_LOG_LEVEL_WARNING);
-
-    argv.rval().setUndefined();
-    return true;
-}
-
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-gjs_print_parse_args(JSContext              *cx,
-                     const JS::CallArgs&    argv,
-                     GjsAutoChar            *buffer)
-{
-    GString *str;
-    guint n;
-
-    str = g_string_new("");
-    for (n = 0; n < argv.length(); ++n) {
-        /* JS::ToString might throw, in which case we will only log that the
-         * value could not be converted to string */
-        JS::AutoSaveExceptionState exc_state(cx);
-        JS::RootedString jstr(cx, JS::ToString(cx, argv[n]));
-        exc_state.restore();
-
-        if (jstr) {
-            JS::UniqueChars s(JS_EncodeStringToUTF8(cx, jstr));
-            if (!s) {
-                g_string_free(str, true);
-                return false;
-            }
-
-            g_string_append(str, s.get());
-            if (n < (argv.length()-1))
-                g_string_append_c(str, ' ');
-        } else {
-            *buffer = g_string_free(str, true);
-            if (!*buffer)
-                *buffer = g_strdup("<invalid string>");
-            return true;
-        }
-
-    }
-    *buffer = g_string_free(str, false);
-
-    return true;
-}
-
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-gjs_print(JSContext *context,
-          unsigned   argc,
-          JS::Value *vp)
-{
-    JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-
-    GjsAutoChar buffer;
-    if (!gjs_print_parse_args(context, argv, &buffer))
-        return false;
-
-    g_print("%s\n", buffer.get());
-
-    argv.rval().setUndefined();
-    return true;
-}
-
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-gjs_printerr(JSContext *context,
-             unsigned   argc,
-             JS::Value *vp)
-{
-    JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
-
-    GjsAutoChar buffer;
-    if (!gjs_print_parse_args(context, argv, &buffer))
-        return false;
-
-    g_printerr("%s\n", buffer.get());
-
-    argv.rval().setUndefined();
-    return true;
-}
-
 const JSClassOps defaultclassops = JS::DefaultGlobalClassOps;
 
 class GjsGlobal {
@@ -237,10 +94,6 @@ class GjsGlobal {
     };
 
     static constexpr JSFunctionSpec static_funcs[] = {
-        JS_FN("log", gjs_log, 1, GJS_MODULE_PROP_FLAGS),
-        JS_FN("logError", gjs_log_error, 2, GJS_MODULE_PROP_FLAGS),
-        JS_FN("print", gjs_print, 0, GJS_MODULE_PROP_FLAGS),
-        JS_FN("printerr", gjs_printerr, 0, GJS_MODULE_PROP_FLAGS),
         JS_FS_END};
 
  public:
diff --git a/meson.build b/meson.build
index 574ae1b1..5cf0cb56 100644
--- a/meson.build
+++ b/meson.build
@@ -387,6 +387,7 @@ libgjs_sources = [
     'gjs/stack.cpp',
     'modules/console.cpp', 'modules/console.h',
     'modules/modules.cpp', 'modules/modules.h',
+    'modules/print.cpp', 'modules/print.h',
     'modules/system.cpp', 'modules/system.h',
 ]
 
diff --git a/modules/modules.cpp b/modules/modules.cpp
index ff8aa24e..0e994cfb 100644
--- a/modules/modules.cpp
+++ b/modules/modules.cpp
@@ -26,6 +26,7 @@
 #include "gjs/native.h"
 #include "modules/console.h"
 #include "modules/modules.h"
+#include "modules/print.h"
 #include "modules/system.h"
 
 #ifdef ENABLE_CAIRO
@@ -40,4 +41,5 @@ gjs_register_static_modules (void)
 #endif
     gjs_register_native_module("system", gjs_js_define_system_stuff);
     gjs_register_native_module("console", gjs_define_console_stuff);
+    gjs_register_native_module("_print", gjs_define_print_stuff);
 }
diff --git a/modules/print.cpp b/modules/print.cpp
new file mode 100644
index 00000000..5c82c5c7
--- /dev/null
+++ b/modules/print.cpp
@@ -0,0 +1,159 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+ *
+ * Copyright (c) 2008  litl, LLC
+ * Copyright (c) 2009 Red Hat, Inc.
+ */
+
+#include <config.h>
+
+#include <glib.h>
+
+#include <js/CallArgs.h>
+#include <js/CharacterEncoding.h>  // for JS_EncodeStringToUTF8
+#include <js/Conversions.h>
+#include <js/PropertySpec.h>  // for JS_FN, JSFunctionSpec, JS_FS_END
+#include <js/RootingAPI.h>
+#include <js/TypeDecls.h>
+#include <js/Utility.h>  // for UniqueChars
+#include <js/Value.h>
+#include <jsapi.h>
+
+#include "gjs/jsapi-util.h"
+#include "modules/print.h"
+
+GJS_JSAPI_RETURN_CONVENTION
+static bool gjs_log(JSContext* cx, unsigned argc, JS::Value* vp) {
+    JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
+
+    if (argc != 1) {
+        gjs_throw(cx, "Must pass a single argument to log()");
+        return false;
+    }
+
+    /* JS::ToString might throw, in which case we will only log that the value
+     * could not be converted to string */
+    JS::AutoSaveExceptionState exc_state(cx);
+    JS::RootedString jstr(cx, JS::ToString(cx, argv[0]));
+    exc_state.restore();
+
+    if (!jstr) {
+        g_message("JS LOG: <cannot convert value to string>");
+        return true;
+    }
+
+    JS::UniqueChars s(JS_EncodeStringToUTF8(cx, jstr));
+    if (!s)
+        return false;
+
+    g_message("JS LOG: %s", s.get());
+
+    argv.rval().setUndefined();
+    return true;
+}
+
+GJS_JSAPI_RETURN_CONVENTION
+static bool gjs_log_error(JSContext* cx, unsigned argc, JS::Value* vp) {
+    JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
+
+    if ((argc != 1 && argc != 2) || !argv[0].isObject()) {
+        gjs_throw(
+            cx,
+            "Must pass an exception and optionally a message to logError()");
+        return false;
+    }
+
+    JS::RootedString jstr(cx);
+
+    if (argc == 2) {
+        /* JS::ToString might throw, in which case we will only log that the
+         * value could not be converted to string */
+        JS::AutoSaveExceptionState exc_state(cx);
+        jstr = JS::ToString(cx, argv[1]);
+        exc_state.restore();
+    }
+
+    gjs_log_exception_full(cx, argv[0], jstr, G_LOG_LEVEL_WARNING);
+
+    argv.rval().setUndefined();
+    return true;
+}
+
+GJS_JSAPI_RETURN_CONVENTION
+static bool gjs_print_parse_args(JSContext* cx, const JS::CallArgs& argv,
+                                 GjsAutoChar* buffer) {
+    GString* str = g_string_new("");
+    for (unsigned n = 0; n < argv.length(); ++n) {
+        /* JS::ToString might throw, in which case we will only log that the
+         * value could not be converted to string */
+        JS::AutoSaveExceptionState exc_state(cx);
+        JS::RootedString jstr(cx, JS::ToString(cx, argv[n]));
+        exc_state.restore();
+
+        if (jstr) {
+            JS::UniqueChars s(JS_EncodeStringToUTF8(cx, jstr));
+            if (!s) {
+                g_string_free(str, true);
+                return false;
+            }
+
+            g_string_append(str, s.get());
+            if (n < (argv.length() - 1))
+                g_string_append_c(str, ' ');
+        } else {
+            *buffer = g_string_free(str, true);
+            if (!*buffer)
+                *buffer = g_strdup("<invalid string>");
+            return true;
+        }
+    }
+    *buffer = g_string_free(str, false);
+
+    return true;
+}
+
+GJS_JSAPI_RETURN_CONVENTION
+static bool gjs_print(JSContext* context, unsigned argc, JS::Value* vp) {
+    JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
+
+    GjsAutoChar buffer;
+    if (!gjs_print_parse_args(context, argv, &buffer))
+        return false;
+
+    g_print("%s\n", buffer.get());
+
+    argv.rval().setUndefined();
+    return true;
+}
+
+GJS_JSAPI_RETURN_CONVENTION
+static bool gjs_printerr(JSContext* context, unsigned argc, JS::Value* vp) {
+    JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
+
+    GjsAutoChar buffer;
+    if (!gjs_print_parse_args(context, argv, &buffer))
+        return false;
+
+    g_printerr("%s\n", buffer.get());
+
+    argv.rval().setUndefined();
+    return true;
+}
+
+// clang-format off
+static constexpr JSFunctionSpec funcs[] = {
+    JS_FN("log", gjs_log, 1, GJS_MODULE_PROP_FLAGS),
+    JS_FN("logError", gjs_log_error, 2, GJS_MODULE_PROP_FLAGS),
+    JS_FN("print", gjs_print, 0, GJS_MODULE_PROP_FLAGS),
+    JS_FN("printerr", gjs_printerr, 0, GJS_MODULE_PROP_FLAGS),
+    JS_FS_END};
+// clang-format on
+
+bool gjs_define_print_stuff(JSContext* context,
+                            JS::MutableHandleObject module) {
+    module.set(JS_NewPlainObject(context));
+    if (!module)
+        return false;
+    return JS_DefineFunctions(context, module, funcs);
+}
diff --git a/modules/print.h b/modules/print.h
new file mode 100644
index 00000000..3753248b
--- /dev/null
+++ b/modules/print.h
@@ -0,0 +1,20 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+ *
+ * Copyright (c) 2020 Evan Welsh <noreply evanwelsh com>
+ */
+
+#ifndef MODULES_PRINT_H_
+#define MODULES_PRINT_H_
+
+#include <config.h>
+
+#include <js/TypeDecls.h>
+
+#include "gjs/macros.h"
+
+GJS_JSAPI_RETURN_CONVENTION
+bool gjs_define_print_stuff(JSContext* context, JS::MutableHandleObject module);
+
+#endif  // MODULES_PRINT_H_
diff --git a/modules/script/_bootstrap/.eslintrc.yml b/modules/script/_bootstrap/.eslintrc.yml
new file mode 100644
index 00000000..9cad1d14
--- /dev/null
+++ b/modules/script/_bootstrap/.eslintrc.yml
@@ -0,0 +1,7 @@
+---
+extends: "../../../.eslintrc.yml"
+globals:
+  log: "off"
+  logError: "off"
+  print: "off"
+  printerr: "off"
diff --git a/modules/script/_bootstrap/debugger.js b/modules/script/_bootstrap/debugger.js
index 6538feeb..39a5ff60 100644
--- a/modules/script/_bootstrap/debugger.js
+++ b/modules/script/_bootstrap/debugger.js
@@ -16,6 +16,8 @@
  * the first frame is executed.
  */
 
+const {print, logError} = imports._print;
+
 // Debugger state.
 var focusedFrame = null;
 var topFrame = null;
diff --git a/modules/script/_bootstrap/default.js b/modules/script/_bootstrap/default.js
index 86ef0211..6b220096 100644
--- a/modules/script/_bootstrap/default.js
+++ b/modules/script/_bootstrap/default.js
@@ -1,7 +1,28 @@
 (function (exports) {
     'use strict';
 
-    // Do early initialization here.
-    void exports;
+    const {print, printerr, log, logError} = imports._print;
 
+    Object.defineProperties(exports, {
+        print: {
+            configurable: false,
+            enumerable: true,
+            value: print,
+        },
+        printerr: {
+            configurable: false,
+            enumerable: true,
+            value: printerr,
+        },
+        log: {
+            configurable: false,
+            enumerable: true,
+            value: log,
+        },
+        logError: {
+            configurable: false,
+            enumerable: true,
+            value: logError,
+        },
+    });
 })(globalThis);
diff --git a/tools/run_iwyu.sh b/tools/run_iwyu.sh
index f46d807c..ef96b7a0 100755
--- a/tools/run_iwyu.sh
+++ b/tools/run_iwyu.sh
@@ -53,8 +53,8 @@ for FILE in $SRCDIR/gi/*.cpp $SRCDIR/gjs/atoms.cpp $SRCDIR/gjs/byteArray.cpp \
     $SRCDIR/gjs/jsapi-util-error.cpp $SRCDIR/gjs/jsapi-util-string.cpp \
     $SRCDIR/gjs/module.cpp $SRCDIR/gjs/native.cpp $SRCDIR/gjs/stack.cpp \
     $SRCDIR/modules/cairo-*.cpp $SRCDIR/modules/console.cpp \
-    $SRCDIR/modules/system.cpp $SRCDIR/test/*.cpp $SRCDIR/util/*.cpp \
-    $SRCDIR/libgjs-private/*.c
+    $SRCDIR/modules/print.cpp $SRCDIR/modules/system.cpp $SRCDIR/test/*.cpp \
+    $SRCDIR/util/*.cpp $SRCDIR/libgjs-private/*.c
 do
     if should_analyze $FILE; then
         if ! $IWYU $FILE -- $PRIVATE_MAPPING | $POSTPROCESS; then


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