8020283: Don't use exceptions for widening of ArrayData
Reviewed-by: jlaskey, attila
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Mon Jul 15 16:31:49 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Mon Jul 15 16:35:38 2013 +0200
@@ -75,7 +75,9 @@
}
private static Object[] toObjectArray(final int[] array, final int length) {
- final Object[] oarray = new Object[length];
+ assert length <= array.length : "length exceeds internal array size";
+ final Object[] oarray = new Object[array.length];
+
for (int index = 0; index < length; index++) {
oarray[index] = Integer.valueOf(array[index]);
}
@@ -83,18 +85,22 @@
return oarray;
}
- private static double[] toDoubleArray(final int[] array) {
+ private static double[] toDoubleArray(final int[] array, final int length) {
+ assert length <= array.length : "length exceeds internal array size";
final double[] darray = new double[array.length];
- for (int index = 0; index < array.length; index++) {
+
+ for (int index = 0; index < length; index++) {
darray[index] = array[index];
}
return darray;
}
- private static long[] toLongArray(final int[] array) {
+ private static long[] toLongArray(final int[] array, final int length) {
+ assert length <= array.length : "length exceeds internal array size";
final long[] larray = new long[array.length];
- for (int index = 0; index < array.length; index++) {
+
+ for (int index = 0; index < length; index++) {
larray[index] = array[index];
}
@@ -105,12 +111,14 @@
public ArrayData convert(final Class<?> type) {
if (type == Integer.class) {
return this;
- } else if (type == Long.class) {
- return new LongArrayData(IntArrayData.toLongArray(array), (int) length());
+ }
+ final int length = (int) length();
+ if (type == Long.class) {
+ return new LongArrayData(IntArrayData.toLongArray(array, length), length);
} else if (type == Double.class) {
- return new NumberArrayData(IntArrayData.toDoubleArray(array), (int) length());
+ return new NumberArrayData(IntArrayData.toDoubleArray(array, length), length);
} else {
- return new ObjectArrayData(IntArrayData.toObjectArray(array, array.length), (int) length());
+ return new ObjectArrayData(IntArrayData.toObjectArray(array, length), length);
}
}
@@ -161,26 +169,13 @@
@Override
public ArrayData set(final int index, final Object value, final boolean strict) {
- try {
- final int intValue = ((Integer)value).intValue();
- array[index] = intValue;
- setLength(Math.max(index + 1, length()));
- return this;
- } catch (final NullPointerException | ClassCastException e) {
- if (value instanceof Short || value instanceof Byte) {
- final int intValue = ((Number)value).intValue();
- array[index] = intValue;
- setLength(Math.max(index + 1, length()));
- return this;
- }
-
- if (value == ScriptRuntime.UNDEFINED) {
- return new UndefinedArrayFilter(this).set(index, value, strict);
- }
+ if (value instanceof Integer) {
+ return set(index, ((Number)value).intValue(), strict);
+ } else if (value == ScriptRuntime.UNDEFINED) {
+ return new UndefinedArrayFilter(this).set(index, value, strict);
}
final ArrayData newData = convert(value == null ? Object.class : value.getClass());
-
return newData.set(index, value, strict);
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Mon Jul 15 16:31:49 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Mon Jul 15 16:35:38 2013 +0200
@@ -55,7 +55,9 @@
}
private static Object[] toObjectArray(final long[] array, final int length) {
- final Object[] oarray = new Object[length];
+ assert length <= array.length : "length exceeds internal array size";
+ final Object[] oarray = new Object[array.length];
+
for (int index = 0; index < length; index++) {
oarray[index] = Long.valueOf(array[index]);
}
@@ -71,9 +73,11 @@
return super.asArrayOfType(componentType);
}
- private static double[] toDoubleArray(final long[] array) {
+ private static double[] toDoubleArray(final long[] array, final int length) {
+ assert length <= array.length : "length exceeds internal array size";
final double[] darray = new double[array.length];
- for (int index = 0; index < array.length; index++) {
+
+ for (int index = 0; index < length; index++) {
darray[index] = array[index];
}
@@ -84,10 +88,12 @@
public ArrayData convert(final Class<?> type) {
if (type == Long.class) {
return this;
- } else if (type == Double.class) {
- return new NumberArrayData(LongArrayData.toDoubleArray(array), (int) length());
+ }
+ final int length = (int) length();
+ if (type == Double.class) {
+ return new NumberArrayData(LongArrayData.toDoubleArray(array, length), length);
} else {
- return new ObjectArrayData(LongArrayData.toObjectArray(array, array.length), (int) length());
+ return new ObjectArrayData(LongArrayData.toObjectArray(array, length), length);
}
}
@@ -138,19 +144,13 @@
@Override
public ArrayData set(final int index, final Object value, final boolean strict) {
- try {
- final long longValue = ((Long)value).longValue();
- array[index] = longValue;
- setLength(Math.max(index + 1, length()));
- return this;
- } catch (final NullPointerException | ClassCastException e) {
- if (value == ScriptRuntime.UNDEFINED) {
- return new UndefinedArrayFilter(this).set(index, value, strict);
- }
+ if (value instanceof Long || value instanceof Integer) {
+ return set(index, ((Number)value).longValue(), strict);
+ } else if (value == ScriptRuntime.UNDEFINED) {
+ return new UndefinedArrayFilter(this).set(index, value, strict);
}
final ArrayData newData = convert(value == null ? Object.class : value.getClass());
-
return newData.set(index, value, strict);
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Mon Jul 15 16:31:49 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Mon Jul 15 16:35:38 2013 +0200
@@ -58,7 +58,9 @@
}
private static Object[] toObjectArray(final double[] array, final int length) {
- final Object[] oarray = new Object[length];
+ assert length <= array.length : "length exceeds internal array size";
+ final Object[] oarray = new Object[array.length];
+
for (int index = 0; index < length; index++) {
oarray[index] = Double.valueOf(array[index]);
}
@@ -76,7 +78,8 @@
@Override
public ArrayData convert(final Class<?> type) {
if (type != Double.class && type != Integer.class && type != Long.class) {
- return new ObjectArrayData(NumberArrayData.toObjectArray(array, array.length), (int) length());
+ final int length = (int) length();
+ return new ObjectArrayData(NumberArrayData.toObjectArray(array, length), length);
}
return this;
}
@@ -127,16 +130,12 @@
@Override
public ArrayData set(final int index, final Object value, final boolean strict) {
- try {
- final double doubleValue = ((Number)value).doubleValue();
- array[index] = doubleValue;
- setLength(Math.max(index + 1, length()));
- return this;
- } catch (final NullPointerException | ClassCastException e) {
- if (value == UNDEFINED) {
- return new UndefinedArrayFilter(this).set(index, value, strict);
- }
+ if (value instanceof Double || value instanceof Integer || value instanceof Long) {
+ return set(index, ((Number)value).doubleValue(), strict);
+ } else if (value == UNDEFINED) {
+ return new UndefinedArrayFilter(this).set(index, value, strict);
}
+
final ArrayData newData = convert(value == null ? Object.class : value.getClass());
return newData.set(index, value, strict);
}