src/jdk/nashorn/internal/objects/NativeArray.java

Print this page




  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