private static Object coercibleIterativeMethod()

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