Bug 1468406 part 4 - Remove remaining JSObject::realm() calls. r=luke

This commit is contained in:
Jan de Mooij 2018-06-20 11:04:02 +02:00
Родитель 5070dbcceb
Коммит d1ca5feadb
19 изменённых файлов: 106 добавлений и 40 удалений

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

@ -1360,7 +1360,7 @@ CaptureFirstSubsumedFrame(JSContext* cx, unsigned argc, JS::Value* vp)
return false;
}
JS::StackCapture capture(JS::FirstSubsumedFrame(cx, obj->realm()->principals()));
JS::StackCapture capture(JS::FirstSubsumedFrame(cx, obj->nonCCWRealm()->principals()));
if (args.length() > 1)
capture.as<JS::FirstSubsumedFrame>().ignoreSelfHosted = JS::ToBoolean(args[1]);

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

@ -1128,7 +1128,7 @@ GetPropIRGenerator::tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperan
// so we optimize for that case as well.
isWindowProxy = IsWindowProxy(unwrapped);
if (isWindowProxy) {
MOZ_ASSERT(ToWindowIfWindowProxy(unwrapped) == unwrapped->realm()->maybeGlobal());
MOZ_ASSERT(ToWindowIfWindowProxy(unwrapped) == &unwrapped->nonCCWGlobal());
unwrapped = cx_->global();
MOZ_ASSERT(unwrapped);
}

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

@ -7,6 +7,8 @@
#include "jsapi-tests/tests.h"
#include "vm/JSObject-inl.h"
using namespace JS;
static void
@ -28,7 +30,7 @@ unsigned
countIonScripts(JSObject* global)
{
unsigned count = 0;
js::IterateScripts(cx, global->realm(), &count, ScriptCallback);
js::IterateScripts(cx, global->nonCCWRealm(), &count, ScriptCallback);
return count;
}

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

@ -12,6 +12,8 @@
#include "vm/Realm.h"
#include "vm/SavedFrame.h"
#include "vm/JSObject-inl.h"
using JS::RootedObject;
using JS::RootedScript;
using JS::RootedString;
@ -128,8 +130,8 @@ BEGIN_TEST(test_ubiNodeCompartment)
CHECK(global1->compartment() != global2->compartment());
CHECK(JS::ubi::Node(global2).compartment() == global2->compartment());
CHECK(JS::ubi::Node(global2).compartment() != global1->compartment());
CHECK(JS::ubi::Node(global2).realm() == global2->realm());
CHECK(JS::ubi::Node(global2).realm() != global1->realm());
CHECK(JS::ubi::Node(global2).realm() == global2->nonCCWRealm());
CHECK(JS::ubi::Node(global2).realm() != global1->nonCCWRealm());
JS::CompileOptions options(cx);
@ -147,8 +149,8 @@ BEGIN_TEST(test_ubiNodeCompartment)
CHECK(JS::ubi::Node(script1).compartment() == global1->compartment());
CHECK(JS::ubi::Node(script2).compartment() == global2->compartment());
CHECK(JS::ubi::Node(script1).realm() == global1->realm());
CHECK(JS::ubi::Node(script2).realm() == global2->realm());
CHECK(JS::ubi::Node(script1).realm() == global1->nonCCWRealm());
CHECK(JS::ubi::Node(script2).realm() == global2->nonCCWRealm());
// Now create a wrapper for global1 in global2's compartment.
RootedObject wrappedGlobal1(cx, global1);

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

