Attachment #756136: final patch for bug #869996

View | Details | Raw Unified | Return to bug 869996
Collapse All | Expand All

(-)a/js/src/builtin/MapObject.cpp (-13 / +86 lines)
Line     Link Here 
 Lines 1033-1050   const JSPropertySpec MapObject::properti Link Here 
1033
1033
1034
const JSFunctionSpec MapObject::methods[] = {
1034
const JSFunctionSpec MapObject::methods[] = {
1035
    JS_FN("get", get, 1, 0),
1035
    JS_FN("get", get, 1, 0),
1036
    JS_FN("has", has, 1, 0),
1036
    JS_FN("has", has, 1, 0),
1037
    JS_FN("set", set, 2, 0),
1037
    JS_FN("set", set, 2, 0),
1038
    JS_FN("delete", delete_, 1, 0),
1038
    JS_FN("delete", delete_, 1, 0),
1039
    JS_FN("keys", keys, 0, 0),
1039
    JS_FN("keys", keys, 0, 0),
1040
    JS_FN("values", values, 0, 0),
1040
    JS_FN("values", values, 0, 0),
1041
    JS_FN("entries", entries, 0, 0),
1042
    JS_FN("iterator", entries, 0, 0),
1043
    JS_FN("clear", clear, 0, 0),
1041
    JS_FN("clear", clear, 0, 0),
1044
    JS_FS_END
1042
    JS_FS_END
1045
};
1043
};
1046
1044
1047
static JSObject *
1045
static JSObject *
1048
InitClass(JSContext *cx, Handle<GlobalObject*> global, Class *clasp, JSProtoKey key, Native construct,
1046
InitClass(JSContext *cx, Handle<GlobalObject*> global, Class *clasp, JSProtoKey key, Native construct,
1049
          const JSPropertySpec *properties, const JSFunctionSpec *methods)
1047
          const JSPropertySpec *properties, const JSFunctionSpec *methods)
