rt/emul/mini/src/main/java/java/lang/reflect/Array.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 07 May 2014 08:49:54 +0200
branchclosure
changeset 1541 3471d74a6b99
parent 1535 c02c6d409461
child 1702 228f26fc1159
permissions -rw-r--r--
Methods in Array are shared between different VMs, but other types like Integer, or Float, aren't. Need to be careful when using equality then
jaroslav@475
     1
/*
jaroslav@475
     2
 * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
jaroslav@475
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@475
     4
 *
jaroslav@475
     5
 * This code is free software; you can redistribute it and/or modify it
jaroslav@475
     6
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@475
     7
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@475
     8
 * particular file as subject to the "Classpath" exception as provided
jaroslav@475
     9
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@475
    10
 *
jaroslav@475
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@475
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@475
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@475
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@475
    15
 * accompanied this code).
jaroslav@475
    16
 *
jaroslav@475
    17
 * You should have received a copy of the GNU General Public License version
jaroslav@475
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@475
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@475
    20
 *
jaroslav@475
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@475
    22
 * or visit www.oracle.com if you need additional information or have any
jaroslav@475
    23
 * questions.
jaroslav@475
    24
 */
jaroslav@475
    25
jaroslav@475
    26
package java.lang.reflect;
jaroslav@475
    27
lubomir@967
    28
import org.apidesign.bck2brwsr.core.Exported;
jaroslav@477
    29
import org.apidesign.bck2brwsr.core.JavaScriptBody;
jaroslav@479
    30
import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
jaroslav@477
    31
jaroslav@475
    32
/**
jaroslav@475
    33
 * The {@code Array} class provides static methods to dynamically create and
jaroslav@475
    34
 * access Java arrays.
jaroslav@475
    35
 *
jaroslav@475
    36
 * <p>{@code Array} permits widening conversions to occur during a get or set
jaroslav@475
    37
 * operation, but throws an {@code IllegalArgumentException} if a narrowing
jaroslav@475
    38
 * conversion would occur.
jaroslav@475
    39
 *
jaroslav@475
    40
 * @author Nakul Saraiya
jaroslav@475
    41
 */
jaroslav@479
    42
@JavaScriptPrototype(prototype = "new Array", container = "Array.prototype")
jaroslav@475
    43
public final
jaroslav@475
    44
