Bug 906891: Short-circuit isSealed and isFrozen for typed arrays. r=sfink

This commit is contained in:
Jim Blandy 2013-08-20 18:00:02 -07:00
Родитель 6dcf06e509
Коммит ab3b10c27a
2 изменённых файлов: 65 добавлений и 0 удалений

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

@ -0,0 +1,53 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
// Typed arrays are always sealed.
load(libdir + "asserts.js")
const constructors = [
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array
];
for (constructor of constructors) {
print("testing non-empty " + constructor.name);
let a = new constructor(10);
assertEq(Object.isExtensible(a), false);
assertEq(Object.isSealed(a), true);
assertEq(Object.isFrozen(a), false);
// Should not throw.
Object.seal(a);
// Should complain that it can't change attributes of indexed typed array properties.
assertThrowsInstanceOf(() => Object.freeze(a), InternalError);
}
print();
for (constructor of constructors) {
print("testing zero-length " + constructor.name);
let a = new constructor(0);
assertEq(Object.isExtensible(a), false);
assertEq(Object.isSealed(a), true);
assertEq(Object.isFrozen(a), true);
// Should not throw.
Object.seal(a);
Object.freeze(a);
}
// isSealed and isFrozen should not try to build an array of all the
// property names of a typed array, since they're often especially large.
// This should not throw an allocation error.
let a = new Uint8Array(1 << 24);
Object.isSealed(a);
Object.isFrozen(a);

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

@ -1186,6 +1186,18 @@ JSObject::isSealedOrFrozen(JSContext *cx, HandleObject obj, ImmutabilityType it,
return true;
}
if (obj->is<TypedArrayObject>()) {
if (it == SEAL) {
// Typed arrays are always sealed.
*resultp = true;
} else {
// Typed arrays cannot be frozen, but an empty typed array is
// trivially frozen.
*resultp = (obj->as<TypedArrayObject>().length() == 0);
}
return true;
}
AutoIdVector props(cx);
if (!GetPropertyNames(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY, &props))
return false;