Attachment #753764: patch v2 for bug #869996

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

(-)a/js/src/builtin/MapObject.cpp (-9 / +73 lines)
Line     Link Here 
 Lines 1414-1437   js_InitMapClass(JSContext *cx, HandleObj Link Here 
1414
}
1414
}
1415
1415
1416
1416
1417
/*** SetIterator *********************************************************************************/
1417
/*** SetIterator *********************************************************************************/
1418
1418
1419
class js::SetIteratorObject : public JSObject
1419
class js::SetIteratorObject : public JSObject
1420
{
1420
{
1421
  public:
1421
  public:
1422
    enum { TargetSlot, RangeSlot, SlotCount };
1422
    enum { TargetSlot, KindSlot, RangeSlot, SlotCount };
1423
    static const JSFunctionSpec methods[];
1423
    static const JSFunctionSpec methods[];
1424
    static SetIteratorObject *create(JSContext *cx, HandleObject setobj, ValueSet *data);
1424
    static SetIteratorObject *create(JSContext *cx, HandleObject setobj, ValueSet *data,
1425
                                     SetObject::IteratorKind kind);
1425
    static void finalize(FreeOp *fop, JSObject *obj);
1426
    static void finalize(FreeOp *fop, JSObject *obj);
1426
1427
1427
  private:
1428
  private:
1428
    static inline bool is(const Value &v);
1429
    static inline bool is(const Value &v);
1429
    inline ValueSet::Range *range();
1430
    inline ValueSet::Range *range();
1431
    inline SetObject::IteratorKind kind() const;
1430
    static bool next_impl(JSContext *cx, CallArgs args);
1432
    static bool next_impl(JSContext *cx, CallArgs args);
1431
    static JSBool next(JSContext *cx, unsigned argc, Value *vp);
1433
    static JSBool next(JSContext *cx, unsigned argc, Value *vp);
1432
};
1434
};
1433
1435
1434
inline js::SetIteratorObject &
1436
inline js::SetIteratorObject &
1435
JSObject::asSetIterator()
1437
JSObject::asSetIterator()
1436
{
1438
{
1437
    JS_ASSERT(isSetIterator());
1439
    JS_ASSERT(isSetIterator());
 Lines 1458-1473   const JSFunctionSpec SetIteratorObject:: Link Here 
1458
};
1460
};
1459
1461
1460
inline ValueSet::Range *
1462
inline ValueSet::Range *
1461
SetIteratorObject::range()
1463
SetIteratorObject::range()
1462
{
1464
{
1463
    return static_cast<ValueSet::Range *>(getSlot(RangeSlot).toPrivate());
1465
    return static_cast<ValueSet::Range *>(getSlot(RangeSlot).toPrivate());
1464
}
1466
}
1465
1467
1468
inline SetObject::IteratorKind
1469
SetIteratorObject::kind() const
1470
{
1471
    int32_t i = getSlot(KindSlot).toInt32();
1472
    JS_ASSERT(i == SetObject::Keys || i == SetObject::Values || i == SetObject::Entries);
1473
    return SetObject::IteratorKind(i);
1474
}
1475
1466
bool
1476
bool
1467
GlobalObject::initSetIteratorProto(JSContext *cx, Handle<GlobalObject*> global)
1477
GlobalObject::initSetIteratorProto(JSContext *cx, Handle<GlobalObject*> global)
1468
{
1478
{
1469
    JSObject *base = global->getOrCreateIteratorPrototype(cx);
1479
    JSObject *base = global->getOrCreateIteratorPrototype(cx);
1470
    if (!base)
1480
    if (!base)
1471
        return false;
1481
        return false;
1472
    RootedObject proto(cx, NewObjectWithGivenProto(cx, &SetIteratorClass, base, global));
1482
    RootedObject proto(cx, NewObjectWithGivenProto(cx, &SetIteratorClass, base, global));
1473
    if (!proto)
1483
    if (!proto)
 Lines 1475-1507   GlobalObject::initSetIteratorProto(JSCon Link Here 
1475
    proto->setSlot(SetIteratorObject::RangeSlot, PrivateValue(NULL));
1485
    proto->setSlot(SetIteratorObject::RangeSlot, PrivateValue(NULL));
1476
    if (!JS_DefineFunctions(cx, proto, SetIteratorObject::methods))
1486
    if (!JS_DefineFunctions(cx, proto, SetIteratorObject::methods))
1477
        return false;
1487
        return false;
1478
    global->setReservedSlot(SET_ITERATOR_PROTO, ObjectValue(*proto));
1488
    global->setReservedSlot(SET_ITERATOR_PROTO, ObjectValue(*proto));
1479
    return true;
1489
    return true;
1480
}
1490
}
1481
1491
1482
SetIteratorObject *
1492
SetIteratorObject *
1483
SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data)
1493
SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data,
1494
                          SetObject::IteratorKind kind)
