Bug 1125437 - Get rid of SetPropertyAttributes and use DefineProperty to follow ES6 specification. r=efaust

This commit is contained in:
Tom Schuster 2015-02-11 23:40:47 +01:00
Родитель 728f780bfe
Коммит 43324bd36f
20 изменённых файлов: 69 добавлений и 142 удалений

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

@ -397,7 +397,6 @@ class CGDOMJSClass(CGThing):
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* getOwnPropertyDescriptor */
nullptr, /* setPropertyAttributes */
nullptr, /* deleteProperty */
nullptr, /* watch */
nullptr, /* unwatch */

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

@ -227,7 +227,6 @@ const static js::Class sNPObjectJSWrapperClass =
nullptr, // getProperty
nullptr, // setProperty
nullptr, // getOwnPropertyDescriptor
nullptr, // setPropertyAttributes
nullptr, // deleteProperty
nullptr, nullptr, // watch/unwatch
nullptr, // getElements

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

@ -177,8 +177,6 @@ typedef bool
(* GetOwnPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
typedef bool
(* SetAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp);
typedef bool
(* DeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
typedef bool
@ -346,7 +344,6 @@ struct ObjectOps
GetPropertyOp getProperty;
SetPropertyOp setProperty;
GetOwnPropertyOp getOwnPropertyDescriptor;
SetAttributesOp setAttributes;
DeletePropertyOp deleteProperty;
WatchOp watch;
UnwatchOp unwatch;
@ -357,7 +354,7 @@ struct ObjectOps
#define JS_NULL_OBJECT_OPS \
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, \
nullptr, nullptr, nullptr, nullptr}
nullptr, nullptr, nullptr}
} // namespace js
@ -368,7 +365,7 @@ typedef void (*JSClassInternal)();
struct JSClass {
JS_CLASS_MEMBERS(JSFinalizeOp);
void *reserved[24];
void *reserved[23];
};
#define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot

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

@ -2042,22 +2042,6 @@ IsOwnId(JSContext *cx, HandleObject obj, HandleId id)
return false;
}
bool
TypedObject::obj_setPropertyAttributes(JSContext *cx, HandleObject obj, HandleId id,
unsigned *attrsp)
{
if (IsOwnId(cx, obj, id))
return ReportPropertyError(cx, JSMSG_CANT_REDEFINE_PROP, id);
RootedObject proto(cx, obj->getProto());
if (!proto) {
*attrsp = 0;
return true;
}
return SetPropertyAttributes(cx, proto, id, attrsp);
}
bool
TypedObject::obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
{
@ -2333,7 +2317,6 @@ LazyArrayBufferTable::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
TypedObject::obj_getProperty, \
TypedObject::obj_setProperty, \
TypedObject::obj_getOwnPropertyDescriptor, \
TypedObject::obj_setPropertyAttributes, \
TypedObject::obj_deleteProperty, \
nullptr, nullptr, /* watch/unwatch */ \
nullptr, /* getElements */ \

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

@ -550,9 +550,6 @@ class TypedObject : public JSObject
static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc);
static bool obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
HandleId id, unsigned *attrsp);
static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded);
static bool obj_enumerate(JSContext *cx, HandleObject obj, AutoIdVector &properties);

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

@ -26,7 +26,7 @@ for (constructor of constructors) {
Object.seal(a);
// Should complain that it can't change attributes of indexed typed array properties.
assertThrowsInstanceOf(() => Object.freeze(a), InternalError);
assertThrowsInstanceOf(() => Object.freeze(a), TypeError);
}
print();

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

@ -0,0 +1,22 @@
var called = [];
var proxy = new Proxy({a: 1, get b() {}}, {
getOwnPropertyDescriptor(target, P) {
called.push("getOwnPropertyDescriptor");
return Object.getOwnPropertyDescriptor(target, P);
},
defineProperty(target, P, desc) {
called.push("defineProperty");
if (P == "a") {
assertEq(Object.getOwnPropertyNames(desc).length, 2);
assertEq(desc.configurable, false);
assertEq(desc.writable, false);
} else {
assertEq(Object.getOwnPropertyNames(desc).length, 1);
assertEq(desc.configurable, false);
}
return Object.defineProperty(target, P, desc);
}
});
Object.freeze(proxy);
assertEq(called.toString(), "getOwnPropertyDescriptor,defineProperty,getOwnPropertyDescriptor,defineProperty");

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

@ -0,0 +1,16 @@
var called = [];
var proxy = new Proxy({a: 1}, {
getOwnPropertyDescriptor(target, P) {
called.push("getOwnPropertyDescriptor");
return Object.getOwnPropertyDescriptor(target, P);
},
defineProperty(target, P, desc) {
called.push("defineProperty");
assertEq(Object.getOwnPropertyNames(desc).length, 1);
assertEq(desc.configurable, false);
return Object.defineProperty(target, P, desc);
}
});
Object.seal(proxy);
assertEq(called.toString(), "defineProperty");

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

@ -302,7 +302,6 @@ namespace js {
js::proxy_GetProperty, \
js::proxy_SetProperty, \
js::proxy_GetOwnPropertyDescriptor, \
js::proxy_SetPropertyAttributes, \
js::proxy_DeleteProperty, \
js::proxy_Watch, js::proxy_Unwatch, \
js::proxy_GetElements, \
@ -342,9 +341,6 @@ extern JS_FRIEND_API(bool)
proxy_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
extern JS_FRIEND_API(bool)
proxy_SetPropertyAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
unsigned *attrsp);
extern JS_FRIEND_API(bool)
proxy_DeleteProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
extern JS_FRIEND_API(void)

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

@ -1038,31 +1038,47 @@ js::SetIntegrityLevel(JSContext *cx, HandleObject obj, IntegrityLevel level)
} else {
RootedId id(cx);
Rooted<PropertyDescriptor> desc(cx);
const unsigned AllowConfigure = JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_READONLY |
JSPROP_IGNORE_VALUE;
const unsigned AllowConfigureAndWritable = AllowConfigure & ~JSPROP_IGNORE_READONLY;
// 8.a/9.a. The two different loops are merged here.
for (size_t i = 0; i < keys.length(); i++) {
id = keys[i];
if (!GetOwnPropertyDescriptor(cx, obj, id, &desc))
return false;
if (level == IntegrityLevel::Sealed) {
// 8.a.i.
desc.setAttributes(AllowConfigure | JSPROP_PERMANENT);
} else {
// 9.a.i-ii.
Rooted<PropertyDescriptor> currentDesc(cx);
if (!GetOwnPropertyDescriptor(cx, obj, id, &currentDesc))
return false;
if (!desc.object())
continue;
// 9.a.iii.
if (!currentDesc.object())
continue;
unsigned attrs = desc.attributes();
unsigned new_attrs = GetSealedOrFrozenAttributes(attrs, level);
// 9.a.iii.1-2
if (currentDesc.isAccessorDescriptor())
desc.setAttributes(AllowConfigure | JSPROP_PERMANENT);
else
desc.setAttributes(AllowConfigureAndWritable | JSPROP_PERMANENT | JSPROP_READONLY);
}
// If we already have the attributes we need, skip the setAttributes call.
if ((attrs | new_attrs) == attrs)
continue;
desc.object().set(obj);
attrs |= new_attrs;
if (!SetPropertyAttributes(cx, obj, id, &attrs))
// 8.a.i-ii. / 9.a.iii.3-4
bool result;
if (!StandardDefineProperty(cx, obj, id, desc, &result))
return false;
}
}
// Ordinarily ArraySetLength handles this, but we're going behind its back
// right now, so we must do this manually. Neither the custom property
// tree mutations nor the setPropertyAttributes call in the above code will
// tree mutations nor the StandardDefineProperty call in the above code will
// do this for us.
//
// ArraySetLength also implements the capacity <= length invariant for

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

@ -940,13 +940,6 @@ LookupProperty(JSContext *cx, HandleObject obj, PropertyName *name,
extern bool
HasOwnProperty(JSContext *cx, HandleObject obj, HandleId id, bool *result);
/*
* Deprecated. Search the prototype chain for `obj[id]` and redefine it to have
* the given property attributes.
*/
inline bool
SetPropertyAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp);
/*
* Set a watchpoint: a synchronous callback when the given property of the
* given object is set.

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

@ -196,16 +196,6 @@ js::DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, bool *succeed
/* * */
inline bool
js::SetPropertyAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
{
MarkTypePropertyNonData(cx, obj, id);
SetAttributesOp op = obj->getOps()->setAttributes;
if (op)
return op(cx, obj, id, attrsp);
return NativeSetPropertyAttributes(cx, obj.as<NativeObject>(), id, attrsp);
}
inline bool
JSObject::isQualifiedVarObj()
{

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

@ -579,17 +579,6 @@ js::proxy_GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
return Proxy::getOwnPropertyDescriptor(cx, obj, id, desc);
}
bool
js::proxy_SetPropertyAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
{
/* Lookup the current property descriptor so we have setter/getter/value. */
Rooted<PropertyDescriptor> desc(cx);
if (!Proxy::getOwnPropertyDescriptor(cx, obj, id, &desc))
return false;
desc.setAttributes(*attrsp);
return Proxy::defineProperty(cx, obj, id, &desc);
}
bool
js::proxy_DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
{

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

@ -2266,37 +2266,3 @@ js::NativeDeleteProperty(JSContext *cx, HandleNativeObject obj, HandleId id, boo
return SuppressDeletedProperty(cx, obj, id);
}
/* * */
bool
js::NativeSetPropertyAttributes(JSContext *cx, HandleNativeObject obj, HandleId id,
unsigned *attrsp)
{
RootedObject nobj(cx);
RootedShape shape(cx);
if (!NativeLookupProperty<CanGC>(cx, obj, id, &nobj, &shape))
return false;
if (!shape)
return true;
if (nobj->isNative() && IsImplicitDenseOrTypedArrayElement(shape)) {
if (IsAnyTypedArray(nobj.get())) {
if (*attrsp == (JSPROP_ENUMERATE | JSPROP_PERMANENT))
return true;
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_SET_ARRAY_ATTRS);
return false;
}
if (!NativeObject::sparsifyDenseElement(cx, nobj.as<NativeObject>(), JSID_TO_INT(id)))
return false;
shape = nobj->as<NativeObject>().lookup(cx, id);
}
if (nobj->isNative()) {
if (!NativeObject::changePropertyAttributes(cx, nobj.as<NativeObject>(), shape, *attrsp))
return false;
if (*attrsp & JSPROP_READONLY)
MarkTypePropertyNonWritable(cx, nobj, id);
return true;
} else {
return SetPropertyAttributes(cx, nobj, id, attrsp);
}
}

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

