提交 1cd60278 编写于 作者: H hannesw

8015350: Array.prototype.reduceRight issue with large length and index

Reviewed-by: attila, sundar, lagergren
上级 04fc0191
......@@ -75,7 +75,7 @@ public final class NativeArray extends ScriptObject {
private static final MethodHandle FILTER_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
Object.class, Undefined.class, Object.class, Object.class, int.class, Object.class);
Object.class, Undefined.class, Object.class, Object.class, long.class, Object.class);
private static final MethodHandle CALL_CMP = Bootstrap.createDynamicInvoker("dyn:call", double.class,
ScriptFunction.class, Object.class, Object.class, Object.class);
......@@ -1086,7 +1086,7 @@ public final class NativeArray extends ScriptObject {
private static boolean applyEvery(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, true) {
@Override
protected boolean forEach(final Object val, final int i) throws Throwable {
protected boolean forEach(final Object val, final long i) throws Throwable {
return (result = (boolean)EVERY_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self));
}
}.apply();
......@@ -1104,7 +1104,7 @@ public final class NativeArray extends ScriptObject {
public static Object some(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) {
@Override
protected boolean forEach(final Object val, final int i) throws Throwable {
protected boolean forEach(final Object val, final long i) throws Throwable {
return !(result = (boolean)SOME_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self));
}
}.apply();
......@@ -1122,7 +1122,7 @@ public final class NativeArray extends ScriptObject {
public static Object forEach(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<Object>(Global.toObject(self), callbackfn, thisArg, ScriptRuntime.UNDEFINED) {
@Override
protected boolean forEach(final Object val, final int i) throws Throwable {
protected boolean forEach(final Object val, final long i) throws Throwable {
FOREACH_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self);
return true;
}
......@@ -1141,9 +1141,9 @@ public final class NativeArray extends ScriptObject {
public static Object map(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) {
@Override
protected boolean forEach(final Object val, final int i) throws Throwable {
protected boolean forEach(final Object val, final long i) throws Throwable {
final Object r = MAP_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self);
result.defineOwnProperty(index, r);
result.defineOwnProperty((int)index, r);
return true;
}
......@@ -1167,12 +1167,12 @@ public final class NativeArray extends ScriptObject {
@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 int to = 0;
private long to = 0;
@Override
protected boolean forEach(final Object val, final int i) throws Throwable {
protected boolean forEach(final Object val, final long i) throws Throwable {
if ((boolean)FILTER_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)) {
result.defineOwnProperty(to++, val);
result.defineOwnProperty((int)(to++), val);
}
return true;
}
......@@ -1200,7 +1200,7 @@ public final class NativeArray extends ScriptObject {
//if initial value is ScriptRuntime.UNDEFINED - step forward once.
return new IteratorAction<Object>(Global.toObject(self), callbackfn, ScriptRuntime.UNDEFINED, initialValue, iter) {
@Override
protected boolean forEach(final Object val, final int i) throws Throwable {
protected boolean forEach(final Object val, final long i) throws Throwable {
// TODO: why can't I declare the second arg as Undefined.class?
result = REDUCE_CALLBACK_INVOKER.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self);
return true;
......@@ -1258,7 +1258,7 @@ public final class NativeArray extends ScriptObject {
private static MethodHandle createIteratorCallbackInvoker(final Class<?> rtype) {
return Bootstrap.createDynamicInvoker("dyn:call", rtype, Object.class, Object.class, Object.class,
int.class, Object.class);
long.class, Object.class);
}
}
......@@ -36,7 +36,7 @@ public class ArrayIterator extends ArrayLikeIterator<Object> {
protected final ScriptObject array;
/** length of array */
protected final int length;
protected final long length;
/**
* Constructor
......@@ -46,7 +46,7 @@ public class ArrayIterator extends ArrayLikeIterator<Object> {
protected ArrayIterator(final ScriptObject array, final boolean includeUndefined) {
super(includeUndefined);
this.array = array;
this.length = (int) array.getArray().length();
this.length = array.getArray().length();
}
/**
......@@ -63,7 +63,7 @@ public class ArrayIterator extends ArrayLikeIterator<Object> {
}
@Override
public int getLength() {
public long getLength() {
return length;
}
......
......@@ -38,7 +38,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
abstract public class ArrayLikeIterator<T> implements Iterator<T> {
/** current element index in iteration */
protected int index;
protected long index;
/** should undefined elements be included in the iteration? */
protected final boolean includeUndefined;
......@@ -65,7 +65,7 @@ abstract public class ArrayLikeIterator<T> implements Iterator<T> {
* Go the the next valid element index of the iterator
* @return next index
*/
protected int bumpIndex() {
protected long bumpIndex() {
return index++;
}
......@@ -73,7 +73,7 @@ abstract public class ArrayLikeIterator<T> implements Iterator<T> {
* Return the next valid element index of the iterator
* @return next index
*/
public int nextIndex() {
public long nextIndex() {
return index;
}
......@@ -86,7 +86,7 @@ abstract public class ArrayLikeIterator<T> implements Iterator<T> {
* Get the length of the iteration
* @return length
*/
public abstract int getLength();
public abstract long getLength();
/**
* ArrayLikeIterator factory
......
......@@ -47,7 +47,7 @@ final class EmptyArrayLikeIterator extends ArrayLikeIterator<Object> {
}
@Override
public int getLength() {
public long getLength() {
return 0;
}
}
......@@ -49,7 +49,7 @@ public abstract class IteratorAction<T> {
protected T result;
/** Current array index of iterator */
protected int index;
protected long index;
/** Iterator object */
private final ArrayLikeIterator<Object> iter;
......@@ -134,6 +134,6 @@ public abstract class IteratorAction<T> {
*
* @throws Throwable if invocation throws an exception/error
*/
protected abstract boolean forEach(final Object val, final int i) throws Throwable;
protected abstract boolean forEach(final Object val, final long i) throws Throwable;
}
......@@ -49,8 +49,8 @@ class MapIterator extends ArrayLikeIterator<Object> {
}
@Override
public int getLength() {
return (int) length;
public long getLength() {
return length;
}
@Override
......
......@@ -39,7 +39,7 @@ public final class ReverseArrayIterator extends ArrayIterator {
*/
public ReverseArrayIterator(final ScriptObject array, final boolean includeUndefined) {
super(array, includeUndefined);
this.index = (int) (array.getArray().length() - 1);
this.index = array.getArray().length() - 1;
}
@Override
......@@ -53,7 +53,7 @@ public final class ReverseArrayIterator extends ArrayIterator {
}
@Override
protected int bumpIndex() {
protected long bumpIndex() {
return index--;
}
}
......@@ -35,7 +35,7 @@ final class ReverseMapIterator extends MapIterator {
ReverseMapIterator(final ScriptObject obj, final boolean includeUndefined) {
super(obj, includeUndefined);
this.index = JSType.toInt32(obj.getLength()) - 1;
this.index = JSType.toUint32(obj.getLength()) - 1;
}
@Override
......@@ -49,7 +49,7 @@ final class ReverseMapIterator extends MapIterator {
}
@Override
protected int bumpIndex() {
protected long bumpIndex() {
return index--;
}
}
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8015350: Array.prototype.reduceRight issue with large length and index
*
* @test
* @run
*/
function reduce(obj) {
try {
Array.prototype.reduceRight.call(obj, function(acc, v, i, o){
print(v + i);
throw "stop";
}, 0);
} catch (error) {
print(error);
}
}
// array-like object
reduce({
length:0xffffffff,
0xfffffffe: "index: "
});
// actual sparse array
var array = [];
array[0xfffffffe] = "index: ";
reduce(array);
index: 4294967294
stop
index: 4294967294
stop
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册