mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backout changeset 8e3bc766092d (bug 725909) because of merge conflicts with the rest of the backouts
This commit is contained in:
parent
a809593e1c
commit
f051d81342
@ -18,7 +18,6 @@
|
||||
#include "vm/Stack.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
#include "vm/MethodGuard-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
@ -704,126 +703,6 @@ HashableValue::mark(JSTracer *trc) const
|
||||
return hv;
|
||||
}
|
||||
|
||||
|
||||
/*** MapIterator *********************************************************************************/
|
||||
|
||||
class js::MapIteratorObject : public JSObject {
|
||||
public:
|
||||
enum { TargetSlot, RangeSlot, SlotCount };
|
||||
static JSFunctionSpec methods[];
|
||||
static MapIteratorObject *create(JSContext *cx, HandleObject mapobj, ValueMap *data);
|
||||
static void finalize(FreeOp *fop, JSObject *obj);
|
||||
|
||||
private:
|
||||
inline ValueMap::Range *range();
|
||||
static JSBool next(JSContext *cx, unsigned argc, Value *vp);
|
||||
};
|
||||
|
||||
inline js::MapIteratorObject &
|
||||
JSObject::asMapIterator()
|
||||
{
|
||||
JS_ASSERT(isMapIterator());
|
||||
return *static_cast<js::MapIteratorObject *>(this);
|
||||
}
|
||||
|
||||
Class js::MapIteratorClass = {
|
||||
"Iterator",
|
||||
JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(MapIteratorObject::SlotCount),
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_PropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
MapIteratorObject::finalize
|
||||
};
|
||||
|
||||
JSFunctionSpec MapIteratorObject::methods[] = {
|
||||
JS_FN("next", next, 0, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
inline ValueMap::Range *
|
||||
MapIteratorObject::range()
|
||||
{
|
||||
return static_cast<ValueMap::Range *>(getSlot(RangeSlot).toPrivate());
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalObject::initMapIteratorProto(JSContext *cx, Handle<GlobalObject *> global)
|
||||
{
|
||||
JSObject *base = global->getOrCreateIteratorPrototype(cx);
|
||||
if (!base)
|
||||
return false;
|
||||
Rooted<JSObject*> proto(cx,
|
||||
NewObjectWithGivenProto(cx, &MapIteratorClass, base, global));
|
||||
if (!proto)
|
||||
return false;
|
||||
proto->setSlot(MapIteratorObject::RangeSlot, PrivateValue(NULL));
|
||||
if (!JS_DefineFunctions(cx, proto, MapIteratorObject::methods))
|
||||
return false;
|
||||
global->setReservedSlot(MAP_ITERATOR_PROTO, ObjectValue(*proto));
|
||||
return true;
|
||||
}
|
||||
|
||||
MapIteratorObject *
|
||||
MapIteratorObject::create(JSContext *cx, HandleObject mapobj, ValueMap *data)
|
||||
{
|
||||
Rooted<GlobalObject *> global(cx, &mapobj->global());
|
||||
Rooted<JSObject*> proto(cx, global->getOrCreateMapIteratorPrototype(cx));
|
||||
if (!proto)
|
||||
return false;
|
||||
|
||||
ValueMap::Range *range = cx->new_<ValueMap::Range>(data->all());
|
||||
if (!range)
|
||||
return false;
|
||||
|
||||
JSObject *iterobj = NewObjectWithGivenProto(cx, &MapIteratorClass, proto, global);
|
||||
if (!iterobj) {
|
||||
cx->delete_(range);
|
||||
return false;
|
||||
}
|
||||
iterobj->setSlot(TargetSlot, ObjectValue(*mapobj));
|
||||
iterobj->setSlot(RangeSlot, PrivateValue(range));
|
||||
return static_cast<MapIteratorObject *>(iterobj);
|
||||
}
|
||||
|
||||
void
|
||||
MapIteratorObject::finalize(FreeOp *fop, JSObject *obj)
|
||||
{
|
||||
fop->delete_(obj->asMapIterator().range());
|
||||
}
|
||||
|
||||
JSBool
|
||||
MapIteratorObject::next(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
JSObject *thisobj;
|
||||
if (!NonGenericMethodGuard(cx, args, next, &MapIteratorClass, &thisobj))
|
||||
return false;
|
||||
if (!thisobj)
|
||||
return true;
|
||||
|
||||
ValueMap::Range *range = thisobj->asMapIterator().range();
|
||||
if (!range)
|
||||
return js_ThrowStopIteration(cx);
|
||||
if (range->empty()) {
|
||||
cx->delete_(range);
|
||||
thisobj->setReservedSlot(RangeSlot, PrivateValue(NULL));
|
||||
return js_ThrowStopIteration(cx);
|
||||
}
|
||||
|
||||
Value pair[2] = { range->front().key.get(), range->front().value };
|
||||
JSObject *pairobj = NewDenseCopiedArray(cx, 2, pair);
|
||||
if (!pairobj)
|
||||
return false;
|
||||
range->popFront();
|
||||
args.rval().setObject(*pairobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*** Map *****************************************************************************************/
|
||||
|
||||
@ -852,7 +731,6 @@ JSFunctionSpec MapObject::methods[] = {
|
||||
JS_FN("has", has, 1, 0),
|
||||
JS_FN("set", set, 2, 0),
|
||||
JS_FN("delete", delete_, 1, 0),
|
||||
JS_FN("iterator", iterator, 0, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
@ -934,7 +812,7 @@ MapObject::finalize(FreeOp *fop, JSObject *obj)
|
||||
JSBool
|
||||
MapObject::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
Rooted<JSObject*> obj(cx, NewBuiltinClassInstance(cx, &class_));
|
||||
RootedObject obj(cx, NewBuiltinClassInstance(cx, &class_));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
@ -1061,138 +939,12 @@ MapObject::delete_(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
MapObject::iterator(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
THIS_MAP(iterator, cx, argc, vp, args, map);
|
||||
Rooted<JSObject*> mapobj(cx, &args.thisv().toObject());
|
||||
Rooted<JSObject*> iterobj(cx, MapIteratorObject::create(cx, mapobj, &map));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
args.rval().setObject(*iterobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitMapClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return MapObject::initClass(cx, obj);
|
||||
}
|
||||
|
||||
|
||||
/*** SetIterator *********************************************************************************/
|
||||
|
||||
class js::SetIteratorObject : public JSObject {
|
||||
public:
|
||||
enum { TargetSlot, RangeSlot, SlotCount };
|
||||
static JSFunctionSpec methods[];
|
||||
static SetIteratorObject *create(JSContext *cx, HandleObject setobj, ValueSet *data);
|
||||
static void finalize(FreeOp *fop, JSObject *obj);
|
||||
private:
|
||||
inline ValueSet::Range *range();
|
||||
static JSBool next(JSContext *cx, unsigned argc, Value *vp);
|
||||
};
|
||||
|
||||
inline js::SetIteratorObject &
|
||||
JSObject::asSetIterator()
|
||||
{
|
||||
JS_ASSERT(isSetIterator());
|
||||
return *static_cast<js::SetIteratorObject *>(this);
|
||||
}
|
||||
|
||||
Class js::SetIteratorClass = {
|
||||
"Iterator",
|
||||
JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(SetIteratorObject::SlotCount),
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_PropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
SetIteratorObject::finalize
|
||||
};
|
||||
|
||||
JSFunctionSpec SetIteratorObject::methods[] = {
|
||||
JS_FN("next", next, 0, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
inline ValueSet::Range *
|
||||
SetIteratorObject::range()
|
||||
{
|
||||
return static_cast<ValueSet::Range *>(getSlot(RangeSlot).toPrivate());
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalObject::initSetIteratorProto(JSContext *cx, Handle<GlobalObject*> global)
|
||||
{
|
||||
JSObject *base = global->getOrCreateIteratorPrototype(cx);
|
||||
if (!base)
|
||||
return false;
|
||||
JSObject *proto = NewObjectWithGivenProto(cx, &SetIteratorClass, base, global);
|
||||
if (!proto)
|
||||
return false;
|
||||
proto->setSlot(SetIteratorObject::RangeSlot, PrivateValue(NULL));
|
||||
if (!JS_DefineFunctions(cx, proto, SetIteratorObject::methods))
|
||||
return false;
|
||||
global->setReservedSlot(SET_ITERATOR_PROTO, ObjectValue(*proto));
|
||||
return true;
|
||||
}
|
||||
|
||||
SetIteratorObject *
|
||||
SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data)
|
||||
{
|
||||
Rooted<GlobalObject *> global(cx, &setobj->global());
|
||||
Rooted<JSObject*> proto(cx, global->getOrCreateSetIteratorPrototype(cx));
|
||||
if (!proto)
|
||||
return false;
|
||||
|
||||
ValueSet::Range *range = cx->new_<ValueSet::Range>(data->all());
|
||||
if (!range)
|
||||
return false;
|
||||
|
||||
JSObject *iterobj = NewObjectWithGivenProto(cx, &SetIteratorClass, proto, global);
|
||||
if (!iterobj) {
|
||||
cx->delete_(range);
|
||||
return false;
|
||||
}
|
||||
iterobj->setSlot(TargetSlot, ObjectValue(*setobj));
|
||||
iterobj->setSlot(RangeSlot, PrivateValue(range));
|
||||
return static_cast<SetIteratorObject *>(iterobj);
|
||||
}
|
||||
|
||||
void
|
||||
SetIteratorObject::finalize(FreeOp *fop, JSObject *obj)
|
||||
{
|
||||
fop->delete_(obj->asSetIterator().range());
|
||||
}
|
||||
|
||||
JSBool
|
||||
SetIteratorObject::next(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
JSObject *thisobj;
|
||||
if (!NonGenericMethodGuard(cx, args, next, &SetIteratorClass, &thisobj))
|
||||
return false;
|
||||
if (!thisobj)
|
||||
return true;
|
||||
|
||||
ValueSet::Range *range = thisobj->asSetIterator().range();
|
||||
if (!range || range->empty()) {
|
||||
if (range) {
|
||||
cx->delete_(range);
|
||||
thisobj->setReservedSlot(RangeSlot, PrivateValue(NULL));
|
||||
}
|
||||
return js_ThrowStopIteration(cx);
|
||||
}
|
||||
|
||||
args.rval() = range->front().get();
|
||||
range->popFront();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*** Set *****************************************************************************************/
|
||||
|
||||
@ -1220,7 +972,6 @@ JSFunctionSpec SetObject::methods[] = {
|
||||
JS_FN("has", has, 1, 0),
|
||||
JS_FN("add", add, 1, 0),
|
||||
JS_FN("delete", delete_, 1, 0),
|
||||
JS_FN("iterator", iterator, 0, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
@ -1252,7 +1003,7 @@ SetObject::finalize(FreeOp *fop, JSObject *obj)
|
||||
JSBool
|
||||
SetObject::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
Rooted<JSObject*> obj(cx, NewBuiltinClassInstance(cx, &class_));
|
||||
RootedObject obj(cx, NewBuiltinClassInstance(cx, &class_));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
@ -1331,18 +1082,6 @@ SetObject::delete_(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
SetObject::iterator(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
THIS_SET(iterator, cx, argc, vp, args, set);
|
||||
Rooted<JSObject*> setobj(cx, &args.thisv().toObject());
|
||||
Rooted<JSObject*> iterobj(cx, SetIteratorObject::create(cx, setobj, &set));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
args.rval().setObject(*iterobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitSetClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
|
@ -95,7 +95,6 @@ class MapObject : public JSObject {
|
||||
static JSBool has(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool set(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool delete_(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool iterator(JSContext *cx, unsigned argc, Value *vp);
|
||||
};
|
||||
|
||||
class SetObject : public JSObject {
|
||||
@ -113,7 +112,6 @@ class SetObject : public JSObject {
|
||||
static JSBool has(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool add(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool delete_(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool iterator(JSContext *cx, unsigned argc, Value *vp);
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -1,11 +0,0 @@
|
||||
// for-of can be used to iterate over a Map twice.
|
||||
|
||||
var map = Map([['a', 0], ['b', 1], ['c', 2]]);
|
||||
var log = '';
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
for (let [k, v] of map)
|
||||
log += k + v;
|
||||
log += ';'
|
||||
}
|
||||
assertEq(log, 'a0b1c2;a0b1c2;');
|
@ -1,11 +0,0 @@
|
||||
// Nested for-of loops can iterate over a Map.
|
||||
|
||||
var map = Map([['a', 0], ['b', 1]]);
|
||||
var log = '';
|
||||
for (let [k0, v0] of map) {
|
||||
log += k0 + v0 + ':'
|
||||
for (let [k1, v1] of map)
|
||||
log += k1 + v1;
|
||||
log += ';'
|
||||
};
|
||||
assertEq(log, 'a0:a0b1;b1:a0b1;');
|
@ -1,15 +0,0 @@
|
||||
// map.iterator() is live: entries added during iteration are visited.
|
||||
|
||||
var map = Map();
|
||||
function force(k) {
|
||||
if (!map.has(k) && k >= 0)
|
||||
map.set(k, k - 1);
|
||||
}
|
||||
force(5);
|
||||
var log = '';
|
||||
for (let [k, v] of map) {
|
||||
log += k + ';';
|
||||
force(v);
|
||||
}
|
||||
assertEq(log, '5;4;3;2;1;0;');
|
||||
assertEq(map.size(), 6);
|
@ -1,11 +0,0 @@
|
||||
// A Map iterator does not iterate over new entries added after it throws StopIteration.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
load(libdir + "eqArrayHelper.js");
|
||||
|
||||
var map = Map();
|
||||
var iter0 = map.iterator(), iter1 = map.iterator();
|
||||
assertThrowsValue(function () { iter0.next(); }, StopIteration); // closes iter0
|
||||
map.set(1, 2);
|
||||
assertThrowsValue(function () { iter0.next(); }, StopIteration); // already closed
|
||||
assertEqArray(iter1.next(), [1, 2]); // was not yet closed
|
@ -1,14 +0,0 @@
|
||||
// Removing and re-adding entries while an iterator is live causes the iterator to visit them again.
|
||||
|
||||
var map = Map([['a', 1]]);
|
||||
var n = 5;
|
||||
for (let [k, v] of map) {
|
||||
assertEq(k, 'a');
|
||||
assertEq(v, 1);
|
||||
if (n === 0)
|
||||
break;
|
||||
map.delete('a');
|
||||
map.set('a', 1);
|
||||
n--;
|
||||
}
|
||||
assertEq(n, 0);
|
@ -1,15 +0,0 @@
|
||||
// Map iterators produces entries in the order they were inserted.
|
||||
|
||||
load(libdir + "eqArrayHelper.js");
|
||||
|
||||
var map = Map();
|
||||
for (var i = 7; i !== 1; i = i * 7 % 1117)
|
||||
map.set("" + i, i);
|
||||
assertEq(map.size(), 557);
|
||||
|
||||
i = 7;
|
||||
for (var pair of map) {
|
||||
assertEqArray(pair, ["" + i, i]);
|
||||
i = i * 7 % 1117;
|
||||
}
|
||||
assertEq(i, 1);
|
@ -1,15 +0,0 @@
|
||||
// mapiter.next() returns an actual array.
|
||||
|
||||
var key = {};
|
||||
var map = Map([[key, 'value']]);
|
||||
var entry = map.iterator().next();
|
||||
assertEq(Array.isArray(entry), true);
|
||||
assertEq(Object.getPrototypeOf(entry), Array.prototype);
|
||||
assertEq(Object.isExtensible(entry), true);
|
||||
|
||||
assertEq(entry.length, 2);
|
||||
var names = Object.getOwnPropertyNames(entry).sort();
|
||||
assertEq(names.length, 3);
|
||||
assertEq(names.join(","), "0,1,length");
|
||||
assertEq(entry[0], key);
|
||||
assertEq(entry[1], 'value');
|
@ -1,10 +0,0 @@
|
||||
// mapiter.next() returns a fresh array each time.
|
||||
|
||||
var map = Map([['a', 1], ['b', 2]]);
|
||||
var iter = map.iterator();
|
||||
var a = iter.next(), b = iter.next();
|
||||
assertEq(a !== b, true);
|
||||
assertEq(a[0], 'a');
|
||||
assertEq(b[0], 'b');
|
||||
var a1 = map.iterator().next();
|
||||
assertEq(a !== a1, true);
|
@ -1,12 +0,0 @@
|
||||
// Modifying an array returned by mapiter.next() does not modify the Map.
|
||||
|
||||
var map = Map([['a', 1]]);
|
||||
var pair = map.iterator().next();
|
||||
assertEq(pair[0], 'a');
|
||||
pair[0] = 'b';
|
||||
pair[1] = 2;
|
||||
assertEq(pair[0], 'b');
|
||||
assertEq(pair[1], 2);
|
||||
assertEq(map.get('a'), 1);
|
||||
assertEq(map.has('b'), false);
|
||||
assertEq(map.size(), 1);
|
@ -1,8 +0,0 @@
|
||||
// for-of works on a cross-compartment wrapper of a Map.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
var mw = g.eval("Map([['a', 1], ['b', 2]])");
|
||||
var log = '';
|
||||
for (let [k, v] of mw)
|
||||
log += k + v;
|
||||
assertEq(log, "a1b2");
|
@ -1,19 +0,0 @@
|
||||
// map.iterator() and iter.next() are non-generic but work on cross-compartment wrappers.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
load(libdir + "eqArrayHelper.js");
|
||||
var g = newGlobal('new-compartment');
|
||||
|
||||
var iterator_fn = Map.prototype.iterator;
|
||||
assertThrowsInstanceOf(function () { iterator_fn.call({}); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { iterator_fn.call(Set()); }, TypeError);
|
||||
var mapw = g.eval("Map([['x', 1], ['y', 2]])");
|
||||
assertEqArray(iterator_fn.call(mapw).next(), ["x", 1]);
|
||||
|
||||
var next_fn = Map().iterator().next;
|
||||
assertThrowsInstanceOf(function () { next_fn.call({}); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { next_fn.call(Set().iterator()); }, TypeError);
|
||||
var iterw = mapw.iterator();
|
||||
assertEqArray(next_fn.call(iterw), ["x", 1]);
|
||||
assertEqArray(next_fn.call(iterw), ["y", 2]);
|
||||
assertThrowsValue(function () { next_fn.call(iterw); }, g.StopIteration);
|
@ -1,40 +0,0 @@
|
||||
// A map iterator can cope with removing the current entry.
|
||||
|
||||
function test(pairs) {
|
||||
print(uneval(pairs));
|
||||
var map = Map(pairs);
|
||||
|
||||
var all_keys = '';
|
||||
var false_keys = '';
|
||||
for (let [k, v] of map) {
|
||||
all_keys += k;
|
||||
if (!v)
|
||||
false_keys += k;
|
||||
}
|
||||
|
||||
var log = '';
|
||||
for (let [k, remove] of map) {
|
||||
log += k;
|
||||
if (remove)
|
||||
map.delete(k);
|
||||
}
|
||||
assertEq(log, all_keys);
|
||||
|
||||
var remaining_keys = [k for ([k] of map)].join('');
|
||||
assertEq(remaining_keys, false_keys);
|
||||
}
|
||||
|
||||
// removing the only entry
|
||||
test([['a', true]]);
|
||||
|
||||
// removing the first entry
|
||||
test([['a', true], ['b', false], ['c', false]]);
|
||||
|
||||
// removing a middle entry
|
||||
test([['a', false], ['b', true], ['c', false]]);
|
||||
|
||||
// removing the last entry
|
||||
test([['a', false], ['b', false], ['c', true]]);
|
||||
|
||||
// removing all entries
|
||||
test([['a', true], ['b', true], ['c', true]]);
|
@ -1,11 +0,0 @@
|
||||
// A map iterator can cope with removing the next entry.
|
||||
|
||||
var map = Map([['a', 0], ['b', 1], ['c', 2], ['d', 3]]);
|
||||
var iter = map.iterator();
|
||||
var log = '';
|
||||
for (let [k, v] of iter) {
|
||||
log += k + v;
|
||||
if (k === 'b')
|
||||
map.delete('c');
|
||||
}
|
||||
assertEq(log, 'a0b1d3');
|
@ -1,12 +0,0 @@
|
||||
// A map iterator can cope with removing the next entry, then the current entry.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var map = Map([['a', 0], ['b', 1], ['c', 2], ['d', 3]]);
|
||||
var iter = map.iterator();
|
||||
assertEq(iter.next()[0], 'a');
|
||||
assertEq(iter.next()[0], 'b');
|
||||
map.delete('c');
|
||||
map.delete('b');
|
||||
assertEq(iter.next()[0], 'd');
|
||||
assertThrowsValue(function () { iter.next(); }, StopIteration);
|
@ -1,32 +0,0 @@
|
||||
// Multiple live iterators on the same Map can cope with removing entries.
|
||||
|
||||
load(libdir + "eqArrayHelper.js");
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
// Make a map.
|
||||
var map = Map();
|
||||
var SIZE = 7;
|
||||
for (var j = 0; j < SIZE; j++)
|
||||
map.set(j, j);
|
||||
|
||||
// Make lots of iterators pointing to entry 2 of the map.
|
||||
var NITERS = 5;
|
||||
var iters = [];
|
||||
for (var i = 0; i < NITERS; i++) {
|
||||
var iter = map.iterator();
|
||||
assertEqArray(iter.next(), [0, 0]);
|
||||
assertEqArray(iter.next(), [1, 1]);
|
||||
iters[i] = iter;
|
||||
}
|
||||
|
||||
// Remove half of the map entries.
|
||||
for (var j = 0; j < SIZE; j += 2)
|
||||
map.delete(j);
|
||||
|
||||
// Make sure all the iterators still work.
|
||||
for (var i = 0; i < NITERS; i++) {
|
||||
var iter = iters[i];
|
||||
for (var j = 3; j < SIZE; j += 2)
|
||||
assertEqArray(iter.next(), [j, j]);
|
||||
assertThrowsValue(function () { iter.next(); }, StopIteration);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// Removing a Map entry already visited by an iterator does not cause any
|
||||
// entries to be skipped.
|
||||
|
||||
var map = Map();
|
||||
for (var i = 0; i < 20; i++)
|
||||
map.set(String.fromCharCode('A'.charCodeAt(0) + i), i);
|
||||
|
||||
var log = '';
|
||||
for (var [k, v] of map) {
|
||||
log += k;
|
||||
if (v % 5 === 4) {
|
||||
// Delete all entries preceding this one.
|
||||
for (let [k1, v1] of map) {
|
||||
if (k1 === k)
|
||||
break;
|
||||
map.delete(k1);
|
||||
}
|
||||
}
|
||||
}
|
||||
assertEq(log, 'ABCDEFGHIJKLMNOPQRST');
|
||||
assertEq(map.size(), 1); // Only the last entry remains.
|
||||
assertEq(map.get('T'), 19);
|
@ -1,20 +0,0 @@
|
||||
// Removing many Map entries does not cause a live iterator to skip any of the
|
||||
// entries that were not removed. (Compacting a Map must not be observable to
|
||||
// script.)
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var map = Map();
|
||||
for (var i = 0; i < 32; i++)
|
||||
map.set(i, i);
|
||||
var iter = map.iterator();
|
||||
assertEq(iter.next()[0], 0);
|
||||
for (var i = 0; i < 30; i++)
|
||||
map.delete(i);
|
||||
assertEq(map.size(), 2);
|
||||
for (var i = 32; i < 100; i++)
|
||||
map.set(i, i); // eventually triggers compaction
|
||||
|
||||
for (var i = 30; i < 100; i++)
|
||||
assertEq(iter.next()[0], i);
|
||||
assertThrowsValue(function () { iter.next(); }, StopIteration);
|
@ -1,11 +0,0 @@
|
||||
// for-of can be used to iterate over a Set twice.
|
||||
|
||||
var set = Set(['a', 'b', 'c']);
|
||||
var log = '';
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
for (let x of set)
|
||||
log += x;
|
||||
log += ';'
|
||||
}
|
||||
assertEq(log, 'abc;abc;');
|
@ -1,11 +0,0 @@
|
||||
// Nested for-of loops can iterate over a Set.
|
||||
|
||||
var map = Set(['a', 'b']);
|
||||
var log = '';
|
||||
for (let x of map) {
|
||||
log += x + ':'
|
||||
for (let y of map)
|
||||
log += y;
|
||||
log += ';'
|
||||
};
|
||||
assertEq(log, 'a:ab;b:ab;');
|
@ -1,11 +0,0 @@
|
||||
// Iterating over a set of objects yields those exact objects.
|
||||
|
||||
var arr = [{}, {}, {}, [], /xyz/, new Date];
|
||||
var set = Set(arr);
|
||||
assertEq(set.size(), arr.length);
|
||||
|
||||
var i = 0;
|
||||
for (var x of set)
|
||||
assertEq(x, arr[i++]);
|
||||
assertEq(i, arr.length);
|
||||
|
@ -1,11 +0,0 @@
|
||||
// set.iterator() is live: entries added during iteration are visited.
|
||||
|
||||
var set = Set([5]);
|
||||
var log = '';
|
||||
for (let x of set) {
|
||||
log += x + ';';
|
||||
if (x > 0)
|
||||
set.add(x - 1);
|
||||
}
|
||||
assertEq(log, '5;4;3;2;1;0;');
|
||||
assertEq(set.size(), 6);
|
@ -1,10 +0,0 @@
|
||||
// A Set iterator does not iterate over new entries added after it throws StopIteration.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var set = Set();
|
||||
var iter0 = set.iterator(), iter1 = set.iterator();
|
||||
assertThrowsValue(function () { iter0.next(); }, StopIteration); // closes iter0
|
||||
set.add("x");
|
||||
assertThrowsValue(function () { iter0.next(); }, StopIteration); // already closed
|
||||
assertEq(iter1.next(), "x"); // was not yet closed
|
@ -1,13 +0,0 @@
|
||||
// Removing and re-adding entries while an iterator is live causes the iterator to visit them again.
|
||||
|
||||
var set = Set(['a']);
|
||||
var n = 5;
|
||||
for (let v of set) {
|
||||
assertEq(v, 'a');
|
||||
if (n === 0)
|
||||
break;
|
||||
set.delete('a');
|
||||
set.add('a');
|
||||
n--;
|
||||
}
|
||||
assertEq(n, 0);
|
@ -1,8 +0,0 @@
|
||||
// A Set iterator keeps the data alive.
|
||||
|
||||
load(libdir + "referencesVia.js");
|
||||
var key = {};
|
||||
var set = Set([key]);
|
||||
var iter = set.iterator();
|
||||
referencesVia(iter, "**UNKNOWN SLOT 0**", set);
|
||||
referencesVia(set, "key", key);
|
@ -1,8 +0,0 @@
|
||||
// GC-ing during a for-of loop doesn't crash.
|
||||
|
||||
var i = 0;
|
||||
for (var x of Set(Object.getOwnPropertyNames(this))) {
|
||||
gc();
|
||||
if (++i >= 20)
|
||||
break;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// GC in nested for-loops is safe.
|
||||
|
||||
var x;
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
for (x of Set([1]))
|
||||
gc();
|
@ -1,14 +0,0 @@
|
||||
// Set iterators produces entries in the order they were inserted.
|
||||
|
||||
var set = Set();
|
||||
var i;
|
||||
for (i = 7; i !== 1; i = i * 7 % 1117)
|
||||
set.add(i);
|
||||
assertEq(set.size(), 557);
|
||||
|
||||
i = 7;
|
||||
for (var v of set) {
|
||||
assertEq(v, i);
|
||||
i = i * 7 % 1117;
|
||||
}
|
||||
assertEq(i, 1);
|
@ -1,8 +0,0 @@
|
||||
// for-of works on a cross-compartment wrapper of a Set.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
var mw = g.eval("Set(['a', 'b', 1, 2])");
|
||||
var log = '';
|
||||
for (let x of mw)
|
||||
log += x;
|
||||
assertEq(log, "ab12");
|
@ -1,18 +0,0 @@
|
||||
// map.iterator() and iter.next() are non-generic but work on cross-compartment wrappers.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
var g = newGlobal('new-compartment');
|
||||
|
||||
var iterator_fn = Set.prototype.iterator;
|
||||
assertThrowsInstanceOf(function () { iterator_fn.call({}); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { iterator_fn.call(Map()); }, TypeError);
|
||||
var setw = g.eval("Set(['x', 'y'])");
|
||||
assertEq(iterator_fn.call(setw).next(), "x");
|
||||
|
||||
var next_fn = Set().iterator().next;
|
||||
assertThrowsInstanceOf(function () { next_fn.call({}); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { next_fn.call(Map().iterator()); }, TypeError);
|
||||
var iterw = setw.iterator();
|
||||
assertEq(next_fn.call(iterw), "x");
|
||||
assertEq(next_fn.call(iterw), "y");
|
||||
assertThrowsValue(function () { next_fn.call(iterw); }, g.StopIteration);
|
@ -1,26 +0,0 @@
|
||||
// A set iterator can cope with removing the current entry.
|
||||
|
||||
function test(letters, toRemove) {
|
||||
var set = Set(letters);
|
||||
toRemove = Set(toRemove);
|
||||
|
||||
var leftovers = [x for (x of set) if (!toRemove.has(x))].join("");
|
||||
|
||||
var log = "";
|
||||
for (let x of set) {
|
||||
log += x;
|
||||
if (toRemove.has(x))
|
||||
set.delete(x);
|
||||
}
|
||||
assertEq(log, letters);
|
||||
|
||||
var remaining = [x for (x of set)].join("");
|
||||
assertEq(remaining, leftovers);
|
||||
}
|
||||
|
||||
test('a', 'a'); // removing the only entry
|
||||
test('abc', 'a'); // removing the first entry
|
||||
test('abc', 'b'); // removing a middle entry
|
||||
test('abc', 'c'); // removing the last entry
|
||||
test('abc', 'abc') // removing all entries
|
||||
|
@ -1,11 +0,0 @@
|
||||
// A map iterator can cope with removing the next entry.
|
||||
|
||||
var set = Set("abcd");
|
||||
var iter = set.iterator();
|
||||
var log = "";
|
||||
for (let x of iter) {
|
||||
log += x;
|
||||
if (x === "b")
|
||||
set.delete("c");
|
||||
}
|
||||
assertEq(log, "abd");
|
@ -1,12 +0,0 @@
|
||||
// A set iterator can cope with removing the next entry, then the current entry.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var set = Set("abcd");
|
||||
var iter = set.iterator();
|
||||
assertEq(iter.next(), "a");
|
||||
assertEq(iter.next(), "b");
|
||||
set.delete("c");
|
||||
set.delete("b");
|
||||
assertEq(iter.next(), "d");
|
||||
assertThrowsValue(function () { iter.next(); }, StopIteration);
|
@ -1,31 +0,0 @@
|
||||
// Multiple live iterators on the same Set can cope with removing entries.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
// Make a set.
|
||||
var set = Set();
|
||||
var SIZE = 7;
|
||||
for (var j = 0; j < SIZE; j++)
|
||||
set.add(j);
|
||||
|
||||
// Make lots of iterators pointing to entry 2 of the set.
|
||||
var NITERS = 5;
|
||||
var iters = [];
|
||||
for (var i = 0; i < NITERS; i++) {
|
||||
var iter = set.iterator();
|
||||
assertEq(iter.next(), 0);
|
||||
assertEq(iter.next(), 1);
|
||||
iters[i] = iter;
|
||||
}
|
||||
|
||||
// Remove half of the set entries.
|
||||
for (var j = 0; j < SIZE; j += 2)
|
||||
set.delete(j);
|
||||
|
||||
// Make sure all the iterators still work.
|
||||
for (var i = 0; i < NITERS; i++) {
|
||||
var iter = iters[i];
|
||||
for (var j = 3; j < SIZE; j += 2)
|
||||
assertEq(iter.next(), j);
|
||||
assertThrowsValue(function () { iter.next(); }, StopIteration);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// Removing a Set entry already visited by an iterator does not cause any
|
||||
// entries to be skipped.
|
||||
|
||||
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
var set = Set(str);
|
||||
|
||||
var log = '';
|
||||
var i = 0;
|
||||
for (var x of set) {
|
||||
log += x;
|
||||
if (i++ % 5 === 0) {
|
||||
// Delete all entries preceding this one.
|
||||
for (let y of set) {
|
||||
if (y === x)
|
||||
break;
|
||||
set.delete(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
assertEq(log, str);
|
||||
assertEq(set.size(), 1); // Elements 0 to 24 are removed, leaving only 25 (Z).
|
||||
assertEq(set.has('Z'), true);
|
@ -1,20 +0,0 @@
|
||||
// Removing many Set entries does not cause a live iterator to skip any of the
|
||||
// entries that were not removed. (Compacting a Set must not be observable to
|
||||
// script.)
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var set = Set();
|
||||
for (var i = 0; i < 32; i++)
|
||||
set.add(i);
|
||||
var iter = set.iterator();
|
||||
assertEq(iter.next(), 0);
|
||||
for (var i = 0; i < 30; i++)
|
||||
set.delete(i);
|
||||
assertEq(set.size(), 2);
|
||||
for (var i = 32; i < 100; i++)
|
||||
set.add(i); // eventually triggers compaction
|
||||
|
||||
for (var i = 30; i < 100; i++)
|
||||
assertEq(iter.next(), i);
|
||||
assertThrowsValue(function () { iter.next(); }, StopIteration);
|
@ -1,12 +0,0 @@
|
||||
// collection.iterator() returns an Iterator object.
|
||||
|
||||
function test(obj) {
|
||||
var iter = obj.iterator();
|
||||
assertEq(typeof iter, "object");
|
||||
assertEq(iter instanceof Iterator, true);
|
||||
assertEq(iter.toString(), "[object Iterator]");
|
||||
}
|
||||
|
||||
test([]);
|
||||
test(new Map);
|
||||
test(new Set);
|
@ -1,12 +0,0 @@
|
||||
// for-of on an empty collection does not execute the loop body or modify the loop variable.
|
||||
|
||||
function test(empty) {
|
||||
var x = 'unchanged';
|
||||
for (x of empty)
|
||||
throw fit;
|
||||
assertEq(x, 'unchanged');
|
||||
}
|
||||
|
||||
test([]);
|
||||
test(new Map);
|
||||
test(new Set);
|
@ -1,14 +0,0 @@
|
||||
// An iterator keeps its data alive.
|
||||
|
||||
load(libdir + "referencesVia.js");
|
||||
var key = {};
|
||||
|
||||
function test(obj, edgeName) {
|
||||
var iter = obj.iterator();
|
||||
referencesVia(iter, "**UNKNOWN SLOT 0**", obj);
|
||||
referencesVia(obj, edgeName, key);
|
||||
}
|
||||
|
||||
test([key], "element[0]");
|
||||
test(Map([[key, 'value']]), "key");
|
||||
test(Set([key]), "key");
|
@ -1,13 +0,0 @@
|
||||
// All iterators of the same collection type share their immediate prototype.
|
||||
// Those prototype objects in turn inherit directly from Iterator.prototype.
|
||||
|
||||
function test(obj0, obj1) {
|
||||
var iter0 = obj0.iterator(), iter1 = obj1.iterator();
|
||||
var proto = Object.getPrototypeOf(iter0);
|
||||
assertEq(Object.getPrototypeOf(iter1), proto);
|
||||
assertEq(Object.getPrototypeOf(proto), Iterator.prototype);
|
||||
}
|
||||
|
||||
test([], [1]);
|
||||
test(Map(), Map([[1, 1]]));
|
||||
test(Set(), Set([1]));
|
@ -1,11 +0,0 @@
|
||||
// Iterators of different collection types have different prototypes.
|
||||
|
||||
var aproto = Object.getPrototypeOf(Array().iterator());
|
||||
var mproto = Object.getPrototypeOf(Map().iterator());
|
||||
var sproto = Object.getPrototypeOf(Set().iterator());
|
||||
assertEq(aproto !== mproto, true);
|
||||
assertEq(aproto !== sproto, true);
|
||||
assertEq(mproto !== sproto, true);
|
||||
assertEq(aproto.next !== mproto.next, true);
|
||||
assertEq(aproto.next !== sproto.next, true);
|
||||
assertEq(mproto.next !== sproto.next, true);
|
@ -1,22 +0,0 @@
|
||||
// Iterator prototype surfaces.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
function test(constructor) {
|
||||
var proto = Object.getPrototypeOf(constructor().iterator());
|
||||
var names = Object.getOwnPropertyNames(proto);
|
||||
assertEq(names.length, 1);
|
||||
assertEq(names[0], 'next');
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(proto, 'next');
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.writable, true);
|
||||
|
||||
assertEq(proto.iterator(), proto);
|
||||
assertThrowsValue(function () { proto.next(); }, StopIteration);
|
||||
}
|
||||
|
||||
//test(Array);
|
||||
test(Map);
|
||||
test(Set);
|
@ -3786,7 +3786,7 @@ struct JSClass {
|
||||
* with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was
|
||||
* prevously allowed, but is now an ES5 violation and thus unsupported.
|
||||
*/
|
||||
#define JSCLASS_GLOBAL_SLOT_COUNT (JSProto_LIMIT * 3 + 11)
|
||||
#define JSCLASS_GLOBAL_SLOT_COUNT (JSProto_LIMIT * 3 + 9)
|
||||
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
|
||||
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
|
||||
#define JSCLASS_GLOBAL_FLAGS \
|
||||
|
@ -210,7 +210,6 @@ extern Class ErrorClass;
|
||||
extern Class ElementIteratorClass;
|
||||
extern Class GeneratorClass;
|
||||
extern Class JSONClass;
|
||||
extern Class MapIteratorClass;
|
||||
extern Class MathClass;
|
||||
extern Class NumberClass;
|
||||
extern Class NormalArgumentsObjectClass;
|
||||
@ -218,7 +217,6 @@ extern Class ObjectClass;
|
||||
extern Class ProxyClass;
|
||||
extern Class RegExpClass;
|
||||
extern Class RegExpStaticsClass;
|
||||
extern Class SetIteratorClass;
|
||||
extern Class SlowArrayClass;
|
||||
extern Class StopIterationClass;
|
||||
extern Class StringClass;
|
||||
@ -237,14 +235,12 @@ class DebugScopeObject;
|
||||
class DeclEnvObject;
|
||||
class ElementIteratorObject;
|
||||
class GlobalObject;
|
||||
class MapIteratorObject;
|
||||
class NestedScopeObject;
|
||||
class NewObjectCache;
|
||||
class NormalArgumentsObject;
|
||||
class NumberObject;
|
||||
class PropertyIteratorObject;
|
||||
class ScopeObject;
|
||||
class SetIteratorObject;
|
||||
class StaticBlockObject;
|
||||
class StrictArgumentsObject;
|
||||
class StringObject;
|
||||
@ -553,6 +549,7 @@ struct JSObject : public js::ObjectImpl
|
||||
bool growElements(JSContext *cx, unsigned cap);
|
||||
void shrinkElements(JSContext *cx, unsigned cap);
|
||||
|
||||
inline js::ElementIteratorObject *asElementIterator();
|
||||
|
||||
/*
|
||||
* Array-specific getters and setters (for both dense and slow arrays).
|
||||
@ -901,7 +898,6 @@ struct JSObject : public js::ObjectImpl
|
||||
inline bool isFunction() const;
|
||||
inline bool isGenerator() const;
|
||||
inline bool isGlobal() const;
|
||||
inline bool isMapIterator() const;
|
||||
inline bool isObject() const;
|
||||
inline bool isPrimitive() const;
|
||||
inline bool isPropertyIterator() const;
|
||||
@ -910,7 +906,6 @@ struct JSObject : public js::ObjectImpl
|
||||
inline bool isRegExpStatics() const;
|
||||
inline bool isScope() const;
|
||||
inline bool isScript() const;
|
||||
inline bool isSetIterator() const;
|
||||
inline bool isStopIteration() const;
|
||||
inline bool isTypedArray() const;
|
||||
inline bool isWeakMap() const;
|
||||
@ -956,14 +951,12 @@ struct JSObject : public js::ObjectImpl
|
||||
inline js::DeclEnvObject &asDeclEnv();
|
||||
inline js::DebugScopeObject &asDebugScope();
|
||||
inline js::GlobalObject &asGlobal();
|
||||
inline js::MapIteratorObject &asMapIterator();
|
||||
inline js::NestedScopeObject &asNestedScope();
|
||||
inline js::NormalArgumentsObject &asNormalArguments();
|
||||
inline js::NumberObject &asNumber();
|
||||
inline js::PropertyIteratorObject &asPropertyIterator();
|
||||
inline js::RegExpObject &asRegExp();
|
||||
inline js::ScopeObject &asScope();
|
||||
inline js::SetIteratorObject &asSetIterator();
|
||||
inline js::StrictArgumentsObject &asStrictArguments();
|
||||
inline js::StaticBlockObject &asStaticBlock();
|
||||
inline js::StringObject &asString();
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "jsxml.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "builtin/MapObject.h"
|
||||
#include "gc/Barrier.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "gc/Root.h"
|
||||
@ -788,7 +787,6 @@ inline bool JSObject::isError() const { return hasClass(&js::ErrorClass); }
|
||||
inline bool JSObject::isFunction() const { return hasClass(&js::FunctionClass); }
|
||||
inline bool JSObject::isFunctionProxy() const { return hasClass(&js::FunctionProxyClass); }
|
||||
inline bool JSObject::isGenerator() const { return hasClass(&js::GeneratorClass); }
|
||||
inline bool JSObject::isMapIterator() const { return hasClass(&js::MapIteratorClass); }
|
||||
inline bool JSObject::isNestedScope() const { return isBlock() || isWith(); }
|
||||
inline bool JSObject::isNormalArguments() const { return hasClass(&js::NormalArgumentsObjectClass); }
|
||||
inline bool JSObject::isNumber() const { return hasClass(&js::NumberClass); }
|
||||
@ -797,7 +795,6 @@ inline bool JSObject::isPrimitive() const { return isNumber() || isString() || i
|
||||
inline bool JSObject::isRegExp() const { return hasClass(&js::RegExpClass); }
|
||||
inline bool JSObject::isRegExpStatics() const { return hasClass(&js::RegExpStaticsClass); }
|
||||
inline bool JSObject::isScope() const { return isCall() || isDeclEnv() || isNestedScope(); }
|
||||
inline bool JSObject::isSetIterator() const { return hasClass(&js::SetIteratorClass); }
|
||||
inline bool JSObject::isStaticBlock() const { return isBlock() && !getProto(); }
|
||||
inline bool JSObject::isStopIteration() const { return hasClass(&js::StopIterationClass); }
|
||||
inline bool JSObject::isStrictArguments() const { return hasClass(&js::StrictArgumentsObjectClass); }
|
||||
|
@ -293,14 +293,14 @@ GlobalObject::initStandardClasses(JSContext *cx, Handle<GlobalObject*> global)
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
(!VersionHasAllowXML(cx->findVersion()) || js_InitXMLClasses(cx, global)) &&
|
||||
#endif
|
||||
#if JS_HAS_GENERATORS
|
||||
js_InitIteratorClasses(cx, global) &&
|
||||
#endif
|
||||
js_InitDateClass(cx, global) &&
|
||||
js_InitWeakMapClass(cx, global) &&
|
||||
js_InitProxyClass(cx, global) &&
|
||||
js_InitMapClass(cx, global) &&
|
||||
GlobalObject::initMapIteratorProto(cx, global) &&
|
||||
js_InitSetClass(cx, global) &&
|
||||
GlobalObject::initSetIteratorProto(cx, global);
|
||||
js_InitSetClass(cx, global);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -73,9 +73,7 @@ class GlobalObject : public JSObject
|
||||
static const unsigned THROWTYPEERROR = STANDARD_CLASS_SLOTS;
|
||||
static const unsigned ELEMENT_ITERATOR_PROTO = THROWTYPEERROR + 1;
|
||||
static const unsigned GENERATOR_PROTO = ELEMENT_ITERATOR_PROTO + 1;
|
||||
static const unsigned MAP_ITERATOR_PROTO = GENERATOR_PROTO + 1;
|
||||
static const unsigned SET_ITERATOR_PROTO = MAP_ITERATOR_PROTO + 1;
|
||||
static const unsigned REGEXP_STATICS = SET_ITERATOR_PROTO + 1;
|
||||
static const unsigned REGEXP_STATICS = GENERATOR_PROTO + 1;
|
||||
static const unsigned FUNCTION_NS = REGEXP_STATICS + 1;
|
||||
static const unsigned RUNTIME_CODEGEN_ENABLED = FUNCTION_NS + 1;
|
||||
static const unsigned EVAL = RUNTIME_CODEGEN_ENABLED + 1;
|
||||
@ -275,37 +273,23 @@ class GlobalObject : public JSObject
|
||||
}
|
||||
|
||||
private:
|
||||
typedef bool (*ObjectInitOp)(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
JSObject *getOrCreateObject(JSContext *cx, unsigned slot, ObjectInitOp init) {
|
||||
JSObject *getOrCreateIteratorSubclassPrototype(JSContext *cx, unsigned slot) {
|
||||
Value v = getSlotRef(slot);
|
||||
if (v.isObject())
|
||||
return &v.toObject();
|
||||
Rooted<GlobalObject*> self(cx, this);
|
||||
if (!init(cx, self))
|
||||
if (!initIteratorClasses(cx, self))
|
||||
return NULL;
|
||||
return &self->getSlot(slot).toObject();
|
||||
}
|
||||
|
||||
public:
|
||||
JSObject *getOrCreateIteratorPrototype(JSContext *cx) {
|
||||
return getOrCreateObject(cx, JSProto_LIMIT + JSProto_Iterator, initIteratorClasses);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateElementIteratorPrototype(JSContext *cx) {
|
||||
return getOrCreateObject(cx, ELEMENT_ITERATOR_PROTO, initIteratorClasses);
|
||||
return getOrCreateIteratorSubclassPrototype(cx, ELEMENT_ITERATOR_PROTO);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateGeneratorPrototype(JSContext *cx) {
|
||||
return getOrCreateObject(cx, GENERATOR_PROTO, initIteratorClasses);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateMapIteratorPrototype(JSContext *cx) {
|
||||
return getOrCreateObject(cx, MAP_ITERATOR_PROTO, initMapIteratorProto);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateSetIteratorPrototype(JSContext *cx) {
|
||||
return getOrCreateObject(cx, SET_ITERATOR_PROTO, initSetIteratorProto);
|
||||
return getOrCreateIteratorSubclassPrototype(cx, GENERATOR_PROTO);
|
||||
}
|
||||
|
||||
inline RegExpStatics *getRegExpStatics() const;
|
||||
@ -333,10 +317,6 @@ class GlobalObject : public JSObject
|
||||
// Implemented in jsiter.cpp.
|
||||
static bool initIteratorClasses(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
// Implemented in builtin/MapObject.cpp.
|
||||
static bool initMapIteratorProto(JSContext *cx, Handle<GlobalObject*> global);
|
||||
static bool initSetIteratorProto(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
static bool initStandardClasses(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
typedef js::Vector<js::Debugger *, 0, js::SystemAllocPolicy> DebuggerVector;
|
||||
|
Loading…
Reference in New Issue
Block a user