зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
ed080d201a
Коммит
6578f9c064
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче