From 6578f9c0647c18f74722aa5888fb2bead80763e9 Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Wed, 26 Nov 2014 16:04:55 -0500 Subject: [PATCH] Bug 1052139 - Refactor global-object creation code to distinguish the unique self-hosting global from all other run-of-the-mill globals. r=till --HG-- extra : rebase_source : fe126e03e2fa778fdee3420ad5c39f00caea2495 --- js/src/jsapi.cpp | 69 +--------------------------------- js/src/vm/GlobalObject.cpp | 44 +++++++++++++++++++++- js/src/vm/GlobalObject.h | 12 +++++- js/src/vm/Runtime.h | 3 ++ js/src/vm/SelfHosting.cpp | 76 +++++++++++++++++++++++--------------- 5 files changed, 105 insertions(+), 99 deletions(-) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index e1a8ea861784..4c6aa7f467c7 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2308,39 +2308,6 @@ JS_GetConstructor(JSContext *cx, HandleObject proto) return &cval.toObject(); } -namespace { - -class AutoCompartmentRooter : private JS::CustomAutoRooter -{ - public: - explicit AutoCompartmentRooter(JSContext *cx, JSCompartment *comp - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : CustomAutoRooter(cx), compartment(comp) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - operator JSCompartment *() { - return compartment; - } - - JSCompartment *operator->() { - return compartment; - } - - protected: - virtual void trace(JSTracer *trc) - { - compartment->mark(); - } - - private: - JSCompartment *compartment; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -} /* anonymous namespace */ - bool JS::CompartmentOptions::extraWarnings(JSRuntime *rt) const { @@ -2392,42 +2359,8 @@ JS_NewGlobalObject(JSContext *cx, const JSClass *clasp, JSPrincipals *principals { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); - MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); - MOZ_ASSERT(!cx->isExceptionPending()); - JSRuntime *rt = cx->runtime(); - - Zone *zone; - if (options.zoneSpecifier() == JS::SystemZone) - zone = rt->gc.systemZone; - else if (options.zoneSpecifier() == JS::FreshZone) - zone = nullptr; - else - zone = static_cast(options.zonePointer()); - - AutoCompartmentRooter compartment(cx, NewCompartment(cx, zone, principals, options)); - if (!compartment) - return nullptr; - - // Lazily create the system zone. - if (!rt->gc.systemZone && options.zoneSpecifier() == JS::SystemZone) { - rt->gc.systemZone = compartment->zone(); - rt->gc.systemZone->isSystem = true; - } - - Rooted global(cx); - { - AutoCompartment ac(cx, compartment); - global = GlobalObject::create(cx, Valueify(clasp)); - } - - if (!global) - return nullptr; - - if (hookOption == JS::FireOnNewGlobalHook) - JS_FireOnNewGlobalObject(cx, global); - - return global; + return GlobalObject::new_(cx, Valueify(clasp), principals, hookOption, options); } JS_PUBLIC_API(void) diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 18c5c1d8cbce..ea00056d906e 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -229,7 +229,7 @@ GlobalObject::initBuiltinConstructor(JSContext *cx, Handle global } GlobalObject * -GlobalObject::create(JSContext *cx, const Class *clasp) +GlobalObject::createInternal(JSContext *cx, const Class *clasp) { MOZ_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL); MOZ_ASSERT(clasp->trace == JS_GlobalObjectTraceHook); @@ -257,6 +257,48 @@ GlobalObject::create(JSContext *cx, const Class *clasp) return global; } +GlobalObject * +GlobalObject::new_(JSContext *cx, const Class *clasp, JSPrincipals *principals, + JS::OnNewGlobalHookOption hookOption, + const JS::CompartmentOptions &options) +{ + MOZ_ASSERT(!cx->isExceptionPending()); + MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); + + JSRuntime *rt = cx->runtime(); + + Zone *zone; + if (options.zoneSpecifier() == JS::SystemZone) + zone = rt->gc.systemZone; + else if (options.zoneSpecifier() == JS::FreshZone) + zone = nullptr; + else + zone = static_cast(options.zonePointer()); + + JSCompartment *compartment = NewCompartment(cx, zone, principals, options); + if (!compartment) + return nullptr; + + // Lazily create the system zone. + if (!rt->gc.systemZone && options.zoneSpecifier() == JS::SystemZone) { + rt->gc.systemZone = compartment->zone(); + rt->gc.systemZone->isSystem = true; + } + + Rooted global(cx); + { + AutoCompartment ac(cx, compartment); + global = GlobalObject::createInternal(cx, clasp); + if (!global) + return nullptr; + } + + if (hookOption == JS::FireOnNewGlobalHook) + JS_FireOnNewGlobalObject(cx, global); + + return global; +} + /* static */ bool GlobalObject::getOrCreateEval(JSContext *cx, Handle global, MutableHandleObject eval) diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h index 80a16064b661..d778c2f23339 100644 --- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -17,6 +17,7 @@ #include "js/Vector.h" #include "vm/ArrayBufferObject.h" #include "vm/ErrorObject.h" +#include "vm/Runtime.h" extern JSObject * js_InitSharedArrayBufferClass(JSContext *cx, js::HandleObject obj); @@ -259,8 +260,17 @@ class GlobalObject : public NativeObject template inline void setCreateArrayFromBuffer(Handle fun); + private: + // Disallow use of unqualified JSObject::create in GlobalObject. + static GlobalObject *create(...) MOZ_DELETE; + + friend struct ::JSRuntime; + static GlobalObject *createInternal(JSContext *cx, const Class *clasp); + public: - static GlobalObject *create(JSContext *cx, const Class *clasp); + static GlobalObject * + new_(JSContext *cx, const Class *clasp, JSPrincipals *principals, + JS::OnNewGlobalHookOption hookOption, const JS::CompartmentOptions &options); /* * Create a constructor function with the specified name and length using diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 55c040be182a..85a8515ddf04 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -841,6 +841,9 @@ struct JSRuntime : public JS::shadow::Runtime, */ js::NativeObject *selfHostingGlobal_; + static js::GlobalObject * + createSelfHostingGlobal(JSContext *cx); + /* Space for interpreter frames. */ js::InterpreterStack interpreterStack_; diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 2917752cc2b0..171b342da423 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -49,16 +49,6 @@ selfHosting_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep PrintError(cx, stderr, message, report, true); } -static const JSClass self_hosting_global_class = { - "self-hosting-global", JSCLASS_GLOBAL_FLAGS, - JS_PropertyStub, JS_DeletePropertyStub, - JS_PropertyStub, JS_StrictPropertyStub, - JS_EnumerateStub, JS_ResolveStub, - JS_ConvertStub, nullptr, - nullptr, nullptr, nullptr, - JS_GlobalObjectTraceHook -}; - bool js::intrinsic_ToObject(JSContext *cx, unsigned argc, Value *vp) { @@ -1233,6 +1223,47 @@ js::FillSelfHostingCompileOptions(CompileOptions &options) #endif } +GlobalObject * +JSRuntime::createSelfHostingGlobal(JSContext *cx) +{ + MOZ_ASSERT(!cx->isExceptionPending()); + MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); + + JS::CompartmentOptions options; + options.setDiscardSource(true); + options.setZone(JS::FreshZone); + + JSCompartment *compartment = NewCompartment(cx, nullptr, nullptr, options); + if (!compartment) + return nullptr; + + static const Class shgClass = { + "self-hosting-global", JSCLASS_GLOBAL_FLAGS, + JS_PropertyStub, JS_DeletePropertyStub, + JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, + JS_ConvertStub, nullptr, + nullptr, nullptr, nullptr, + JS_GlobalObjectTraceHook + }; + + AutoCompartment ac(cx, compartment); + Rooted shg(cx, GlobalObject::createInternal(cx, &shgClass)); + if (!shg) + return nullptr; + + cx->runtime()->selfHostingGlobal_ = shg; + compartment->isSelfHosting = true; + compartment->isSystem = true; + + if (!GlobalObject::initSelfHostingBuiltins(cx, shg, intrinsic_functions)) + return nullptr; + + JS_FireOnNewGlobalObject(cx, shg); + + return shg; +} + bool JSRuntime::initSelfHosting(JSContext *cx) { @@ -1249,24 +1280,11 @@ JSRuntime::initSelfHosting(JSContext *cx) */ JS::AutoDisableGenerationalGC disable(cx->runtime()); - JS::CompartmentOptions compartmentOptions; - compartmentOptions.setDiscardSource(true); - if (!(selfHostingGlobal_ = MaybeNativeObject(JS_NewGlobalObject(cx, &self_hosting_global_class, - nullptr, JS::DontFireOnNewGlobalHook, - compartmentOptions)))) - { - return false; - } - - JSAutoCompartment ac(cx, selfHostingGlobal_); - Rooted shg(cx, &selfHostingGlobal_->as()); - selfHostingGlobal_->compartment()->isSelfHosting = true; - selfHostingGlobal_->compartment()->isSystem = true; - - if (!GlobalObject::initSelfHostingBuiltins(cx, shg, intrinsic_functions)) + Rooted shg(cx, JSRuntime::createSelfHostingGlobal(cx)); + if (!shg) return false; - JS_FireOnNewGlobalObject(cx, shg); + JSAutoCompartment ac(cx, shg); CompileOptions options(cx); FillSelfHostingCompileOptions(options); @@ -1278,7 +1296,7 @@ JSRuntime::initSelfHosting(JSContext *cx) */ JSErrorReporter oldReporter = JS_SetErrorReporter(cx->runtime(), selfHosting_ErrorReporter); RootedValue rv(cx); - bool ok = false; + bool ok = true; char *filename = getenv("MOZ_SELFHOSTEDJS"); if (filename) { @@ -1294,10 +1312,10 @@ JSRuntime::initSelfHosting(JSContext *cx) if (!src || !DecompressString(compressed, compressedLen, reinterpret_cast(src.get()), srcLen)) { - return false; + ok = false; } - ok = Evaluate(cx, shg, options, src, srcLen, &rv); + ok = ok && Evaluate(cx, shg, options, src, srcLen, &rv); } JS_SetErrorReporter(cx->runtime(), oldReporter); return ok;