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