Backed out 7 changesets (bug 1002737) for sm-rootanalysis test failures.

CLOSED TREE

Backed out changeset ec411f0ce167 (bug 1002737)
Backed out changeset 8a63bad8faed (bug 1002737)
Backed out changeset 5afce70dad1f (bug 1002737)
Backed out changeset 6d4043272a0a (bug 1002737)
Backed out changeset ad09630ae9a3 (bug 1002737)
Backed out changeset c0dd6b9cc07a (bug 1002737)
Backed out changeset b82adb960c54 (bug 1002737)
This commit is contained in:
Ryan VanderMeulen 2014-06-03 17:07:47 -04:00
Родитель 9ff23dd001
Коммит 39a95b6e0d
12 изменённых файлов: 197 добавлений и 209 удалений

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

@ -388,11 +388,16 @@ AutoGCRooter::trace(JSTracer *trc)
return;
}
case DESCVECTOR: {
AutoPropDescVector::VectorImpl &descriptors =
static_cast<AutoPropDescVector *>(this)->vector;
for (size_t i = 0, len = descriptors.length(); i < len; i++)
descriptors[i].trace(trc);
case DESCRIPTORS: {
PropDescArray &descriptors =
static_cast<AutoPropDescArrayRooter *>(this)->descriptors;
for (size_t i = 0, len = descriptors.length(); i < len; i++) {
PropDesc &desc = descriptors[i];
MarkValueRoot(trc, &desc.pd_, "PropDesc::pd_");
MarkValueRoot(trc, &desc.value_, "PropDesc::value_");
MarkValueRoot(trc, &desc.get_, "PropDesc::get_");
MarkValueRoot(trc, &desc.set_, "PropDesc::set_");
}
return;
}

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

@ -106,7 +106,7 @@ class JS_PUBLIC_API(AutoGCRooter) {
PARSER = -3, /* js::frontend::Parser */
SHAPEVECTOR = -4, /* js::AutoShapeVector */
IDARRAY = -6, /* js::AutoIdArray */
DESCVECTOR = -7, /* js::AutoPropDescVector */
DESCRIPTORS = -7, /* js::AutoPropDescArrayRooter */
VALVECTOR = -10, /* js::AutoValueVector */
IDVECTOR = -13, /* js::AutoIdVector */
OBJVECTOR = -14, /* js::AutoObjectVector */

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

@ -495,41 +495,6 @@ JSCompartment::wrap(JSContext *cx, AutoIdVector &props)
return true;
}
bool
JSCompartment::wrap(JSContext *cx, MutableHandle<PropDesc> desc)
{
if (desc.isUndefined())
return true;
JSCompartment *comp = cx->compartment();
if (desc.hasValue()) {
RootedValue value(cx, desc.value());
if (!comp->wrap(cx, &value))
return false;
desc.setValue(value);
}
if (desc.hasGet()) {
RootedValue get(cx, desc.getterValue());
if (!comp->wrap(cx, &get))
return false;
desc.setGetter(get);
}
if (desc.hasSet()) {
RootedValue set(cx, desc.setterValue());
if (!comp->wrap(cx, &set))
return false;
desc.setSetter(set);
}
if (desc.descriptorValue().isObject()) {
RootedObject descObj(cx, &desc.descriptorValue().toObject());
if (!comp->wrap(cx, &descObj))
return false;
desc.setDescriptorObject(descObj);
}
return true;
}
/*
* This method marks pointers that cross compartment boundaries. It should be
* called only for per-compartment GCs, since full GCs naturally follow pointers

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

@ -318,7 +318,6 @@ struct JSCompartment
bool wrap(JSContext *cx, js::StrictPropertyOp *op);
bool wrap(JSContext *cx, JS::MutableHandle<js::PropertyDescriptor> desc);
bool wrap(JSContext *cx, js::AutoIdVector &props);
bool wrap(JSContext *cx, JS::MutableHandle<js::PropDesc> desc);
bool putWrapper(JSContext *cx, const js::CrossCompartmentKey& wrapped, const js::Value& wrapper);

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

@ -268,17 +268,15 @@ js::NewPropertyDescriptorObject(JSContext *cx, Handle<PropertyDescriptor> desc,
d.initFromPropertyDescriptor(desc);
if (!d.makeObject(cx))
return false;
vp.set(d.descriptorValue());
vp.set(d.pd());
return true;
}
void
PropDesc::initFromPropertyDescriptor(Handle<PropertyDescriptor> desc)
{
MOZ_ASSERT(isUndefined());
isUndefined_ = false;
descObj_ = nullptr;
pd_.setUndefined();
attrs = uint8_t(desc.attributes());
JS_ASSERT_IF(attrs & JSPROP_READONLY, !(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
if (desc.hasGetterOrSetterObject()) {
@ -335,7 +333,7 @@ PropDesc::makeObject(JSContext *cx)
return false;
}
descObj_ = obj;
pd_.setObject(*obj);
return true;
}
@ -435,8 +433,6 @@ HasProperty(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp,
bool
PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
{
MOZ_ASSERT(isUndefined());
RootedValue v(cx, origval);
/* 8.10.5 step 1 */
@ -447,7 +443,7 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
RootedObject desc(cx, &v.toObject());
/* Make a copy of the descriptor. We might need it later. */
descObj_ = desc;
pd_ = v;
isUndefined_ = false;
@ -539,8 +535,6 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
void
PropDesc::complete()
{
MOZ_ASSERT(!isUndefined());
if (isGenericDescriptor() || isDataDescriptor()) {
if (!hasValue_) {
hasValue_ = true;
@ -1054,7 +1048,7 @@ js::DefineProperty(JSContext *cx, HandleObject obj, HandleId id, const PropDesc
* TrapDefineOwnProperty directly
*/
if (obj->is<ProxyObject>()) {
RootedValue pd(cx, desc.descriptorValue());
RootedValue pd(cx, desc.pd());
return Proxy::defineProperty(cx, obj, id, pd);
}
return Reject(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE, throwError, rval);
@ -1096,7 +1090,7 @@ js::DefineOwnProperty(JSContext *cx, HandleObject obj, HandleId id,
bool
js::ReadPropertyDescriptors(JSContext *cx, HandleObject props, bool checkAccessors,
AutoIdVector *ids, AutoPropDescVector *descs)
AutoIdVector *ids, AutoPropDescArrayRooter *descs)
{
if (!GetPropertyNames(cx, props, JSITER_OWNONLY, ids))
return false;
@ -1104,11 +1098,11 @@ js::ReadPropertyDescriptors(JSContext *cx, HandleObject props, bool checkAccesso
RootedId id(cx);
for (size_t i = 0, len = ids->length(); i < len; i++) {
id = (*ids)[i];
Rooted<PropDesc> desc(cx);
PropDesc* desc = descs->append();
RootedValue v(cx);
if (!JSObject::getGeneric(cx, props, props, id, &v) ||
!desc.initialize(cx, v, checkAccessors) ||
!descs->append(desc))
if (!desc ||
!JSObject::getGeneric(cx, props, props, id, &v) ||
!desc->initialize(cx, v, checkAccessors))
{
return false;
}
@ -1120,7 +1114,7 @@ bool
js::DefineProperties(JSContext *cx, HandleObject obj, HandleObject props)
{
AutoIdVector ids(cx);
AutoPropDescVector descs(cx);
AutoPropDescArrayRooter descs(cx);
if (!ReadPropertyDescriptors(cx, props, true, &ids, &descs))
return false;
@ -1141,7 +1135,7 @@ js::DefineProperties(JSContext *cx, HandleObject obj, HandleObject props)
*/
if (obj->is<ProxyObject>()) {
for (size_t i = 0, len = ids.length(); i < len; i++) {
RootedValue pd(cx, descs[i].descriptorValue());
RootedValue pd(cx, descs[i].pd());
if (!Proxy::defineProperty(cx, obj, ids[i], pd))
return false;
}

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

@ -32,7 +32,7 @@ struct ObjectsExtraSizes;
namespace js {
class AutoPropDescVector;
class AutoPropDescArrayRooter;
struct GCMarker;
struct NativeIterator;
class Nursery;
@ -1401,7 +1401,7 @@ DefineProperties(JSContext *cx, HandleObject obj, HandleObject props);
*/
extern bool
ReadPropertyDescriptors(JSContext *cx, HandleObject props, bool checkAccessors,
AutoIdVector *ids, AutoPropDescVector *descs);
AutoIdVector *ids, AutoPropDescArrayRooter *descs);
/* Read the name using a dynamic lookup on the scopeChain. */
extern bool

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

@ -644,7 +644,7 @@ namespace js {
PropDesc::PropDesc(const Value &getter, const Value &setter,
Enumerability enumerable, Configurability configurable)
: descObj_(nullptr),
: pd_(UndefinedValue()),
value_(UndefinedValue()),
get_(getter), set_(setter),
attrs(JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED |
@ -772,17 +772,32 @@ IsInternalFunctionObject(JSObject *funobj)
return fun->isLambda() && !funobj->getParent();
}
class AutoPropDescVector : public AutoVectorRooter<PropDesc>
class AutoPropDescArrayRooter : private AutoGCRooter
{
public:
explicit AutoPropDescVector(JSContext *cx
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoVectorRooter<PropDesc>(cx, DESCVECTOR)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
explicit AutoPropDescArrayRooter(JSContext *cx)
: AutoGCRooter(cx, DESCRIPTORS), descriptors(cx)
{ }
PropDesc *append() {
if (!descriptors.append(PropDesc()))
return nullptr;
return &descriptors.back();
}
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
bool reserve(size_t n) {
return descriptors.reserve(n);
}
PropDesc& operator[](size_t i) {
JS_ASSERT(i < descriptors.length());
return descriptors[i];
}
friend void AutoGCRooter::trace(JSTracer *trc);
private:
PropDescArray descriptors;
};
/*

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

@ -1111,7 +1111,7 @@ FromGenericPropertyDescriptor(JSContext *cx, MutableHandle<PropDesc> desc, Mutab
// steps 3-9
if (!desc.makeObject(cx))
return false;
rval.set(desc.descriptorValue());
rval.set(desc.pd());
return true;
}

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

@ -809,63 +809,6 @@ Debugger::unwrapDebuggeeValue(JSContext *cx, MutableHandleValue vp)
return true;
}
/*
* Convert Debugger.Objects in desc to debuggee values.
* Reject non-callable getters and setters.
*/
static bool
CheckArgCompartment(JSContext *cx, JSObject *obj, HandleValue v,
const char *methodname, const char *propname)
{
if (v.isObject() && v.toObject().compartment() != obj->compartment()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEBUG_COMPARTMENT_MISMATCH,
methodname, propname);
return false;
}
return true;
}
bool
Debugger::unwrapPropDescInto(JSContext *cx, HandleObject obj, Handle<PropDesc> wrapped,
MutableHandle<PropDesc> unwrapped)
{
MOZ_ASSERT(!wrapped.isUndefined());
unwrapped.set(wrapped);
if (unwrapped.hasValue()) {
RootedValue value(cx, unwrapped.value());
if (!unwrapDebuggeeValue(cx, &value) ||
!CheckArgCompartment(cx, obj, value, "defineProperty", "value"))
{
return false;
}
unwrapped.setValue(value);
}
if (unwrapped.hasGet()) {
RootedValue get(cx, unwrapped.getterValue());
if (!unwrapDebuggeeValue(cx, &get) ||
!CheckArgCompartment(cx, obj, get, "defineProperty", "get"))
{
return false;
}
unwrapped.setGetter(get);
}
if (unwrapped.hasSet()) {
RootedValue set(cx, unwrapped.setterValue());
if (!unwrapDebuggeeValue(cx, &set) ||
!CheckArgCompartment(cx, obj, set, "defineProperty", "set"))
{
return false;
}
unwrapped.setSetter(set);
}
return true;
}
JSTrapStatus
Debugger::handleUncaughtExceptionHelper(Maybe<AutoCompartment> &ac,
MutableHandleValue *vp, bool callHook)
@ -5317,26 +5260,24 @@ DebuggerObject_defineProperty(JSContext *cx, unsigned argc, Value *vp)
Rooted<PropDesc> desc(cx);
if (!desc.initialize(cx, args[1], false))
return false;
desc.clearDescriptorObject();
desc.clearPd();
if (!dbg->unwrapPropDescInto(cx, obj, desc, &desc))
if (!desc.get().unwrapDebuggerObjectsInto(cx, dbg, obj, desc.address()))
return false;
if (!desc.checkGetter(cx) || !desc.checkSetter(cx))
return false;
{
RootedId wrappedId(cx);
Maybe<AutoCompartment> ac;
ac.construct(cx, obj);
if (!cx->compartment()->wrapId(cx, id.address()))
return false;
if (!cx->compartment()->wrap(cx, &desc))
return false;
if (!desc.makeObject(cx))
if (!desc.get().wrapInto(cx, obj, id, wrappedId.address(), desc.address()))
return false;
ErrorCopier ec(ac, dbg->toJSObject());
bool dummy;
if (!DefineProperty(cx, obj, id, desc, true, &dummy))
if (!DefineProperty(cx, obj, wrappedId, desc, true, &dummy))
return false;
}
@ -5356,35 +5297,44 @@ DebuggerObject_defineProperties(JSContext *cx, unsigned argc, Value *vp)
return false;
AutoIdVector ids(cx);
AutoPropDescVector descs(cx);
AutoPropDescArrayRooter descs(cx);
if (!ReadPropertyDescriptors(cx, props, false, &ids, &descs))
return false;
size_t n = ids.length();
AutoPropDescArrayRooter unwrappedDescs(cx);
for (size_t i = 0; i < n; i++) {
if (!dbg->unwrapPropDescInto(cx, obj, descs[i], descs[i]))
if (!unwrappedDescs.append())
return false;
if (!descs[i].checkGetter(cx) || !descs[i].checkSetter(cx))
if (!descs[i].unwrapDebuggerObjectsInto(cx, dbg, obj, &unwrappedDescs[i]))
return false;
if (!unwrappedDescs[i].checkGetter(cx) || !unwrappedDescs[i].checkSetter(cx))
return false;
}
{
AutoIdVector rewrappedIds(cx);
AutoPropDescArrayRooter rewrappedDescs(cx);
Maybe<AutoCompartment> ac;
ac.construct(cx, obj);
RootedId id(cx);
for (size_t i = 0; i < n; i++) {
if (!cx->compartment()->wrapId(cx, ids[i].address()))
if (!rewrappedIds.append(JSID_VOID) || !rewrappedDescs.append())
return false;
if (!cx->compartment()->wrap(cx, descs[i]))
return false;
if (descs[i].descriptorValue().isUndefined() && !descs[i].makeObject(cx))
id = ids[i];
if (!unwrappedDescs[i].wrapInto(cx, obj, id, rewrappedIds[i].address(), &rewrappedDescs[i]))
return false;
}
ErrorCopier ec(ac, dbg->toJSObject());
for (size_t i = 0; i < n; i++) {
bool dummy;
if (!DefineProperty(cx, obj, ids[i], descs[i], true, &dummy))
if (!DefineProperty(cx, obj, rewrappedIds[i],
rewrappedDescs[i], true, &dummy))
{
return false;
}
}
}

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

@ -506,8 +506,6 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
* happens in the target compartment--rotational symmetry.)
*/
bool unwrapDebuggeeValue(JSContext *cx, MutableHandleValue vp);
bool unwrapPropDescInto(JSContext *cx, HandleObject obj, Handle<PropDesc> wrapped,
MutableHandle<PropDesc> unwrapped);
/*
* Store the Debugger.Frame object for frame in *vp.

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

@ -18,29 +18,21 @@ using namespace js;
using JS::GenericNaN;
PropDesc::PropDesc()
: pd_(UndefinedValue()),
value_(UndefinedValue()),
get_(UndefinedValue()),
set_(UndefinedValue()),
attrs(0),
hasGet_(false),
hasSet_(false),
hasValue_(false),
hasWritable_(false),
hasEnumerable_(false),
hasConfigurable_(false),
isUndefined_(true)
{
setUndefined();
}
void
PropDesc::setUndefined()
{
descObj_ = nullptr;
value_ = UndefinedValue();
get_ = UndefinedValue();
set_ = UndefinedValue();
attrs = 0;
hasGet_ = false;
hasSet_ = false;
hasValue_ = false;
hasWritable_ = false;
hasEnumerable_ = false;
hasConfigurable_ = false;
isUndefined_ = true;
}
bool
PropDesc::checkGetter(JSContext *cx)
{
@ -67,6 +59,94 @@ PropDesc::checkSetter(JSContext *cx)
return true;
}
static bool
CheckArgCompartment(JSContext *cx, JSObject *obj, HandleValue v,
const char *methodname, const char *propname)
{
if (v.isObject() && v.toObject().compartment() != obj->compartment()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEBUG_COMPARTMENT_MISMATCH,
methodname, propname);
return false;
}
return true;
}
/*
* Convert Debugger.Objects in desc to debuggee values.
* Reject non-callable getters and setters.
*/
bool
PropDesc::unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
PropDesc *unwrapped) const
{
MOZ_ASSERT(!isUndefined());
*unwrapped = *this;
if (unwrapped->hasValue()) {
RootedValue value(cx, unwrapped->value_);
if (!dbg->unwrapDebuggeeValue(cx, &value) ||
!CheckArgCompartment(cx, obj, value, "defineProperty", "value"))
{
return false;
}
unwrapped->value_ = value;
}
if (unwrapped->hasGet()) {
RootedValue get(cx, unwrapped->get_);
if (!dbg->unwrapDebuggeeValue(cx, &get) ||
!CheckArgCompartment(cx, obj, get, "defineProperty", "get"))
{
return false;
}
unwrapped->get_ = get;
}
if (unwrapped->hasSet()) {
RootedValue set(cx, unwrapped->set_);
if (!dbg->unwrapDebuggeeValue(cx, &set) ||
!CheckArgCompartment(cx, obj, set, "defineProperty", "set"))
{
return false;
}
unwrapped->set_ = set;
}
return true;
}
/*
* Rewrap *idp and the fields of *desc for the current compartment. Also:
* defining a property on a proxy requires pd_ to contain a descriptor object,
* so reconstitute desc->pd_ if needed.
*/
bool
PropDesc::wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
PropDesc *desc) const
{
MOZ_ASSERT(!isUndefined());
JSCompartment *comp = cx->compartment();
*wrappedId = id;
if (!comp->wrapId(cx, wrappedId))
return false;
*desc = *this;
RootedValue value(cx, desc->value_);
RootedValue get(cx, desc->get_);
RootedValue set(cx, desc->set_);
if (!comp->wrap(cx, &value) || !comp->wrap(cx, &get) || !comp->wrap(cx, &set))
return false;
desc->value_ = value;
desc->get_ = get;
desc->set_ = set;
return !obj->is<ProxyObject>() || desc->makeObject(cx);
}
static const ObjectElements emptyElementsHeader(0, 0);
/* Objects with no elements share one empty set of elements. */
@ -302,7 +382,7 @@ js::ObjectImpl::markChildren(JSTracer *trc)
void
PropDesc::trace(JSTracer *trc)
{
gc::MarkObjectRoot(trc, &descObj_, "PropDesc descriptor object");
gc::MarkValueRoot(trc, &pd_, "PropDesc pd");
gc::MarkValueRoot(trc, &value_, "PropDesc value");
gc::MarkValueRoot(trc, &get_, "PropDesc get");
gc::MarkValueRoot(trc, &set_, "PropDesc set");

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

@ -12,6 +12,8 @@
namespace js {
class Debugger;
static inline JSPropertyOp
CastAsPropertyOp(JSObject *object)
{
@ -34,7 +36,7 @@ struct PropDesc {
* Original object from which this descriptor derives, passed through for
* the benefit of proxies.
*/
JSObject *descObj_;
Value pd_;
Value value_, get_, set_;
@ -53,7 +55,7 @@ struct PropDesc {
bool isUndefined_ : 1;
explicit PropDesc(const Value &v)
: descObj_(nullptr),
: pd_(UndefinedValue()),
value_(v),
get_(UndefinedValue()), set_(UndefinedValue()),
attrs(0),
@ -64,6 +66,7 @@ struct PropDesc {
}
public:
friend void JS::AutoGCRooter::trace(JSTracer *trc);
friend struct GCMethods<PropDesc>;
void trace(JSTracer *trc);
@ -79,7 +82,7 @@ struct PropDesc {
PropDesc(const Value &v, Writability writable,
Enumerability enumerable, Configurability configurable)
: descObj_(nullptr),
: pd_(UndefinedValue()),
value_(v),
get_(UndefinedValue()), set_(UndefinedValue()),
attrs((writable ? 0 : JSPROP_READONLY) |
@ -126,8 +129,8 @@ struct PropDesc {
void initFromPropertyDescriptor(Handle<JSPropertyDescriptor> desc);
bool makeObject(JSContext *cx);
/* Reset the descriptor entirely. */
void setUndefined();
void setUndefined() { isUndefined_ = true; }
bool isUndefined() const { return isUndefined_; }
bool hasGet() const { MOZ_ASSERT(!isUndefined()); return hasGet_; }
@ -137,12 +140,8 @@ struct PropDesc {
bool hasEnumerable() const { MOZ_ASSERT(!isUndefined()); return hasEnumerable_; }
bool hasConfigurable() const { MOZ_ASSERT(!isUndefined()); return hasConfigurable_; }
Value descriptorValue() const {
MOZ_ASSERT(!isUndefined());
return descObj_ ? ObjectValue(*descObj_) : UndefinedValue();
}
void setDescriptorObject(JSObject *obj) { descObj_ = obj; }
void clearDescriptorObject() { setDescriptorObject(nullptr); }
Value pd() const { MOZ_ASSERT(!isUndefined()); return pd_; }
void clearPd() { pd_ = UndefinedValue(); }
uint8_t attributes() const { MOZ_ASSERT(!isUndefined()); return attrs; }
@ -183,11 +182,6 @@ struct PropDesc {
MOZ_ASSERT(hasValue());
return HandleValue::fromMarkedLocation(&value_);
}
void setValue(const Value &value) {
MOZ_ASSERT(!isUndefined());
value_ = value;
hasValue_ = true;
}
JSObject * getterObject() const {
MOZ_ASSERT(!isUndefined());
@ -211,17 +205,6 @@ struct PropDesc {
return HandleValue::fromMarkedLocation(&set_);
}
void setGetter(const Value &getter) {
MOZ_ASSERT(!isUndefined());
get_ = getter;
hasGet_ = true;
}
void setSetter(const Value &setter) {
MOZ_ASSERT(!isUndefined());
set_ = setter;
hasSet_ = true;
}
/*
* Unfortunately the values produced by these methods are used such that
* we can't assert anything here. :-(
@ -240,6 +223,12 @@ struct PropDesc {
*/
bool checkGetter(JSContext *cx);
bool checkSetter(JSContext *cx);
bool unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
PropDesc *unwrapped) const;
bool wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
PropDesc *wrappedDesc) const;
};
} /* namespace js */
@ -261,7 +250,7 @@ class PropDescOperations
bool hasEnumerable() const { return desc()->hasEnumerable(); }
bool hasConfigurable() const { return desc()->hasConfigurable(); }
Value descriptorValue() const { return desc()->descriptorValue(); }
Value pd() const { return desc()->pd(); }
uint8_t attributes() const { return desc()->attributes(); }
@ -280,6 +269,10 @@ class PropDescOperations
JSPropertyOp getter() const { return desc()->getter(); }
JSStrictPropertyOp setter() const { return desc()->setter(); }
// We choose not to expose the debugger-specific parts of PropDesc, both
// because they are not really general use, but also because they are a
// pain to expose.
};
template <typename Outer>
@ -306,20 +299,8 @@ class MutablePropDescOperations : public PropDescOperations<Outer>
return desc()->makeObject(cx);
}
void setValue(const Value &value) {
desc()->setValue(value);
}
void setGetter(const Value &getter) {
desc()->setGetter(getter);
}
void setSetter(const Value &setter) {
desc()->setSetter(setter);
}
void setUndefined() { desc()->setUndefined(); }
void setDescriptorObject(JSObject *obj) { desc()->setDescriptorObject(obj); }
void clearDescriptorObject() { desc()->clearDescriptorObject(); }
void clearPd() { desc()->clearPd(); }
};
} /* namespace JS */
@ -331,7 +312,8 @@ struct GCMethods<PropDesc> {
static PropDesc initial() { return PropDesc(); }
static ThingRootKind kind() { return THING_ROOT_PROP_DESC; }
static bool poisoned(const PropDesc &desc) {
return JS::IsPoisonedPtr(desc.descObj_) ||
return (desc.pd_.isGCThing() &&
JS::IsPoisonedPtr(desc.pd_.toGCThing())) ||
(desc.value_.isGCThing() &&
JS::IsPoisonedPtr(desc.value_.toGCThing())) ||
(desc.get_.isGCThing() &&