mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 14:45:29 +00:00
Bug 599464 - Object.preventExtensions should be idempotent. r=brendan
This commit is contained in:
parent
08acfd00c4
commit
c036e81169
@ -2542,15 +2542,18 @@ obj_preventExtensions(JSContext *cx, uintN argc, Value *vp)
|
||||
return false;
|
||||
|
||||
vp->setObject(*obj);
|
||||
if (!obj->isExtensible())
|
||||
return true;
|
||||
|
||||
AutoIdVector props(cx);
|
||||
return obj->preventExtensions(cx, &props);
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::sealOrFreeze(JSContext *cx, bool freeze)
|
||||
JSObject::sealOrFreeze(JSContext *cx, ImmutabilityType it)
|
||||
{
|
||||
assertSameCompartment(cx, this);
|
||||
JS_ASSERT(it == SEAL || it == FREEZE);
|
||||
|
||||
AutoIdVector props(cx);
|
||||
if (isExtensible()) {
|
||||
@ -2573,7 +2576,7 @@ JSObject::sealOrFreeze(JSContext *cx, bool freeze)
|
||||
|
||||
/* Make all attributes permanent; if freezing, make data attributes read-only. */
|
||||
uintN new_attrs;
|
||||
if (freeze && !(attrs & (JSPROP_GETTER | JSPROP_SETTER)))
|
||||
if (it == FREEZE && !(attrs & (JSPROP_GETTER | JSPROP_SETTER)))
|
||||
new_attrs = JSPROP_PERMANENT | JSPROP_READONLY;
|
||||
else
|
||||
new_attrs = JSPROP_PERMANENT;
|
||||
|
@ -708,22 +708,24 @@ struct JSObject : js::gc::Cell {
|
||||
*/
|
||||
|
||||
private:
|
||||
enum ImmutabilityType { SEAL, FREEZE };
|
||||
|
||||
/*
|
||||
* The guts of Object.seal (ES5 15.2.3.8) and Object.freeze (ES5 15.2.3.9): mark the
|
||||
* object as non-extensible, and adjust each property's attributes appropriately: each
|
||||
* property becomes non-configurable, and if |freeze|, data properties become
|
||||
* read-only as well.
|
||||
*/
|
||||
bool sealOrFreeze(JSContext *cx, bool freeze = false);
|
||||
bool sealOrFreeze(JSContext *cx, ImmutabilityType it);
|
||||
|
||||
public:
|
||||
bool isExtensible() const { return !(flags & NOT_EXTENSIBLE); }
|
||||
bool preventExtensions(JSContext *cx, js::AutoIdVector *props);
|
||||
|
||||
|
||||
/* ES5 15.2.3.8: non-extensible, all props non-configurable */
|
||||
inline bool seal(JSContext *cx) { return sealOrFreeze(cx); }
|
||||
inline bool seal(JSContext *cx) { return sealOrFreeze(cx, SEAL); }
|
||||
/* ES5 15.2.3.9: non-extensible, all properties non-configurable, all data props read-only */
|
||||
bool freeze(JSContext *cx) { return sealOrFreeze(cx, true); }
|
||||
bool freeze(JSContext *cx) { return sealOrFreeze(cx, FREEZE); }
|
||||
|
||||
/*
|
||||
* Primitive-specific getters and setters.
|
||||
|
@ -41,3 +41,4 @@ script object-toString-01.js
|
||||
script vacuous-accessor-unqualified-name.js
|
||||
script add-property-non-extensible.js
|
||||
skip-if(!xulRuntime.shell) script freeze-global-eval-const.js # uses evalcx
|
||||
script preventExtensions-idempotent.js
|
||||
|
30
js/src/tests/ecma_5/Object/preventExtensions-idempotent.js
Normal file
30
js/src/tests/ecma_5/Object/preventExtensions-idempotent.js
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
* Contributor:
|
||||
* Jeff Walden <jwalden+code@mit.edu>
|
||||
*/
|
||||
|
||||
var gTestfile = 'preventExtensions-idempotent.js';
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 599459;
|
||||
var summary = 'Object.preventExtensions should be idempotent';
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
var obj = {};
|
||||
assertEq(Object.preventExtensions(obj), obj);
|
||||
assertEq(Object.isExtensible(obj), false);
|
||||
assertEq(Object.preventExtensions(obj), obj);
|
||||
assertEq(Object.isExtensible(obj), false);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("All tests passed!");
|
Loading…
Reference in New Issue
Block a user