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
This commit is contained in:
Jeff Walden 2014-11-26 16:04:55 -05:00
Родитель ed080d201a
Коммит 6578f9c064
5 изменённых файлов: 105 добавлений и 99 удалений

Просмотреть файл

@ -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<Zone *>(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<GlobalObject *> 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)

Просмотреть файл

@ -229,7 +229,7 @@ GlobalObject::initBuiltinConstructor(JSContext *cx, Handle<GlobalObject*> 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<Zone *>(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<GlobalObject*> 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<GlobalObject*> global,
MutableHandleObject eval)

Просмотреть файл

@ -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<typename T>
inline void setCreateArrayFromBuffer(Handle<JSFunction*> 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

Просмотреть файл

@ -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_;

Просмотреть файл

@ -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<GlobalObject*> 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<GlobalObject*> shg(cx, &selfHostingGlobal_->as<GlobalObject>());
selfHostingGlobal_->compartment()->isSelfHosting = true;
selfHostingGlobal_->compartment()->isSystem = true;
if (!GlobalObject::initSelfHostingBuiltins(cx, shg, intrinsic_functions))
Rooted<GlobalObject*> 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<unsigned char *>(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;