[gjs/mozjs78: 16/17] coverage: Enable coverage before creating GjsContext




commit 293750f705cc93a5b563b65297287583346caff7
Author: Philip Chimento <philip chimento gmail com>
Date:   Tue Aug 11 12:35:09 2020 -0700

    coverage: Enable coverage before creating GjsContext
    
    Due to changes in SpiderMonkey 78, js::EnableCodeCoverage() must be
    called before using the code coverage APIs. Add a public GJS API that
    wraps this function, and gives a clear error message if it's not called.
    
    See: GNOME/gjs#329

 NEWS                            |  6 ++++++
 gjs/console.cpp                 | 17 +++++++++--------
 gjs/coverage.cpp                | 30 +++++++++++++++++++++++++++++-
 gjs/coverage.h                  |  2 ++
 installed-tests/minijasmine.cpp |  3 +++
 test/gjs-test-coverage.cpp      |  1 +
 6 files changed, 50 insertions(+), 9 deletions(-)
---
diff --git a/NEWS b/NEWS
index 2e136e8f..801fb92f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,12 @@
 NEXT
 ----
 
+- New API: gjs_coverage_enable() allows the collection of code coverage metrics.
+  If you are using GjsCoverage, it is now required to call gjs_coverage_enable()
+  before you create the first GjsContext. Previously this was not necessary, but
+  due to changes in SpiderMonkey 78 you must now indicate in advance if you want
+  to collect code coverage metrics.
+
 - New JavaScript features! This version of GJS is based on SpiderMonkey 78, an
   upgrade from the previous ESR (Extended Support Release) of SpiderMonkey 68.
   Here are the highlights of the new JavaScript features.
diff --git a/gjs/console.cpp b/gjs/console.cpp
index ad571e0e..1406a713 100644
--- a/gjs/console.cpp
+++ b/gjs/console.cpp
@@ -216,7 +216,6 @@ main(int argc, char **argv)
     char **gjs_argv, **gjs_argv_addr;
     char * const *script_argv;
     const char *env_coverage_output_path;
-    const char *env_coverage_prefixes;
     bool interactive_mode = false;
 
     setlocale(LC_ALL, "");
@@ -326,6 +325,15 @@ main(int argc, char **argv)
         g_unsetenv("GJS_TRACE_FD");         /* ignore env var in eval() */
     }
 
+    const char* env_coverage_prefixes = g_getenv("GJS_COVERAGE_PREFIXES");
+    if (env_coverage_prefixes) {
+        if (coverage_prefixes)
+            g_strfreev(coverage_prefixes);
+        coverage_prefixes = g_strsplit(env_coverage_prefixes, ":", -1);
+    }
+    if (coverage_prefixes)
+        gjs_coverage_enable();
+
     js_context = (GjsContext*) g_object_new(GJS_TYPE_CONTEXT,
                                             "search-path", include_path,
                                             "program-name", program_name,
@@ -338,13 +346,6 @@ main(int argc, char **argv)
         coverage_output_path = g_strdup(env_coverage_output_path);
     }
 
-    env_coverage_prefixes = g_getenv("GJS_COVERAGE_PREFIXES");
-    if (env_coverage_prefixes != NULL) {
-        if (coverage_prefixes != NULL)
-            g_strfreev(coverage_prefixes);
-        coverage_prefixes = g_strsplit(env_coverage_prefixes, ":", -1);
-    }
-
     if (coverage_prefixes) {
         if (!coverage_output_path)
             g_error("--coverage-output is required when taking coverage statistics");
diff --git a/gjs/coverage.cpp b/gjs/coverage.cpp
index c975a467..1daf492b 100644
--- a/gjs/coverage.cpp
+++ b/gjs/coverage.cpp
@@ -38,6 +38,7 @@
 #include <js/TracingAPI.h>
 #include <js/TypeDecls.h>
 #include <js/Value.h>
+#include <js/experimental/CodeCoverage.h>  // for EnableCodeCoverage
 #include <jsapi.h>        // for JSAutoRealm, JS_SetPropertyById
 #include <jsfriendapi.h>  // for GetCodeCoverageSummary
 
@@ -49,6 +50,8 @@
 #include "gjs/jsapi-util.h"
 #include "gjs/macros.h"
 
+static bool s_coverage_enabled = false;
+
 struct _GjsCoverage {
     GObject parent;
 };
@@ -196,6 +199,13 @@ write_line(GOutputStream *out,
 
 [[nodiscard]] static GjsAutoUnref<GFile> write_statistics_internal(
     GjsCoverage* coverage, JSContext* cx, GError** error) {
+    if (!s_coverage_enabled) {
+        g_critical(
+            "Code coverage requested, but gjs_coverage_enable() was not called."
+            " You must call this function before creating any GjsContext.");
+        return nullptr;
+    }
+
     GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
 
     /* Create output directory if it doesn't exist */
@@ -304,7 +314,12 @@ gjs_coverage_write_statistics(GjsCoverage *coverage)
     g_message("Wrote coverage statistics to %s", output_file_path.get());
 }
 
-static void gjs_coverage_init(GjsCoverage*) {}
+static void gjs_coverage_init(GjsCoverage*) {
+    if (!s_coverage_enabled)
+        g_critical(
+            "Code coverage requested, but gjs_coverage_enable() was not called."
+            " You must call this function before creating any GjsContext.");
+}
 
 static void
 coverage_tracer(JSTracer *trc, void *data)
@@ -490,3 +505,16 @@ gjs_coverage_new (const char * const *prefixes,
 
     return coverage;
 }
+
+/**
+ * gjs_coverage_enable:
+ *
+ * This function must be called before creating any #GjsContext, if you intend
+ * to use any #GjsCoverage APIs.
+ *
+ * Since: 1.66
+ */
+void gjs_coverage_enable() {
+    js::EnableCodeCoverage();
+    s_coverage_enabled = true;
+}
diff --git a/gjs/coverage.h b/gjs/coverage.h
index 75acf4bb..fc4b0e55 100644
--- a/gjs/coverage.h
+++ b/gjs/coverage.h
@@ -43,6 +43,8 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE(GjsCoverage, gjs_coverage, GJS, COVERAGE, GObject);
 
+GJS_EXPORT void gjs_coverage_enable(void);
+
 GJS_EXPORT
 void gjs_coverage_write_statistics(GjsCoverage *self);
 
diff --git a/installed-tests/minijasmine.cpp b/installed-tests/minijasmine.cpp
index 3c73a226..b4a54f27 100644
--- a/installed-tests/minijasmine.cpp
+++ b/installed-tests/minijasmine.cpp
@@ -59,6 +59,9 @@ main(int argc, char **argv)
     const char *coverage_output_path = g_getenv("GJS_UNIT_COVERAGE_OUTPUT");
     const char *search_path[] = { "resource:///org/gjs/jsunit", NULL };
 
+    if (coverage_prefix)
+        gjs_coverage_enable();
+
     GjsContext *cx = gjs_context_new_with_search_path((char **)search_path);
     GjsCoverage *coverage = NULL;
 
diff --git a/test/gjs-test-coverage.cpp b/test/gjs-test-coverage.cpp
index 5273675b..0ddb3aa3 100644
--- a/test/gjs-test-coverage.cpp
+++ b/test/gjs-test-coverage.cpp
@@ -133,6 +133,7 @@ static void gjs_coverage_fixture_set_up(void* fixture_data, const void*) {
         NULL
     };
 
+    gjs_coverage_enable();
     fixture->context = gjs_context_new_with_search_path((char **) search_paths);
     fixture->coverage = gjs_coverage_new(coverage_paths, fixture->context,
                                          fixture->lcov_output_dir);


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