|
|
|
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); |