1050
{
1048
{
 Lines 1063-1079   InitClass(JSContext *cx, Handle<GlobalOb Link Here 
1063
    }
1061
    }
1064
    return proto;
1062
    return proto;
1065
}
1063
}
1066
1064
1067
JSObject *
1065
JSObject *
1068
MapObject::initClass(JSContext *cx, JSObject *obj)
1066
MapObject::initClass(JSContext *cx, JSObject *obj)
1069
{
1067
{
1070
    Rooted<GlobalObject*> global(cx, &obj->asGlobal());
1068
    Rooted<GlobalObject*> global(cx, &obj->asGlobal());
1071
    return InitClass(cx, global, &class_, JSProto_Map, construct, properties, methods);
1069
    RootedObject proto(cx,
1070
        InitClass(cx, global, &class_, JSProto_Map, construct, properties, methods));
1071
    if (proto) {
1072
        // Define the "entries" method.
1073
        JSFunction *fun = JS_DefineFunction(cx, proto, "entries", entries, 0, 0);
1074
        if (!fun)
1075
            return NULL;
1076
1077
        // Define its alias.
1078
        RootedValue funval(cx, ObjectValue(*fun));
1079
        if (!JS_DefineProperty(cx, proto, "iterator", funval, NULL, NULL, 0))
1080
            return NULL;
1081
    }
1082
    return proto;
1072
}
1083
}
1073
1084
1074
template <class Range>
1085
template <class Range>
1075
static void
1086
static void
1076
MarkKey(Range &r, const HashableValue &key, JSTracer *trc)
1087
MarkKey(Range &r, const HashableValue &key, JSTracer *trc)
1077
{
1088
{
1078
    HashableValue newKey = key.mark(trc);
1089
    HashableValue newKey = key.mark(trc);
1079
1090
 Lines 1414-1437   js_InitMapClass(JSContext *cx, HandleObj Link Here 
1414
}
1425
}
1415
1426
1416
1427
1417
/*** SetIterator *********************************************************************************/
1428
/*** SetIterator *********************************************************************************/
1418
1429
1419
class js::SetIteratorObject : public JSObject
1430
class js::SetIteratorObject : public JSObject
1420
{
1431
{
1421
  public:
1432
  public:
1422
    enum { TargetSlot, RangeSlot, SlotCount };
1433
    enum { TargetSlot, KindSlot, RangeSlot, SlotCount };
1423
    static const JSFunctionSpec methods[];
1434
    static const JSFunctionSpec methods[];
1424
    static SetIteratorObject *create(JSContext *cx, HandleObject setobj, ValueSet *data);
1435
    static SetIteratorObject *create(JSContext *cx, HandleObject setobj, ValueSet *data,
1436
                                     SetObject::IteratorKind kind);
1425
    static void finalize(FreeOp *fop, JSObject *obj);
1437
    static void finalize(FreeOp *fop, JSObject *obj);
1426
1438
1427
  private:
1439
  private:
1428
    static inline bool is(const Value &v);
1440
    static inline bool is(const Value &v);
1429
    inline ValueSet::Range *range();
1441
    inline ValueSet::Range *range();
1442
    inline SetObject::IteratorKind kind() const;
1430
    static bool next_impl(JSContext *cx, CallArgs args);
1443
    static bool next_impl(JSContext *cx, CallArgs args);
1431
    static JSBool next(JSContext *cx, unsigned argc, Value *vp);
1444
    static JSBool next(JSContext *cx, unsigned argc, Value *vp);
1432
};
1445
};
1433
1446
1434
inline js::SetIteratorObject &
1447
inline js::SetIteratorObject &
1435
JSObject::asSetIterator()
1448
JSObject::asSetIterator()
1436
{
1449
{
1437
    JS_ASSERT(isSetIterator());
1450
    JS_ASSERT(isSetIterator());
 Lines 1458-1473   const JSFunctionSpec SetIteratorObject:: Link Here 
1458
};
1471
};
1459
1472
1460
inline ValueSet::Range *
1473
inline ValueSet::Range *
1461
SetIteratorObject::range()
1474
SetIteratorObject::range()
1462
{
1475
{
1463
    return static_cast<ValueSet::Range *>(getSlot(RangeSlot).toPrivate());
1476
    return static_cast<ValueSet::Range *>(getSlot(RangeSlot).toPrivate());
1464
}
1477
}
1465
1478
1479
inline SetObject::IteratorKind
1480
SetIteratorObject::kind() const
1481
{
1482
    int32_t i = getSlot(KindSlot).toInt32();
1483
    JS_ASSERT(i == SetObject::Keys || i == SetObject::Values || i == SetObject::Entries);
1484
    return SetObject::IteratorKind(i);
1485
}
1486
1466
bool
1487
bool
1467
GlobalObject::initSetIteratorProto(JSContext *cx, Handle<GlobalObject*> global)
1488
GlobalObject::initSetIteratorProto(JSContext *cx, Handle<GlobalObject*> global)
1468
{
1489
{
1469
    JSObject *base = global->getOrCreateIteratorPrototype(cx);
1490
    JSObject *base = global->getOrCreateIteratorPrototype(cx);
1470
    if (!base)
1491
    if (!base)
1471
        return false;
1492
        return false;
1472
    RootedObject proto(cx, NewObjectWithGivenProto(cx, &SetIteratorClass, base, global));
1493
    RootedObject proto(cx, NewObjectWithGivenProto(cx, &SetIteratorClass, base, global));
1473
    if (!proto)
1494
    if (!proto)
 Lines 1475-1507   GlobalObject::initSetIteratorProto(JSCon Link Here 
1475
    proto->setSlot(SetIteratorObject::RangeSlot, PrivateValue(NULL));
1496
    proto->setSlot(SetIteratorObject::RangeSlot, PrivateValue(NULL));
1476
    if (!JS_DefineFunctions(cx, proto, SetIteratorObject::methods))
1497
    if (!JS_DefineFunctions(cx, proto, SetIteratorObject::methods))
1477
        return false;
1498
        return false;
1478
    global->setReservedSlot(SET_ITERATOR_PROTO, ObjectValue(*proto));
1499
    global->setReservedSlot(SET_ITERATOR_PROTO, ObjectValue(*proto));
1479
    return true;
1500
    return true;
1480
}
1501
}
1481
1502
1482
SetIteratorObject *
1503
SetIteratorObject *
1483
SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data)
1504
SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data,
1505
                          SetObject::IteratorKind kind)
