Bug 699705. When forwarding property gets to the proto for arrays, send along the right receiver even if the property lives on a non-native object. r=waldo

This commit is contained in:
Boris Zbarsky 2011-11-04 12:26:03 -04:00
Родитель c902bf7a4f
Коммит ad3dbcae5e
4 изменённых файлов: 58 добавлений и 81 удалений

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

@ -820,26 +820,13 @@ array_getGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Valu
if (!js_IdIsIndex(id, &i) || i >= obj->getDenseArrayInitializedLength() ||
obj->getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE)) {
JSObject *obj2;
JSProperty *prop;
const Shape *shape;
JSObject *proto = obj->getProto();
if (!proto) {
vp->setUndefined();
return JS_TRUE;
}
vp->setUndefined();
if (!LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags, &obj2, &prop))
return JS_FALSE;
if (prop && obj2->isNative()) {
shape = (const Shape *) prop;
if (!js_NativeGet(cx, obj, obj2, shape, JSGET_METHOD_BARRIER, vp))
return JS_FALSE;
}
return JS_TRUE;
return proto->getGeneric(cx, receiver, id, vp);
}
*vp = obj->getDenseArrayElement(i);
@ -876,22 +863,7 @@ array_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32 index,
return true;
}
vp->setUndefined();
jsid id;
if (!IndexToId(cx, index, &id))
return false;
JSObject *obj2;
JSProperty *prop;
if (!LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags, &obj2, &prop))
return false;
if (!prop || !obj2->isNative())
return true;
const Shape *shape = (const Shape *) prop;
return js_NativeGet(cx, obj, obj2, shape, JSGET_METHOD_BARRIER, vp);
return proto->getElement(cx, receiver, index, vp);
}
static JSBool

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

@ -1014,31 +1014,16 @@ class TypedArrayTemplate
if (isArrayIndex(cx, tarray, id, &index)) {
// this inline function is specialized for each type
copyIndexToValue(cx, tarray, index, vp);
} else {
JSObject *obj2;
JSProperty *prop;
const Shape *shape;
JSObject *proto = obj->getProto();
if (!proto) {
vp->setUndefined();
return true;
}
vp->setUndefined();
if (!LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags, &obj2, &prop))
return false;
if (prop) {
if (obj2->isNative()) {
shape = (Shape *) prop;
if (!js_NativeGet(cx, obj, obj2, shape, JSGET_METHOD_BARRIER, vp))
return false;
}
}
return true;
}
return true;
JSObject *proto = obj->getProto();
if (!proto) {
vp->setUndefined();
return true;
}
return proto->getGeneric(cx, receiver, id, vp);
}
static JSBool
@ -1065,22 +1050,7 @@ class TypedArrayTemplate
return true;
}
vp->setUndefined();
jsid id;
if (!IndexToId(cx, index, &id))
return false;
JSObject *obj2;
JSProperty *prop;
if (!LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags, &obj2, &prop))
return false;
if (!prop || !obj2->isNative())
return true;
const Shape *shape = (Shape *) prop;
return js_NativeGet(cx, obj, obj2, shape, JSGET_METHOD_BARRIER, vp);
return proto->getElement(cx, receiver, index, vp);
}
static JSBool
@ -1096,21 +1066,13 @@ class TypedArrayTemplate
return true;
}
// Just fall back on obj_getElement so we pick up whatever
// wacky semantics that has.
JSObject *obj2;
JSProperty *prop;
if (!obj_lookupElement(cx, obj, index, &obj2, &prop))
return false;
if (!prop) {
*present = false;
Debug_SetValueRangeToCrashOnTouch(vp, 1);
JSObject *proto = obj->getProto();
if (!proto) {
vp->setUndefined();
return true;
}
*present = true;
return obj_getElement(cx, obj, receiver, index, vp);
return proto->getElementIfPresent(cx, receiver, index, vp, present);
}
static JSBool

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

@ -0,0 +1,42 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
//-----------------------------------------------------------------------------
var BUGNUMBER = 699705;
var summary =
"When getting a property from a dense array that lives on the proto chain "+
"and in particular lives on a non-native object, we should still invoke "+
"property getter";
print(BUGNUMBER + ": " + summary);
/**************
* BEGIN TEST *
**************/
var protoArr = Proxy.create({
getOwnPropertyDescriptor: function(name) {
if (name == "foo") return { get: function() { return this[0]; } };
return (void 0);
},
getPropertyDescriptor: function(name) {
return this.getOwnPropertyDescriptor(name);
},
}, null);
void (Array.prototype.__proto__ = protoArr);
var testArr = [ "PASS" ];
// Make sure we don't optimize the get to a .foo get, so do the dance
// with passing in a string.
function f(name) {
return testArr[name];
}
var propValue = f("foo");
assertEq(propValue, "PASS",
"expected to get 'PASS' out of the getter, got: " + propValue);
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("All tests passed!");

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

@ -61,3 +61,4 @@ script regress-677924.js
skip-if(!xulRuntime.shell) script regress-696109.js
script regress-691746.js
script regress-697515.js
script correct-this-for-nonnatives-on-array-proto-chain.js