зеркало из https://github.com/mozilla/pjs.git
Bug 746262 - Augment PropDesc so that it can represent the absence of a property by adding an isUndefined() method and bit, and checking it in all the relevant accessors. r=jorendorff
--HG-- extra : rebase_source : 45b29d3f65a9e01119f01d9a30f574038abcaea1
This commit is contained in:
Родитель
c86091dc20
Коммит
a97bbc022d
|
@ -1529,6 +1529,7 @@ NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value
|
|||
void
|
||||
PropDesc::initFromPropertyDescriptor(const PropertyDescriptor &desc)
|
||||
{
|
||||
isUndefined_ = false;
|
||||
pd_.setUndefined();
|
||||
attrs = uint8_t(desc.attrs);
|
||||
JS_ASSERT_IF(attrs & JSPROP_READONLY, !(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
|
||||
|
@ -1560,6 +1561,8 @@ PropDesc::initFromPropertyDescriptor(const PropertyDescriptor &desc)
|
|||
bool
|
||||
PropDesc::makeObject(JSContext *cx)
|
||||
{
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
@ -1728,21 +1731,6 @@ HasProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, bool *foundp)
|
|||
return !!obj->getGeneric(cx, id, vp);
|
||||
}
|
||||
|
||||
PropDesc::PropDesc()
|
||||
: pd_(UndefinedValue()),
|
||||
value_(UndefinedValue()),
|
||||
get_(UndefinedValue()),
|
||||
set_(UndefinedValue()),
|
||||
attrs(0),
|
||||
hasGet_(false),
|
||||
hasSet_(false),
|
||||
hasValue_(false),
|
||||
hasWritable_(false),
|
||||
hasEnumerable_(false),
|
||||
hasConfigurable_(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
|
||||
{
|
||||
|
@ -1758,7 +1746,12 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
|
|||
/* Make a copy of the descriptor. We might need it later. */
|
||||
pd_ = v;
|
||||
|
||||
/* Start with the proper defaults. */
|
||||
isUndefined_ = false;
|
||||
|
||||
/*
|
||||
* Start with the proper defaults. XXX shouldn't be necessary when we get
|
||||
* rid of PropDesc::attributes()
|
||||
*/
|
||||
attrs = JSPROP_PERMANENT | JSPROP_READONLY;
|
||||
|
||||
bool found;
|
||||
|
|
|
@ -20,12 +20,27 @@
|
|||
|
||||
using namespace js;
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
PropDesc::checkGetter(JSContext *cx)
|
||||
{
|
||||
if (hasGet()) {
|
||||
const Value &get = getterValue();
|
||||
if (!js_IsCallable(get) && !get.isUndefined()) {
|
||||
if (hasGet_) {
|
||||
if (!js_IsCallable(get_) && !get_.isUndefined()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_GET_SET_FIELD,
|
||||
js_getter_str);
|
||||
return false;
|
||||
|
@ -37,9 +52,8 @@ PropDesc::checkGetter(JSContext *cx)
|
|||
bool
|
||||
PropDesc::checkSetter(JSContext *cx)
|
||||
{
|
||||
if (hasSet()) {
|
||||
const Value &set = setterValue();
|
||||
if (!js_IsCallable(set) && !set.isUndefined()) {
|
||||
if (hasSet_) {
|
||||
if (!js_IsCallable(set_) && !set_.isUndefined()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_GET_SET_FIELD,
|
||||
js_setter_str);
|
||||
return false;
|
||||
|
@ -68,6 +82,8 @@ bool
|
|||
PropDesc::unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, JSObject *obj,
|
||||
PropDesc *unwrapped) const
|
||||
{
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
|
||||
*unwrapped = *this;
|
||||
|
||||
if (unwrapped->hasValue()) {
|
||||
|
@ -106,6 +122,8 @@ bool
|
|||
PropDesc::wrapInto(JSContext *cx, JSObject *obj, const jsid &id, jsid *wrappedId,
|
||||
PropDesc *desc) const
|
||||
{
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
|
||||
JSCompartment *comp = cx->compartment;
|
||||
|
||||
*wrappedId = id;
|
||||
|
|
|
@ -61,6 +61,9 @@ struct PropDesc {
|
|||
bool hasEnumerable_ : 1;
|
||||
bool hasConfigurable_ : 1;
|
||||
|
||||
/* Or maybe this represents a property's absence, and it's undefined. */
|
||||
bool isUndefined_ : 1;
|
||||
|
||||
public:
|
||||
friend class AutoPropDescArrayRooter;
|
||||
friend void JS::AutoGCRooter::trace(JSTracer *trc);
|
||||
|
@ -91,68 +94,79 @@ struct PropDesc {
|
|||
void initFromPropertyDescriptor(const PropertyDescriptor &desc);
|
||||
bool makeObject(JSContext *cx);
|
||||
|
||||
bool hasGet() const { return hasGet_; }
|
||||
bool hasSet() const { return hasSet_; }
|
||||
bool hasValue() const { return hasValue_; }
|
||||
bool hasWritable() const { return hasWritable_; }
|
||||
bool hasEnumerable() const { return hasEnumerable_; }
|
||||
bool hasConfigurable() const { return hasConfigurable_; }
|
||||
void setUndefined() { isUndefined_ = true; }
|
||||
|
||||
Value pd() const { return pd_; }
|
||||
bool isUndefined() const { return isUndefined_; }
|
||||
|
||||
bool hasGet() const { MOZ_ASSERT(!isUndefined()); return hasGet_; }
|
||||
bool hasSet() const { MOZ_ASSERT(!isUndefined()); return hasSet_; }
|
||||
bool hasValue() const { MOZ_ASSERT(!isUndefined()); return hasValue_; }
|
||||
bool hasWritable() const { MOZ_ASSERT(!isUndefined()); return hasWritable_; }
|
||||
bool hasEnumerable() const { MOZ_ASSERT(!isUndefined()); return hasEnumerable_; }
|
||||
bool hasConfigurable() const { MOZ_ASSERT(!isUndefined()); return hasConfigurable_; }
|
||||
|
||||
Value pd() const { MOZ_ASSERT(!isUndefined()); return pd_; }
|
||||
void clearPd() { pd_ = UndefinedValue(); }
|
||||
|
||||
uint8_t attributes() const { return attrs; }
|
||||
uint8_t attributes() const { MOZ_ASSERT(!isUndefined()); return attrs; }
|
||||
|
||||
/* 8.10.1 IsAccessorDescriptor(desc) */
|
||||
bool isAccessorDescriptor() const {
|
||||
return hasGet_ || hasSet_;
|
||||
return !isUndefined() && (hasGet() || hasSet());
|
||||
}
|
||||
|
||||
/* 8.10.2 IsDataDescriptor(desc) */
|
||||
bool isDataDescriptor() const {
|
||||
return hasValue_ || hasWritable_;
|
||||
return !isUndefined() && (hasValue() || hasWritable());
|
||||
}
|
||||
|
||||
/* 8.10.3 IsGenericDescriptor(desc) */
|
||||
bool isGenericDescriptor() const {
|
||||
return !isAccessorDescriptor() && !isDataDescriptor();
|
||||
return !isUndefined() && !isAccessorDescriptor() && !isDataDescriptor();
|
||||
}
|
||||
|
||||
bool configurable() const {
|
||||
MOZ_ASSERT(hasConfigurable_);
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasConfigurable());
|
||||
return (attrs & JSPROP_PERMANENT) == 0;
|
||||
}
|
||||
|
||||
bool enumerable() const {
|
||||
MOZ_ASSERT(hasEnumerable_);
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasEnumerable());
|
||||
return (attrs & JSPROP_ENUMERATE) != 0;
|
||||
}
|
||||
|
||||
bool writable() const {
|
||||
MOZ_ASSERT(hasWritable_);
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasWritable());
|
||||
return (attrs & JSPROP_READONLY) == 0;
|
||||
}
|
||||
|
||||
const Value & value() const {
|
||||
MOZ_ASSERT(hasValue_);
|
||||
MOZ_ASSERT(hasValue());
|
||||
return value_;
|
||||
}
|
||||
|
||||
JSObject * getterObject() const {
|
||||
MOZ_ASSERT(hasGet_);
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasGet());
|
||||
return get_.isUndefined() ? NULL : &get_.toObject();
|
||||
}
|
||||
JSObject * setterObject() const {
|
||||
MOZ_ASSERT(hasSet_);
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasSet());
|
||||
return set_.isUndefined() ? NULL : &set_.toObject();
|
||||
}
|
||||
|
||||
const Value & getterValue() const {
|
||||
MOZ_ASSERT(hasGet_);
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasGet());
|
||||
return get_;
|
||||
}
|
||||
const Value & setterValue() const {
|
||||
MOZ_ASSERT(hasSet_);
|
||||
MOZ_ASSERT(!isUndefined());
|
||||
MOZ_ASSERT(hasSet());
|
||||
return set_;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче