| 1186 | } |
| 1187 | |
| 1188 | static bool array_findIndex(JSContext *cx, unsigned argc, JS::Value *vp) { |
| 1189 | JS::CallArgs args = JS::CallArgsFromVp(argc, vp); |
| 1190 | |
| 1191 | if (!args.requireAtLeast(cx, "findIndex", 1)) { |
| 1192 | return false; |
| 1193 | } |
| 1194 | |
| 1195 | JS::RootedObject proxy(cx, JS::ToObject(cx, args.thisv())); |
| 1196 | if (!proxy) { |
| 1197 | return false; |
| 1198 | } |
| 1199 | PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot); |
| 1200 | |
| 1201 | JS::Value callbackfn = args[0].get(); |
| 1202 | |
| 1203 | if (!callbackfn.isObject() || !JS::IsCallable(&callbackfn.toObject())) { |
| 1204 | JS_ReportErrorNumberASCII(cx, js::GetErrorMessage, nullptr, JSMSG_NOT_FUNCTION, "findIndex: callback"); |
| 1205 | return false; |
| 1206 | } |
| 1207 | |
| 1208 | JS::RootedValue selfValue(cx, jsTypeFactory(cx, self)); |
| 1209 | JS::RootedValue callBack(cx, callbackfn); |
| 1210 | |
| 1211 | JS::Rooted<JS::ValueArray<3>> jArgs(cx); |
| 1212 | JS::RootedValue rval(cx); |
| 1213 | |
| 1214 | JS::RootedObject rootedThisArg(cx); |
| 1215 | if (args.length() > 1) { |
| 1216 | JS::Value thisArg = args[1].get(); |
| 1217 | if (!thisArg.isObjectOrNull()) { |
| 1218 | JS_ReportErrorNumberASCII(cx, js::GetErrorMessage, nullptr, JSMSG_NOT_OBJORNULL, "'this' argument"); |
| 1219 | return false; |
| 1220 | } |
| 1221 | |
| 1222 | // TODO support null, currently gets TypeError |
| 1223 | rootedThisArg.set(thisArg.toObjectOrNull()); |
| 1224 | // check if callback is a PyMethod, need to make a new method bound to thisArg |
| 1225 | if (!makeNewPyMethod(cx, &callBack, rootedThisArg)) { |
| 1226 | return false; |
| 1227 | } |
| 1228 | } |
| 1229 | else { |
| 1230 | rootedThisArg.set(nullptr); |
| 1231 | } |
| 1232 | |
| 1233 | Py_ssize_t len = PyList_GET_SIZE(self); |
| 1234 | for (Py_ssize_t index = 0, toIndex = 0; index < len; index++) { |
| 1235 | jArgs[0].set(jsTypeFactory(cx, PyList_GetItem(self, index))); |
| 1236 | jArgs[1].setInt32(index); |
| 1237 | jArgs[2].set(selfValue); |
| 1238 | |
| 1239 | if (!JS_CallFunctionValue(cx, rootedThisArg, callBack, jArgs, &rval)) { |
| 1240 | return false; |
| 1241 | } |
| 1242 | |
| 1243 | if (rval.toBoolean()) { |
| 1244 | args.rval().setInt32(index); |
| 1245 | return true; |
nothing calls this directly
no test coverage detected