@ -1344,10 +1344,6 @@ extern bool
NativeGetExistingProperty(JSContext *cx, HandleObject receiver, HandleNativeObject obj,
HandleShape shape, MutableHandle<Value> vp);
extern bool
NativeSetPropertyAttributes(JSContext *cx, HandleNativeObject obj, HandleId id, unsigned *attrsp);
/* * */
/*

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

@ -500,13 +500,6 @@ with_GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
return GetOwnPropertyDescriptor(cx, actual, id, desc);
}
static bool
with_SetPropertyAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
{
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
return SetPropertyAttributes(cx, actual, id, attrsp);
}
static bool
with_DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
{
@ -551,7 +544,6 @@ const Class DynamicWithObject::class_ = {
with_GetProperty,
with_SetProperty,
with_GetOwnPropertyDescriptor,
with_SetPropertyAttributes,
with_DeleteProperty,
nullptr, nullptr, /* watch/unwatch */
nullptr, /* getElements */
@ -943,13 +935,6 @@ uninitialized_GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId
return false;
}
static bool
uninitialized_SetPropertyAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
{
ReportUninitializedLexicalId(cx, id);
return false;
}
static bool
uninitialized_DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
{
@ -981,7 +966,6 @@ const Class UninitializedLexicalObject::class_ = {
uninitialized_GetProperty,
uninitialized_SetProperty,
uninitialized_GetOwnPropertyDescriptor,
uninitialized_SetPropertyAttributes,
uninitialized_DeleteProperty,
nullptr, nullptr, /* watch/unwatch */
nullptr, /* getElements */

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

@ -333,15 +333,6 @@ UnboxedPlainObject::obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj
return true;
}
/* static */ bool
UnboxedPlainObject::obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
HandleId id, unsigned *attrsp)
{
if (!obj->as<UnboxedPlainObject>().convertToNative(cx))
return false;
return SetPropertyAttributes(cx, obj, id, attrsp);
}
/* static */ bool
UnboxedPlainObject::obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id,
bool *succeeded)
@ -393,7 +384,6 @@ const Class UnboxedPlainObject::class_ = {
UnboxedPlainObject::obj_getProperty,
UnboxedPlainObject::obj_setProperty,
UnboxedPlainObject::obj_getOwnPropertyDescriptor,
UnboxedPlainObject::obj_setPropertyAttributes,
UnboxedPlainObject::obj_deleteProperty,
UnboxedPlainObject::obj_watch,
nullptr, /* No unwatch needed, as watch() converts the object to native */

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

@ -148,9 +148,6 @@ class UnboxedPlainObject : public JSObject
static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc);
static bool obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
HandleId id, unsigned *attrsp);
static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded);
static bool obj_enumerate(JSContext *cx, HandleObject obj, AutoIdVector &properties);

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

@ -686,7 +686,6 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
nullptr, // getProperty
nullptr, // setProperty
nullptr, // getOwnPropertyDescriptor
nullptr, // setPropertyAttributes
nullptr, // deleteProperty
nullptr, nullptr, // watch/unwatch
nullptr, // getElements

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

@ -978,7 +978,6 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* getProperty */ \
nullptr, /* setProperty */ \
nullptr, /* getOwnPropertyDescriptor */ \
nullptr, /* setPropertyAttributes */ \
nullptr, /* deleteProperty */ \
nullptr, nullptr, /* watch/unwatch */ \
nullptr, /* getElements */ \
@ -993,7 +992,6 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* getProperty */ \
nullptr, /* setProperty */ \
nullptr, /* getOwnPropertyDescriptor */ \
nullptr, /* setPropertyAttributes */ \
nullptr, /* deleteProperty */ \
nullptr, nullptr, /* watch/unwatch */ \
nullptr, /* getElements */ \