[gjs/esm/static-imports: 60/63] console: Add --module evaluation option.
- From: Evan Welsh <ewlsh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/esm/static-imports: 60/63] console: Add --module evaluation option.
- Date: Mon, 23 Nov 2020 21:04:43 +0000 (UTC)
commit 963b6af0427a0692057da6b95af3ca59da0fdcbb
Author: Evan Welsh <noreply evanwelsh com>
Date: Wed Oct 28 19:21:53 2020 -0500
console: Add --module evaluation option.
gjs/console.cpp | 41 +++++++++++++++++++++++-----
gjs/context-private.h | 8 ++++++
gjs/context.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++++++++--
gjs/context.h | 13 +++++++++
4 files changed, 127 insertions(+), 9 deletions(-)
---
diff --git a/gjs/console.cpp b/gjs/console.cpp
index 9654f0b0..1c4aff07 100644
--- a/gjs/console.cpp
+++ b/gjs/console.cpp
@@ -5,6 +5,7 @@
#include <config.h> // for PACKAGE_STRING
#include <locale.h> // for setlocale, LC_ALL
+#include <stdint.h> // for uint8_t
#include <stdlib.h> // for exit
#include <string.h> // for strcmp, strlen
@@ -19,6 +20,7 @@
#include <glib.h>
#include <gjs/gjs.h>
+#include <gjs/jsapi-util.h>
static char **include_path = NULL;
static char **coverage_prefixes = NULL;
@@ -28,6 +30,7 @@ static char *command = NULL;
static gboolean print_version = false;
static gboolean print_js_version = false;
static gboolean debugging = false;
+static gboolean exec_as_module = false;
static bool enable_profiler = false;
static gboolean parse_profile_arg(const char *, const char *, void *, GError **);
@@ -41,6 +44,8 @@ static GOptionEntry entries[] = {
{ "coverage-prefix", 'C', 0, G_OPTION_ARG_STRING_ARRAY, &coverage_prefixes, "Add the prefix PREFIX to
the list of files to generate coverage info for", "PREFIX" },
{ "coverage-output", 0, 0, G_OPTION_ARG_STRING, &coverage_output_path, "Write coverage output to a
directory DIR. This option is mandatory when using --coverage-prefix", "DIR", },
{ "include-path", 'I', 0, G_OPTION_ARG_STRING_ARRAY, &include_path, "Add the directory DIR to the list
of directories to search for js files.", "DIR" },
+ { "module", 'm', 0, G_OPTION_ARG_NONE, &exec_as_module,
+ "Execute the input as a js module (implies strict mode)" },
{ "profile", 0, G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
G_OPTION_ARG_CALLBACK, reinterpret_cast<void *>(&parse_profile_arg),
"Enable the profiler and write output to FILE (default: gjs-$PID.syscap)",
@@ -173,7 +178,22 @@ int define_argv_and_eval_script(GjsContext* js_context, int argc,
/* evaluate the script */
int code;
- if (!gjs_context_eval(js_context, script, len, filename, &code, &error)) {
+ if (exec_as_module) {
+ GjsAutoUnref<GFile> output = g_file_new_for_commandline_arg(filename);
+ char* uri = g_file_get_uri(output);
+ if (!gjs_context_register_module(js_context, uri, uri, &error)) {
+ g_printerr("%s\n", error->message);
+ code = 1;
+ }
+
+ uint8_t code_8 = 0;
+ if (!gjs_context_eval_module(js_context, uri, &code_8, &error)) {
+ code = code_8;
+ if (!g_error_matches(error, GJS_ERROR, GJS_ERROR_SYSTEM_EXIT))
+ g_critical("%s", error->message);
+ }
+ } else if (!gjs_context_eval(js_context, script, len, filename, &code,
+ &error)) {
if (!g_error_matches(error, GJS_ERROR, GJS_ERROR_SYSTEM_EXIT))
g_critical("%s", error->message);
g_clear_error(&error);
@@ -240,6 +260,7 @@ main(int argc, char **argv)
print_version = false;
print_js_version = false;
debugging = false;
+ exec_as_module = false;
g_option_context_set_ignore_unknown_options(context, false);
g_option_context_set_help_enabled(context, true);
if (!g_option_context_parse_strv(context, &gjs_argv, &error)) {
@@ -269,7 +290,14 @@ main(int argc, char **argv)
filename = "<command line>";
program_name = gjs_argv[0];
} else if (gjs_argc == 1) {
- script = g_strdup("const Console = imports.console; Console.interact();");
+ if (exec_as_module) {
+ script = g_strdup(
+ "throw new Error('Console interaction is not implemented with "
+ "the --module option. Exiting with error.')");
+ } else {
+ script = g_strdup(
+ "const Console = imports.console; Console.interact();");
+ }
len = strlen(script);
filename = "<stdin>";
program_name = gjs_argv[0];
@@ -315,11 +343,10 @@ main(int argc, char **argv)
if (coverage_prefixes)
gjs_coverage_enable();
- js_context = (GjsContext*) g_object_new(GJS_TYPE_CONTEXT,
- "search-path", include_path,
- "program-name", program_name,
- "profiler-enabled", enable_profiler,
- NULL);
+ js_context = (GjsContext*)g_object_new(
+ GJS_TYPE_CONTEXT, "search-path", include_path, "program-name",
+ program_name, "profiler-enabled", enable_profiler, "modules",
+ exec_as_module, NULL);
env_coverage_output_path = g_getenv("GJS_COVERAGE_OUTPUT");
if (env_coverage_output_path != NULL) {
diff --git a/gjs/context-private.h b/gjs/context-private.h
index e5af87e5..5f1aec75 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -123,6 +123,7 @@ class GjsContextPrivate : public JS::JobQueue {
bool m_force_gc : 1;
bool m_draining_job_queue : 1;
bool m_should_profile : 1;
+ bool m_exec_as_module : 1;
bool m_should_listen_sigusr2 : 1;
int64_t m_sweep_begin_time;
@@ -176,6 +177,7 @@ class GjsContextPrivate : public JS::JobQueue {
void set_program_name(char* value) { m_program_name = value; }
void set_search_path(char** value) { m_search_path = value; }
void set_should_profile(bool value) { m_should_profile = value; }
+ void set_execute_as_module(bool value) { m_exec_as_module = value; }
void set_should_listen_sigusr2(bool value) {
m_should_listen_sigusr2 = value;
}
@@ -203,6 +205,9 @@ class GjsContextPrivate : public JS::JobQueue {
ssize_t script_len, const char* filename,
JS::MutableHandleValue retval);
GJS_JSAPI_RETURN_CONVENTION
+ bool eval_module(const char* identifier, uint8_t* exit_code_p,
+ GError** error);
+ GJS_JSAPI_RETURN_CONVENTION
bool call_function(JS::HandleObject this_obj, JS::HandleValue func_val,
const JS::HandleValueArray& args,
JS::MutableHandleValue rval);
@@ -230,6 +235,9 @@ class GjsContextPrivate : public JS::JobQueue {
void register_unhandled_promise_rejection(uint64_t id, GjsAutoChar&& stack);
void unregister_unhandled_promise_rejection(uint64_t id);
+ bool register_module(const char* identifier, const char* filename,
+ GError** error);
+
void set_sweeping(bool value);
static void trace(JSTracer* trc, void* data);
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 401583c7..5a430015 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -5,7 +5,7 @@
#include <config.h>
#include <signal.h> // for sigaction, SIGUSR1, sa_handler
-#include <stdint.h>
+#include <stdint.h> // for uint64_t
#include <stdio.h> // for FILE, fclose, size_t
#include <string.h> // for memset
@@ -125,6 +125,7 @@ enum {
PROP_PROGRAM_NAME,
PROP_PROFILER_ENABLED,
PROP_PROFILER_SIGUSR2,
+ PROP_MODULES_ENABLED,
};
static GMutex contexts_lock;
@@ -274,6 +275,13 @@ gjs_context_class_init(GjsContextClass *klass)
g_object_class_install_property(object_class, PROP_PROFILER_SIGUSR2, pspec);
g_param_spec_unref(pspec);
+ pspec = g_param_spec_boolean(
+ "modules", "Modules enabled",
+ "Whether to profile JS code run by this context", FALSE,
+ GParamFlags(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property(object_class, PROP_MODULES_ENABLED, pspec);
+ g_param_spec_unref(pspec);
+
/* For GjsPrivate */
{
#ifdef G_OS_WIN32
@@ -549,8 +557,11 @@ gjs_context_set_property (GObject *object,
case PROP_PROFILER_SIGUSR2:
gjs->set_should_listen_sigusr2(g_value_get_boolean(value));
break;
+ case PROP_MODULES_ENABLED:
+ gjs->set_execute_as_module(g_value_get_boolean(value));
+ break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
@@ -915,6 +926,26 @@ gjs_context_eval(GjsContext *js_context,
return gjs->eval(script, script_len, filename, exit_status_p, error);
}
+bool gjs_context_eval_module(GjsContext* js_context, const char* name,
+ uint8_t* exit_code, GError** error) {
+ g_return_val_if_fail(GJS_IS_CONTEXT(js_context), false);
+
+ GjsAutoUnref<GjsContext> js_context_ref(js_context, GjsAutoTakeOwnership());
+
+ GjsContextPrivate* gjs = GjsContextPrivate::from_object(js_context);
+ return gjs->eval_module(name, exit_code, error);
+}
+
+bool gjs_context_register_module(GjsContext* js_context, const char* identifier,
+ const char* filename, GError** error) {
+ g_return_val_if_fail(GJS_IS_CONTEXT(js_context), false);
+
+ GjsAutoUnref<GjsContext> js_context_ref(js_context, GjsAutoTakeOwnership());
+
+ GjsContextPrivate* gjs = GjsContextPrivate::from_object(js_context);
+ return gjs->register_module(identifier, filename, error);
+}
+
bool GjsContextPrivate::eval(const char* script, ssize_t script_len,
const char* filename, int* exit_status_p,
GError** error) {
@@ -987,6 +1018,36 @@ bool GjsContextPrivate::eval(const char* script, ssize_t script_len,
return true;
}
+bool GjsContextPrivate::eval_module(const char* identifier,
+ uint8_t* exit_status_p, GError** error) {
+ // TODO(ewlsh): Implement eval_module
+ g_print("GjsContextPrivate::eval_module called on identifier %s.",
+ identifier);
+
+ *exit_status_p = 1;
+ *error = nullptr;
+
+ g_error(
+ "GjsContextPrivate::eval_module is not implemented. Exiting with "
+ "error.");
+
+ return false;
+}
+
+bool GjsContextPrivate::register_module(const char* identifier,
+ const char* filename,
+ GError** error G_GNUC_UNUSED) {
+ // TODO(ewlsh): Implement register_module
+ g_warning(
+ "GjsContextPrivate::register_module is not yet implemented. Printing "
+ "module...");
+
+ *error = nullptr;
+
+ g_warning("Identifier: %s\nFilename: %s\n", identifier, filename);
+ return true;
+}
+
bool
gjs_context_eval_file(GjsContext *js_context,
const char *filename,
@@ -1006,6 +1067,15 @@ gjs_context_eval_file(GjsContext *js_context,
exit_status_p, error);
}
+bool gjs_context_eval_module_file(GjsContext* js_context, const char* filename,
+ uint8_t* exit_status_p, GError** error) {
+ GjsAutoUnref<GFile> file = g_file_new_for_commandline_arg(filename);
+ char* fileuri = g_file_get_uri(file);
+
+ return gjs_context_register_module(js_context, fileuri, fileuri, error) &&
+ gjs_context_eval_module(js_context, fileuri, exit_status_p, error);
+}
+
/*
* GjsContextPrivate::eval_with_scope:
* @scope_object: an object to use as the global scope, or nullptr
diff --git a/gjs/context.h b/gjs/context.h
index 43f936b5..af0a9d33 100644
--- a/gjs/context.h
+++ b/gjs/context.h
@@ -12,6 +12,7 @@
#endif
#include <stdbool.h> /* IWYU pragma: keep */
+#include <stdint.h>
#ifndef _WIN32
# include <signal.h> /* for siginfo_t */
@@ -44,10 +45,22 @@ GJS_EXPORT GJS_USE bool gjs_context_eval_file(GjsContext* js_context,
const char* filename,
int* exit_status_p,
GError** error);
+GJS_EXPORT GJS_USE bool gjs_context_eval_module_file(GjsContext* js_context,
+ const char* filename,
+ uint8_t* exit_status_p,
+ GError** error);
GJS_EXPORT GJS_USE bool gjs_context_eval(GjsContext* js_context,
const char* script, gssize script_len,
const char* filename,
int* exit_status_p, GError** error);
+GJS_EXPORT GJS_USE bool gjs_context_register_module(GjsContext* context,
+ const char* name,
+ const char* filename,
+ GError** error);
+GJS_EXPORT GJS_USE bool gjs_context_eval_module(GjsContext* context,
+ const char* name,
+ uint8_t* exit_code,
+ GError** error);
GJS_EXPORT GJS_USE bool gjs_context_define_string_array(
GjsContext* js_context, const char* array_name, gssize array_length,
const char** array_values, GError** error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]