1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/emul/src/main/java/java/lang/NegativeArraySizeException.java Fri Jan 18 22:17:01 2013 +0100
1.3 @@ -0,0 +1,55 @@
1.4 +/*
1.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.lang;
1.30 +
1.31 +/**
1.32 + * Thrown if an application tries to create an array with negative size.
1.33 + *
1.34 + * @author unascribed
1.35 + * @since JDK1.0
1.36 + */
1.37 +public
1.38 +class NegativeArraySizeException extends RuntimeException {
1.39 + private static final long serialVersionUID = -8960118058596991861L;
1.40 +
1.41 + /**
1.42 + * Constructs a <code>NegativeArraySizeException</code> with no
1.43 + * detail message.
1.44 + */
1.45 + public NegativeArraySizeException() {
1.46 + super();
1.47 + }
1.48 +
1.49 + /**
1.50 + * Constructs a <code>NegativeArraySizeException</code> with the
1.51 + * specified detail message.
1.52 + *
1.53 + * @param s the detail message.
1.54 + */
1.55 + public NegativeArraySizeException(String s) {
1.56 + super(s);
1.57 + }
1.58 +}
2.1 --- a/emul/src/main/java/java/lang/Object.java Tue Jan 15 12:44:33 2013 +0100
2.2 +++ b/emul/src/main/java/java/lang/Object.java Fri Jan 18 22:17:01 2013 +0100
2.3 @@ -25,6 +25,7 @@
2.4
2.5 package java.lang;
2.6
2.7 +import java.lang.reflect.Array;
2.8 import org.apidesign.bck2brwsr.core.JavaScriptBody;
2.9 import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
2.10
2.11 @@ -40,8 +41,13 @@
2.12 @JavaScriptPrototype(container = "Object.prototype", prototype = "new Object")
2.13 public class Object {
2.14
2.15 - @JavaScriptBody(args = {}, body = "")
2.16 - private static native void registerNatives();
2.17 + private static void registerNatives() {
2.18 + try {
2.19 + Array.get(null, 0);
2.20 + } catch (Throwable ex) {
2.21 + // ignore
2.22 + }
2.23 + }
2.24 static {
2.25 registerNatives();
2.26 }
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/emul/src/main/java/java/lang/reflect/Array.java Fri Jan 18 22:17:01 2013 +0100
3.3 @@ -0,0 +1,659 @@
3.4 +/*
3.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3.7 + *
3.8 + * This code is free software; you can redistribute it and/or modify it
3.9 + * under the terms of the GNU General Public License version 2 only, as
3.10 + * published by the Free Software Foundation. Oracle designates this
3.11 + * particular file as subject to the "Classpath" exception as provided
3.12 + * by Oracle in the LICENSE file that accompanied this code.
3.13 + *
3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3.17 + * version 2 for more details (a copy is included in the LICENSE file that
3.18 + * accompanied this code).
3.19 + *
3.20 + * You should have received a copy of the GNU General Public License version
3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3.23 + *
3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3.25 + * or visit www.oracle.com if you need additional information or have any
3.26 + * questions.
3.27 + */
3.28 +
3.29 +package java.lang.reflect;
3.30 +
3.31 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
3.32 +import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
3.33 +
3.34 +/**
3.35 + * The {@code Array} class provides static methods to dynamically create and
3.36 + * access Java arrays.
3.37 + *
3.38 + * <p>{@code Array} permits widening conversions to occur during a get or set
3.39 + * operation, but throws an {@code IllegalArgumentException} if a narrowing
3.40 + * conversion would occur.
3.41 + *
3.42 + * @author Nakul Saraiya
3.43 + */
3.44 +@JavaScriptPrototype(prototype = "new Array", container = "Array.prototype")
3.45 +public final
3.46 +class Array {
3.47 +
3.48 + /**
3.49 + * Constructor. Class Array is not instantiable.
3.50 + */
3.51 + private Array() {}
3.52 +
3.53 + /**
3.54 + * Creates a new array with the specified component type and
3.55 + * length.
3.56 + * Invoking this method is equivalent to creating an array
3.57 + * as follows:
3.58 + * <blockquote>
3.59 + * <pre>
3.60 + * int[] x = {length};
3.61 + * Array.newInstance(componentType, x);
3.62 + * </pre>
3.63 + * </blockquote>
3.64 + *
3.65 + * @param componentType the {@code Class} object representing the
3.66 + * component type of the new array
3.67 + * @param length the length of the new array
3.68 + * @return the new array
3.69 + * @exception NullPointerException if the specified
3.70 + * {@code componentType} parameter is null
3.71 + * @exception IllegalArgumentException if componentType is {@link Void#TYPE}
3.72 + * @exception NegativeArraySizeException if the specified {@code length}
3.73 + * is negative
3.74 + */
3.75 + public static Object newInstance(Class<?> componentType, int length)
3.76 + throws NegativeArraySizeException {
3.77 + if (length < 0) {
3.78 + throw new NegativeArraySizeException();
3.79 + }
3.80 + String sig = findSignature(componentType);
3.81 + return newArray(componentType.isPrimitive(), sig, length);
3.82 + }
3.83 +
3.84 + private static String findSignature(Class<?> type) {
3.85 + if (type == Integer.TYPE) {
3.86 + return "[I";
3.87 + }
3.88 + if (type == Long.TYPE) {
3.89 + return "[J";
3.90 + }
3.91 + if (type == Double.TYPE) {
3.92 + return "[D";
3.93 + }
3.94 + if (type == Float.TYPE) {
3.95 + return "[F";
3.96 + }
3.97 + if (type == Byte.TYPE) {
3.98 + return "[B";
3.99 + }
3.100 + if (type == Boolean.TYPE) {
3.101 + return "[Z";
3.102 + }
3.103 + if (type == Short.TYPE) {
3.104 + return "[S";
3.105 + }
3.106 + if (type == Character.TYPE) {
3.107 + return "[C";
3.108 + }
3.109 + if (type.getName().equals("void")) {
3.110 + throw new IllegalStateException("Can't create array for " + type);
3.111 + }
3.112 + return "[L" + type.getName() + ";";
3.113 + }
3.114 + /**
3.115 + * Creates a new array
3.116 + * with the specified component type and dimensions.
3.117 + * If {@code componentType}
3.118 + * represents a non-array class or interface, the new array
3.119 + * has {@code dimensions.length} dimensions and
3.120 + * {@code componentType} as its component type. If
3.121 + * {@code componentType} represents an array class, the
3.122 + * number of dimensions of the new array is equal to the sum
3.123 + * of {@code dimensions.length} and the number of
3.124 + * dimensions of {@code componentType}. In this case, the
3.125 + * component type of the new array is the component type of
3.126 + * {@code componentType}.
3.127 + *
3.128 + * <p>The number of dimensions of the new array must not
3.129 + * exceed the number of array dimensions supported by the
3.130 + * implementation (typically 255).
3.131 + *
3.132 + * @param componentType the {@code Class} object representing the component
3.133 + * type of the new array
3.134 + * @param dimensions an array of {@code int} representing the dimensions of
3.135 + * the new array
3.136 + * @return the new array
3.137 + * @exception NullPointerException if the specified
3.138 + * {@code componentType} argument is null
3.139 + * @exception IllegalArgumentException if the specified {@code dimensions}
3.140 + * argument is a zero-dimensional array, or if the number of
3.141 + * requested dimensions exceeds the limit on the number of array dimensions
3.142 + * supported by the implementation (typically 255), or if componentType
3.143 + * is {@link Void#TYPE}.
3.144 + * @exception NegativeArraySizeException if any of the components in
3.145 + * the specified {@code dimensions} argument is negative.
3.146 + */
3.147 + public static Object newInstance(Class<?> componentType, int... dimensions)
3.148 + throws IllegalArgumentException, NegativeArraySizeException {
3.149 + StringBuilder sig = new StringBuilder();
3.150 + for (int i = 1; i < dimensions.length; i++) {
3.151 + sig.append('[');
3.152 + }
3.153 + sig.append(findSignature(componentType));
3.154 + return multiNewArray(sig.toString(), dimensions, 0);
3.155 + }
3.156 +
3.157 + /**
3.158 + * Returns the length of the specified array object, as an {@code int}.
3.159 + *
3.160 + * @param array the array
3.161 + * @return the length of the array
3.162 + * @exception IllegalArgumentException if the object argument is not
3.163 + * an array
3.164 + */
3.165 + public static int getLength(Object array)
3.166 + throws IllegalArgumentException {
3.167 + if (!array.getClass().isArray()) {
3.168 + throw new IllegalArgumentException("Argument is not an array");
3.169 + }
3.170 + return length(array);
3.171 + }
3.172 +
3.173 + @JavaScriptBody(args = { "arr" }, body = "return arr.length;")
3.174 + private static native int length(Object arr);
3.175 +
3.176 + /**
3.177 + * Returns the value of the indexed component in the specified
3.178 + * array object. The value is automatically wrapped in an object
3.179 + * if it has a primitive type.
3.180 + *
3.181 + * @param array the array
3.182 + * @param index the index
3.183 + * @return the (possibly wrapped) value of the indexed component in
3.184 + * the specified array
3.185 + * @exception NullPointerException If the specified object is null
3.186 + * @exception IllegalArgumentException If the specified object is not
3.187 + * an array
3.188 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.189 + * argument is negative, or if it is greater than or equal to the
3.190 + * length of the specified array
3.191 + */
3.192 + public static Object get(Object array, int index)
3.193 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.194 + final Class<?> t = array.getClass().getComponentType();
3.195 + if (t.isPrimitive()) {
3.196 + return Array.fromPrimitive(t, array, index);
3.197 + } else {
3.198 + return ((Object[])array)[index];
3.199 + }
3.200 + }
3.201 +
3.202 + /**
3.203 + * Returns the value of the indexed component in the specified
3.204 + * array object, as a {@code boolean}.
3.205 + *
3.206 + * @param array the array
3.207 + * @param index the index
3.208 + * @return the value of the indexed component in the specified array
3.209 + * @exception NullPointerException If the specified object is null
3.210 + * @exception IllegalArgumentException If the specified object is not
3.211 + * an array, or if the indexed element cannot be converted to the
3.212 + * return type by an identity or widening conversion
3.213 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.214 + * argument is negative, or if it is greater than or equal to the
3.215 + * length of the specified array
3.216 + * @see Array#get
3.217 + */
3.218 + public static native boolean getBoolean(Object array, int index)
3.219 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
3.220 +
3.221 + /**
3.222 + * Returns the value of the indexed component in the specified
3.223 + * array object, as a {@code byte}.
3.224 + *
3.225 + * @param array the array
3.226 + * @param index the index
3.227 + * @return the value of the indexed component in the specified array
3.228 + * @exception NullPointerException If the specified object is null
3.229 + * @exception IllegalArgumentException If the specified object is not
3.230 + * an array, or if the indexed element cannot be converted to the
3.231 + * return type by an identity or widening conversion
3.232 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.233 + * argument is negative, or if it is greater than or equal to the
3.234 + * length of the specified array
3.235 + * @see Array#get
3.236 + */
3.237 + public static byte getByte(Object array, int index)
3.238 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.239 + if (array.getClass().getComponentType() != Byte.TYPE) {
3.240 + throw new IllegalArgumentException();
3.241 + }
3.242 + byte[] arr = (byte[]) array;
3.243 + return arr[index];
3.244 + }
3.245 +
3.246 + /**
3.247 + * Returns the value of the indexed component in the specified
3.248 + * array object, as a {@code char}.
3.249 + *
3.250 + * @param array the array
3.251 + * @param index the index
3.252 + * @return the value of the indexed component in the specified array
3.253 + * @exception NullPointerException If the specified object is null
3.254 + * @exception IllegalArgumentException If the specified object is not
3.255 + * an array, or if the indexed element cannot be converted to the
3.256 + * return type by an identity or widening conversion
3.257 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.258 + * argument is negative, or if it is greater than or equal to the
3.259 + * length of the specified array
3.260 + * @see Array#get
3.261 + */
3.262 + public static native char getChar(Object array, int index)
3.263 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
3.264 +
3.265 + /**
3.266 + * Returns the value of the indexed component in the specified
3.267 + * array object, as a {@code short}.
3.268 + *
3.269 + * @param array the array
3.270 + * @param index the index
3.271 + * @return the value of the indexed component in the specified array
3.272 + * @exception NullPointerException If the specified object is null
3.273 + * @exception IllegalArgumentException If the specified object is not
3.274 + * an array, or if the indexed element cannot be converted to the
3.275 + * return type by an identity or widening conversion
3.276 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.277 + * argument is negative, or if it is greater than or equal to the
3.278 + * length of the specified array
3.279 + * @see Array#get
3.280 + */
3.281 + public static short getShort(Object array, int index)
3.282 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.283 + final Class<?> t = array.getClass().getComponentType();
3.284 + if (t == Short.TYPE) {
3.285 + short[] arr = (short[]) array;
3.286 + return arr[index];
3.287 + }
3.288 + return getByte(array, index);
3.289 + }
3.290 +
3.291 + /**
3.292 + * Returns the value of the indexed component in the specified
3.293 + * array object, as an {@code int}.
3.294 + *
3.295 + * @param array the array
3.296 + * @param index the index
3.297 + * @return the value of the indexed component in the specified array
3.298 + * @exception NullPointerException If the specified object is null
3.299 + * @exception IllegalArgumentException If the specified object is not
3.300 + * an array, or if the indexed element cannot be converted to the
3.301 + * return type by an identity or widening conversion
3.302 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.303 + * argument is negative, or if it is greater than or equal to the
3.304 + * length of the specified array
3.305 + * @see Array#get
3.306 + */
3.307 + public static int getInt(Object array, int index)
3.308 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.309 + final Class<?> t = array.getClass().getComponentType();
3.310 + if (t == Integer.TYPE) {
3.311 + int[] arr = (int[]) array;
3.312 + return arr[index];
3.313 + }
3.314 + return getShort(array, index);
3.315 + }
3.316 +
3.317 + /**
3.318 + * Returns the value of the indexed component in the specified
3.319 + * array object, as a {@code long}.
3.320 + *
3.321 + * @param array the array
3.322 + * @param index the index
3.323 + * @return the value of the indexed component in the specified array
3.324 + * @exception NullPointerException If the specified object is null
3.325 + * @exception IllegalArgumentException If the specified object is not
3.326 + * an array, or if the indexed element cannot be converted to the
3.327 + * return type by an identity or widening conversion
3.328 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.329 + * argument is negative, or if it is greater than or equal to the
3.330 + * length of the specified array
3.331 + * @see Array#get
3.332 + */
3.333 + public static long getLong(Object array, int index)
3.334 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.335 + final Class<?> t = array.getClass().getComponentType();
3.336 + if (t == Long.TYPE) {
3.337 + long[] arr = (long[]) array;
3.338 + return arr[index];
3.339 + }
3.340 + return getInt(array, index);
3.341 + }
3.342 +
3.343 + /**
3.344 + * Returns the value of the indexed component in the specified
3.345 + * array object, as a {@code float}.
3.346 + *
3.347 + * @param array the array
3.348 + * @param index the index
3.349 + * @return the value of the indexed component in the specified array
3.350 + * @exception NullPointerException If the specified object is null
3.351 + * @exception IllegalArgumentException If the specified object is not
3.352 + * an array, or if the indexed element cannot be converted to the
3.353 + * return type by an identity or widening conversion
3.354 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.355 + * argument is negative, or if it is greater than or equal to the
3.356 + * length of the specified array
3.357 + * @see Array#get
3.358 + */
3.359 + public static float getFloat(Object array, int index)
3.360 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.361 + final Class<?> t = array.getClass().getComponentType();
3.362 + if (t == Float.TYPE) {
3.363 + float[] arr = (float[]) array;
3.364 + return arr[index];
3.365 + }
3.366 + return getLong(array, index);
3.367 + }
3.368 +
3.369 + /**
3.370 + * Returns the value of the indexed component in the specified
3.371 + * array object, as a {@code double}.
3.372 + *
3.373 + * @param array the array
3.374 + * @param index the index
3.375 + * @return the value of the indexed component in the specified array
3.376 + * @exception NullPointerException If the specified object is null
3.377 + * @exception IllegalArgumentException If the specified object is not
3.378 + * an array, or if the indexed element cannot be converted to the
3.379 + * return type by an identity or widening conversion
3.380 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.381 + * argument is negative, or if it is greater than or equal to the
3.382 + * length of the specified array
3.383 + * @see Array#get
3.384 + */
3.385 + public static double getDouble(Object array, int index)
3.386 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.387 + final Class<?> t = array.getClass().getComponentType();
3.388 + if (t == Double.TYPE) {
3.389 + double[] arr = (double[]) array;
3.390 + return arr[index];
3.391 + }
3.392 + return getFloat(array, index);
3.393 + }
3.394 +
3.395 + /**
3.396 + * Sets the value of the indexed component of the specified array
3.397 + * object to the specified new value. The new value is first
3.398 + * automatically unwrapped if the array has a primitive component
3.399 + * type.
3.400 + * @param array the array
3.401 + * @param index the index into the array
3.402 + * @param value the new value of the indexed component
3.403 + * @exception NullPointerException If the specified object argument
3.404 + * is null
3.405 + * @exception IllegalArgumentException If the specified object argument
3.406 + * is not an array, or if the array component type is primitive and
3.407 + * an unwrapping conversion fails
3.408 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.409 + * argument is negative, or if it is greater than or equal to
3.410 + * the length of the specified array
3.411 + */
3.412 + public static void set(Object array, int index, Object value)
3.413 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.414 + if (array.getClass().getComponentType().isPrimitive()) {
3.415 + throw new IllegalArgumentException();
3.416 + } else {
3.417 + Object[] arr = (Object[])array;
3.418 + arr[index] = value;
3.419 + }
3.420 + }
3.421 +
3.422 + /**
3.423 + * Sets the value of the indexed component of the specified array
3.424 + * object to the specified {@code boolean} value.
3.425 + * @param array the array
3.426 + * @param index the index into the array
3.427 + * @param z the new value of the indexed component
3.428 + * @exception NullPointerException If the specified object argument
3.429 + * is null
3.430 + * @exception IllegalArgumentException If the specified object argument
3.431 + * is not an array, or if the specified value cannot be converted
3.432 + * to the underlying array's component type by an identity or a
3.433 + * primitive widening conversion
3.434 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.435 + * argument is negative, or if it is greater than or equal to
3.436 + * the length of the specified array
3.437 + * @see Array#set
3.438 + */
3.439 + public static native void setBoolean(Object array, int index, boolean z)
3.440 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
3.441 +
3.442 + /**
3.443 + * Sets the value of the indexed component of the specified array
3.444 + * object to the specified {@code byte} value.
3.445 + * @param array the array
3.446 + * @param index the index into the array
3.447 + * @param b the new value of the indexed component
3.448 + * @exception NullPointerException If the specified object argument
3.449 + * is null
3.450 + * @exception IllegalArgumentException If the specified object argument
3.451 + * is not an array, or if the specified value cannot be converted
3.452 + * to the underlying array's component type by an identity or a
3.453 + * primitive widening conversion
3.454 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.455 + * argument is negative, or if it is greater than or equal to
3.456 + * the length of the specified array
3.457 + * @see Array#set
3.458 + */
3.459 + public static void setByte(Object array, int index, byte b)
3.460 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.461 + Class<?> t = array.getClass().getComponentType();
3.462 + if (t == Byte.TYPE) {
3.463 + byte[] arr = (byte[]) array;
3.464 + arr[index] = b;
3.465 + } else {
3.466 + setShort(array, index, b);
3.467 + }
3.468 + }
3.469 +
3.470 + /**
3.471 + * Sets the value of the indexed component of the specified array
3.472 + * object to the specified {@code char} value.
3.473 + * @param array the array
3.474 + * @param index the index into the array
3.475 + * @param c the new value of the indexed component
3.476 + * @exception NullPointerException If the specified object argument
3.477 + * is null
3.478 + * @exception IllegalArgumentException If the specified object argument
3.479 + * is not an array, or if the specified value cannot be converted
3.480 + * to the underlying array's component type by an identity or a
3.481 + * primitive widening conversion
3.482 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.483 + * argument is negative, or if it is greater than or equal to
3.484 + * the length of the specified array
3.485 + * @see Array#set
3.486 + */
3.487 + public static native void setChar(Object array, int index, char c)
3.488 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
3.489 +
3.490 + /**
3.491 + * Sets the value of the indexed component of the specified array
3.492 + * object to the specified {@code short} value.
3.493 + * @param array the array
3.494 + * @param index the index into the array
3.495 + * @param s the new value of the indexed component
3.496 + * @exception NullPointerException If the specified object argument
3.497 + * is null
3.498 + * @exception IllegalArgumentException If the specified object argument
3.499 + * is not an array, or if the specified value cannot be converted
3.500 + * to the underlying array's component type by an identity or a
3.501 + * primitive widening conversion
3.502 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.503 + * argument is negative, or if it is greater than or equal to
3.504 + * the length of the specified array
3.505 + * @see Array#set
3.506 + */
3.507 + public static void setShort(Object array, int index, short s)
3.508 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.509 + Class<?> t = array.getClass().getComponentType();
3.510 + if (t == Short.TYPE) {
3.511 + short[] arr = (short[]) array;
3.512 + arr[index] = s;
3.513 + } else {
3.514 + setInt(array, index, s);
3.515 + }
3.516 +
3.517 + }
3.518 +
3.519 + /**
3.520 + * Sets the value of the indexed component of the specified array
3.521 + * object to the specified {@code int} value.
3.522 + * @param array the array
3.523 + * @param index the index into the array
3.524 + * @param i the new value of the indexed component
3.525 + * @exception NullPointerException If the specified object argument
3.526 + * is null
3.527 + * @exception IllegalArgumentException If the specified object argument
3.528 + * is not an array, or if the specified value cannot be converted
3.529 + * to the underlying array's component type by an identity or a
3.530 + * primitive widening conversion
3.531 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.532 + * argument is negative, or if it is greater than or equal to
3.533 + * the length of the specified array
3.534 + * @see Array#set
3.535 + */
3.536 + public static void setInt(Object array, int index, int i)
3.537 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.538 + Class<?> t = array.getClass().getComponentType();
3.539 + if (t == Integer.TYPE) {
3.540 + long[] arr = (long[]) array;
3.541 + arr[index] = i;
3.542 + } else {
3.543 + setLong(array, index, i);
3.544 + }
3.545 + }
3.546 +
3.547 + /**
3.548 + * Sets the value of the indexed component of the specified array
3.549 + * object to the specified {@code long} value.
3.550 + * @param array the array
3.551 + * @param index the index into the array
3.552 + * @param l the new value of the indexed component
3.553 + * @exception NullPointerException If the specified object argument
3.554 + * is null
3.555 + * @exception IllegalArgumentException If the specified object argument
3.556 + * is not an array, or if the specified value cannot be converted
3.557 + * to the underlying array's component type by an identity or a
3.558 + * primitive widening conversion
3.559 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.560 + * argument is negative, or if it is greater than or equal to
3.561 + * the length of the specified array
3.562 + * @see Array#set
3.563 + */
3.564 + public static void setLong(Object array, int index, long l)
3.565 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.566 + Class<?> t = array.getClass().getComponentType();
3.567 + if (t == Long.TYPE) {
3.568 + long[] arr = (long[]) array;
3.569 + arr[index] = l;
3.570 + } else {
3.571 + setFloat(array, index, l);
3.572 + }
3.573 + }
3.574 +
3.575 + /**
3.576 + * Sets the value of the indexed component of the specified array
3.577 + * object to the specified {@code float} value.
3.578 + * @param array the array
3.579 + * @param index the index into the array
3.580 + * @param f the new value of the indexed component
3.581 + * @exception NullPointerException If the specified object argument
3.582 + * is null
3.583 + * @exception IllegalArgumentException If the specified object argument
3.584 + * is not an array, or if the specified value cannot be converted
3.585 + * to the underlying array's component type by an identity or a
3.586 + * primitive widening conversion
3.587 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.588 + * argument is negative, or if it is greater than or equal to
3.589 + * the length of the specified array
3.590 + * @see Array#set
3.591 + */
3.592 + public static void setFloat(Object array, int index, float f)
3.593 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.594 + Class<?> t = array.getClass().getComponentType();
3.595 + if (t == Float.TYPE) {
3.596 + float[] arr = (float[])array;
3.597 + arr[index] = f;
3.598 + } else {
3.599 + setDouble(array, index, f);
3.600 + }
3.601 + }
3.602 +
3.603 + /**
3.604 + * Sets the value of the indexed component of the specified array
3.605 + * object to the specified {@code double} value.
3.606 + * @param array the array
3.607 + * @param index the index into the array
3.608 + * @param d the new value of the indexed component
3.609 + * @exception NullPointerException If the specified object argument
3.610 + * is null
3.611 + * @exception IllegalArgumentException If the specified object argument
3.612 + * is not an array, or if the specified value cannot be converted
3.613 + * to the underlying array's component type by an identity or a
3.614 + * primitive widening conversion
3.615 + * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
3.616 + * argument is negative, or if it is greater than or equal to
3.617 + * the length of the specified array
3.618 + * @see Array#set
3.619 + */
3.620 + public static void setDouble(Object array, int index, double d)
3.621 + throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
3.622 + Class<?> t = array.getClass().getComponentType();
3.623 + if (t == Double.TYPE) {
3.624 + double[] arr = (double[])array;
3.625 + arr[index] = d;
3.626 + } else {
3.627 + throw new IllegalArgumentException("argument type mismatch");
3.628 + }
3.629 + }
3.630 +
3.631 + /*
3.632 + * Private
3.633 + */
3.634 +
3.635 + @JavaScriptBody(args = { "primitive", "sig", "length" }, body =
3.636 + "var arr = new Array(length);\n"
3.637 + + "var value = primitive ? 0 : null;\n"
3.638 + + "for(var i = 0; i < length; i++) arr[i] = value;\n"
3.639 + + "arr.jvmName = sig;\n"
3.640 + + "return arr;"
3.641 + )
3.642 + private static native Object newArray(boolean primitive, String sig, int length);
3.643 +
3.644 + private static Object multiNewArray(String sig, int[] dims, int index)
3.645 + throws IllegalArgumentException, NegativeArraySizeException {
3.646 + if (dims.length == index + 1) {
3.647 + return newArray(sig.length() == 2, sig, dims[index]);
3.648 + }
3.649 + Object[] arr = (Object[]) newArray(false, sig, dims[index]);
3.650 + String compsig = sig.substring(1);
3.651 + for (int i = 0; i < arr.length; i++) {
3.652 + arr[i] = multiNewArray(compsig, dims, index + 1);
3.653 + }
3.654 + return arr;
3.655 + }
3.656 + private static Object fromPrimitive(Class<?> t, Object array, int index) {
3.657 + return Method.fromPrimitive(t, atArray(array, index));
3.658 + }
3.659 +
3.660 + @JavaScriptBody(args = { "array", "index" }, body = "return array[index]")
3.661 + private static native Object atArray(Object array, int index);
3.662 +}
4.1 --- a/emul/src/main/java/java/lang/reflect/Method.java Tue Jan 15 12:44:33 2013 +0100
4.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java Fri Jan 18 22:17:01 2013 +0100
4.3 @@ -537,7 +537,7 @@
4.4 )
4.5 private static native Object invoke0(boolean isStatic, Method m, Object self, Object[] args);
4.6
4.7 - private static Object fromPrimitive(Class<?> type, Object o) {
4.8 + static Object fromPrimitive(Class<?> type, Object o) {
4.9 if (type == Integer.TYPE) {
4.10 return fromRaw(Integer.class, "valueOf__Ljava_lang_Integer_2I", o);
4.11 }
5.1 --- a/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Tue Jan 15 12:44:33 2013 +0100
5.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Fri Jan 18 22:17:01 2013 +0100
5.3 @@ -1,12 +1,7 @@
5.4 -// initialize methods on String constants
5.5 +// initialize methods on arrays and String constants
5.6 +vm.java_lang_reflect_Array(false);
5.7 vm.java_lang_String(false);
5.8
5.9 -// we need initialized arrays
5.10 -Array.prototype.initWith = function(sig, value) {
5.11 - for(var i = 0; i < this.length; i++) this[i] = value;
5.12 - this.jvmName = sig;
5.13 - return this;
5.14 -};
5.15 Array.prototype.at = function(indx, value) {
5.16 if (indx < 0 || indx > this.length) {
5.17 var e = vm.java_lang_ArrayIndexOutOfBoundsException(true);
6.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Jan 15 12:44:33 2013 +0100
6.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Jan 18 22:17:01 2013 +0100
6.3 @@ -926,7 +926,7 @@
6.4 case 11: jvmType = "[J"; break;
6.5 default: throw new IllegalStateException("Array type: " + atype);
6.6 }
6.7 - emit(out, "@2 = new Array(@1).initWith('@3', 0);",
6.8 + emit(out, "@2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(true, '@3', @1);",
6.9 smapper.popI(), smapper.pushA(), jvmType);
6.10 break;
6.11 case opc_anewarray: {
6.12 @@ -938,7 +938,7 @@
6.13 } else {
6.14 typeName = "[L" + typeName + ";";
6.15 }
6.16 - emit(out, "@2 = new Array(@1).initWith('@3', null);",
6.17 + emit(out, "@2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(false, '@3', @1);",
6.18 smapper.popI(), smapper.pushA(), typeName);
6.19 break;
6.20 }
6.21 @@ -947,26 +947,17 @@
6.22 i += 2;
6.23 String typeName = jc.getClassName(type);
6.24 int dim = readByte(byteCodes, ++i);
6.25 - out.append("{ var a0 = new Array(").append(smapper.popI())
6.26 - .append(").initWith('").append(typeName).append("', null);");
6.27 - for (int d = 1; d < dim; d++) {
6.28 - typeName = typeName.substring(1);
6.29 - out.append("\n var l" + d).append(" = ")
6.30 - .append(smapper.popI()).append(';');
6.31 - out.append("\n for (var i" + d).append (" = 0; i" + d).
6.32 - append(" < a" + (d - 1)).
6.33 - append(".length; i" + d).append("++) {");
6.34 - out.append("\n var a" + d).
6.35 - append (" = new Array(l" + d).append(").initWith('")
6.36 - .append(typeName).append("', ")
6.37 - .append(typeName.length() == 2 ? "0" : "null").append(");");
6.38 - out.append("\n a" + (d - 1)).append("[i" + d).append("] = a" + d).
6.39 - append(";");
6.40 + StringBuilder dims = new StringBuilder();
6.41 + dims.append('[');
6.42 + for (int d = 0; d < dim; d++) {
6.43 + if (d != 0) {
6.44 + dims.append(",");
6.45 + }
6.46 + dims.append(smapper.popI());
6.47 }
6.48 - for (int d = 1; d < dim; d++) {
6.49 - out.append("\n }");
6.50 - }
6.51 - out.append("\n").append(smapper.pushA()).append(" = a0; }");
6.52 + dims.append(']');
6.53 + emit(out, "@2 = Array.prototype.multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II('@3', @1, 0);",
6.54 + dims.toString(), smapper.pushA(), typeName);
6.55 break;
6.56 }
6.57 case opc_arraylength:
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionArrayTest.java Fri Jan 18 22:17:01 2013 +0100
7.3 @@ -0,0 +1,135 @@
7.4 +/**
7.5 + * Back 2 Browser Bytecode Translator
7.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
7.7 + *
7.8 + * This program is free software: you can redistribute it and/or modify
7.9 + * it under the terms of the GNU General Public License as published by
7.10 + * the Free Software Foundation, version 2 of the License.
7.11 + *
7.12 + * This program is distributed in the hope that it will be useful,
7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.15 + * GNU General Public License for more details.
7.16 + *
7.17 + * You should have received a copy of the GNU General Public License
7.18 + * along with this program. Look for COPYING file in the top folder.
7.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
7.20 + */
7.21 +package org.apidesign.bck2brwsr.tck;
7.22 +
7.23 +import java.lang.reflect.Array;
7.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
7.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
7.26 +import org.testng.annotations.Factory;
7.27 +
7.28 +/**
7.29 + *
7.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
7.31 + */
7.32 +public class ReflectionArrayTest {
7.33 + @Compare public int lengthOfStringArray() {
7.34 + String[] arr = (String[]) Array.newInstance(String.class, 10);
7.35 + return arr.length;
7.36 + }
7.37 +
7.38 + @Compare public int reflectiveLengthOfStringArray() {
7.39 + Object arr = Array.newInstance(String.class, 10);
7.40 + return Array.getLength(arr);
7.41 + }
7.42 +
7.43 + @Compare public int reflectiveLengthOneNonArray() {
7.44 + Object arr = "non-array";
7.45 + return Array.getLength(arr);
7.46 + }
7.47 +
7.48 + @Compare public String compTypeOfStringArray() {
7.49 + String[] arr = (String[]) Array.newInstance(String.class, 10);
7.50 + return arr.getClass().getComponentType().getName();
7.51 + }
7.52 +
7.53 + @Compare public Object negativeArrayExcp() {
7.54 + return Array.newInstance(String.class, -5);
7.55 + }
7.56 +
7.57 + @Compare public int lengthOfIntArray() {
7.58 + int[] arr = (int[]) Array.newInstance(Integer.TYPE, 10);
7.59 + return arr.length;
7.60 + }
7.61 +
7.62 + @Compare public int reflectiveLengthOfIntArray() {
7.63 + Object arr = Array.newInstance(Integer.TYPE, 10);
7.64 + return Array.getLength(arr);
7.65 + }
7.66 +
7.67 + @Compare public String compTypeOfIntArray() {
7.68 + int[] arr = (int[]) Array.newInstance(int.class, 10);
7.69 + return arr.getClass().getComponentType().getName();
7.70 + }
7.71 +
7.72 + @Compare public Object intNegativeArrayExcp() {
7.73 + return Array.newInstance(int.class, -5);
7.74 + }
7.75 +
7.76 + @Compare public Integer verifyAutobox() {
7.77 + int[] arr = (int[]) Array.newInstance(int.class, 5);
7.78 + return (Integer) Array.get(arr, 0);
7.79 + }
7.80 + @Compare public String verifyObjectArray() {
7.81 + String[] arr = (String[]) Array.newInstance(String.class, 5);
7.82 + Array.set(arr, 0, "Hello");
7.83 + return (String) Array.get(arr, 0);
7.84 + }
7.85 + @Compare public int verifyInt() {
7.86 + int[] arr = (int[]) Array.newInstance(int.class, 5);
7.87 + return Array.getInt(arr, 0);
7.88 + }
7.89 + @Compare public long verifyConvertToLong() {
7.90 + int[] arr = (int[]) Array.newInstance(int.class, 5);
7.91 + return Array.getLong(arr, 0);
7.92 + }
7.93 +
7.94 + @Compare public Object verifySetIntToObject() {
7.95 + try {
7.96 + Object[] arr = (Object[]) Array.newInstance(Object.class, 5);
7.97 + Array.setInt(arr, 0, 10);
7.98 + return Array.get(arr, 0);
7.99 + } catch (Exception exception) {
7.100 + return exception.getClass().getName();
7.101 + }
7.102 + }
7.103 + @Compare public long verifySetShort() {
7.104 + int[] arr = (int[]) Array.newInstance(int.class, 5);
7.105 + Array.setShort(arr, 0, (short)10);
7.106 + return Array.getLong(arr, 0);
7.107 + }
7.108 + @Compare public long verifyCantSetLong() {
7.109 + int[] arr = (int[]) Array.newInstance(int.class, 5);
7.110 + Array.setLong(arr, 0, 10);
7.111 + return Array.getLong(arr, 0);
7.112 + }
7.113 + @Compare public float verifyLongToFloat() {
7.114 + Object arr = Array.newInstance(float.class, 5);
7.115 + Array.setLong(arr, 0, 10);
7.116 + return Array.getFloat(arr, 0);
7.117 + }
7.118 +
7.119 + @Compare public double verifyConvertToDouble() {
7.120 + int[] arr = (int[]) Array.newInstance(int.class, 5);
7.121 + return Array.getDouble(arr, 0);
7.122 + }
7.123 +
7.124 + @Compare public int multiIntArray() {
7.125 + int[][][] arr = (int[][][]) Array.newInstance(int.class, 3, 3, 3);
7.126 + return arr[0][1][2] + 5 + arr[2][2][0];
7.127 + }
7.128 +
7.129 + @Compare public String multiIntArrayCompType() {
7.130 + return Array.newInstance(int.class, 3, 3, 3).getClass().getName();
7.131 + }
7.132 +
7.133 +
7.134 + @Factory
7.135 + public static Object[] create() {
7.136 + return VMTest.create(ReflectionArrayTest.class);
7.137 + }
7.138 +}