class Array {
jaroslav@475
    45
jaroslav@475
    46
    /**
jaroslav@475
    47
     * Constructor.  Class Array is not instantiable.
jaroslav@475
    48
     */
jaroslav@475
    49
    private Array() {}
jaroslav@475
    50
jaroslav@475
    51
    /**
jaroslav@475
    52
     * Creates a new array with the specified component type and
jaroslav@475
    53
     * length.
jaroslav@475
    54
     * Invoking this method is equivalent to creating an array
jaroslav@475
    55
     * as follows:
jaroslav@475
    56
     * <blockquote>
jaroslav@475
    57
     * <pre>
jaroslav@475
    58
     * int[] x = {length};
jaroslav@475
    59
     * Array.newInstance(componentType, x);
jaroslav@475
    60
     * </pre>
jaroslav@475
    61
     * </blockquote>
jaroslav@475
    62
     *
jaroslav@475
    63
     * @param componentType the {@code Class} object representing the
jaroslav@475
    64
     * component type of the new array
jaroslav@475
    65
     * @param length the length of the new array
jaroslav@475
    66
     * @return the new array
jaroslav@475
    67
     * @exception NullPointerException if the specified
jaroslav@475
    68
     * {@code componentType} parameter is null
jaroslav@475
    69
     * @exception IllegalArgumentException if componentType is {@link Void#TYPE}
jaroslav@475
    70
     * @exception NegativeArraySizeException if the specified {@code length}
jaroslav@475
    71
     * is negative
jaroslav@475
    72
     */
jaroslav@475
    73
    public static Object newInstance(Class<?> componentType, int length)
jaroslav@477
    74
    throws NegativeArraySizeException {
jaroslav@477
    75
        if (length < 0) {
jaroslav@477
    76
            throw new NegativeArraySizeException();
jaroslav@477
    77
        }
jaroslav@1541
    78
        String sig = Method.findArraySignature(componentType);
jaroslav@1532
    79
        return newArray(componentType.isPrimitive(), sig, null, length);
jaroslav@475
    80
    }
jaroslav@477
    81
    
jaroslav@475
    82
    /**
jaroslav@475
    83
     * Creates a new array
jaroslav@475
    84
     * with the specified component type and dimensions.
jaroslav@475
    85
     * If {@code componentType}
jaroslav@475
    86
     * represents a non-array class or interface, the new array
jaroslav@475
    87
     * has {@code dimensions.length} dimensions and
jaroslav@475
    88
     * {@code componentType} as its component type. If
jaroslav@475
    89
     * {@code componentType} represents an array class, the
jaroslav@475
    90
     * number of dimensions of the new array is equal to the sum
jaroslav@475
    91
     * of {@code dimensions.length} and the number of
jaroslav@475
    92
     * dimensions of {@code componentType}. In this case, the
jaroslav@475
    93
     * component type of the new array is the component type of
jaroslav@475
    94
     * {@code componentType}.
jaroslav@475
    95
     *
jaroslav@475
    96
     * <p>The number of dimensions of the new array must not
jaroslav@475
    97
     * exceed the number of array dimensions supported by the
jaroslav@475
    98
     * implementation (typically 255).
jaroslav@475
    99
     *
jaroslav@475
   100
     * @param componentType the {@code Class} object representing the component
jaroslav@475
   101
     * type of the new array
jaroslav@475
   102
     * @param dimensions an array of {@code int} representing the dimensions of
jaroslav@475
   103
     * the new array
jaroslav@475
   104
     * @return the new array
jaroslav@475
   105
     * @exception NullPointerException if the specified
jaroslav@475
   106
     * {@code componentType} argument is null
jaroslav@475
   107
     * @exception IllegalArgumentException if the specified {@code dimensions}
jaroslav@475
   108
     * argument is a zero-dimensional array, or if the number of
jaroslav@475
   109
     * requested dimensions exceeds the limit on the number of array dimensions
jaroslav@475
   110
     * supported by the implementation (typically 255), or if componentType
jaroslav@475
   111
     * is {@link Void#TYPE}.
jaroslav@475
   112
     * @exception NegativeArraySizeException if any of the components in
jaroslav@475
   113
     * the specified {@code dimensions} argument is negative.
jaroslav@475
   114
     */
jaroslav@475
   115
    public static Object newInstance(Class<?> componentType, int... dimensions)
jaroslav@475
   116
        throws IllegalArgumentException, NegativeArraySizeException {
jaroslav@480
   117
        StringBuilder sig = new StringBuilder();
jaroslav@480
   118
        for (int i = 1; i < dimensions.length; i++) {
jaroslav@480
   119
            sig.append('[');
jaroslav@480
   120
        }
jaroslav@1541
   121
        sig.append(Method.findArraySignature(componentType));
jaroslav@480
   122
        return multiNewArray(sig.toString(), dimensions, 0);
jaroslav@475
   123
    }
jaroslav@475
   124
jaroslav@475
   125
    /**
jaroslav@475
   126
     * Returns the length of the specified array object, as an {@code int}.
jaroslav@475
   127
     *
jaroslav@475
   128
     * @param array the array
jaroslav@475
   129
     * @return the length of the array
jaroslav@475
   130
     * @exception IllegalArgumentException if the object argument is not
jaroslav@475
   131
     * an array
jaroslav@475
   132
     */
jaroslav@482
   133
    public static int getLength(Object array)
jaroslav@482
   134
    throws IllegalArgumentException {
jaroslav@482
   135
        if (!array.getClass().isArray()) {
jaroslav@483
   136
            throw new IllegalArgumentException("Argument is not an array");
jaroslav@482
   137
        }
jaroslav@482
   138
        return length(array);
jaroslav@482
   139
    }
jaroslav@482
   140
    
jaroslav@482
   141
    @JavaScriptBody(args = { "arr" }, body = "return arr.length;")
jaroslav@482
   142
    private static native int length(Object arr);
jaroslav@475
   143
jaroslav@475
   144
    /**
jaroslav@475
   145
     * Returns the value of the indexed component in the specified
jaroslav@475
   146
     * array object.  The value is automatically wrapped in an object
jaroslav@475
   147
     * if it has a primitive type.
jaroslav@475
   148
     *
jaroslav@475
   149
     * @param array the array
jaroslav@475
   150
     * @param index the index
jaroslav@475
   151
     * @return the (possibly wrapped) value of the indexed component in
jaroslav@475
   152
     * the specified array
jaroslav@475
   153
     * @exception NullPointerException If the specified object is null
jaroslav@475
   154
     * @exception IllegalArgumentException If the specified object is not
jaroslav@475
   155
     * an array
jaroslav@475
   156
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   157
     * argument is negative, or if it is greater than or equal to the
jaroslav@475
   158
     * length of the specified array
jaroslav@475
   159
     */
jaroslav@485
   160
    public static Object get(Object array, int index)
jaroslav@485
   161
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@486
   162
        final Class<?> t = array.getClass().getComponentType();
jaroslav@486
   163
        if (t.isPrimitive()) {
jaroslav@571
   164
            return fromPrimitive(t, array, index);
jaroslav@485
   165
        } else {
jaroslav@485
   166
            return ((Object[])array)[index];
jaroslav@485
   167
        }
jaroslav@485
   168
    }
