/** * ECMA 15.4.4.19 Array.prototype.map ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return array with elements transformed by map function */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static NativeArray map(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) { private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final long i) throws Throwable { final Object r = mapInvoker.invokeExact(callbackfn, thisArg, val, i, self); result.defineOwnProperty(ArrayIndex.getArrayIndex(index), r); return true; } @Override public void applyLoopBegin(final ArrayLikeIterator<Object> iter0) { // map return array should be of same length as source array // even if callback reduces source array length result = new NativeArray(iter0.getLength()); } }.apply(); }
/** * ECMA 15.4.4.20 Array.prototype.filter ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return filtered array */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static NativeArray filter(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) { private long to = 0; private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final long i) throws Throwable { if ((boolean)filterInvoker.invokeExact(callbackfn, thisArg, val, i, self)) { result.defineOwnProperty(ArrayIndex.getArrayIndex(to++), val); } return true; } }.apply(); }
/** * ECMA 15.4.4.19 Array.prototype.map ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return array with elements transformed by map function */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static NativeArray map(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) { private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final double i) throws Throwable { final Object r = mapInvoker.invokeExact(callbackfn, thisArg, val, i, self); result.defineOwnProperty(ArrayIndex.getArrayIndex(index), r); return true; } @Override public void applyLoopBegin(final ArrayLikeIterator<Object> iter0) { // map return array should be of same length as source array // even if callback reduces source array length result = new NativeArray(iter0.getLength()); } }.apply(); }
/** * ECMA 15.4.4.20 Array.prototype.filter ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return filtered array */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static NativeArray filter(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) { private long to = 0; private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final double i) throws Throwable { if ((boolean)filterInvoker.invokeExact(callbackfn, thisArg, val, i, self)) { result.defineOwnProperty(ArrayIndex.getArrayIndex(to++), val); } return true; } }.apply(); }
/** * ECMA 15.4.4.19 Array.prototype.map ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return array with elements transformed by map function */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object map(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) { private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final long i) throws Throwable { final Object r = mapInvoker.invokeExact(callbackfn, thisArg, val, i, self); result.defineOwnProperty(ArrayIndex.getArrayIndex(index), r); return true; } @Override public void applyLoopBegin(final ArrayLikeIterator<Object> iter0) { // map return array should be of same length as source array // even if callback reduces source array length result = new NativeArray(iter0.getLength()); } }.apply(); }
/** * ECMA 15.4.4.20 Array.prototype.filter ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return filtered array */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object filter(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) { private long to = 0; private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final long i) throws Throwable { if ((boolean)filterInvoker.invokeExact(callbackfn, thisArg, val, i, self)) { result.defineOwnProperty(ArrayIndex.getArrayIndex(to++), val); } return true; } }.apply(); }
private static boolean applyEvery(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, true) { private final MethodHandle everyInvoker = getEVERY_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final long i) throws Throwable { return result = (boolean)everyInvoker.invokeExact(callbackfn, thisArg, val, i, self); } }.apply(); }
/** * ECMA 15.4.4.17 Array.prototype.some ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return true if callback function returned true for any element in the array, false otherwise */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static boolean some(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) { private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final long i) throws Throwable { return !(result = (boolean)someInvoker.invokeExact(callbackfn, thisArg, val, i, self)); } }.apply(); }
/** * ECMA 15.4.4.18 Array.prototype.forEach ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return undefined */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object forEach(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<Object>(Global.toObject(self), callbackfn, thisArg, ScriptRuntime.UNDEFINED) { private final MethodHandle forEachInvoker = getFOREACH_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final long i) throws Throwable { forEachInvoker.invokeExact(callbackfn, thisArg, val, i, self); return true; } }.apply(); }
private static Object reduceInner(final ArrayLikeIterator<Object> iter, final Object self, final Object... args) { final Object callbackfn = args.length > 0 ? args[0] : ScriptRuntime.UNDEFINED; final boolean initialValuePresent = args.length > 1; Object initialValue = initialValuePresent ? args[1] : ScriptRuntime.UNDEFINED; if (callbackfn == ScriptRuntime.UNDEFINED) { throw typeError("not.a.function", "undefined"); } if (!initialValuePresent) { if (iter.hasNext()) { initialValue = iter.next(); } else { throw typeError("array.reduce.invalid.init"); } } //if initial value is ScriptRuntime.UNDEFINED - step forward once. return new IteratorAction<Object>(Global.toObject(self), callbackfn, ScriptRuntime.UNDEFINED, initialValue, iter) { private final MethodHandle reduceInvoker = getREDUCE_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final long i) throws Throwable { // TODO: why can't I declare the second arg as Undefined.class? result = reduceInvoker.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self); return true; } }.apply(); }
private static boolean applyEvery(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, true) { private final MethodHandle everyInvoker = getEVERY_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final double i) throws Throwable { return result = (boolean)everyInvoker.invokeExact(callbackfn, thisArg, val, i, self); } }.apply(); }
/** * ECMA 15.4.4.17 Array.prototype.some ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return true if callback function returned true for any element in the array, false otherwise */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static boolean some(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) { private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final double i) throws Throwable { return !(result = (boolean)someInvoker.invokeExact(callbackfn, thisArg, val, i, self)); } }.apply(); }
/** * ECMA 15.4.4.18 Array.prototype.forEach ( callbackfn [ , thisArg ] ) * * @param self self reference * @param callbackfn callback function per element * @param thisArg this argument * @return undefined */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object forEach(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction<Object>(Global.toObject(self), callbackfn, thisArg, ScriptRuntime.UNDEFINED) { private final MethodHandle forEachInvoker = getFOREACH_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final double i) throws Throwable { forEachInvoker.invokeExact(callbackfn, thisArg, val, i, self); return true; } }.apply(); }
private static Object reduceInner(final ArrayLikeIterator<Object> iter, final Object self, final Object... args) { final Object callbackfn = args.length > 0 ? args[0] : ScriptRuntime.UNDEFINED; final boolean initialValuePresent = args.length > 1; Object initialValue = initialValuePresent ? args[1] : ScriptRuntime.UNDEFINED; if (callbackfn == ScriptRuntime.UNDEFINED) { throw typeError("not.a.function", "undefined"); } if (!initialValuePresent) { if (iter.hasNext()) { initialValue = iter.next(); } else { throw typeError("array.reduce.invalid.init"); } } //if initial value is ScriptRuntime.UNDEFINED - step forward once. return new IteratorAction<Object>(Global.toObject(self), callbackfn, ScriptRuntime.UNDEFINED, initialValue, iter) { private final MethodHandle reduceInvoker = getREDUCE_CALLBACK_INVOKER(); @Override protected boolean forEach(final Object val, final double i) throws Throwable { // TODO: why can't I declare the second arg as Undefined.class? result = reduceInvoker.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self); return true; } }.apply(); }