| 1798 | static JSClass listIteratorClass = {"ListIterator", JSCLASS_HAS_RESERVED_SLOTS(ListIteratorSlotCount)}; |
| 1799 | |
| 1800 | static bool iterator_next(JSContext *cx, unsigned argc, JS::Value *vp) { |
| 1801 | JS::CallArgs args = JS::CallArgsFromVp(argc, vp); |
| 1802 | JS::RootedObject thisObj(cx); |
| 1803 | if (!args.computeThis(cx, &thisObj)) return false; |
| 1804 | |
| 1805 | PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(thisObj, ListIteratorSlotIteratedObject); |
| 1806 | |
| 1807 | JS::RootedValue rootedNextIndex(cx, JS::GetReservedSlot(thisObj, ListIteratorSlotNextIndex)); |
| 1808 | JS::RootedValue rootedItemKind(cx, JS::GetReservedSlot(thisObj, ListIteratorSlotItemKind)); |
| 1809 | |
| 1810 | int32_t nextIndex; |
| 1811 | int32_t itemKind; |
| 1812 | if (!JS::ToInt32(cx, rootedNextIndex, &nextIndex) || !JS::ToInt32(cx, rootedItemKind, &itemKind)) return false; |
| 1813 | |
| 1814 | JS::RootedObject result(cx, JS_NewPlainObject(cx)); |
| 1815 | |
| 1816 | Py_ssize_t len = PyList_GET_SIZE(self); |
| 1817 | |
| 1818 | if (nextIndex >= len) { |
| 1819 | // UnsafeSetReservedSlot(obj, ITERATOR_SLOT_TARGET, null); // TODO lose ref |
| 1820 | JS::RootedValue done(cx, JS::BooleanValue(true)); |
| 1821 | if (!JS_SetProperty(cx, result, "done", done)) return false; |
| 1822 | args.rval().setObject(*result); |
| 1823 | return result; |
| 1824 | } |
| 1825 | |
| 1826 | JS::SetReservedSlot(thisObj, ListIteratorSlotNextIndex, JS::Int32Value(nextIndex + 1)); |
| 1827 | |
| 1828 | JS::RootedValue done(cx, JS::BooleanValue(false)); |
| 1829 | if (!JS_SetProperty(cx, result, "done", done)) return false; |
| 1830 | |
| 1831 | if (itemKind == ITEM_KIND_VALUE) { |
| 1832 | PyObject *item = PyList_GetItem(self, nextIndex); |
| 1833 | if (!item) { |
| 1834 | return false; |
| 1835 | } |
| 1836 | JS::RootedValue value(cx, jsTypeFactory(cx, item)); |
| 1837 | if (!JS_SetProperty(cx, result, "value", value)) return false; |
| 1838 | } |
| 1839 | else if (itemKind == ITEM_KIND_KEY_AND_VALUE) { |
| 1840 | JS::Rooted<JS::ValueArray<2>> items(cx); |
| 1841 | |
| 1842 | JS::RootedValue rootedNextIndex(cx, JS::Int32Value(nextIndex)); |
| 1843 | items[0].set(rootedNextIndex); |
| 1844 | |
| 1845 | PyObject *item = PyList_GetItem(self, nextIndex); |
| 1846 | if (!item) { |
| 1847 | return false; |
| 1848 | } |
| 1849 | JS::RootedValue value(cx, jsTypeFactory(cx, item)); |
| 1850 | items[1].set(value); |
| 1851 | |
| 1852 | JS::RootedValue pair(cx); |
| 1853 | JSObject *array = JS::NewArrayObject(cx, items); |
| 1854 | pair.setObject(*array); |
| 1855 | if (!JS_SetProperty(cx, result, "value", pair)) return false; |
| 1856 | } |
| 1857 | else { // itemKind == ITEM_KIND_KEY |
nothing calls this directly
no test coverage detected