1484
{
1495
{
1485
    Rooted<GlobalObject *> global(cx, &setobj->global());
1496
    Rooted<GlobalObject *> global(cx, &setobj->global());
1486
    Rooted<JSObject*> proto(cx, global->getOrCreateSetIteratorPrototype(cx));
1497
    Rooted<JSObject*> proto(cx, global->getOrCreateSetIteratorPrototype(cx));
1487
    if (!proto)
1498
    if (!proto)
1488
        return NULL;
1499
        return NULL;
1489
1500
1490
    ValueSet::Range *range = cx->new_<ValueSet::Range>(data->all());
1501
    ValueSet::Range *range = cx->new_<ValueSet::Range>(data->all());
1491
    if (!range)
1502
    if (!range)
1492
        return NULL;
1503
        return NULL;
1493
1504
1494
    JSObject *iterobj = NewObjectWithGivenProto(cx, &SetIteratorClass, proto, global);
1505
    JSObject *iterobj = NewObjectWithGivenProto(cx, &SetIteratorClass, proto, global);
1495
    if (!iterobj) {
1506
    if (!iterobj) {
1496
        js_delete(range);
1507
        js_delete(range);
1497
        return NULL;
1508
        return NULL;
1498
    }
1509
    }
1499
    iterobj->setSlot(TargetSlot, ObjectValue(*setobj));
1510
    iterobj->setSlot(TargetSlot, ObjectValue(*setobj));
1511
    iterobj->setSlot(KindSlot, Int32Value(int32_t(kind)));
1500
    iterobj->setSlot(RangeSlot, PrivateValue(range));
1512
    iterobj->setSlot(RangeSlot, PrivateValue(range));
1501
    return static_cast<SetIteratorObject *>(iterobj);
1513
    return static_cast<SetIteratorObject *>(iterobj);
1502
}
1514
}
1503
1515
1504
void
1516
void
1505
SetIteratorObject::finalize(FreeOp *fop, JSObject *obj)
1517
SetIteratorObject::finalize(FreeOp *fop, JSObject *obj)
1506
{
1518
{
1507
    fop->delete_(obj->asSetIterator().range());
1519
    fop->delete_(obj->asSetIterator().range());
 Lines 1521-1537   SetIteratorObject::next_impl(JSContext * Link Here 
1521
    if (!range)
1533
    if (!range)
1522
        return js_ThrowStopIteration(cx);
1534
        return js_ThrowStopIteration(cx);
1523
    if (range->empty()) {
1535
    if (range->empty()) {
1524
        js_delete(range);
1536
        js_delete(range);
1525
        thisobj.setReservedSlot(RangeSlot, PrivateValue(NULL));
1537
        thisobj.setReservedSlot(RangeSlot, PrivateValue(NULL));
1526
        return js_ThrowStopIteration(cx);
1538
        return js_ThrowStopIteration(cx);
1527
    }
1539
    }
1528
1540
1529
    args.rval().set(range->front().get());
1541
    switch (thisobj.kind()) {
1542
        case SetObject::Keys:
1543
        case SetObject::Values:
1544
            args.rval().set(range->front().get());
1545
            break;
1546
1547
        case SetObject::Entries: {
1548
            Value pair[2] = { range->front().get(), range->front().get() };
1549
            AutoValueArray root(cx, pair, 2);
1550
1551
            JSObject *pairobj = NewDenseCopiedArray(cx, 2, pair);
1552
            if(!pairobj)
1553
                return false;
1554
            args.rval().setObject(*pairobj);
1555
            break;
1556
        }
1557
    }
1558
1530
    range->popFront();
1559
    range->popFront();
1531
    return true;
1560
    return true;
1532
}
1561
}
1533
1562
1534
JSBool
1563
JSBool
1535
SetIteratorObject::next(JSContext *cx, unsigned argc, Value *vp)
1564
SetIteratorObject::next(JSContext *cx, unsigned argc, Value *vp)
1536
{
1565
{
1537
    CallArgs args = CallArgsFromVp(argc, vp);
1566
    CallArgs args = CallArgsFromVp(argc, vp);
 Lines 1571-1587   const JSPropertySpec SetObject::properti Link Here 
1571
    JS_PSG("size", size, 0),
1600
    JS_PSG("size", size, 0),
1572
    JS_PS_END
1601
    JS_PS_END
1573
};
1602
};
1574
1603
1575
const JSFunctionSpec SetObject::methods[] = {
1604
const JSFunctionSpec SetObject::methods[] = {
1576
    JS_FN("has", has, 1, 0),
1605
    JS_FN("has", has, 1, 0),
1577
    JS_FN("add", add, 1, 0),
1606
    JS_FN("add", add, 1, 0),
1578
    JS_FN("delete", delete_, 1, 0),
1607
    JS_FN("delete", delete_, 1, 0),
1579
    JS_FN("iterator", iterator, 0, 0),
1608
    JS_FN("keys", keys, 0, 0),
1609
    JS_FN("values", values, 0, 0),
1610
    JS_FN("entries", entries, 0, 0),
1611
    JS_FN("iterator", values, 0, 0),
1580
    JS_FN("clear", clear, 0, 0),
1612
    JS_FN("clear", clear, 0, 0),
1581
    JS_FS_END
1613
    JS_FS_END
1582
};
1614
};
1583
1615
1584
JSObject *
1616
JSObject *
1585
SetObject::initClass(JSContext *cx, JSObject *obj)
1617
SetObject::initClass(JSContext *cx, JSObject *obj)
1586
{
1618
{
1587
    Rooted<GlobalObject*> global(cx, &obj->asGlobal());
1619
    Rooted<GlobalObject*> global(cx, &obj->asGlobal());
 Lines 1735-1766   SetObject::delete_impl(JSContext *cx, Ca Link Here 
1735
JSBool
1767
JSBool
1736
SetObject::delete_(JSContext *cx, unsigned argc, Value *vp)
1768
SetObject::delete_(JSContext *cx, unsigned argc, Value *vp)
1737
{
1769
{
1738
    CallArgs args = CallArgsFromVp(argc, vp);
1770
    CallArgs args = CallArgsFromVp(argc, vp);
1739
    return CallNonGenericMethod<SetObject::is, SetObject::delete_impl>(cx, args);
1771
    return CallNonGenericMethod<SetObject::is, SetObject::delete_impl>(cx, args);
1740
}
1772
}
1741
1773
1742
bool
1774
bool
1743
SetObject::iterator_impl(JSContext *cx, CallArgs args)
1775
SetObject::iterator_impl(JSContext *cx, CallArgs args, IteratorKind kind)
1744
{
1776
{
1745
    Rooted<SetObject*> setobj(cx, &args.thisv().toObject().asSet());
1777
    Rooted<SetObject*> setobj(cx, &args.thisv().toObject().asSet());
1746
    ValueSet &set = *setobj->getData();
1778
    ValueSet &set = *setobj->getData();
1747
    Rooted<JSObject*> iterobj(cx, SetIteratorObject::create(cx, setobj, &set));
1779
    Rooted<JSObject*> iterobj(cx, SetIteratorObject::create(cx, setobj, &set, kind));
1748
    if (!iterobj)
1780
    if (!iterobj)
1749
        return false;
1781
        return false;
1750
    args.rval().setObject(*iterobj);
1782
    args.rval().setObject(*iterobj);
1751
    return true;
1783
    return true;
1752
}
1784
}
1753
1785
1786
bool
1787
SetObject::keys_impl(JSContext *cx, CallArgs args)
1788
{
1789
    return iterator_impl(cx, args, Keys);
1790
}
1791
1754
JSBool
1792
JSBool
1755
SetObject::iterator(JSContext *cx, unsigned argc, Value *vp)
1793
SetObject::keys(JSContext *cx, unsigned argc, Value *vp)
1756
{
1794
{
1757
    CallArgs args = CallArgsFromVp(argc, vp);
1795
    CallArgs args = CallArgsFromVp(argc, vp);
1758
    return CallNonGenericMethod(cx, is, iterator_impl, args);
1796
    return CallNonGenericMethod(cx, is, keys_impl, args);
1797
}
1798
1799
bool
1800
SetObject::values_impl(JSContext *cx, CallArgs args)
1801
{
1802
    return iterator_impl(cx, args, Values);
1803
}
1804
1805
JSBool
1806
SetObject::values(JSContext *cx, unsigned argc, Value *vp)
1807
{
1808
    CallArgs args = CallArgsFromVp(argc, vp);
1809
    return CallNonGenericMethod(cx, is, values_impl, args);
1810
}
1811
1812
bool
1813
SetObject::entries_impl(JSContext *cx, CallArgs args)
1814
{
1815
    return iterator_impl(cx, args, Entries);
1816
}
1817
1818
JSBool
1819
SetObject::entries(JSContext *cx, unsigned argc, Value *vp)
1820
{
1821
    CallArgs args = CallArgsFromVp(argc, vp);
1822
    return CallNonGenericMethod(cx, is, entries_impl, args);
1759
}
1823
}
1760
1824
1761
bool
1825
bool
1762
SetObject::clear_impl(JSContext *cx, CallArgs args)
1826
SetObject::clear_impl(JSContext *cx, CallArgs args)
1763
{
1827
{
1764
    Rooted<SetObject*> setobj(cx, &args.thisv().toObject().asSet());
1828
    Rooted<SetObject*> setobj(cx, &args.thisv().toObject().asSet());
1765
    if (!setobj->getData()->clear()) {
1829
    if (!setobj->getData()->clear()) {
1766
        js_ReportOutOfMemory(cx);
1830
        js_ReportOutOfMemory(cx);
(-)a/js/src/builtin/MapObject.h (-2 / +9 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 { Keys, 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 keys_impl(JSContext *cx, CallArgs args);
152
    static JSBool iterator(JSContext *cx, unsigned argc, Value *vp);
155
    static JSBool keys(JSContext *cx, unsigned argc, Value *vp);
156
    static bool values_impl(JSContext *cx, CallArgs args);
157
    static JSBool values(JSContext *cx, unsigned argc, Value *vp);
158
    static bool entries_impl(JSContext *cx, CallArgs args);
159
    static JSBool entries(JSContext *cx, unsigned argc, Value *vp);
153
    static bool clear_impl(JSContext *cx, CallArgs args);
160
    static bool clear_impl(JSContext *cx, CallArgs args);
154
    static JSBool clear(JSContext *cx, unsigned argc, Value *vp);
161
    static JSBool clear(JSContext *cx, unsigned argc, Value *vp);
155
};
162
};
156
163
157
} /* namespace js */
164
} /* namespace js */
158
165
159
extern JSObject *
166
extern JSObject *
160
js_InitMapClass(JSContext *cx, js::HandleObject obj);
167
js_InitMapClass(JSContext *cx, js::HandleObject obj);
(-)a/js/src/jit-test/tests/collections/Set-values-1.js (+14 lines)
Line     Link Here 
Line 0    Link Here 
1
// set.keys(), .values(), and .entries() on an empty set produce empty iterators
2
3
var s = Set();
4
var ki = s.keys(), vi = s.values(), ei = s.entries();
5
var p = Object.getPrototypeOf(ki);
6
assertEq(Object.getPrototypeOf(vi), p);
7
assertEq(Object.getPrototypeOf(ei), p);
8
9
for (let k or ki)
10
	throw "FAIL";
11
for (let v of vi)
12
	throw "FAIL";
13
for (let [k, v] of ei)
14
	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([k for (k of s.keys())].toSource(), [1, 2, 3, 4].toSource());
18
assertEq([k for (k of s.values())].toSource(), [1, 2, 3, 4].toSource());
19
assertEq([k for (k of s.entries())].toSource(), values.toSource());

Return to bug 869996