jaroslav@475
   169
jaroslav@475
   170
    /**
jaroslav@475
   171
     * Returns the value of the indexed component in the specified
jaroslav@475
   172
     * array object, as a {@code boolean}.
jaroslav@475
   173
     *
jaroslav@475
   174
     * @param array the array
jaroslav@475
   175
     * @param index the index
jaroslav@475
   176
     * @return the value of the indexed component in the specified array
jaroslav@475
   177
     * @exception NullPointerException If the specified object is null
jaroslav@475
   178
     * @exception IllegalArgumentException If the specified object is not
jaroslav@475
   179
     * an array, or if the indexed element cannot be converted to the
jaroslav@475
   180
     * return type by an identity or widening conversion
jaroslav@475
   181
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   182
     * argument is negative, or if it is greater than or equal to the
jaroslav@475
   183
     * length of the specified array
jaroslav@475
   184
     * @see Array#get
jaroslav@475
   185
     */
jaroslav@475
   186
    public static native boolean getBoolean(Object array, int index)
jaroslav@475
   187
        throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
jaroslav@475
   188
jaroslav@475
   189
    /**
jaroslav@475
   190
     * Returns the value of the indexed component in the specified
jaroslav@475
   191
     * array object, as a {@code byte}.
jaroslav@475
   192
     *
jaroslav@475
   193
     * @param array the array
jaroslav@475
   194
     * @param index the index
jaroslav@475
   195
     * @return the value of the indexed component in the specified array
jaroslav@475
   196
     * @exception NullPointerException If the specified object is null
jaroslav@475
   197
     * @exception IllegalArgumentException If the specified object is not
jaroslav@475
   198
     * an array, or if the indexed element cannot be converted to the
jaroslav@475
   199
     * return type by an identity or widening conversion
jaroslav@475
   200
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   201
     * argument is negative, or if it is greater than or equal to the
jaroslav@475
   202
     * length of the specified array
jaroslav@475
   203
     * @see Array#get
jaroslav@475
   204
     */
jaroslav@483
   205
    public static byte getByte(Object array, int index)
jaroslav@483
   206
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@1541
   207
        if (!Method.samePrimitive(array.getClass().getComponentType(), Byte.TYPE)) {
jaroslav@483
   208
            throw new IllegalArgumentException();
jaroslav@483
   209
        }
jaroslav@483
   210
        byte[] arr = (byte[]) array;
jaroslav@483
   211
        return arr[index];
jaroslav@483
   212
    }
jaroslav@475
   213
jaroslav@475
   214
    /**
jaroslav@475
   215
     * Returns the value of the indexed component in the specified
jaroslav@475
   216
     * array object, as a {@code char}.
jaroslav@475
   217
     *
jaroslav@475
   218
     * @param array the array
jaroslav@475
   219
     * @param index the index
jaroslav@475
   220
     * @return the value of the indexed component in the specified array
jaroslav@475
   221
     * @exception NullPointerException If the specified object is null
jaroslav@475
   222
     * @exception IllegalArgumentException If the specified object is not
jaroslav@475
   223
     * an array, or if the indexed element cannot be converted to the
jaroslav@475
   224
     * return type by an identity or widening conversion
jaroslav@475
   225
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   226
     * argument is negative, or if it is greater than or equal to the
jaroslav@475
   227
     * length of the specified array
jaroslav@475
   228
     * @see Array#get
jaroslav@475
   229
     */
jaroslav@475
   230
    public static native char getChar(Object array, int index)
jaroslav@475
   231
        throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
jaroslav@475
   232
jaroslav@475
   233
    /**
jaroslav@475
   234
     * Returns the value of the indexed component in the specified
jaroslav@475
   235
     * array object, as a {@code short}.
jaroslav@475
   236
     *
jaroslav@475
   237
     * @param array the array
jaroslav@475
   238
     * @param index the index
jaroslav@475
   239
     * @return the value of the indexed component in the specified array
jaroslav@475
   240
     * @exception NullPointerException If the specified object is null
jaroslav@475
   241
     * @exception IllegalArgumentException If the specified object is not
jaroslav@475
   242
     * an array, or if the indexed element cannot be converted to the
jaroslav@475
   243
     * return type by an identity or widening conversion
jaroslav@475
   244
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   245
     * argument is negative, or if it is greater than or equal to the
jaroslav@475
   246
     * length of the specified array
jaroslav@475
   247
     * @see Array#get
jaroslav@475
   248
     */
jaroslav@483
   249
    public static short getShort(Object array, int index)