@ -885,7 +885,7 @@ JS_TransplantObject(JSContext* cx, HandleObject origobj, HandleObject target)
// destination, then we know that we won't find a wrapper in the
// destination's cross compartment map and that the same
// object will continue to work.
AutoRealmUnchecked ar(cx, origobj->realm());
AutoRealmUnchecked ar(cx, origobj->deprecatedRealm());
if (!JSObject::swap(cx, origobj, target))
MOZ_CRASH();
newIdentity = origobj;
@ -919,7 +919,7 @@ JS_TransplantObject(JSContext* cx, HandleObject origobj, HandleObject target)
// Lastly, update the original object to point to the new one.
if (origobj->compartment() != destination) {
RootedObject newIdentityWrapper(cx, newIdentity);
AutoRealmUnchecked ar(cx, origobj->realm());
AutoRealmUnchecked ar(cx, origobj->deprecatedRealm());
if (!JS_WrapObject(cx, &newIdentityWrapper))
MOZ_CRASH();
MOZ_ASSERT(Wrapper::wrappedObject(newIdentityWrapper) == newIdentity);

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

@ -614,7 +614,7 @@ js::RemapWrapper(JSContext* cx, JSObject* wobjArg, JSObject* newTargetArg)
MOZ_ASSERT(!JS_IsDeadWrapper(origTarget),
"We don't want a dead proxy in the wrapper map");
Value origv = ObjectValue(*origTarget);
Realm* wrealm = wobj->realm();
Realm* wrealm = wobj->deprecatedRealm();
JS::Compartment* wcompartment = wobj->compartment();
AutoDisableProxyCheck adpc;

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

@ -10669,7 +10669,7 @@ DebuggerObject::unwrap(JSContext* cx, HandleDebuggerObject object,
// Don't allow unwrapping to create a D.O whose referent is in an
// invisible-to-Debugger global. (If our referent is a *wrapper* to such,
// and the wrapper is in a visible realm, that's fine.)
if (unwrapped->realm()->creationOptions().invisibleToDebugger()) {
if (unwrapped->nonCCWRealm()->creationOptions().invisibleToDebugger()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_INVISIBLE_COMPARTMENT);
return false;
}
@ -11545,7 +11545,27 @@ Debugger::isDebuggerCrossCompartmentEdge(JSObject* obj, const gc::Cell* target)
return referent == target;
}
#endif
static void
CheckDebuggeeThingRealm(Realm* realm, bool invisibleOk)
{
MOZ_ASSERT(!realm->creationOptions().mergeable());
MOZ_ASSERT_IF(!invisibleOk, !realm->creationOptions().invisibleToDebugger());
}
void
js::CheckDebuggeeThing(JSScript* script, bool invisibleOk)
{
CheckDebuggeeThingRealm(script->realm(), invisibleOk);
}
void
js::CheckDebuggeeThing(JSObject* obj, bool invisibleOk)
{
if (Realm* realm = JS::GetObjectRealmOrNull(obj))
CheckDebuggeeThingRealm(realm, invisibleOk);
}
#endif // DEBUG
/*** JS::dbg::GarbageCollectionEvent **************************************************************/

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

@ -89,6 +89,14 @@ typedef HashSet<ReadBarrieredGlobalObject,
MovableCellHasher<ReadBarrieredGlobalObject>,
ZoneAllocPolicy> WeakGlobalObjectSet;
#ifdef DEBUG
extern void
CheckDebuggeeThing(JSScript* script, bool invisibleOk);
extern void
CheckDebuggeeThing(JSObject* obj, bool invisibleOk);
#endif
/*
* A weakmap from GC thing keys to JSObject values that supports the keys being
* in different compartments to the values. All values must be in the same
@ -161,9 +169,9 @@ class DebuggerWeakMap : private WeakMap<HeapPtr<UnbarrieredKey>, HeapPtr<JSObjec
template<typename KeyInput, typename ValueInput>
bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) {
MOZ_ASSERT(v->compartment() == this->compartment);
MOZ_ASSERT(!k->realm()->creationOptions().mergeable());
MOZ_ASSERT_IF(!InvisibleKeysOk,
!k->realm()->creationOptions().invisibleToDebugger());
#ifdef DEBUG
CheckDebuggeeThing(k, InvisibleKeysOk);
#endif
MOZ_ASSERT(!Base::has(k));
if (!incZoneCount(k->zone()))
return false;

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

@ -2552,7 +2552,7 @@ DebugEnvironments::addDebugEnvironment(JSContext* cx, Handle<EnvironmentObject*>
Handle<DebugEnvironmentProxy*> debugEnv)
{
MOZ_ASSERT(cx->realm() == env->realm());
MOZ_ASSERT(cx->realm() == debugEnv->realm());
MOZ_ASSERT(cx->realm() == debugEnv->nonCCWRealm());
if (!CanUseDebugEnvironmentMaps(cx))
return true;
@ -2585,7 +2585,7 @@ DebugEnvironments::addDebugEnvironment(JSContext* cx, const EnvironmentIter& ei,
Handle<DebugEnvironmentProxy*> debugEnv)
{
MOZ_ASSERT(!ei.hasSyntacticEnvironment());
MOZ_ASSERT(cx->realm() == debugEnv->realm());
MOZ_ASSERT(cx->realm() == debugEnv->nonCCWRealm());
// Generators should always have environments.
MOZ_ASSERT_IF(ei.scope().is<FunctionScope>(),
!ei.scope().as<FunctionScope>().canonicalFunction()->isGenerator() &&
@ -2867,7 +2867,7 @@ DebugEnvironments::updateLiveEnvironments(JSContext* cx)
continue;
AbstractFramePtr frame = i.abstractFramePtr();
if (frame.environmentChain()->realm() != cx->realm())
if (frame.realm() != cx->realm())
continue;
if (frame.isFunctionFrame()) {
@ -2896,7 +2896,7 @@ DebugEnvironments::updateLiveEnvironments(JSContext* cx)
if (frame.prevUpToDate())
return true;
MOZ_ASSERT(frame.environmentChain()->realm()->isDebuggee());
MOZ_ASSERT(frame.realm()->isDebuggee());
frame.setPrevUpToDate();
}
@ -2935,7 +2935,7 @@ DebugEnvironments::unsetPrevUpToDateUntil(JSContext* cx, AbstractFramePtr until)
if (frame == until)
return;
if (frame.environmentChain()->realm() != cx->realm())
if (frame.realm() != cx->realm())
continue;
frame.unsetPrevUpToDate();

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

@ -478,9 +478,22 @@ JSContext::enterAtomsZone(const js::AutoLockForExclusiveAccess& lock)
arenas_ = &zone_->arenas;
}
template <typename T>
inline void
JSContext::enterRealmOf(const T& target)
JSContext::enterRealmOf(JSObject* target)
{
MOZ_ASSERT(JS::CellIsNotGray(target));
enterRealm(target->deprecatedRealm());
}
inline void
JSContext::enterRealmOf(JSScript* target)
{
MOZ_ASSERT(JS::CellIsNotGray(target));
enterRealm(target->realm());
}
inline void
JSContext::enterRealmOf(js::ObjectGroup* target)
{
MOZ_ASSERT(JS::CellIsNotGray(target));
enterRealm(target->realm());

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

@ -212,8 +212,9 @@ struct JSContext : public JS::RootingContext,
friend class js::AutoRealm;
public:
template <typename T>
inline void enterRealmOf(const T& target);
inline void enterRealmOf(JSObject* target);
inline void enterRealmOf(JSScript* target);
inline void enterRealmOf(js::ObjectGroup* target);
inline void enterNullRealm();
inline void leaveRealm(JS::Realm* oldRealm);

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

@ -393,21 +393,19 @@ SetNewObjectMetadata(JSContext* cx, T* obj)
inline js::GlobalObject&
JSObject::deprecatedGlobal() const
{
return *realm()->unsafeUnbarrieredMaybeGlobal();
return *deprecatedRealm()->unsafeUnbarrieredMaybeGlobal();
}
inline js::GlobalObject&
JSObject::nonCCWGlobal() const
{
MOZ_ASSERT(!js::IsCrossCompartmentWrapper(this));
/*
* The global is read-barriered so that it is kept live by access through
* the Realm. When accessed through a JSObject, however, the global will be
* already kept live by the black JSObject's group pointer, so does not
* need to be read-barriered.
*/
return *realm()->unsafeUnbarrieredMaybeGlobal();
return *nonCCWRealm()->unsafeUnbarrieredMaybeGlobal();
}
inline bool

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

