Reduce JSNI usage for Arrays.
Change-Id: Ic73f052d1aa3d0688968d4eb40f9759ebf086fe6
diff --git a/user/super/com/google/gwt/emul/java/util/Arrays.java b/user/super/com/google/gwt/emul/java/util/Arrays.java
index f3e1e4e..a8ed4ce 100644
--- a/user/super/com/google/gwt/emul/java/util/Arrays.java
+++ b/user/super/com/google/gwt/emul/java/util/Arrays.java
@@ -41,7 +41,8 @@
import java.util.stream.StreamSupport;
import javaemul.internal.ArrayHelper;
-import jsinterop.annotations.JsFunction;
+import javaemul.internal.JsUtils;
+import javaemul.internal.NativeArray.CompareFunction;
/**
* Utility methods related to native arrays.
@@ -1279,7 +1280,7 @@
}
public static void sort(double[] array) {
- nativeSort(array, getDoubleComparator());
+ ArrayHelper.asNativeArray(array).sort(getDoubleComparator());
}
public static void sort(double[] array, int fromIndex, int toIndex) {
@@ -1288,7 +1289,7 @@
}
public static void sort(float[] array) {
- nativeSort(array, getDoubleComparator());
+ ArrayHelper.asNativeArray(array).sort(getDoubleComparator());
}
public static void sort(float[] array, int fromIndex, int toIndex) {
@@ -1306,7 +1307,7 @@
}
public static void sort(long[] array) {
- nativeSort(array, getLongComparator());
+ ArrayHelper.asNativeArray(array).sort(getLongComparator());
}
public static void sort(long[] array, int fromIndex, int toIndex) {
@@ -1734,18 +1735,11 @@
}
/**
- * Sort an entire array using the given comparator
- */
- private static native void nativeSort(Object array, Object compareFunction) /*-{
- array.sort(compareFunction);
- }-*/;
-
- /**
* Sort a subset of an array using the given comparator
*/
- private static void nativeSort(Object array, int fromIndex, int toIndex, Object compareFunction) {
+ private static void nativeSort(Object array, int fromIndex, int toIndex, CompareFunction fn) {
Object temp = ArrayHelper.unsafeClone(array, fromIndex, toIndex);
- nativeSort(temp, compareFunction);
+ ArrayHelper.asNativeArray(temp).sort(fn);
ArrayHelper.copy(temp, 0, array, fromIndex, toIndex - fromIndex);
}
@@ -1753,7 +1747,7 @@
* Sort an entire array of number primitives of integral type.
*/
private static void nativeIntegerSort(Object array) {
- nativeSort(array, getIntComparator());
+ ArrayHelper.asNativeArray(array).sort(getIntComparator());
}
/**
@@ -1763,32 +1757,16 @@
nativeSort(array, fromIndex, toIndex, getIntComparator());
}
- @JsFunction
- private interface CompareDoubleFunction {
- int compare(double d1, double d2);
+ private static CompareFunction getIntComparator() {
+ return (a, b) -> JsUtils.unsafeCastToDouble(a) - JsUtils.unsafeCastToDouble(b);
}
- private static CompareDoubleFunction getDoubleComparator() {
- return Double::compare;
+ private static CompareFunction getDoubleComparator() {
+ return (a, b) -> Double.compare(JsUtils.unsafeCastToDouble(a), JsUtils.unsafeCastToDouble(b));
}
- @JsFunction
- private interface CompareLongFunction {
- @SuppressWarnings("unusable-by-js")
- int compare(long d1, long d2);
- }
-
- private static CompareLongFunction getLongComparator() {
- return Long::compare;
- }
-
- @JsFunction
- private interface CompareIntFunction {
- int compare(int d1, int d2);
- }
-
- private static CompareIntFunction getIntComparator() {
- return (a, b) -> a - b;
+ private static CompareFunction getLongComparator() {
+ return (a, b) -> Long.compare(JsUtils.unsafeCastToLong(a), JsUtils.unsafeCastToLong(b));
}
private Arrays() { }
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java b/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java
index 1fc2a0e..c1a66f5 100644
--- a/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java
+++ b/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java
@@ -15,6 +15,10 @@
*/
package javaemul.internal;
+import jsinterop.annotations.JsPackage;
+import jsinterop.annotations.JsProperty;
+import jsinterop.annotations.JsType;
+
/**
* Provides utilities to perform operations on Arrays.
*/
@@ -31,34 +35,29 @@
* Unlike clone, this method returns a copy of the array that is not type marked. This is only
* safe for temp arrays as returned array will not do any type checks.
*/
- public static native Object[] unsafeClone(Object array, int fromIndex, int toIndex) /*-{
- return array.slice(fromIndex, toIndex);
- }-*/;
-
- public static <T> T[] createFrom(T[] array, int length) {
- Object result = createNativeArray(length);
- return ArrayStamper.stampJavaTypeInfo(result, array);
+ public static Object[] unsafeClone(Object array, int fromIndex, int toIndex) {
+ return asNativeArray(array).slice(fromIndex, toIndex);
}
- private static native Object createNativeArray(int length)/*-{
- return new Array(length);
- }-*/;
+ public static <T> T[] createFrom(T[] array, int length) {
+ return ArrayStamper.stampJavaTypeInfo(new NativeArray(length), array);
+ }
- public static native int getLength(Object array) /*-{
- return array.length;
- }-*/;
+ public static int getLength(Object array) {
+ return asNativeArray(array).length;
+ }
- public static native void setLength(Object array, int length)/*-{
- array.length = length;
- }-*/;
+ public static void setLength(Object array, int length) {
+ asNativeArray(array).length = length;
+ }
- public static native void removeFrom(Object array, int index, int deleteCount) /*-{
- array.splice(index, deleteCount);
- }-*/;
+ public static void removeFrom(Object array, int index, int deleteCount) {
+ asNativeArray(array).splice(index, deleteCount);
+ }
- public static native void insertTo(Object array, int index, Object value) /*-{
- array.splice(index, 0, value);
- }-*/;
+ public static void insertTo(Object array, int index, Object value) {
+ asNativeArray(array).splice(index, 0, value);
+ }
public static void insertTo(Object array, int index, Object[] values) {
copy(values, 0, array, index, values.length, false);
@@ -80,19 +79,29 @@
src = unsafeClone(src, srcOfs, srcOfs + len);
srcOfs = 0;
}
+ NativeArray destArray = asNativeArray(dest);
for (int batchStart = srcOfs, end = srcOfs + len; batchStart < end;) {
// increment in block
int batchEnd = Math.min(batchStart + ARRAY_PROCESS_BATCH_SIZE, end);
len = batchEnd - batchStart;
- applySplice(dest, destOfs, overwrite ? len : 0, unsafeClone(src, batchStart, batchEnd));
+ Object[] spliceArgs = unsafeClone(src, batchStart, batchEnd);
+ asNativeArray(spliceArgs).splice(0, 0, destOfs, overwrite ? len : 0);
+ getSpliceFunction().apply(destArray, spliceArgs);
batchStart = batchEnd;
destOfs += len;
}
}
- private static native void applySplice(Object array, int index, int deleteCount,
- Object arrayToAdd) /*-{
- Array.prototype.splice.apply(array, [index, deleteCount].concat(arrayToAdd));
- }-*/;
+ @JsType(isNative = true, name = "Function", namespace = JsPackage.GLOBAL)
+ private static class NativeFunction {
+ public native String apply(Object thisContext, Object[] argsArray);
+ }
+
+ @JsProperty(name = "Array.prototype.splice", namespace = "<window>")
+ private static native NativeFunction getSpliceFunction();
+
+ public static NativeArray asNativeArray(Object array) {
+ return JsUtils.unsafeCastToNativeArray(array);
+ }
}
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/JsUtils.java b/user/super/com/google/gwt/emul/javaemul/internal/JsUtils.java
index 8796b61..c0477ac 100644
--- a/user/super/com/google/gwt/emul/javaemul/internal/JsUtils.java
+++ b/user/super/com/google/gwt/emul/javaemul/internal/JsUtils.java
@@ -52,6 +52,14 @@
return bool;
}-*/;
+ public static native long unsafeCastToLong(Object l) /*-{
+ return l;
+ }-*/;
+
+ public static native NativeArray unsafeCastToNativeArray(Object array) /*-{
+ return array;
+ }-*/;
+
public static native <T> T getProperty(Object map, String key) /*-{
return map[key];
}-*/;
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/NativeArray.java b/user/super/com/google/gwt/emul/javaemul/internal/NativeArray.java
new file mode 100644
index 0000000..7f0ea99
--- /dev/null
+++ b/user/super/com/google/gwt/emul/javaemul/internal/NativeArray.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package javaemul.internal;
+
+import javaemul.internal.annotations.DoNotAutobox;
+import jsinterop.annotations.JsFunction;
+import jsinterop.annotations.JsType;
+
+/**
+ * Simple class to work with native array API.
+ */
+@JsType(isNative = true, name = "Array", namespace = "<window>")
+public class NativeArray {
+ /**
+ * Compare function for sort.
+ */
+ @JsFunction
+ public interface CompareFunction {
+ double compare(Object d1, Object d2);
+ }
+
+ public int length;
+ public NativeArray() { }
+ public NativeArray(int length) { }
+ public native Object concat(Object arrayToAdd);
+ public native Object[] slice(int fromIndex, int toIndex);
+ public native void splice(int index, int deleteCount, @DoNotAutobox Object... value);
+ public native <T> void sort(CompareFunction compareFunction);
+}