Bug 1124934 - Implement ES6 HasProperty. r=jorendorff

This commit is contained in:
Tom Schuster 2015-02-13 12:20:02 +01:00
Родитель 797b78de4b
Коммит 08212467e7
5 изменённых файлов: 116 добавлений и 13 удалений

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

@ -0,0 +1,20 @@
if (!this.hasOwnProperty("TypedObject"))
quit();
var array = new (TypedObject.uint8.array(5));
for (var i = 0; i < array.length; i++)
assertEq(i in array, true);
for (var v of [20, 300, -1, 5, -10, Math.pow(2, 32) - 1, -Math.pow(2, 32)])
assertEq(v in array, false);
// Don't inherit elements
array.__proto__[50] = "hello";
assertEq(array.__proto__[50], "hello");
assertEq(50 in array, false);
// Do inherit normal properties
array.__proto__.a = "world";
assertEq(array.__proto__.a, "world");
assertEq("a" in array, true);

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

@ -134,19 +134,6 @@ js::IsExtensible(ExclusiveContext *cx, HandleObject obj, bool *extensible)
return true;
}
inline bool
js::HasProperty(JSContext *cx, HandleObject obj, HandleId id, bool *found)
{
RootedObject pobj(cx);
RootedShape prop(cx);
if (!LookupProperty(cx, obj, id, &pobj, &prop)) {
*found = false; /* initialize to shut GCC up */
return false;
}
*found = !!prop;
return true;
}
inline bool
js::HasProperty(JSContext *cx, HandleObject obj, PropertyName *name, bool *found)
{

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

@ -0,0 +1,34 @@
const constructors = [
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array
];
for (var constructor of constructors) {
var obj = new constructor(5);
for (var i = 0; i < obj.length; i++)
assertEq(i in obj, true);
for (var v of [20, 300, -1, 5, -10, Math.pow(2, 32) - 1, -Math.pow(2, 32)])
assertEq(v in obj, false);
// Don't inherit elements
obj.__proto__[50] = "hello";
assertEq(obj.__proto__[50], "hello");
assertEq(50 in obj, false);
// Do inherit normal properties
obj.__proto__.a = "world";
assertEq(obj.__proto__.a, "world");
assertEq("a" in obj, true);
}
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -1565,6 +1565,57 @@ js::NativeDefineElement(ExclusiveContext *cx, HandleNativeObject obj, uint32_t i
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs);
}
/*** [[HasProperty]] *****************************************************************************/
// ES6 draft rev31 9.1.7.1 OrdinaryHasProperty
bool
js::NativeHasProperty(JSContext *cx, HandleNativeObject obj, HandleId id, bool *foundp)
{
RootedNativeObject pobj(cx, obj);
RootedShape shape(cx);
// This loop isn't explicit in the spec algorithm. See the comment on step
// 7.a. below.
for (;;) {
// Steps 2-3. ('done' is a SpiderMonkey-specific thing, used below.)
bool done;
if (!LookupOwnPropertyInline<CanGC>(cx, pobj, id, &shape, &done))
return false;
// Step 4.
if (shape) {
*foundp = true;
return true;
}
// Step 5-6. The check for 'done' on this next line is tricky.
// done can be true in exactly these unlikely-sounding cases:
// - We're looking up an element, and pobj is a TypedArray that
// doesn't have that many elements.
// - We're being called from a resolve hook to assign to the property
// being resolved.
// What they all have in common is we do not want to keep walking
// the prototype chain, and always claim that the property
// doesn't exist.
RootedObject proto(cx, done ? nullptr : pobj->getProto());
// Step 8.
if (!proto) {
*foundp = false;
return true;
}
// Step 7.a. If the prototype is also native, this step is a
// recursive tail call, and we don't need to go through all the
// plumbing of HasProperty; the top of the loop is where
// we're going to end up anyway. But if pobj is non-native,
// that optimization would be incorrect.
if (!proto->isNative())
return HasProperty(cx, proto, id, foundp);
pobj = &proto->as<NativeObject>();
}
}
/*** [[Get]] *************************************************************************************/

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

@ -1256,6 +1256,9 @@ extern bool
NativeDefineElement(ExclusiveContext *cx, HandleNativeObject obj, uint32_t index, HandleValue value,
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
extern bool
NativeHasProperty(JSContext *cx, HandleNativeObject obj, HandleId id, bool *foundp);
extern bool
NativeGetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
MutableHandleValue vp);
@ -1379,6 +1382,14 @@ MaybeNativeObject(JSObject *obj)
/*** Inline functions declared in jsobj.h that use the native declarations above *****************/
inline bool
js::HasProperty(JSContext *cx, HandleObject obj, HandleId id, bool *foundp)
{
if (HasPropertyOp op = obj->getOps()->hasProperty)
return op(cx, obj, id, foundp);
return NativeHasProperty(cx, obj.as<NativeObject>(), id, foundp);
}
inline bool
js::GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
MutableHandleValue vp)