in rhino/src/main/java/org/mozilla/javascript/ArrayLikeAbstractOperations.java [112:214]
private static Object coercibleIterativeMethod(
Context cx,
IterativeOperation operation,
Scriptable scope,
Object[] args,
Scriptable o) {
long length = getLengthProperty(cx, o);
if (operation == IterativeOperation.MAP && length > Integer.MAX_VALUE) {
String msg = ScriptRuntime.getMessageById("msg.arraylength.bad");
throw ScriptRuntime.rangeError(msg);
}
Object callbackArg = args.length > 0 ? args[0] : Undefined.instance;
Function f = getCallbackArg(cx, callbackArg);
Scriptable parent = ScriptableObject.getTopLevelScope(f);
Scriptable thisArg;
if (args.length < 2 || args[1] == null || args[1] == Undefined.instance) {
thisArg = parent;
} else {
thisArg = ScriptRuntime.toObject(cx, scope, args[1]);
}
Scriptable array = null;
if (operation == IterativeOperation.FILTER || operation == IterativeOperation.MAP) {
int resultLength = operation == IterativeOperation.MAP ? (int) length : 0;
array = arraySpeciesCreate(cx, scope, o, resultLength);
}
long j = 0;
long start =
(operation == IterativeOperation.FIND_LAST
|| operation == IterativeOperation.FIND_LAST_INDEX)
? length - 1
: 0;
long end =
(operation == IterativeOperation.FIND_LAST
|| operation == IterativeOperation.FIND_LAST_INDEX)
? -1
: length;
long increment =
(operation == IterativeOperation.FIND_LAST
|| operation == IterativeOperation.FIND_LAST_INDEX)
? -1
: +1;
for (long i = start; i != end; i += increment) {
Object[] innerArgs = new Object[3];
Object elem = getRawElem(o, i);
if (elem == NOT_FOUND) {
if (operation == IterativeOperation.FIND
|| operation == IterativeOperation.FIND_INDEX
|| operation == IterativeOperation.FIND_LAST
|| operation == IterativeOperation.FIND_LAST_INDEX) {
elem = Undefined.instance;
} else {
continue;
}
}
innerArgs[0] = elem;
innerArgs[1] = Long.valueOf(i);
innerArgs[2] = o;
Object result = f.call(cx, parent, thisArg, innerArgs);
switch (operation) {
case EVERY:
if (!ScriptRuntime.toBoolean(result)) return Boolean.FALSE;
break;
case FILTER:
if (ScriptRuntime.toBoolean(result)) defineElem(cx, array, j++, innerArgs[0]);
break;
case FOR_EACH:
break;
case MAP:
defineElem(cx, array, i, result);
break;
case SOME:
if (ScriptRuntime.toBoolean(result)) return Boolean.TRUE;
break;
case FIND:
case FIND_LAST:
if (ScriptRuntime.toBoolean(result)) return elem;
break;
case FIND_INDEX:
case FIND_LAST_INDEX:
if (ScriptRuntime.toBoolean(result))
return ScriptRuntime.wrapNumber((double) i);
break;
}
}
switch (operation) {
case EVERY:
return Boolean.TRUE;
case FILTER:
case MAP:
return array;
case SOME:
return Boolean.FALSE;
case FIND_INDEX:
case FIND_LAST_INDEX:
return ScriptRuntime.wrapNumber(-1);
case FOR_EACH:
default:
return Undefined.instance;
}
}