1484
{
1506
{
1485
    Rooted<GlobalObject *> global(cx, &setobj->global());
1507
    Rooted<GlobalObject *> global(cx, &setobj->global());
1486
    Rooted<JSObject*> proto(cx, global->getOrCreateSetIteratorPrototype(cx));
1508
    Rooted<JSObject*> proto(cx, global->getOrCreateSetIteratorPrototype(cx));
1487
    if (!proto)
1509
    if (!proto)
1488
        return NULL;
1510
        return NULL;
1489
1511
1490
    ValueSet::Range *range = cx->new_<ValueSet::Range>(data->all());
1512
    ValueSet::Range *range = cx->new_<ValueSet::Range>(data->all());
1491
    if (!range)
1513
    if (!range)
1492
        return NULL;
1514
        return NULL;
1493
1515
1494
    JSObject *iterobj = NewObjectWithGivenProto(cx, &SetIteratorClass, proto, global);
1516
    JSObject *iterobj = NewObjectWithGivenProto(cx, &SetIteratorClass, proto, global);
1495
    if (!iterobj) {
1517
    if (!iterobj) {
1496
        js_delete(range);
1518
        js_delete(range);
1497
        return NULL;
1519
        return NULL;
1498
    }
1520
    }
1499
    iterobj->setSlot(TargetSlot, ObjectValue(*setobj));
1521
    iterobj->setSlot(TargetSlot, ObjectValue(*setobj));
1522
    iterobj->setSlot(KindSlot, Int32Value(int32_t(kind)));
1500
    iterobj->setSlot(RangeSlot, PrivateValue(range));
1523
    iterobj->setSlot(RangeSlot, PrivateValue(range));
1501
    return static_cast<SetIteratorObject *>(iterobj);
1524
    return static_cast<SetIteratorObject *>(iterobj);
1502
}
1525
}
1503
1526
1504
void
1527
void
1505
SetIteratorObject::finalize(FreeOp *fop, JSObject *obj)
1528
SetIteratorObject::finalize(FreeOp *fop, JSObject *obj)
1506
{
1529
{
1507
    fop->delete_(obj->asSetIterator().range());
1530
    fop->delete_(obj->asSetIterator().range());
 Lines 1521-1537   SetIteratorObject::next_impl(JSContext * Link Here 
1521
    if (!range)
1544
    if (!range)
1522
        return js_ThrowStopIteration(cx);
1545
        return js_ThrowStopIteration(cx);
1523
    if (range->empty()) {
1546
    if (range->empty()) {
1524
        js_delete(range);
1547
        js_delete(range);
1525
        thisobj.setReservedSlot(RangeSlot, PrivateValue(NULL));
1548
        thisobj.setReservedSlot(RangeSlot, PrivateValue(NULL));
1526
        return js_ThrowStopIteration(cx);
1549
        return js_ThrowStopIteration(cx);
1527
    }
1550
    }
1528
1551
1529
    args.rval().set(range->front().get());
1552
    switch (thisobj.kind()) {
1553
        case SetObject::Values:
1554
          args.rval().set(range->front().get());
1555
          break;
1556
1557
        case SetObject::Entries: {
1558
          Value pair[2] = { range->front().get(), range->front().get() };
1559
          AutoValueArray root(cx, pair, 2);
1560
1561
          JSObject *pairobj = NewDenseCopiedArray(cx, 2, pair);
1562
          if (!pairobj)
1563
            return false;
1564
          args.rval().setObject(*pairobj);
1565
          break;
1566
        }
1567
    }
1568
1530
    range->popFront();
1569
    range->popFront();
1531
    return true;
1570
    return true;
1532
}
1571
}
1533
1572
1534
JSBool
1573
JSBool
1535
SetIteratorObject::next(JSContext *cx, unsigned argc, Value *vp)
1574
SetIteratorObject::next(JSContext *cx, unsigned argc, Value *vp)
1536
{
1575
{
1537
    CallArgs args = CallArgsFromVp(argc, vp);
1576
    CallArgs args = CallArgsFromVp(argc, vp);
 Lines 1571-1596   const JSPropertySpec SetObject::properti Link Here 
1571
    JS_PSG("size", size, 0),
1610
    JS_PSG("size", size, 0),
1572
    JS_PS_END
1611
    JS_PS_END
1573
};
1612
};
1574
1613
1575
const JSFunctionSpec SetObject::methods[] = {
1614
const JSFunctionSpec SetObject::methods[] = {
1576
    JS_FN("has", has, 1, 0),
1615
    JS_FN("has", has, 1, 0),
1577
    JS_FN("add", add, 1, 0),
1616
    JS_FN("add", add, 1, 0),
1578
    JS_FN("delete", delete_, 1, 0),
1617
    JS_FN("delete", delete_, 1, 0),
1579
    JS_FN("iterator", iterator, 0, 0),
1618
    JS_FN("entries", entries, 0, 0),
1580
    JS_FN("clear", clear, 0, 0),
1619
    JS_FN("clear", clear, 0, 0),
1581
    JS_FS_END
1620
    JS_FS_END
1582
};
1621
};
1583
1622
1584
JSObject *
1623
JSObject *
1585
SetObject::initClass(JSContext *cx, JSObject *obj)
1624
SetObject::initClass(JSContext *cx, JSObject *obj)
1586
{
1625
{
1587
    Rooted<GlobalObject*> global(cx, &obj->asGlobal());
1626
    Rooted<GlobalObject*> global(cx, &obj->asGlobal());
1588
    return InitClass(cx, global, &class_, JSProto_Set, construct, properties, methods);
1627
    RootedObject proto(cx,
1628
        InitClass(cx, global, &class_, JSProto_Set, construct, properties, methods));
1629
    if (proto) {
1630
        // Define the "values" method.
1631
        JSFunction *fun = JS_DefineFunction(cx, proto, "values", values, 0, 0);
1632
        if (!fun)
1633
            return NULL;
1634
1635
        // Define its aliases.
1636
        RootedValue funval(cx, ObjectValue(*fun));
1637
        if (!JS_DefineProperty(cx, proto, "keys", funval, NULL, NULL, 0))
1638
            return NULL;
1639
        if (!JS_DefineProperty(cx, proto, "iterator", funval, NULL, NULL, 0))
1640
            return NULL;
1641
    }
1642
    return proto;
1589
}
1643
}
1590
1644
1591
void
1645
void
1592
SetObject::mark(JSTracer *trc, JSObject *obj)
1646
SetObject::mark(JSTracer *trc, JSObject *obj)
1593
{
1647
{
1594
    SetObject *setobj = static_cast<SetObject *>(obj);
1648
    SetObject *setobj = static_cast<SetObject *>(obj);
1595
    if (ValueSet *set = setobj->getData()) {
1649
    if (ValueSet *set = setobj->getData()) {
1596
        for (ValueSet::Range r = set->all(); !r.empty(); r.popFront())
1650
        for (ValueSet::Range r = set->all(); !r.empty(); r.popFront())
 Lines 1735-1766   SetObject::delete_impl(JSContext *cx, Ca Link Here 
1735
JSBool
1789
JSBool
1736
SetObject::delete_(JSContext *cx, unsigned argc, Value *vp)
1790
SetObject::delete_(JSContext *cx, unsigned argc, Value *vp)
1737
{
1791
{
1738
    CallArgs args = CallArgsFromVp(argc, vp);
1792
    CallArgs args = CallArgsFromVp(argc, vp);
1739
    return CallNonGenericMethod<SetObject::is, SetObject::delete_impl>(cx, args);
1793
    return CallNonGenericMethod<SetObject::is, SetObject::delete_impl>(cx, args);
1740
}
1794
}
1741
1795
1742
bool
1796
bool
1743
SetObject::iterator_impl(JSContext *cx, CallArgs args)
1797
SetObject::iterator_impl(JSContext *cx, CallArgs args, IteratorKind kind)
1744
{
1798
{
1745
    Rooted<SetObject*> setobj(cx, &args.thisv().toObject().asSet());
1799
    Rooted<SetObject*> setobj(cx, &args.thisv().toObject().asSet());
1746
    ValueSet &set = *setobj->getData();
1800
    ValueSet &set = *setobj->getData();
1747
    Rooted<JSObject*> iterobj(cx, SetIteratorObject::create(cx, setobj, &set));
1801
    Rooted<JSObject*> iterobj(cx, SetIteratorObject::create(cx, setobj, &set, kind));
1748
    if (!iterobj)
1802
    if (!iterobj)
1749
        return false;
1803
        return false;
1750
    args.rval().setObject(*iterobj);
1804
    args.rval().setObject(*iterobj);
1751
    return true;
1805
    return true;
1752
}
1806
}
1753
1807
1808
bool
1809
SetObject::values_impl(JSContext *cx, CallArgs args)
1810
{
1811
    return iterator_impl(cx, args, Values);
1812
}
1813
1754
JSBool
1814
JSBool
1755
SetObject::iterator(JSContext *cx, unsigned argc, Value *vp)
1815
SetObject::values(JSContext *cx, unsigned argc, Value *vp)
1756
{
1816
{
1757
    CallArgs args = CallArgsFromVp(argc, vp);
1817
    CallArgs args = CallArgsFromVp(argc, vp);
1758
    return CallNonGenericMethod(cx, is, iterator_impl, args);
1818
    return CallNonGenericMethod(cx, is, values_impl, args);
1819
}
1820
1821
bool
1822
SetObject::entries_impl(JSContext *cx, CallArgs args)
1823
{
1824
    return iterator_impl(cx, args, Entries);
1825
}
1826
1827
JSBool
1828
SetObject::entries(JSContext *cx, unsigned argc, Value *vp)
1829
{
1830
    CallArgs args = CallArgsFromVp(argc, vp);
1831
    return CallNonGenericMethod(cx, is, entries_impl, args);
1759
}
1832
}
1760
1833
1761
bool
1834
bool
1762
SetObject::clear_impl(JSContext *cx, CallArgs args)
1835
SetObject::clear_impl(JSContext *cx, CallArgs args)
1763
{
1836
{
1764
    Rooted<SetObject*> setobj(cx, &args.thisv().toObject().asSet());
1837
    Rooted<SetObject*> setobj(cx, &args.thisv().toObject().asSet());
1765
    if (!setobj->getData()->clear()) {
1838
    if (!setobj->getData()->clear()) {
1766
        js_ReportOutOfMemory(cx);
1839
        js_ReportOutOfMemory(cx);
(-)a/js/src/builtin/MapObject.h (-2 / +7 lines)
Line     Link Here 
 Lines 122-160   class MapObject : public JSObject { Link Here 
122
    static bool entries_impl(JSContext *cx, CallArgs args);
122
    static bool entries_impl(JSContext *cx, CallArgs args);
123
    static JSBool entries(JSContext *cx, unsigned argc, Value *vp);
123
    static JSBool entries(JSContext *cx, unsigned argc, Value *vp);
124
    static bool clear_impl(JSContext *cx, CallArgs args);
124
    static bool clear_impl(JSContext *cx, CallArgs args);
125
    static JSBool clear(JSContext *cx, unsigned argc, Value *vp);
125
    static JSBool clear(JSContext *cx, unsigned argc, Value *vp);
126
};
126
};
127
127
128
class SetObject : public JSObject {
128
class SetObject : public JSObject {
129
  public:
129
  public:
130
    enum IteratorKind { Values, Entries };
130
    static JSObject *initClass(JSContext *cx, JSObject *obj);
131
    static JSObject *initClass(JSContext *cx, JSObject *obj);
131
    static Class class_;
132
    static Class class_;
132
  private:
133
  private:
133
    static const JSPropertySpec properties[];
134
    static const JSPropertySpec properties[];
134
    static const JSFunctionSpec methods[];
135
    static const JSFunctionSpec methods[];
135
    ValueSet *getData() { return static_cast<ValueSet *>(getPrivate()); }
136
    ValueSet *getData() { return static_cast<ValueSet *>(getPrivate()); }
136
    static ValueSet & extract(CallReceiver call);
137
    static ValueSet & extract(CallReceiver call);
137
    static void mark(JSTracer *trc, JSObject *obj);
138
    static void mark(JSTracer *trc, JSObject *obj);
138
    static void finalize(FreeOp *fop, JSObject *obj);
139
    static void finalize(FreeOp *fop, JSObject *obj);
139
    static JSBool construct(JSContext *cx, unsigned argc, Value *vp);
140
    static JSBool construct(JSContext *cx, unsigned argc, Value *vp);
140
141
141
    static bool is(const Value &v);
142
    static bool is(const Value &v);
142
143
144
    static bool iterator_impl(JSContext *cx, CallArgs args, IteratorKind kind);
145
143
    static bool size_impl(JSContext *cx, CallArgs args);
146
    static bool size_impl(JSContext *cx, CallArgs args);
144
    static JSBool size(JSContext *cx, unsigned argc, Value *vp);
147
    static JSBool size(JSContext *cx, unsigned argc, Value *vp);
145
    static bool has_impl(JSContext *cx, CallArgs args);
148
    static bool has_impl(JSContext *cx, CallArgs args);
146
    static JSBool has(JSContext *cx, unsigned argc, Value *vp);
149
    static JSBool has(JSContext *cx, unsigned argc, Value *vp);
147
    static bool add_impl(JSContext *cx, CallArgs args);
150
    static bool add_impl(JSContext *cx, CallArgs args);
148
    static JSBool add(JSContext *cx, unsigned argc, Value *vp);
151
    static JSBool add(JSContext *cx, unsigned argc, Value *vp);
149
    static bool delete_impl(JSContext *cx, CallArgs args);
152
    static bool delete_impl(JSContext *cx, CallArgs args);
150
    static JSBool delete_(JSContext *cx, unsigned argc, Value *vp);
153
    static JSBool delete_(JSContext *cx, unsigned argc, Value *vp);
151
    static bool iterator_impl(JSContext *cx, CallArgs args);
154
    static bool values_impl(JSContext *cx, CallArgs args);
152
    static JSBool iterator(JSContext *cx, unsigned argc, Value *vp);
155
    static JSBool values(JSContext *cx, unsigned argc, Value *vp);
156
    static bool entries_impl(JSContext *cx, CallArgs args);
157
    static JSBool entries(JSContext *cx, unsigned argc, Value *vp);
153
    static bool clear_impl(JSContext *cx, CallArgs args);
158
    static bool clear_impl(JSContext *cx, CallArgs args);
154
    static JSBool clear(JSContext *cx, unsigned argc, Value *vp);
159
    static JSBool clear(JSContext *cx, unsigned argc, Value *vp);
155
};
160
};
156
161
157
} /* namespace js */
162
} /* namespace js */
158
163
159
extern JSObject *
164
extern JSObject *
160
js_InitMapClass(JSContext *cx, js::HandleObject obj);
165
js_InitMapClass(JSContext *cx, js::HandleObject obj);
(-)a/js/src/jit-test/tests/collections/Map-values-1.js (+4 lines)
Line     Link Here 
 Lines 1-8    Link Here 
1
// Map.prototype.iterator and .entries are the same function object
2
3
assertEq(Map.prototype.iterator, Map.prototype.entries);
4
1
// map.keys(), .values(), and .entries() on an empty map produce empty iterators.
5
// map.keys(), .values(), and .entries() on an empty map produce empty iterators.
2
6
3
var m = Map();
7
var m = Map();
4
var ki = m.keys(), vi = m.values(), ei = m.entries();
8
var ki = m.keys(), vi = m.values(), ei = m.entries();
5
var p = Object.getPrototypeOf(ki)
9
var p = Object.getPrototypeOf(ki)
6
assertEq(Object.getPrototypeOf(vi), p);
10
assertEq(Object.getPrototypeOf(vi), p);
7
assertEq(Object.getPrototypeOf(ei), p);
11
assertEq(Object.getPrototypeOf(ei), p);
8
12
(-)a/js/src/jit-test/tests/collections/Set-values-1.js (+18 lines)
Line     Link Here 
Line 0    Link Here 
1
// Set.prototype.keys and .values are the same function object
2
3
assertEq(Set.prototype.keys, Set.prototype.values);
4
5
// set.keys(), .values(), and .entries() on an empty set produce empty iterators
6
7
var s = Set();
8
var ki = s.keys(), vi = s.values(), ei = s.entries();
9
var p = Object.getPrototypeOf(ki);
10
assertEq(Object.getPrototypeOf(vi), p);
11
assertEq(Object.getPrototypeOf(ei), p);
12
13
for (let k of ki)
14
	throw "FAIL";
15
for (let v of vi)
16
	throw "FAIL";
17
for (let [k, v] of ei)
18
	throw "FAIL";
(-)a/js/src/jit-test/tests/collections/Set-values-2.js (+19 lines)
Line     Link Here 
Line 0    Link Here 
1
// set.keys() and set.values() return iterators over the values,
2
// and set.entries() return iterator over a pair of values in the set
3
4
load(libdir + "asserts.js");
5
6
var data = [1, 2, 3, 4];
7
var values = [[1, 1], [2, 2], [3, 3], [4, 4]];
8
var s = Set(data);
9
10
var ki = s.keys();
11
assertEq(ki.next(), 1);
12
assertEq(ki.next(), 2);
13
assertEq(ki.next(), 3);
14
assertEq(ki.next(), 4);
15
assertThrowsValue(function () { ki.next(); }, StopIteration);
16
17
assertEq([...s.keys()].toSource(), [1, 2, 3, 4].toSource());
18
assertEq([...s.values()].toSource(), [1, 2, 3, 4].toSource());
19
assertEq([...s.entries()].toSource(), values.toSource());

Return to bug 869996