@ -162,7 +162,6 @@ class JSObject : public js::gc::Cell
JS::Compartment* compartment() const { return group_->compartment(); }
JS::Compartment* maybeCompartment() const { return compartment(); }
JS::Realm* realm() const { return group_->realm(); }
inline js::Shape* maybeShape() const;
inline js::Shape* ensureShape(JSContext* cx);
@ -433,9 +432,27 @@ class JSObject : public js::gc::Cell
inline js::GlobalObject& deprecatedGlobal() const;
// Cross-compartment wrappers are not associated with a single realm/global,
// so this method asserts the object is not a CCW.
// so these methods assert the object is not a CCW.
inline js::GlobalObject& nonCCWGlobal() const;
JS::Realm* nonCCWRealm() const {
MOZ_ASSERT(!js::IsCrossCompartmentWrapper(this));
return group_->realm();
}
// Returns the object's realm even if the object is a CCW (be careful, in
// this case the realm is not very meaningful because wrappers are shared by
// all realms in the compartment).
JS::Realm* maybeCCWRealm() const {
return group_->realm();
}
// Deprecated: call nonCCWRealm(), maybeCCWRealm(), or NativeObject::realm()
// instead!
JS::Realm* deprecatedRealm() const {
return group_->realm();
}
/*
* ES5 meta-object properties and operations.
*/

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

