Bug 1152550 - Make sure that cross-global Iterator can not be broken. r=Waldo, a=sledru
This commit is contained in:
11
js/src/jit-test/tests/basic/cross-global-for-in.js
Normal file
11
js/src/jit-test/tests/basic/cross-global-for-in.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
var global = newGlobal();
|
||||||
|
|
||||||
|
var arrayIter = (new global.Array())[global.Symbol.iterator]();
|
||||||
|
var ArrayIteratorPrototype = Object.getPrototypeOf(arrayIter);
|
||||||
|
var arrayIterProtoBase = Object.getPrototypeOf(ArrayIteratorPrototype);
|
||||||
|
var IteratorPrototype = arrayIterProtoBase;
|
||||||
|
delete IteratorPrototype.next;
|
||||||
|
|
||||||
|
var obj = global.eval('({a: 1})')
|
||||||
|
for (var x in obj) {}
|
||||||
|
assertEq(x, "a");
|
||||||
@@ -477,6 +477,8 @@ Compare(T* a, T* b, size_t c)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool iterator_next(JSContext* cx, unsigned argc, Value* vp);
|
||||||
|
|
||||||
static inline PropertyIteratorObject*
|
static inline PropertyIteratorObject*
|
||||||
NewPropertyIteratorObject(JSContext* cx, unsigned flags)
|
NewPropertyIteratorObject(JSContext* cx, unsigned flags)
|
||||||
{
|
{
|
||||||
@@ -500,13 +502,35 @@ NewPropertyIteratorObject(JSContext* cx, unsigned flags)
|
|||||||
GetInitialHeap(GenericObject, clasp), shape, group);
|
GetInitialHeap(GenericObject, clasp), shape, group);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
PropertyIteratorObject* res = &obj->as<PropertyIteratorObject>();
|
PropertyIteratorObject* res = &obj->as<PropertyIteratorObject>();
|
||||||
|
|
||||||
MOZ_ASSERT(res->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
|
MOZ_ASSERT(res->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewBuiltinClassInstance<PropertyIteratorObject>(cx);
|
Rooted<PropertyIteratorObject*> res(cx, NewBuiltinClassInstance<PropertyIteratorObject>(cx));
|
||||||
|
if (!res)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (flags == 0) {
|
||||||
|
// Redefine next as an own property. This ensure that deleting the
|
||||||
|
// next method on the prototype doesn't break cross-global for .. in.
|
||||||
|
// We don't have to do this for JSITER_ENUMERATE because that object always
|
||||||
|
// takes an optimized path.
|
||||||
|
RootedFunction next(cx, NewFunctionWithProto(cx, NullPtr(), iterator_next, 0,
|
||||||
|
JSFunction::NATIVE_FUN, NullPtr(),
|
||||||
|
HandlePropertyName(cx->names().next),
|
||||||
|
NullPtr()));
|
||||||
|
if (!next)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
RootedValue value(cx, ObjectValue(*next));
|
||||||
|
if (!DefineProperty(cx, res, cx->names().next, value))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeIterator*
|
NativeIterator*
|
||||||
|
|||||||
Reference in New Issue
Block a user