| 603 | } |
| 604 | |
| 605 | static bool array_lastIndexOf(JSContext *cx, unsigned argc, JS::Value *vp) { |
| 606 | JS::CallArgs args = JS::CallArgsFromVp(argc, vp); |
| 607 | |
| 608 | if (!args.requireAtLeast(cx, "lastIndexOf", 1)) { |
| 609 | return false; |
| 610 | } |
| 611 | |
| 612 | JS::RootedObject proxy(cx, JS::ToObject(cx, args.thisv())); |
| 613 | if (!proxy) { |
| 614 | return false; |
| 615 | } |
| 616 | PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot); |
| 617 | |
| 618 | Py_ssize_t selfLength = PyList_GET_SIZE(self); |
| 619 | |
| 620 | if (selfLength == 0) { |
| 621 | args.rval().setInt32(-1); |
| 622 | return true; |
| 623 | } |
| 624 | |
| 625 | uint64_t start = selfLength - 1; |
| 626 | if (args.length() > 1) { |
| 627 | int64_t n; |
| 628 | if (!JS::ToInt64(cx, args[1], &n)) { |
| 629 | return false; |
| 630 | } |
| 631 | |
| 632 | if (n < 0) { |
| 633 | double d = double(selfLength) + n; |
| 634 | if (d < 0) { |
| 635 | args.rval().setInt32(-1); |
| 636 | return true; |
| 637 | } |
| 638 | start = uint64_t(d); |
| 639 | } else if (n < double(start)) { |
| 640 | start = uint64_t(n); |
| 641 | } |
| 642 | } |
| 643 | |
| 644 | JS::RootedValue elementVal(cx, args[0].get()); |
| 645 | PyObject *element = pyTypeFactory(cx, elementVal); |
| 646 | for (int64_t index = start; index >= 0; index--) { |
| 647 | PyObject *item = PyList_GetItem(self, index); |
| 648 | Py_INCREF(item); |
| 649 | int cmp = PyObject_RichCompareBool(item, element, Py_EQ); |
| 650 | Py_DECREF(item); |
| 651 | if (cmp < 0) { |
| 652 | Py_XDECREF(element); |
| 653 | return false; |
| 654 | } |
| 655 | else if (cmp == 1) { |
| 656 | Py_XDECREF(element); |
| 657 | args.rval().setInt32(index); |
| 658 | return true; |
| 659 | } |
| 660 | } |
| 661 | Py_XDECREF(element); |
| 662 |
nothing calls this directly
no test coverage detected