From 39a95b6e0d8e6200ca578adfd087e3925ed3e476 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 3 Jun 2014 17:07:47 -0400 Subject: [PATCH] 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) --- js/src/gc/RootMarking.cpp | 15 +++-- js/src/jsapi.h | 2 +- js/src/jscompartment.cpp | 35 ----------- js/src/jscompartment.h | 1 - js/src/jsobj.cpp | 30 ++++------ js/src/jsobj.h | 4 +- js/src/jsobjinlines.h | 31 +++++++--- js/src/jsproxy.cpp | 2 +- js/src/vm/Debugger.cpp | 96 +++++++----------------------- js/src/vm/Debugger.h | 2 - js/src/vm/ObjectImpl.cpp | 122 +++++++++++++++++++++++++++++++------- js/src/vm/PropDesc.h | 66 ++++++++------------- 12 files changed, 197 insertions(+), 209 deletions(-) diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 451b346a0e6d..e1bcee128b2f 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -388,11 +388,16 @@ AutoGCRooter::trace(JSTracer *trc) return; } - case DESCVECTOR: { - AutoPropDescVector::VectorImpl &descriptors = - static_cast(this)->vector; - for (size_t i = 0, len = descriptors.length(); i < len; i++) - descriptors[i].trace(trc); + case DESCRIPTORS: { + PropDescArray &descriptors = + static_cast(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; } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index cf1cf71f72c0..7e4176c3a646 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -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 */ diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 0cbb19d92374..55e8c0b08bad 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -495,41 +495,6 @@ JSCompartment::wrap(JSContext *cx, AutoIdVector &props) return true; } -bool -JSCompartment::wrap(JSContext *cx, MutableHandle 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 diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 169e353a2a2c..925968878d17 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -318,7 +318,6 @@ struct JSCompartment bool wrap(JSContext *cx, js::StrictPropertyOp *op); bool wrap(JSContext *cx, JS::MutableHandle desc); bool wrap(JSContext *cx, js::AutoIdVector &props); - bool wrap(JSContext *cx, JS::MutableHandle desc); bool putWrapper(JSContext *cx, const js::CrossCompartmentKey& wrapped, const js::Value& wrapper); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index a0b6670f748f..ced858b44c41 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -268,17 +268,15 @@ js::NewPropertyDescriptorObject(JSContext *cx, Handle desc, d.initFromPropertyDescriptor(desc); if (!d.makeObject(cx)) return false; - vp.set(d.descriptorValue()); + vp.set(d.pd()); return true; } void PropDesc::initFromPropertyDescriptor(Handle 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()) { - 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 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()) { 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; } diff --git a/js/src/jsobj.h b/js/src/jsobj.h index e39c53b221b8..35f24f40c067 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -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 diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index d38692aaaa17..fef7f4a81c76 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -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 +class AutoPropDescArrayRooter : private AutoGCRooter { public: - explicit AutoPropDescVector(JSContext *cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooter(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; }; /* diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index 59e99565e432..53fbd410e3ec 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -1111,7 +1111,7 @@ FromGenericPropertyDescriptor(JSContext *cx, MutableHandle desc, Mutab // steps 3-9 if (!desc.makeObject(cx)) return false; - rval.set(desc.descriptorValue()); + rval.set(desc.pd()); return true; } diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 68196d0c7f89..409fccc0dab0 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -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 wrapped, - MutableHandle 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 &ac, MutableHandleValue *vp, bool callHook) @@ -5317,26 +5260,24 @@ DebuggerObject_defineProperty(JSContext *cx, unsigned argc, Value *vp) Rooted 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 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 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; + } } } diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index 0bc28b238ea0..df6da16ec406 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -506,8 +506,6 @@ class Debugger : private mozilla::LinkedListElement * happens in the target compartment--rotational symmetry.) */ bool unwrapDebuggeeValue(JSContext *cx, MutableHandleValue vp); - bool unwrapPropDescInto(JSContext *cx, HandleObject obj, Handle wrapped, - MutableHandle unwrapped); /* * Store the Debugger.Frame object for frame in *vp. diff --git a/js/src/vm/ObjectImpl.cpp b/js/src/vm/ObjectImpl.cpp index 6c8bdea2d2ac..1538f04af933 100644 --- a/js/src/vm/ObjectImpl.cpp +++ b/js/src/vm/ObjectImpl.cpp @@ -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() || 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"); diff --git a/js/src/vm/PropDesc.h b/js/src/vm/PropDesc.h index b84ea548c786..bea886625635 100644 --- a/js/src/vm/PropDesc.h +++ b/js/src/vm/PropDesc.h @@ -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; 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 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 @@ -306,20 +299,8 @@ class MutablePropDescOperations : public PropDescOperations 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 { 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() &&