jaroslav@483
   250
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@483
   251
        final Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   252
        if (Method.samePrimitive(t, Short.TYPE)) {
jaroslav@483
   253
            short[] arr = (short[]) array;
jaroslav@483
   254
            return arr[index];
jaroslav@483
   255
        }
jaroslav@483
   256
        return getByte(array, index);
jaroslav@483
   257
    }
jaroslav@475
   258
jaroslav@475
   259
    /**
jaroslav@475
   260
     * Returns the value of the indexed component in the specified
jaroslav@475
   261
     * array object, as an {@code int}.
jaroslav@475
   262
     *
jaroslav@475
   263
     * @param array the array
jaroslav@475
   264
     * @param index the index
jaroslav@475
   265
     * @return the value of the indexed component in the specified array
jaroslav@475
   266
     * @exception NullPointerException If the specified object is null
jaroslav@475
   267
     * @exception IllegalArgumentException If the specified object is not
jaroslav@475
   268
     * an array, or if the indexed element cannot be converted to the
jaroslav@475
   269
     * return type by an identity or widening conversion
jaroslav@475
   270
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   271
     * argument is negative, or if it is greater than or equal to the
jaroslav@475
   272
     * length of the specified array
jaroslav@475
   273
     * @see Array#get
jaroslav@475
   274
     */
jaroslav@483
   275
    public static int getInt(Object array, int index) 
jaroslav@483
   276
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@483
   277
        final Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   278
        if (Method.samePrimitive(t, Integer.TYPE)) {
jaroslav@483
   279
            int[] arr = (int[]) array;
jaroslav@483
   280
            return arr[index];
jaroslav@483
   281
        }
jaroslav@483
   282
        return getShort(array, index);
jaroslav@483
   283
    }
jaroslav@475
   284
jaroslav@475
   285
    /**
jaroslav@475
   286
     * Returns the value of the indexed component in the specified
jaroslav@475
   287
     * array object, as a {@code long}.
jaroslav@475
   288
     *
jaroslav@475
   289
     * @param array the array
jaroslav@475
   290
     * @param index the index
jaroslav@475
   291
     * @return the value of the indexed component in the specified array
jaroslav@475
   292
     * @exception NullPointerException If the specified object is null
jaroslav@475
   293
     * @exception IllegalArgumentException If the specified object is not
jaroslav@475
   294
     * an array, or if the indexed element cannot be converted to the
jaroslav@475
   295
     * return type by an identity or widening conversion
jaroslav@475
   296
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   297
     * argument is negative, or if it is greater than or equal to the
jaroslav@475
   298
     * length of the specified array
jaroslav@475
   299
     * @see Array#get
jaroslav@475
   300
     */
jaroslav@483
   301
    public static long getLong(Object array, int index)
jaroslav@483
   302
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@483
   303
        final Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   304
        if (Method.samePrimitive(t, Long.TYPE)) {
jaroslav@483
   305
            long[] arr = (long[]) array;
jaroslav@483
   306
            return arr[index];
jaroslav@483
   307
        }
jaroslav@483
   308
        return getInt(array, index);
jaroslav@483
   309
    }
jaroslav@475
   310
jaroslav@475
   311
    /**
jaroslav@475
   312
     * Returns the value of the indexed component in the specified
jaroslav@475
   313
     * array object, as a {@code float}.
jaroslav@475
   314
     *
jaroslav@475
   315
     * @param array the array
jaroslav@475
   316
     * @param index the index
jaroslav@475
   317
     * @return the value of the indexed component in the specified array
jaroslav@475
   318
     * @exception NullPointerException If the specified object is null
jaroslav@475
   319
     * @exception IllegalArgumentException If the specified object is not
jaroslav@475
   320
     * an array, or if the indexed element cannot be converted to the
jaroslav@475
   321
     * return type by an identity or widening conversion
jaroslav@475
   322
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   323
     * argument is negative, or if it is greater than or equal to the
jaroslav@475
   324
     * length of the specified array
jaroslav@475
   325
     * @see Array#get
jaroslav@475
   326
     */
jaroslav@483
   327
    public static float getFloat(Object array, int index)
jaroslav@483
   328
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@483
   329
        final Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   330
        if (Method.samePrimitive(t, Float.TYPE)) {
jaroslav@483
   331
            float[] arr = (float[]) array;
jaroslav@483
   332
            return arr[index];
jaroslav@483
   333
        }
jaroslav@483
   334
        return getLong(array, index);
jaroslav@483
   335
    }
jaroslav@475
   336
