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