# HG changeset patch # User Jaroslav Tulach # Date 1358246663 -3600 # Node ID 02efb6bda7de726be9b6a29169afa04cd49be2d3 # Parent ac05de5a87866f8067bebd28a38fef76815820c2# Parent 5aca91d003567ac4c8ea311baf59996240eb4922 Bringing arrays back to default branch diff -r ac05de5a8786 -r 02efb6bda7de emul/src/main/java/java/lang/Class.java --- a/emul/src/main/java/java/lang/Class.java Mon Jan 14 18:21:48 2013 +0100 +++ b/emul/src/main/java/java/lang/Class.java Tue Jan 15 11:44:23 2013 +0100 @@ -145,7 +145,15 @@ * @exception ClassNotFoundException if the class cannot be located */ public static Class forName(String className) - throws ClassNotFoundException { + throws ClassNotFoundException { + if (className.startsWith("[")) { + Class arrType = defineArray(className); + Class c = arrType; + while (c != null && c.isArray()) { + c = c.getComponentType0(); // verify component type is sane + } + return arrType; + } Class c = loadCls(className, className.replace('.', '_')); if (c == null) { throw new ClassNotFoundException(className); @@ -1010,9 +1018,59 @@ * @since JDK1.1 */ public Class getComponentType() { + if (isArray()) { + try { + return getComponentType0(); + } catch (ClassNotFoundException cnfe) { + throw new IllegalStateException(cnfe); + } + } return null; } + private Class getComponentType0() throws ClassNotFoundException { + String n = getName().substring(1); + switch (n.charAt(0)) { + case 'L': + n = n.substring(1, n.length() - 1); + return Class.forName(n); + case 'I': + return Integer.TYPE; + case 'J': + return Long.TYPE; + case 'D': + return Double.TYPE; + case 'F': + return Float.TYPE; + case 'B': + return Byte.TYPE; + case 'Z': + return Boolean.TYPE; + case 'S': + return Short.TYPE; + case 'V': + return Void.TYPE; + case 'C': + return Character.TYPE; + case '[': + return defineArray(n); + default: + throw new ClassNotFoundException("Unknown component type of " + getName()); + } + } + + @JavaScriptBody(args = { "sig" }, body = + "var c = Array[sig];\n" + + "if (c) return c;\n" + + "c = vm.java_lang_Class(true);\n" + + "c.jvmName = sig;\n" + + "c.superclass = vm.java_lang_Object(false).$class;\n" + + "c.array = true;\n" + + "Array[sig] = c;\n" + + "return c;" + ) + private static native Class defineArray(String sig); + /** * Returns true if and only if this class was declared as an enum in the * source code. diff -r ac05de5a8786 -r 02efb6bda7de emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js --- a/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Mon Jan 14 18:21:48 2013 +0100 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Tue Jan 15 11:44:23 2013 +0100 @@ -11,14 +11,7 @@ return this; }; Array.prototype.getClass__Ljava_lang_Class_2 = function() { - var c = Array[this.jvmName]; - if (c) return c; - c = vm.java_lang_Class(true); - c.jvmName = this.jvmName; - c.superclass = vm.java_lang_Object(false).$class; - c.array = true; - Array[this.jvmName] = c; - return c; + return vm.java_lang_Class(false).defineArray__Ljava_lang_Class_2Ljava_lang_String_2(this.jvmName); }; Array.prototype.clone__Ljava_lang_Object_2 = function() { var s = this.length; diff -r ac05de5a8786 -r 02efb6bda7de vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 14 18:21:48 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Jan 15 11:44:23 2013 +0100 @@ -945,13 +945,15 @@ out.append("{ var a0 = new Array(").append(smapper.popI()) .append(").fillNulls().arrtype('").append(typeName).append("');"); for (int d = 1; d < dim; d++) { + typeName = typeName.substring(1); out.append("\n var l" + d).append(" = ") .append(smapper.popI()).append(';'); out.append("\n for (var i" + d).append (" = 0; i" + d). append(" < a" + (d - 1)). append(".length; i" + d).append("++) {"); out.append("\n var a" + d). - append (" = new Array(l" + d).append(").fillNulls();"); + append (" = new Array(l" + d).append(").fillNulls().arrtype('") + .append(typeName).append("');"); out.append("\n a" + (d - 1)).append("[i" + d).append("] = a" + d). append(";"); } diff -r ac05de5a8786 -r 02efb6bda7de vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Mon Jan 14 18:21:48 2013 +0100 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Tue Jan 15 11:44:23 2013 +0100 @@ -21,6 +21,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apidesign.bck2brwsr.core.JavaScriptBody; import org.apidesign.bck2brwsr.vmtest.Compare; import org.apidesign.bck2brwsr.vmtest.VMTest; @@ -111,10 +113,61 @@ @Compare public String classGetNameForMultiIntArray() { return (new int[3][4][5][6][7][8][9]).getClass().getName(); } + @Compare public String classGetNameForMultiIntArrayInner() { + final int[][][][][][][] arr = new int[3][4][5][6][7][8][9]; + int[][][][][][] subarr = arr[0]; + int[][][][][] subsubarr = subarr[0]; + return subsubarr.getClass().getName(); + } @Compare public String classGetNameForMultiStringArray() { return (new String[3][4][5][6][7][8][9]).getClass().getName(); } + @Compare public String classForByte() throws Exception { + return Class.forName("[Z").getName(); + } + + @Compare public String classForUnknownArray() { + try { + return Class.forName("[W").getName(); + } catch (Exception ex) { + return ex.getClass().getName(); + } + } + + @Compare public String classForUnknownDeepArray() { + try { + return Class.forName("[[[[[W").getName(); + } catch (Exception ex) { + return ex.getClass().getName(); + } + } + + @Compare public String componentGetNameForObjectArray() { + return (new Object[3]).getClass().getComponentType().getName(); + } + @Compare public boolean sameComponentGetNameForObjectArray() { + return (new Object[3]).getClass().getComponentType() == Object.class; + } + @Compare public String componentGetNameForSimpleIntArray() { + return (new int[3]).getClass().getComponentType().getName(); + } + @Compare public String componentGetNameForMultiIntArray() { + return (new int[3][4][5][6][7][8][9]).getClass().getComponentType().getName(); + } + @Compare public String componentGetNameForMultiStringArray() { + Class c = (new String[3][4][5][6][7][8][9]).getClass(); + StringBuilder sb = new StringBuilder(); + for (;;) { + sb.append(c.getName()).append("\n"); + c = c.getComponentType(); + if (c == null) { + break; + } + } + return sb.toString(); + } + @Compare public boolean isArray() { return new Object[0].getClass().isArray(); }