@ -461,7 +461,7 @@ StatsCellCallback(JSRuntime* rt, void* data, void* thing, JS::TraceKind traceKin
switch (traceKind) {
case JS::TraceKind::Object: {
JSObject* obj = static_cast<JSObject*>(thing);
RealmStats& realmStats = obj->realm()->realmStats();
RealmStats& realmStats = obj->maybeCCWRealm()->realmStats();
JS::ClassInfo info; // This zeroes all the sizes.
info.objectsGCHeap += thingSize;

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

@ -1474,8 +1474,10 @@ class NativeObject : public ShapedObject
// Native objects are never wrappers, so a native object always has a realm
// and global.
JS::Realm* realm() const {
return nonCCWRealm();
}
inline js::GlobalObject& global() const;
JS::Realm* realm() const { return JSObject::realm(); }
/* JIT Accessors */
static size_t offsetOfElements() { return offsetof(NativeObject, elements_); }

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

@ -46,7 +46,10 @@ JS::Realm::globalIsAboutToBeFinalized()
/* static */ inline js::ObjectRealm&
js::ObjectRealm::get(const JSObject* obj)
{
return obj->realm()->objects_;
// Note: obj might be a CCW if we're accessing ObjectRealm::enumerators.
// CCWs here are fine because we always return the same ObjectRealm for a
// particular (CCW) object.
return obj->maybeCCWRealm()->objects_;
}
template <typename T>

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

@ -642,12 +642,12 @@ Realm::forgetAllocationMetadataBuilder()
void
Realm::setNewObjectMetadata(JSContext* cx, HandleObject obj)
{
MOZ_ASSERT(obj->realm() == this);
MOZ_ASSERT(obj->maybeCCWRealm() == this);
assertSameCompartment(cx, compartment(), obj);
AutoEnterOOMUnsafeRegion oomUnsafe;
if (JSObject* metadata = allocationMetadataBuilder_->build(cx, obj, oomUnsafe)) {
MOZ_ASSERT(metadata->realm() == obj->realm());
MOZ_ASSERT(metadata->maybeCCWRealm() == obj->maybeCCWRealm());
assertSameCompartment(cx, metadata);
if (!objects_.objectMetadataTable) {
@ -1016,7 +1016,7 @@ JS::GetCurrentRealmOrNull(JSContext* cx)
JS_PUBLIC_API(JS::Realm*)
JS::GetObjectRealmOrNull(JSObject* obj)
{
return IsCrossCompartmentWrapper(obj) ? nullptr : obj->realm();
return IsCrossCompartmentWrapper(obj) ? nullptr : obj->nonCCWRealm();
}
JS_PUBLIC_API(void*)

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

@ -784,15 +784,15 @@ public:
MOZ_RELEASE_ASSERT(cx->realm());
if (obj)
MOZ_RELEASE_ASSERT(obj->realm());
MOZ_RELEASE_ASSERT(obj->deprecatedRealm());
// Note that obj might be null here, since we're doing this before
// UnwrapSavedFrame.
if (obj && cx->realm() != obj->realm())
if (obj && cx->realm() != obj->deprecatedRealm())
{
JSSubsumesOp subsumes = cx->runtime()->securityCallbacks->subsumes;
if (subsumes && subsumes(cx->realm()->principals(),
obj->realm()->principals()))
obj->deprecatedRealm()->principals()))
{
ar_.emplace(cx, obj);
}

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

@ -497,7 +497,7 @@ AbstractFramePtr::pushVarEnvironment(JSContext* cx, HandleScope scope)
inline JS::Realm*
AbstractFramePtr::realm() const
{
return environmentChain()->realm();
return environmentChain()->nonCCWRealm();
}
inline unsigned