59 import jdk.nashorn.internal.runtime.arrays.IteratorAction;
60 import jdk.nashorn.internal.runtime.linker.Bootstrap;
61 import jdk.nashorn.internal.runtime.linker.InvokeByName;
62
63 /**
64 * Runtime representation of a JavaScript array. NativeArray only holds numeric
65 * keyed values. All other values are stored in spill.
66 */
67 @ScriptClass("Array")
68 public final class NativeArray extends ScriptObject {
69 private static final InvokeByName JOIN = new InvokeByName("join", ScriptObject.class);
70
71 private static final MethodHandle EVERY_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
72 private static final MethodHandle SOME_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
73 private static final MethodHandle FOREACH_CALLBACK_INVOKER = createIteratorCallbackInvoker(void.class);
74 private static final MethodHandle MAP_CALLBACK_INVOKER = createIteratorCallbackInvoker(Object.class);
75 private static final MethodHandle FILTER_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
76
77 private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
78 Object.class, Undefined.class, Object.class, Object.class, int.class, Object.class);
79 private static final MethodHandle CALL_CMP = Bootstrap.createDynamicInvoker("dyn:call", int.class,
80 ScriptFunction.class, Object.class, Object.class, Object.class);
81
82 private static final InvokeByName TO_LOCALE_STRING = new InvokeByName("toLocaleString", ScriptObject.class, String.class);
83
84
85 /*
86 * Constructors.
87 */
88 NativeArray() {
89 this(ArrayData.initialArray());
90 }
91
92 NativeArray(final long length) {
93 // TODO assert valid index in long before casting
94 this(ArrayData.allocate((int) length));
95 }
96
97 NativeArray(final int[] array) {
98 this(ArrayData.allocate(array));
99 }
806
807 private static Object[] sort(final Object[] array, final Object comparefn) {
808 final ScriptFunction cmp = compareFunction(comparefn);
809
810 final List<Object> list = Arrays.asList(array);
811 final Object cmpThis = cmp == null || cmp.isStrict() ? ScriptRuntime.UNDEFINED : Global.instance();
812
813 Collections.sort(list, new Comparator<Object>() {
814 @Override
815 public int compare(final Object x, final Object y) {
816 if (x == ScriptRuntime.UNDEFINED && y == ScriptRuntime.UNDEFINED) {
817 return 0;
818 } else if (x == ScriptRuntime.UNDEFINED) {
819 return 1;
820 } else if (y == ScriptRuntime.UNDEFINED) {
821 return -1;
822 }
823
824 if (cmp != null) {
825 try {
826 return (int)CALL_CMP.invokeExact(cmp, cmpThis, x, y);
827 } catch (final RuntimeException | Error e) {
828 throw e;
829 } catch (final Throwable t) {
830 throw new RuntimeException(t);
831 }
832 }
833
834 return JSType.toString(x).compareTo(JSType.toString(y));
835 }
836 });
837
838 return list.toArray(new Object[array.length]);
839 }
840
841 /**
842 * ECMA 15.4.4.11 Array.prototype.sort ( comparefn )
843 *
844 * @param self self reference
845 * @param comparefn element comparison function
846 * @return sorted array
|
59 import jdk.nashorn.internal.runtime.arrays.IteratorAction;
60 import jdk.nashorn.internal.runtime.linker.Bootstrap;
61 import jdk.nashorn.internal.runtime.linker.InvokeByName;
62
63 /**
64 * Runtime representation of a JavaScript array. NativeArray only holds numeric
65 * keyed values. All other values are stored in spill.
66 */
67 @ScriptClass("Array")
68 public final class NativeArray extends ScriptObject {
69 private static final InvokeByName JOIN = new InvokeByName("join", ScriptObject.class);
70
71 private static final MethodHandle EVERY_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
72 private static final MethodHandle SOME_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
73 private static final MethodHandle FOREACH_CALLBACK_INVOKER = createIteratorCallbackInvoker(void.class);
74 private static final MethodHandle MAP_CALLBACK_INVOKER = createIteratorCallbackInvoker(Object.class);
75 private static final MethodHandle FILTER_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
76
77 private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
78 Object.class, Undefined.class, Object.class, Object.class, int.class, Object.class);
79 private static final MethodHandle CALL_CMP = Bootstrap.createDynamicInvoker("dyn:call", double.class,
80 ScriptFunction.class, Object.class, Object.class, Object.class);
81
82 private static final InvokeByName TO_LOCALE_STRING = new InvokeByName("toLocaleString", ScriptObject.class, String.class);
83
84
85 /*
86 * Constructors.
87 */
88 NativeArray() {
89 this(ArrayData.initialArray());
90 }
91
92 NativeArray(final long length) {
93 // TODO assert valid index in long before casting
94 this(ArrayData.allocate((int) length));
95 }
96
97 NativeArray(final int[] array) {
98 this(ArrayData.allocate(array));
99 }
806
807 private static Object[] sort(final Object[] array, final Object comparefn) {
808 final ScriptFunction cmp = compareFunction(comparefn);
809
810 final List<Object> list = Arrays.asList(array);
811 final Object cmpThis = cmp == null || cmp.isStrict() ? ScriptRuntime.UNDEFINED : Global.instance();
812
813 Collections.sort(list, new Comparator<Object>() {
814 @Override
815 public int compare(final Object x, final Object y) {
816 if (x == ScriptRuntime.UNDEFINED && y == ScriptRuntime.UNDEFINED) {
817 return 0;
818 } else if (x == ScriptRuntime.UNDEFINED) {
819 return 1;
820 } else if (y == ScriptRuntime.UNDEFINED) {
821 return -1;
822 }
823
824 if (cmp != null) {
825 try {
826 double res = (double)CALL_CMP.invokeExact(cmp, cmpThis, x, y);
827 return (int)Math.signum(res);
828 } catch (final RuntimeException | Error e) {
829 throw e;
830 } catch (final Throwable t) {
831 throw new RuntimeException(t);
832 }
833 }
834
835 return JSType.toString(x).compareTo(JSType.toString(y));
836 }
837 });
838
839 return list.toArray(new Object[array.length]);
840 }
841
842 /**
843 * ECMA 15.4.4.11 Array.prototype.sort ( comparefn )
844 *
845 * @param self self reference
846 * @param comparefn element comparison function
847 * @return sorted array
|