#415: M1348095 (consolidated)

This commit is contained in:
Cameron Kaiser 2017-07-09 18:51:17 -07:00
parent 33344c6445
commit d1001e7efa
2 changed files with 42 additions and 11 deletions

View File

@ -162,9 +162,12 @@ XPCWrappedNativeXrayTraits::getWN(JSObject* wrapper)
}
const JSClass XPCWrappedNativeXrayTraits::HolderClass = {
"NativePropertyHolder", JSCLASS_HAS_RESERVED_SLOTS(2)
"NativePropertyHolder", JSCLASS_HAS_RESERVED_SLOTS(HOLDER_SHARED_SLOT_COUNT)
};
const JSClass XrayTraits::HolderClass = {
"XrayHolder", JSCLASS_HAS_RESERVED_SLOTS(HOLDER_SHARED_SLOT_COUNT)
};
const JSClass JSXrayTraits::HolderClass = {
"JSXrayHolder", JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT)
@ -1746,7 +1749,7 @@ DOMXrayTraits::preserveWrapper(JSObject* target)
JSObject*
DOMXrayTraits::createHolder(JSContext* cx, JSObject* wrapper)
{
return JS_NewObjectWithGivenProto(cx, nullptr, nullptr);
return JS_NewObjectWithGivenProto(cx, &HolderClass, nullptr);
}
namespace XrayUtils {
@ -2245,16 +2248,35 @@ XrayWrapper<Base, Traits>::getPrototype(JSContext* cx, JS::HandleObject wrapper,
// only if there's been a set. If there's not an expando, or the expando
// slot is |undefined|, hand back the default proto, appropriately wrapped.
RootedValue v(cx);
if (expando) {
JSAutoCompartment ac(cx, expando);
v = JS_GetReservedSlot(expando, JSSLOT_EXPANDO_PROTOTYPE);
RootedValue v(cx);
{ // Scope for JSAutoCompartment
JSAutoCompartment ac(cx, expando);
v = JS_GetReservedSlot(expando, JSSLOT_EXPANDO_PROTOTYPE);
}
if (!v.isUndefined()) {
protop.set(v.toObjectOrNull());
return JS_WrapObject(cx, protop);
}
}
if (v.isUndefined())
return getPrototypeHelper(cx, wrapper, target, protop);
protop.set(v.toObjectOrNull());
return JS_WrapObject(cx, protop);
// Check our holder, and cache there if we don't have it cached already.
RootedObject holder(cx, Traits::singleton.ensureHolder(cx, wrapper));
if (!holder)
return false;
Value cached = js::GetReservedSlot(holder,
Traits::HOLDER_SLOT_CACHED_PROTO);
if (cached.isUndefined()) {
if (!getPrototypeHelper(cx, wrapper, target, protop))
return false;
js::SetReservedSlot(holder, Traits::HOLDER_SLOT_CACHED_PROTO,
ObjectOrNullValue(protop));
} else {
protop.set(cached.toObjectOrNull());
}
return true;
}
template <typename Base, typename Traits>

View File

@ -94,6 +94,12 @@ public:
JSObject* ensureExpandoObject(JSContext* cx, JS::HandleObject wrapper,
JS::HandleObject target);
// Slots for holder objects.
enum {
HOLDER_SLOT_CACHED_PROTO = 0,
HOLDER_SHARED_SLOT_COUNT
};
JSObject* getHolder(JSObject* wrapper);
JSObject* ensureHolder(JSContext* cx, JS::HandleObject wrapper);
virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) = 0;
@ -102,6 +108,9 @@ public:
bool setExpandoChain(JSContext* cx, JS::HandleObject obj, JS::HandleObject chain);
bool cloneExpandoChain(JSContext* cx, JS::HandleObject dst, JS::HandleObject src);
protected:
static const JSClass HolderClass;
private:
bool expandoObjectMatchesConsumer(JSContext* cx, JS::HandleObject expandoObject,
nsIPrincipal* consumerOrigin,
@ -292,7 +301,7 @@ public:
}
enum {
SLOT_PROTOKEY = 0,
SLOT_PROTOKEY = HOLDER_SHARED_SLOT_COUNT,
SLOT_ISPROTOTYPE,
SLOT_CONSTRUCTOR_FOR,
SLOT_COUNT
@ -406,7 +415,7 @@ public:
virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) override
{
return JS_NewObjectWithGivenProto(cx, nullptr, nullptr);
return JS_NewObjectWithGivenProto(cx, &HolderClass, nullptr);
}
static OpaqueXrayTraits singleton;