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