Skip to content

Commit 1a575d5

Browse files
Expose the init script global to builtins (#227)
This way, builtins can add things to the global for the init script to use. Also exposes the content global as `contentGlobal` in the init script global.
1 parent d9c95e6 commit 1a575d5

File tree

2 files changed

+67
-38
lines changed

2 files changed

+67
-38
lines changed

include/extension-api.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ class Engine {
8484

8585
void finish_pre_initialization();
8686

87-
8887
/**
8988
* Define a new builtin module
9089
*
@@ -120,6 +119,11 @@ class Engine {
120119
*/
121120
bool run_initialization_script();
122121

122+
/**
123+
* Returns the global the initialization script runs in.
124+
*/
125+
HandleObject init_script_global();
126+
123127
/**
124128
* Run the async event loop as long as there's interest registered in keeping it running.
125129
*

runtime/engine.cpp

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ void dump_promise_rejection(JSContext *cx, HandleValue reason, HandleObject prom
199199
static JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS, &JS::DefaultGlobalClassOps};
200200

201201
JS::PersistentRootedObject GLOBAL;
202+
JS::PersistentRootedObject INIT_SCRIPT_GLOBAL;
202203
static ScriptLoader* scriptLoader;
203204
JS::PersistentRootedObject unhandledRejectedPromises;
204205

@@ -256,6 +257,62 @@ bool fix_math_random(JSContext *cx, HandleObject global) {
256257
static Engine *ENGINE;
257258
JS::PersistentRootedValue SCRIPT_VALUE;
258259

260+
bool create_content_global(JSContext * cx) {
261+
JS::RealmOptions options;
262+
options.creationOptions().setStreamsEnabled(true);
263+
264+
JS::DisableIncrementalGC(cx);
265+
// JS_SetGCParameter(cx, JSGC_MAX_EMPTY_CHUNK_COUNT, 1);
266+
267+
RootedObject global(
268+
cx, JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook, options));
269+
if (!global) {
270+
return false;
271+
}
272+
273+
JSAutoRealm ar(cx, global);
274+
if (!JS::InitRealmStandardClasses(cx) || !fix_math_random(cx, global)) {
275+
return false;
276+
}
277+
278+
GLOBAL.init(cx, global);
279+
return true;
280+
}
281+
282+
static bool define_builtin_module(JSContext *cx, unsigned argc, Value *vp);
283+
284+
bool create_initializer_global(Engine *engine) {
285+
auto cx = engine->cx();
286+
287+
JS::RealmOptions options;
288+
options.creationOptions()
289+
.setStreamsEnabled(true)
290+
.setExistingCompartment(engine->global());
291+
292+
static JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS, &JS::DefaultGlobalClassOps};
293+
RootedObject global(cx);
294+
global = JS_NewGlobalObject(cx, &global_class, nullptr, JS::DontFireOnNewGlobalHook, options);
295+
if (!global) {
296+
return false;
297+
}
298+
299+
JSAutoRealm ar(cx, global);
300+
301+
if (!JS_DefineFunction(cx, global, "defineBuiltinModule", ::define_builtin_module, 2, 0) ||
302+
!JS_DefineProperty(cx, global, "contentGlobal", ENGINE->global(), JSPROP_READONLY)) {
303+
return false;
304+
}
305+
306+
#ifdef JS_DEBUGGER
307+
if (!JS_DefineFunction(cx, global, "print", content_debugger::dbg_print, 1, 0)) {
308+
return false;
309+
}
310+
#endif
311+
312+
INIT_SCRIPT_GLOBAL.init(cx, global);
313+
return true;
314+
}
315+
259316
bool init_js() {
260317
JS_Init();
261318

@@ -278,24 +335,11 @@ bool init_js() {
278335
cx, JSJitCompilerOption::JSJITCOMPILER_PORTABLE_BASELINE_WARMUP_THRESHOLD, 0);
279336
}
280337

281-
// TODO: check if we should set a different creation zone.
282-
JS::RealmOptions options;
283-
options.creationOptions().setStreamsEnabled(true);
284-
285-
JS::DisableIncrementalGC(cx);
286-
// JS_SetGCParameter(cx, JSGC_MAX_EMPTY_CHUNK_COUNT, 1);
287-
288-
RootedObject global(
289-
cx, JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook, options));
290-
if (!global) {
338+
if (!create_content_global(cx) || !create_initializer_global(ENGINE)) {
291339
return false;
292340
}
293-
GLOBAL.init(cx, global);
294341

295-
JSAutoRealm ar(cx, global);
296-
if (!JS::InitRealmStandardClasses(cx) || !fix_math_random(cx, global)) {
297-
return false;
298-
}
342+
JSAutoRealm ar(cx, GLOBAL);
299343

300344
JS::SetPromiseRejectionTrackerCallback(cx, rejection_tracker);
301345
unhandledRejectedPromises.init(cx, JS::NewSetObject(cx));
@@ -528,28 +572,7 @@ static bool define_builtin_module(JSContext *cx, unsigned argc, Value *vp) {
528572
bool Engine::run_initialization_script() {
529573
auto cx = this->cx();
530574

531-
JS::RealmOptions options;
532-
options.creationOptions()
533-
.setStreamsEnabled(true)
534-
.setExistingCompartment(this->global());
535-
536-
static JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS, &JS::DefaultGlobalClassOps};
537-
RootedObject global(cx);
538-
global = JS_NewGlobalObject(cx, &global_class, nullptr, JS::DontFireOnNewGlobalHook, options);
539-
if (!global) {
540-
return false;
541-
}
542-
543-
JSAutoRealm ar(cx, global);
544-
545-
if (!JS_DefineFunction(cx, global, "defineBuiltinModule", ::define_builtin_module, 2, 0)) {
546-
return false;
547-
}
548-
#ifdef JS_DEBUGGER
549-
if (!JS_DefineFunction(cx, global, "print", content_debugger::dbg_print, 1, 0)) {
550-
return false;
551-
}
552-
#endif
575+
JSAutoRealm ar(cx, INIT_SCRIPT_GLOBAL);
553576

554577
auto path = config_->initializer_script_path.value();
555578
TRACE("Running initialization script from file " << path);
@@ -568,6 +591,8 @@ bool Engine::run_initialization_script() {
568591
return JS_ExecuteScript(cx, script, &result);
569592
}
570593

594+
HandleObject Engine::init_script_global() { return INIT_SCRIPT_GLOBAL; }
595+
571596
bool Engine::eval_toplevel(JS::SourceText<mozilla::Utf8Unit> &source, const char *path,
572597
MutableHandleValue result) {
573598
MOZ_ASSERT(state() > EngineState::EngineInitializing, "Engine must be done initializing");

0 commit comments

Comments
 (0)