jaroslav@475
   337
    /**
jaroslav@475
   338
     * Returns the value of the indexed component in the specified
jaroslav@475
   339
     * array object, as a {@code double}.
jaroslav@475
   340
     *
jaroslav@475
   341
     * @param array the array
jaroslav@475
   342
     * @param index the index
jaroslav@475
   343
     * @return the value of the indexed component in the specified array
jaroslav@475
   344
     * @exception NullPointerException If the specified object is null
jaroslav@475
   345
     * @exception IllegalArgumentException If the specified object is not
jaroslav@475
   346
     * an array, or if the indexed element cannot be converted to the
jaroslav@475
   347
     * return type by an identity or widening conversion
jaroslav@475
   348
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   349
     * argument is negative, or if it is greater than or equal to the
jaroslav@475
   350
     * length of the specified array
jaroslav@475
   351
     * @see Array#get
jaroslav@475
   352
     */
jaroslav@483
   353
    public static double getDouble(Object array, int index)
jaroslav@483
   354
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@483
   355
        final Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   356
        if (Method.samePrimitive(t, Double.TYPE)) {
jaroslav@483
   357
            double[] arr = (double[]) array;
jaroslav@483
   358
            return arr[index];
jaroslav@483
   359
        }
jaroslav@483
   360
        return getFloat(array, index);
jaroslav@483
   361
    }
jaroslav@475
   362
jaroslav@475
   363
    /**
jaroslav@475
   364
     * Sets the value of the indexed component of the specified array
jaroslav@475
   365
     * object to the specified new value.  The new value is first
jaroslav@475
   366
     * automatically unwrapped if the array has a primitive component
jaroslav@475
   367
     * type.
jaroslav@475
   368
     * @param array the array
jaroslav@475
   369
     * @param index the index into the array
jaroslav@475
   370
     * @param value the new value of the indexed component
jaroslav@475
   371
     * @exception NullPointerException If the specified object argument
jaroslav@475
   372
     * is null
jaroslav@475
   373
     * @exception IllegalArgumentException If the specified object argument
jaroslav@475
   374
     * is not an array, or if the array component type is primitive and
jaroslav@475
   375
     * an unwrapping conversion fails
jaroslav@475
   376
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   377
     * argument is negative, or if it is greater than or equal to
jaroslav@475
   378
     * the length of the specified array
jaroslav@475
   379
     */
jaroslav@485
   380
    public static void set(Object array, int index, Object value)
jaroslav@485
   381
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@485
   382
        if (array.getClass().getComponentType().isPrimitive()) {
jaroslav@485
   383
            throw new IllegalArgumentException();
jaroslav@485
   384
        } else {
jaroslav@485
   385
            Object[] arr = (Object[])array;
jaroslav@485
   386
            arr[index] = value;
jaroslav@485
   387
        }
jaroslav@485
   388
    }
jaroslav@475
   389
jaroslav@475
   390
    /**
jaroslav@475
   391
     * Sets the value of the indexed component of the specified array
jaroslav@475
   392
     * object to the specified {@code boolean} value.
jaroslav@475
   393
     * @param array the array
jaroslav@475
   394
     * @param index the index into the array
jaroslav@475
   395
     * @param z the new value of the indexed component
jaroslav@475
   396
     * @exception NullPointerException If the specified object argument
jaroslav@475
   397
     * is null
jaroslav@475
   398
     * @exception IllegalArgumentException If the specified object argument
jaroslav@475
   399
     * is not an array, or if the specified value cannot be converted
jaroslav@475
   400
     * to the underlying array's component type by an identity or a
jaroslav@475
   401
     * primitive widening conversion
jaroslav@475
   402
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   403
     * argument is negative, or if it is greater than or equal to
jaroslav@475
   404
     * the length of the specified array
jaroslav@475
   405
     * @see Array#set
jaroslav@475
   406
     */
jaroslav@475
   407
    public static native void setBoolean(Object array, int index, boolean z)
jaroslav@475
   408
        throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
jaroslav@475
   409
jaroslav@475
   410
    /**
jaroslav@475
   411
     * Sets the value of the indexed component of the specified array
jaroslav@475
   412
     * object to the specified {@code byte} value.
jaroslav@475
   413
     * @param array the array
jaroslav@475
   414
     * @param index the index into the array
jaroslav@475
   415
     * @param b the new value of the indexed component
jaroslav@475
   416
     * @exception NullPointerException If the specified object argument
jaroslav@475
   417
     * is null
jaroslav@475
   418
     * @exception IllegalArgumentException If the specified object argument
jaroslav@475
   419
     * is not an array, or if the specified value cannot be converted
jaroslav@475
   420
     * to the underlying array's component type by an identity or a
jaroslav@475
   421
     * primitive widening conversion
jaroslav@475
   422
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   423
     * argument is negative, or if it is greater than or equal to
jaroslav@475
   424
     * the length of the specified array
jaroslav@475
   425
     * @see Array#set
jaroslav@475
   426
     */
jaroslav@484
   427
    public static void setByte(Object array, int index, byte b)
