зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1124934 - Implement ES6 HasProperty. r=jorendorff
This commit is contained in:
Родитель
797b78de4b
Коммит
08212467e7
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче