1.1 --- a/emul/src/main/java/java/lang/Class.java Mon Jan 14 18:21:48 2013 +0100
1.2 +++ b/emul/src/main/java/java/lang/Class.java Tue Jan 15 11:44:23 2013 +0100
1.3 @@ -145,7 +145,15 @@
1.4 * @exception ClassNotFoundException if the class cannot be located
1.5 */
1.6 public static Class<?> forName(String className)
1.7 - throws ClassNotFoundException {
1.8 + throws ClassNotFoundException {
1.9 + if (className.startsWith("[")) {
1.10 + Class<?> arrType = defineArray(className);
1.11 + Class<?> c = arrType;
1.12 + while (c != null && c.isArray()) {
1.13 + c = c.getComponentType0(); // verify component type is sane
1.14 + }
1.15 + return arrType;
1.16 + }
1.17 Class<?> c = loadCls(className, className.replace('.', '_'));
1.18 if (c == null) {
1.19 throw new ClassNotFoundException(className);
1.20 @@ -1010,9 +1018,59 @@
1.21 * @since JDK1.1
1.22 */
1.23 public Class<?> getComponentType() {
1.24 + if (isArray()) {
1.25 + try {
1.26 + return getComponentType0();
1.27 + } catch (ClassNotFoundException cnfe) {
1.28 + throw new IllegalStateException(cnfe);
1.29 + }
1.30 + }
1.31 return null;
1.32 }
1.33
1.34 + private Class<?> getComponentType0() throws ClassNotFoundException {
1.35 + String n = getName().substring(1);
1.36 + switch (n.charAt(0)) {
1.37 + case 'L':
1.38 + n = n.substring(1, n.length() - 1);
1.39 + return Class.forName(n);
1.40 + case 'I':
1.41 + return Integer.TYPE;
1.42 + case 'J':
1.43 + return Long.TYPE;
1.44 + case 'D':
1.45 + return Double.TYPE;
1.46 + case 'F':
1.47 + return Float.TYPE;
1.48 + case 'B':
1.49 + return Byte.TYPE;
1.50 + case 'Z':
1.51 + return Boolean.TYPE;
1.52 + case 'S':
1.53 + return Short.TYPE;
1.54 + case 'V':
1.55 + return Void.TYPE;
1.56 + case 'C':
1.57 + return Character.TYPE;
1.58 + case '[':
1.59 + return defineArray(n);
1.60 + default:
1.61 + throw new ClassNotFoundException("Unknown component type of " + getName());
1.62 + }
1.63 + }
1.64 +
1.65 + @JavaScriptBody(args = { "sig" }, body =
1.66 + "var c = Array[sig];\n" +
1.67 + "if (c) return c;\n" +
1.68 + "c = vm.java_lang_Class(true);\n" +
1.69 + "c.jvmName = sig;\n" +
1.70 + "c.superclass = vm.java_lang_Object(false).$class;\n" +
1.71 + "c.array = true;\n" +
1.72 + "Array[sig] = c;\n" +
1.73 + "return c;"
1.74 + )
1.75 + private static native Class<?> defineArray(String sig);
1.76 +
1.77 /**
1.78 * Returns true if and only if this class was declared as an enum in the
1.79 * source code.
2.1 --- a/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Mon Jan 14 18:21:48 2013 +0100
2.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Tue Jan 15 11:44:23 2013 +0100
2.3 @@ -11,14 +11,7 @@
2.4 return this;
2.5 };
2.6 Array.prototype.getClass__Ljava_lang_Class_2 = function() {
2.7 - var c = Array[this.jvmName];
2.8 - if (c) return c;
2.9 - c = vm.java_lang_Class(true);
2.10 - c.jvmName = this.jvmName;
2.11 - c.superclass = vm.java_lang_Object(false).$class;
2.12 - c.array = true;
2.13 - Array[this.jvmName] = c;
2.14 - return c;
2.15 + return vm.java_lang_Class(false).defineArray__Ljava_lang_Class_2Ljava_lang_String_2(this.jvmName);
2.16 };
2.17 Array.prototype.clone__Ljava_lang_Object_2 = function() {
2.18 var s = this.length;
3.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 14 18:21:48 2013 +0100
3.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Jan 15 11:44:23 2013 +0100
3.3 @@ -945,13 +945,15 @@
3.4 out.append("{ var a0 = new Array(").append(smapper.popI())
3.5 .append(").fillNulls().arrtype('").append(typeName).append("');");
3.6 for (int d = 1; d < dim; d++) {
3.7 + typeName = typeName.substring(1);
3.8 out.append("\n var l" + d).append(" = ")
3.9 .append(smapper.popI()).append(';');
3.10 out.append("\n for (var i" + d).append (" = 0; i" + d).
3.11 append(" < a" + (d - 1)).
3.12 append(".length; i" + d).append("++) {");
3.13 out.append("\n var a" + d).
3.14 - append (" = new Array(l" + d).append(").fillNulls();");
3.15 + append (" = new Array(l" + d).append(").fillNulls().arrtype('")
3.16 + .append(typeName).append("');");
3.17 out.append("\n a" + (d - 1)).append("[i" + d).append("] = a" + d).
3.18 append(";");
3.19 }
4.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Mon Jan 14 18:21:48 2013 +0100
4.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Tue Jan 15 11:44:23 2013 +0100
4.3 @@ -21,6 +21,8 @@
4.4 import java.util.Arrays;
4.5 import java.util.Collections;
4.6 import java.util.List;
4.7 +import java.util.logging.Level;
4.8 +import java.util.logging.Logger;
4.9 import org.apidesign.bck2brwsr.core.JavaScriptBody;
4.10 import org.apidesign.bck2brwsr.vmtest.Compare;
4.11 import org.apidesign.bck2brwsr.vmtest.VMTest;
4.12 @@ -111,10 +113,61 @@
4.13 @Compare public String classGetNameForMultiIntArray() {
4.14 return (new int[3][4][5][6][7][8][9]).getClass().getName();
4.15 }
4.16 + @Compare public String classGetNameForMultiIntArrayInner() {
4.17 + final int[][][][][][][] arr = new int[3][4][5][6][7][8][9];
4.18 + int[][][][][][] subarr = arr[0];
4.19 + int[][][][][] subsubarr = subarr[0];
4.20 + return subsubarr.getClass().getName();
4.21 + }
4.22 @Compare public String classGetNameForMultiStringArray() {
4.23 return (new String[3][4][5][6][7][8][9]).getClass().getName();
4.24 }
4.25
4.26 + @Compare public String classForByte() throws Exception {
4.27 + return Class.forName("[Z").getName();
4.28 + }
4.29 +
4.30 + @Compare public String classForUnknownArray() {
4.31 + try {
4.32 + return Class.forName("[W").getName();
4.33 + } catch (Exception ex) {
4.34 + return ex.getClass().getName();
4.35 + }
4.36 + }
4.37 +
4.38 + @Compare public String classForUnknownDeepArray() {
4.39 + try {
4.40 + return Class.forName("[[[[[W").getName();
4.41 + } catch (Exception ex) {
4.42 + return ex.getClass().getName();
4.43 + }
4.44 + }
4.45 +
4.46 + @Compare public String componentGetNameForObjectArray() {
4.47 + return (new Object[3]).getClass().getComponentType().getName();
4.48 + }
4.49 + @Compare public boolean sameComponentGetNameForObjectArray() {
4.50 + return (new Object[3]).getClass().getComponentType() == Object.class;
4.51 + }
4.52 + @Compare public String componentGetNameForSimpleIntArray() {
4.53 + return (new int[3]).getClass().getComponentType().getName();
4.54 + }
4.55 + @Compare public String componentGetNameForMultiIntArray() {
4.56 + return (new int[3][4][5][6][7][8][9]).getClass().getComponentType().getName();
4.57 + }
4.58 + @Compare public String componentGetNameForMultiStringArray() {
4.59 + Class<?> c = (new String[3][4][5][6][7][8][9]).getClass();
4.60 + StringBuilder sb = new StringBuilder();
4.61 + for (;;) {
4.62 + sb.append(c.getName()).append("\n");
4.63 + c = c.getComponentType();
4.64 + if (c == null) {
4.65 + break;
4.66 + }
4.67 + }
4.68 + return sb.toString();
4.69 + }
4.70 +
4.71 @Compare public boolean isArray() {
4.72 return new Object[0].getClass().isArray();
4.73 }