jaroslav@484
   428
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@484
   429
        Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   430
        if (Method.samePrimitive(t, Byte.TYPE)) {
jaroslav@484
   431
            byte[] arr = (byte[]) array;
jaroslav@484
   432
            arr[index] = b;
jaroslav@484
   433
        } else {
jaroslav@484
   434
            setShort(array, index, b);
jaroslav@484
   435
        }
jaroslav@484
   436
    }
jaroslav@475
   437
jaroslav@475
   438
    /**
jaroslav@475
   439
     * Sets the value of the indexed component of the specified array
jaroslav@475
   440
     * object to the specified {@code char} value.
jaroslav@475
   441
     * @param array the array
jaroslav@475
   442
     * @param index the index into the array
jaroslav@475
   443
     * @param c the new value of the indexed component
jaroslav@475
   444
     * @exception NullPointerException If the specified object argument
jaroslav@475
   445
     * is null
jaroslav@475
   446
     * @exception IllegalArgumentException If the specified object argument
jaroslav@475
   447
     * is not an array, or if the specified value cannot be converted
jaroslav@475
   448
     * to the underlying array's component type by an identity or a
jaroslav@475
   449
     * primitive widening conversion
jaroslav@475
   450
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   451
     * argument is negative, or if it is greater than or equal to
jaroslav@475
   452
     * the length of the specified array
jaroslav@475
   453
     * @see Array#set
jaroslav@475
   454
     */
jaroslav@475
   455
    public static native void setChar(Object array, int index, char c)
jaroslav@475
   456
        throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
jaroslav@475
   457
jaroslav@475
   458
    /**
jaroslav@475
   459
     * Sets the value of the indexed component of the specified array
jaroslav@475
   460
     * object to the specified {@code short} value.
jaroslav@475
   461
     * @param array the array
jaroslav@475
   462
     * @param index the index into the array
jaroslav@475
   463
     * @param s the new value of the indexed component
jaroslav@475
   464
     * @exception NullPointerException If the specified object argument
jaroslav@475
   465
     * is null
jaroslav@475
   466
     * @exception IllegalArgumentException If the specified object argument
jaroslav@475
   467
     * is not an array, or if the specified value cannot be converted
jaroslav@475
   468
     * to the underlying array's component type by an identity or a
jaroslav@475
   469
     * primitive widening conversion
jaroslav@475
   470
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   471
     * argument is negative, or if it is greater than or equal to
jaroslav@475
   472
     * the length of the specified array
jaroslav@475
   473
     * @see Array#set
jaroslav@475
   474
     */
jaroslav@484
   475
    public static void setShort(Object array, int index, short s)
jaroslav@484
   476
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@484
   477
        Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   478
        if (Method.samePrimitive(t, Short.TYPE)) {
jaroslav@484
   479
            short[] arr = (short[]) array;
jaroslav@484
   480
            arr[index] = s;
jaroslav@484
   481
        } else {
jaroslav@484
   482
            setInt(array, index, s);
jaroslav@484
   483
        }
jaroslav@484
   484
        
jaroslav@484
   485
    }
jaroslav@571
   486
    
jaroslav@475
   487
    /**
jaroslav@475
   488
     * Sets the value of the indexed component of the specified array
jaroslav@475
   489
     * object to the specified {@code int} value.
jaroslav@475
   490
     * @param array the array
jaroslav@475
   491
     * @param index the index into the array
jaroslav@475
   492
     * @param i the new value of the indexed component
jaroslav@475
   493
     * @exception NullPointerException If the specified object argument
jaroslav@475
   494
     * is null
jaroslav@475
   495
     * @exception IllegalArgumentException If the specified object argument
jaroslav@475
   496
     * is not an array, or if the specified value cannot be converted
jaroslav@475
   497
     * to the underlying array's component type by an identity or a
jaroslav@475
   498
     * primitive widening conversion
jaroslav@475
   499
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   500
     * argument is negative, or if it is greater than or equal to
jaroslav@475
   501
     * the length of the specified array
jaroslav@475
   502
     * @see Array#set
jaroslav@475
   503
     */
jaroslav@484
   504
    public static void setInt(Object array, int index, int i)
jaroslav@484
   505
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@484
   506
        Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   507
        if (Method.samePrimitive(t, Integer.TYPE)) {
jaroslav@571
   508
            int[] arr = (int[]) array;
jaroslav@484
   509
            arr[index] = i;
jaroslav@484
   510
        } else {
jaroslav@484
   511
            setLong(array, index, i);
jaroslav@484
   512
        }
jaroslav@484
   513
    }
jaroslav@475
   514
