Bug 769192 - Typed array accessors should not use JSPROP_READONLY. r=Waldo

--HG--
extra : rebase_source : 5055b1618b876db58c219512e0168dad28104344
This commit is contained in:
Steve Fink 2012-07-11 11:54:56 -07:00
parent 1a345cef20
commit 1a1a0332ce
2 changed files with 25 additions and 85 deletions

View File

@ -299,12 +299,6 @@ JSBool
ArrayBufferObject::obj_lookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
MutableHandleObject objp, MutableHandleShape propp)
{
if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom)) {
MarkNonNativePropertyFound(obj, propp);
objp.set(getArrayBuffer(obj));
return true;
}
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
if (!delegate)
return false;
@ -386,9 +380,6 @@ JSBool
ArrayBufferObject::obj_defineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *v,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom))
return true;
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
@ -433,11 +424,6 @@ ArrayBufferObject::obj_getGeneric(JSContext *cx, HandleObject obj, HandleObject
RootedObject nobj(cx, getArrayBuffer(obj));
JS_ASSERT(nobj);
if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom)) {
vp->setInt32(nobj->asArrayBuffer().byteLength());
return true;
}
nobj = ArrayBufferDelegate(cx, nobj);
if (!nobj)
return false;
@ -459,11 +445,6 @@ ArrayBufferObject::obj_getProperty(JSContext *cx, HandleObject obj,
return false;
}
if (name == cx->runtime->atomState.byteLengthAtom) {
vp->setInt32(nobj->asArrayBuffer().byteLength());
return true;
}
nobj = ArrayBufferDelegate(cx, nobj);
if (!nobj)
return false;
@ -504,9 +485,6 @@ ArrayBufferObject::obj_getSpecial(JSContext *cx, HandleObject obj,
JSBool
ArrayBufferObject::obj_setGeneric(JSContext *cx, HandleObject obj, HandleId id, Value *vp, JSBool strict)
{
if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom))
return true;
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
if (!delegate)
return false;
@ -588,11 +566,6 @@ JSBool
ArrayBufferObject::obj_getGenericAttributes(JSContext *cx, HandleObject obj,
HandleId id, unsigned *attrsp)
{
if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom)) {
*attrsp = JSPROP_PERMANENT | JSPROP_READONLY;
return true;
}
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
if (!delegate)
return false;
@ -629,12 +602,6 @@ JSBool
ArrayBufferObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj,
HandleId id, unsigned *attrsp)
{
if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_SET_ARRAY_ATTRS);
return false;
}
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
if (!delegate)
return false;
@ -671,11 +638,6 @@ JSBool
ArrayBufferObject::obj_deleteProperty(JSContext *cx, HandleObject obj,
HandlePropertyName name, Value *rval, JSBool strict)
{
if (name == cx->runtime->atomState.byteLengthAtom) {
rval->setBoolean(false);
return true;
}
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
if (!delegate)
return false;
@ -833,9 +795,7 @@ TypedArray::obj_lookupSpecial(JSContext *cx, HandleObject obj, HandleSpecialId s
JSBool
TypedArray::obj_getGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
{
*attrsp = (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
? JSPROP_PERMANENT | JSPROP_READONLY
: JSPROP_PERMANENT | JSPROP_ENUMERATE;
*attrsp = JSPROP_PERMANENT | JSPROP_ENUMERATE;
return true;
}
@ -991,13 +951,6 @@ class TypedArrayTemplate
obj_getProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name,
Value *vp)
{
JSObject *tarray = getTypedArray(obj);
if (name == cx->runtime->atomState.lengthAtom) {
*vp = lengthValue(tarray);
return true;
}
JSObject *proto = obj->getProto();
if (!proto) {
vp->setUndefined();
@ -1154,11 +1107,6 @@ class TypedArrayTemplate
RootedObject tarray(cx, getTypedArray(obj));
JS_ASSERT(tarray);
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
vp->setNumber(length(tarray));
return true;
}
uint32_t index;
// We can't just chain to js_SetPropertyHelper, because we're not a normal object.
if (!isArrayIndex(cx, tarray, id, &index)) {
@ -1211,9 +1159,6 @@ class TypedArrayTemplate
obj_defineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *v,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
return true;
Value tmp = *v;
return obj_setGeneric(cx, obj, id, &tmp, false);
}
@ -1245,11 +1190,6 @@ class TypedArrayTemplate
static JSBool
obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Value *rval, JSBool strict)
{
if (name == cx->runtime->atomState.lengthAtom) {
rval->setBoolean(false);
return true;
}
rval->setBoolean(true);
return true;
}
@ -1283,18 +1223,9 @@ class TypedArrayTemplate
JSObject *tarray = getTypedArray(obj);
JS_ASSERT(tarray);
/*
* Iteration is "length" (if JSENUMERATE_INIT_ALL), then [0, length).
* *statep is JSVAL_TRUE if enumerating "length" and
* JSVAL_TO_INT(index) when enumerating index.
*/
uint32_t index;
switch (enum_op) {
case JSENUMERATE_INIT_ALL:
statep->setBoolean(true);
if (idp)
*idp = ::INT_TO_JSID(length(tarray) + 1);
break;
case JSENUMERATE_INIT:
statep->setInt32(0);
if (idp)
@ -1302,18 +1233,13 @@ class TypedArrayTemplate
break;
case JSENUMERATE_NEXT:
if (statep->isTrue()) {
*idp = NameToId(cx->runtime->atomState.lengthAtom);
statep->setInt32(0);
index = static_cast<uint32_t>(statep->toInt32());
if (index < length(tarray)) {
*idp = ::INT_TO_JSID(index);
statep->setInt32(index + 1);
} else {
uint32_t index = statep->toInt32();
if (index < length(tarray)) {
*idp = ::INT_TO_JSID(index);
statep->setInt32(index + 1);
} else {
JS_ASSERT(index == length(tarray));
statep->setNull();
}
JS_ASSERT(index == length(tarray));
statep->setNull();
}
break;
@ -1519,7 +1445,7 @@ class TypedArrayTemplate
DefineGetter(JSContext *cx, PropertyName *name, HandleObject proto)
{
RootedId id(cx, NameToId(name));
unsigned flags = JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_SHARED | JSPROP_GETTER;
unsigned flags = JSPROP_SHARED | JSPROP_GETTER | JSPROP_PERMANENT | JSPROP_ENUMERATE;
Rooted<GlobalObject*> global(cx, cx->compartment->maybeGlobal());
JSObject *getter = js_NewFunction(cx, NULL, Getter<ValueGetter>, 0, 0, global, NULL);
@ -3130,7 +3056,7 @@ InitArrayBufferClass(JSContext *cx)
return NULL;
RootedId byteLengthId(cx, NameToId(cx->runtime->atomState.byteLengthAtom));
unsigned flags = JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_SHARED | JSPROP_GETTER;
unsigned flags = JSPROP_SHARED | JSPROP_GETTER | JSPROP_PERMANENT;
JSObject *getter = js_NewFunction(cx, NULL, ArrayBufferObject::byteLengthGetter, 0, 0, global, NULL);
if (!getter)
return NULL;
@ -3226,7 +3152,7 @@ bool
DefineDataViewGetter(JSContext *cx, PropertyName *name, HandleObject proto)
{
RootedId id(cx, NameToId(name));
unsigned flags = JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_SHARED | JSPROP_GETTER;
unsigned flags = JSPROP_SHARED | JSPROP_GETTER | JSPROP_PERMANENT;
Rooted<GlobalObject*> global(cx, cx->compartment->maybeGlobal());
JSObject *getter = js_NewFunction(cx, NULL, DataViewGetter<ValueGetter>, 0, 0, global, NULL);

View File

@ -457,6 +457,20 @@ function test()
check(function () Object.getPrototypeOf(view) == Object.getPrototypeOf(simple));
check(function () Object.getPrototypeOf(view) == Int8Array.prototype);
// named properties are defined on the prototype
check(function () !Object.getOwnPropertyDescriptor(simple, 'byteLength'));
check(function () Object.getOwnPropertyDescriptor(Int8Array.prototype, 'byteLength'));
// crazy as it sounds, the named properties are configurable per WebIDL.
// But we are currently discussing the situation, and typed arrays may be
// pulled into the ES spec, so for now this is disallowed.
if (false) {
check(function () simple.byteLength == 12);
getter = Object.getOwnPropertyDescriptor(Int8Array.prototype, 'byteLength').get;
Object.defineProperty(Int8Array.prototype, 'byteLength', { get: function () { return 1 + getter.apply(this) } });
check(function () simple.byteLength == 13);
}
// test move()
var numbers = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ];