[gjs/wip/ptomato/develop: 7/12] global: Add a bootstrap system
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/ptomato/develop: 7/12] global: Add a bootstrap system
- Date: Tue, 19 Sep 2017 04:52:27 +0000 (UTC)
commit 8a8e79d80c7bc75e9a7e8f46c9481ff6f64772bd
Author: Philip Chimento <philip chimento gmail com>
Date: Sat Sep 9 17:13:24 2017 -0700
global: Add a bootstrap system
Based on a patch by Jasper St. Pierre. This allows executing a JS script
(which must be a resource in the directory
resource:///org/gnome/gtk/modules/_bootstrap) in order to define extra
properties on a global object when the global object is created.
This is currently not used for anything, but will be used for the code
coverage compartment, and likely for a debugger as well. It can also be
used to implement things in JS that are currently implemented in C++,
like the log() and logError() functions.
https://bugzilla.gnome.org/show_bug.cgi?id=777724
gjs/context.cpp | 2 +-
gjs/global.cpp | 64 ++++++++++++++++++++++++++++++++++++----
gjs/global.h | 3 +-
modules/_bootstrap/default.js | 7 ++++
modules/modules.gresource.xml | 2 +
5 files changed, 69 insertions(+), 9 deletions(-)
---
diff --git a/gjs/context.cpp b/gjs/context.cpp
index c105118..0aaa686 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -342,7 +342,7 @@ gjs_context_constructed(GObject *object)
gjs_set_global_slot(cx, GJS_GLOBAL_SLOT_IMPORTS, JS::ObjectValue(*importer));
- if (!gjs_define_global_properties(cx, global)) {
+ if (!gjs_define_global_properties(cx, global, "default")) {
gjs_log_exception(cx);
g_error("Failed to define properties on global object");
}
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 7d41273..b5bead7 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -31,6 +31,41 @@
#include "jsapi-wrapper.h"
static bool
+run_bootstrap(JSContext *cx,
+ const char *bootstrap_script,
+ JS::HandleObject global)
+{
+ char *script_ptr;
+ size_t script_len;
+ GError *error = nullptr;
+
+ GjsAutoChar uri = g_strdup_printf("resource:///org/gnome/gjs/modules/_bootstrap/%s.js",
+ bootstrap_script);
+ GjsAutoUnref<GFile> file = g_file_new_for_uri(uri);
+
+ if (!g_file_load_contents(file, nullptr, &script_ptr, &script_len, nullptr,
+ &error)) {
+ gjs_throw_g_error(cx, error);
+ return false;
+ }
+
+ GjsAutoChar script(script_ptr);
+ JSAutoCompartment ac(cx, global);
+
+ JS::CompileOptions options(cx);
+ options.setUTF8(true)
+ .setFileAndLine(uri, 1)
+ .setSourceIsLazy(true);
+
+ JS::RootedScript compiled_script(cx);
+ if (!JS::Compile(cx, options, script, script_len, &compiled_script))
+ return false;
+
+ JS::RootedValue ignored(cx);
+ return JS::CloneAndExecuteScript(cx, compiled_script, &ignored);
+}
+
+static bool
gjs_log(JSContext *cx,
unsigned argc,
JS::Value *vp)
@@ -225,7 +260,8 @@ public:
static bool
define_properties(JSContext *cx,
- JS::HandleObject global)
+ JS::HandleObject global,
+ const char *bootstrap_script)
{
if (!JS_DefineProperty(cx, global, "window", global,
JSPROP_READONLY | JSPROP_PERMANENT) ||
@@ -240,9 +276,17 @@ public:
/* Wrapping is a no-op if the importer is already in the same
* compartment. */
- return JS_WrapObject(cx, &root_importer) &&
- gjs_object_define_property(cx, global, GJS_STRING_IMPORTS,
- root_importer, GJS_MODULE_PROP_FLAGS);
+ if (!JS_WrapObject(cx, &root_importer) ||
+ !gjs_object_define_property(cx, global, GJS_STRING_IMPORTS,
+ root_importer, GJS_MODULE_PROP_FLAGS))
+ return false;
+
+ if (bootstrap_script) {
+ if (!run_bootstrap(cx, bootstrap_script, global))
+ return false;
+ }
+
+ return true;
}
};
@@ -265,8 +309,13 @@ gjs_create_global_object(JSContext *cx)
* gjs_define_global_properties:
* @cx: a #JSContext
* @global: a JS global object that has not yet been passed to this function
+ * @bootstrap_script: (nullable): name of a bootstrap script (found at
+ * resource://org/gnome/gjs/modules/_bootstrap/@bootstrap_script) or %NULL for
+ * none
*
- * Defines properties on the global object such as 'window' and 'imports'.
+ * Defines properties on the global object such as 'window' and 'imports', and
+ * runs a bootstrap JS script on the global object to define any properties
+ * that can be defined from JS.
* This function completes the initialization of a new global object, but it
* is separate from gjs_create_global_object() because all globals share the
* same root importer.
@@ -283,9 +332,10 @@ gjs_create_global_object(JSContext *cx)
*/
bool
gjs_define_global_properties(JSContext *cx,
- JS::HandleObject global)
+ JS::HandleObject global,
+ const char *bootstrap_script)
{
- return GjsGlobal::define_properties(cx, global);
+ return GjsGlobal::define_properties(cx, global, bootstrap_script);
}
void
diff --git a/gjs/global.h b/gjs/global.h
index 31056d6..ae99b15 100644
--- a/gjs/global.h
+++ b/gjs/global.h
@@ -58,7 +58,8 @@ typedef enum {
JSObject *gjs_create_global_object(JSContext *cx);
bool gjs_define_global_properties(JSContext *cx,
- JS::HandleObject global);
+ JS::HandleObject global,
+ const char *bootstrap_script);
JS::Value gjs_get_global_slot(JSContext *cx,
GjsGlobalSlot slot);
diff --git a/modules/_bootstrap/default.js b/modules/_bootstrap/default.js
new file mode 100644
index 0000000..29dbdb1
--- /dev/null
+++ b/modules/_bootstrap/default.js
@@ -0,0 +1,7 @@
+(function(exports) {
+ 'use strict';
+
+ // Do early initialization here.
+ void exports;
+
+})(window);
diff --git a/modules/modules.gresource.xml b/modules/modules.gresource.xml
index 2f7cfb6..9ffa492 100644
--- a/modules/modules.gresource.xml
+++ b/modules/modules.gresource.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/gjs">
+ <file>modules/_bootstrap/default.js</file>
+
<file>modules/tweener/equations.js</file>
<file>modules/tweener/tweener.js</file>
<file>modules/tweener/tweenList.js</file>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]