jaroslav@475
   515
    /**
jaroslav@475
   516
     * Sets the value of the indexed component of the specified array
jaroslav@475
   517
     * object to the specified {@code long} value.
jaroslav@475
   518
     * @param array the array
jaroslav@475
   519
     * @param index the index into the array
jaroslav@475
   520
     * @param l the new value of the indexed component
jaroslav@475
   521
     * @exception NullPointerException If the specified object argument
jaroslav@475
   522
     * is null
jaroslav@475
   523
     * @exception IllegalArgumentException If the specified object argument
jaroslav@475
   524
     * is not an array, or if the specified value cannot be converted
jaroslav@475
   525
     * to the underlying array's component type by an identity or a
jaroslav@475
   526
     * primitive widening conversion
jaroslav@475
   527
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   528
     * argument is negative, or if it is greater than or equal to
jaroslav@475
   529
     * the length of the specified array
jaroslav@475
   530
     * @see Array#set
jaroslav@475
   531
     */
jaroslav@484
   532
    public static void setLong(Object array, int index, long l)
jaroslav@484
   533
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@484
   534
        Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   535
        if (Method.samePrimitive(t, Long.TYPE)) {
jaroslav@484
   536
            long[] arr = (long[]) array;
jaroslav@484
   537
            arr[index] = l;
jaroslav@484
   538
        } else {
jaroslav@484
   539
            setFloat(array, index, l);
jaroslav@484
   540
        }
jaroslav@484
   541
    }
jaroslav@475
   542
jaroslav@475
   543
    /**
jaroslav@475
   544
     * Sets the value of the indexed component of the specified array
jaroslav@475
   545
     * object to the specified {@code float} value.
jaroslav@475
   546
     * @param array the array
jaroslav@475
   547
     * @param index the index into the array
jaroslav@475
   548
     * @param f the new value of the indexed component
jaroslav@475
   549
     * @exception NullPointerException If the specified object argument
jaroslav@475
   550
     * is null
jaroslav@475
   551
     * @exception IllegalArgumentException If the specified object argument
jaroslav@475
   552
     * is not an array, or if the specified value cannot be converted
jaroslav@475
   553
     * to the underlying array's component type by an identity or a
jaroslav@475
   554
     * primitive widening conversion
jaroslav@475
   555
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   556
     * argument is negative, or if it is greater than or equal to
jaroslav@475
   557
     * the length of the specified array
jaroslav@475
   558
     * @see Array#set
jaroslav@475
   559
     */
jaroslav@484
   560
    public static void setFloat(Object array, int index, float f)
jaroslav@484
   561
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@484
   562
        Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   563
        if (Method.samePrimitive(t, Float.TYPE)) {
jaroslav@484
   564
            float[] arr = (float[])array;
jaroslav@484
   565
            arr[index] = f;
jaroslav@484
   566
        } else {
jaroslav@484
   567
            setDouble(array, index, f);
jaroslav@484
   568
        }
jaroslav@484
   569
    }
jaroslav@475
   570
jaroslav@475
   571
    /**
jaroslav@475
   572
     * Sets the value of the indexed component of the specified array
jaroslav@475
   573
     * object to the specified {@code double} value.
jaroslav@475
   574
     * @param array the array
jaroslav@475
   575
     * @param index the index into the array
jaroslav@475
   576
     * @param d the new value of the indexed component
jaroslav@475
   577
     * @exception NullPointerException If the specified object argument
jaroslav@475
   578
     * is null
jaroslav@475
   579
     * @exception IllegalArgumentException If the specified object argument
jaroslav@475
   580
     * is not an array, or if the specified value cannot be converted
jaroslav@475
   581
     * to the underlying array's component type by an identity or a
jaroslav@475
   582
     * primitive widening conversion
jaroslav@475
   583
     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
jaroslav@475
   584
     * argument is negative, or if it is greater than or equal to
jaroslav@475
   585
     * the length of the specified array
jaroslav@475
   586
     * @see Array#set
jaroslav@475
   587
     */
jaroslav@484
   588
    public static void setDouble(Object array, int index, double d)
jaroslav@484
   589
    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
jaroslav@484
   590
        Class<?> t = array.getClass().getComponentType();
jaroslav@1541
   591
        if (Method.samePrimitive(t, Double.TYPE)) {
jaroslav@484
   592
            double[] arr = (double[])array;
jaroslav@484
   593
            arr[index] = d;
jaroslav@484
   594
        } else {
jaroslav@484
   595
            throw new IllegalArgumentException("argument type mismatch");
jaroslav@484
   596
        }
jaroslav@484
   597
    }
jaroslav@475
   598
jaroslav@475
   599
    /*
jaroslav@475
   600
     * Private
jaroslav@475
   601
     */
jaroslav@475
   602
