< prev index next >
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java
Print this page
@@ -98,24 +98,42 @@
NativeArray() {
this(ArrayData.initialArray());
}
NativeArray(final long length) {
- // TODO assert valid index in long before casting
- this(ArrayData.allocate((int)length));
+ this(ArrayData.allocate(length));
}
NativeArray(final int[] array) {
this(ArrayData.allocate(array));
}
- NativeArray(final long[] array) {
+ NativeArray(final double[] array) {
this(ArrayData.allocate(array));
}
- NativeArray(final double[] array) {
- this(ArrayData.allocate(array));
+ NativeArray(final long[] array) {
+ this(ArrayData.allocate(array.length));
+
+ ArrayData arrayData = this.getArray();
+ Class<?> widest = int.class;
+
+ for (int index = 0; index < array.length; index++) {
+ final long value = array[index];
+
+ if (widest == int.class && JSType.isRepresentableAsInt(value)) {
+ arrayData = arrayData.set(index, (int) value, false);
+ } else if (widest != Object.class && JSType.isRepresentableAsDouble(value)) {
+ arrayData = arrayData.set(index, (double) value, false);
+ widest = double.class;
+ } else {
+ arrayData = arrayData.set(index, (Object) value, false);
+ widest = Object.class;
+ }
+ }
+
+ this.setArray(arrayData);
}
NativeArray(final Object[] array) {
this(ArrayData.allocate(array.length));
@@ -177,11 +195,11 @@
return Global.instance().getDynamicInvoker(key,
new Callable<MethodHandle>() {
@Override
public MethodHandle call() {
return Bootstrap.createDynamicCallInvoker(rtype, Object.class, Object.class, Object.class,
- long.class, Object.class);
+ double.class, Object.class);
}
});
}
private static MethodHandle getEVERY_CALLBACK_INVOKER() {
@@ -208,11 +226,11 @@
return Global.instance().getDynamicInvoker(REDUCE_CALLBACK_INVOKER,
new Callable<MethodHandle>() {
@Override
public MethodHandle call() {
return Bootstrap.createDynamicCallInvoker(Object.class, Object.class,
- Undefined.class, Object.class, Object.class, long.class, Object.class);
+ Undefined.class, Object.class, Object.class, double.class, Object.class);
}
});
}
private static MethodHandle getCALL_CMP() {
@@ -244,12 +262,13 @@
return "Array";
}
@Override
public Object getLength() {
- final long length = JSType.toUint32(getArray().length());
- if (length < Integer.MAX_VALUE) {
+ final long length = getArray().length();
+ assert length >= 0L;
+ if (length <= Integer.MAX_VALUE) {
return (int)length;
}
return length;
}
@@ -443,11 +462,17 @@
* @return the length of the object
*/
@Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
public static Object length(final Object self) {
if (isArray(self)) {
- return JSType.toUint32(((ScriptObject) self).getArray().length());
+ final long length = ((ScriptObject) self).getArray().length();
+ assert length >= 0L;
+ // Cast to the narrowest supported numeric type to help optimistic type calculator
+ if (length <= Integer.MAX_VALUE) {
+ return (int) length;
+ }
+ return (double) length;
}
return 0;
}
@@ -1551,11 +1576,11 @@
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 {
+ protected boolean forEach(final Object val, final double i) throws Throwable {
return result = (boolean)everyInvoker.invokeExact(callbackfn, thisArg, val, i, self);
}
}.apply();
}
@@ -1571,11 +1596,11 @@
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 {
+ protected boolean forEach(final Object val, final double i) throws Throwable {
return !(result = (boolean)someInvoker.invokeExact(callbackfn, thisArg, val, i, self));
}
}.apply();
}
@@ -1591,11 +1616,11 @@
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 {
+ protected boolean forEach(final Object val, final double i) throws Throwable {
forEachInvoker.invokeExact(callbackfn, thisArg, val, i, self);
return true;
}
}.apply();
}
@@ -1612,11 +1637,11 @@
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 {
+ 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;
}
@@ -1642,11 +1667,11 @@
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 {
+ 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;
}
@@ -1674,11 +1699,11 @@
//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 {
+ 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();
< prev index next >