jaroslav@1532
   603
    @JavaScriptBody(args = { "primitive", "sig", "fn", "length" }, body =
jaroslav@477
   604
          "var arr = new Array(length);\n"
jaroslav@477
   605
        + "var value = primitive ? 0 : null;\n"
jaroslav@477
   606
        + "for(var i = 0; i < length; i++) arr[i] = value;\n"
jaroslav@477
   607
        + "arr.jvmName = sig;\n"
jaroslav@1532
   608
        + "arr.fnc = fn;\n"
jaroslav@1532
   609
//        + "java.lang.System.out.println('Assigned ' + arr.jvmName + ' fn: ' + (!!arr.fnc));\n"
jaroslav@477
   610
        + "return arr;"
jaroslav@477
   611
    )
lubomir@967
   612
    @Exported
jaroslav@1533
   613
    private static native Object newArray(boolean primitive, String sig, Object fn, int length);
jaroslav@475
   614
jaroslav@1534
   615
    @Exported
jaroslav@1534
   616
    private static boolean isInstance(Object arr, String sig)  {
jaroslav@1534
   617
        if (arr == null) {
jaroslav@1534
   618
            return false;
jaroslav@1534
   619
        }
jaroslav@1534
   620
        return sig.equals(arr.getClass().getName());
jaroslav@1534
   621
    }
jaroslav@1534
   622
    
jaroslav@1534
   623
    @Exported
jaroslav@1534
   624
    private static boolean isInstance(Object arr, int dimensions, Object fn) throws ClassNotFoundException {
jaroslav@1534
   625
        if (arr == null) {
jaroslav@1534
   626
            return false;
jaroslav@1534
   627
        }
jaroslav@1534
   628
//        log("isInstance for " + arr + " and " + dimensions);
jaroslav@1534
   629
        Class<?> c = arr.getClass();
jaroslav@1534
   630
        while (dimensions-- > 0) {
jaroslav@1534
   631
//            log(" class: " + c);
jaroslav@1534
   632
            c = c.getComponentType();
jaroslav@1534
   633
//            log(" next class: " + c);
jaroslav@1534
   634
            if (c == null) {
jaroslav@1534
   635
                return false;
jaroslav@1534
   636
            }
jaroslav@1534
   637
        }
jaroslav@1534
   638
        Class<?> t = classFromFn(fn);
jaroslav@1534
   639
//        log(" to check: " + t);
jaroslav@1534
   640
        return t.isAssignableFrom(c);
jaroslav@1534
   641
    }
jaroslav@1534
   642
    
jaroslav@1534
   643
    @JavaScriptBody(args = { "cntstr" }, body = "return cntstr(false).constructor.$class;")
jaroslav@1534
   644
    private static native Class<?> classFromFn(Object cntstr);
lubomir@967
   645
jaroslav@1534
   646
//    @JavaScriptBody(args = { "m" }, body = "java.lang.System.out.println(m.toString().toString());")
jaroslav@1534
   647
//    private static native void log(Object m);
jaroslav@1534
   648
    
lubomir@967
   649
    @Exported
jaroslav@1535
   650
    private static Object multiNewArray(String sig, int[] dims, Object fn)
jaroslav@1535
   651
    throws IllegalArgumentException, NegativeArraySizeException {
jaroslav@1535
   652
        return multiNewArray(sig, dims, 0, fn);
jaroslav@1535
   653
    }
jaroslav@1535
   654
    private static Object multiNewArray(String sig, int[] dims, int index, Object fn)
jaroslav@480
   655
    throws IllegalArgumentException, NegativeArraySizeException {
jaroslav@480
   656
        if (dims.length == index + 1) {
jaroslav@1535
   657
            return newArray(sig.length() == 2, sig, fn, dims[index]);
jaroslav@480
   658
        }
jaroslav@1532
   659
        Object arr = newArray(false, sig, null, dims[index]);
jaroslav@480
   660
        String compsig = sig.substring(1);
jaroslav@571
   661
        int len = getLength(arr);
jaroslav@571
   662
        for (int i = 0; i < len; i++) {
jaroslav@1535
   663
            setArray(arr, i, multiNewArray(compsig, dims, index + 1, fn));
jaroslav@480
   664
        }
jaroslav@480
   665
        return arr;
jaroslav@480
   666
    }
jaroslav@486
   667
    private static Object fromPrimitive(Class<?> t, Object array, int index) {
jaroslav@486
   668
        return Method.fromPrimitive(t, atArray(array, index));
jaroslav@486
   669
    }
jaroslav@486
   670
    
jaroslav@571
   671
    @JavaScriptBody(args = { "array", "index" }, body = "return array[index];")
jaroslav@486
   672
    private static native Object atArray(Object array, int index);
jaroslav@571
   673
jaroslav@571
   674
    @JavaScriptBody(args = { "array", "index", "v" }, body = "array[index] = v;")
jaroslav@571
   675
    private static native Object setArray(Object array, int index, Object v);
jaroslav@475
   676
}