# HG changeset patch # User Jaroslav Tulach # Date 1358184108 -3600 # Node ID ac05de5a87866f8067bebd28a38fef76815820c2 # Parent d49769e4f783cdfa8872838620876fc7f6b88d74 More reflection for arrays. getClass() and isArray() work. diff -r d49769e4f783 -r ac05de5a8786 emul/src/main/java/java/lang/Class.java --- a/emul/src/main/java/java/lang/Class.java Mon Jan 14 11:52:38 2013 +0100 +++ b/emul/src/main/java/java/lang/Class.java Mon Jan 14 18:21:48 2013 +0100 @@ -330,7 +330,7 @@ * @since JDK1.1 */ public boolean isArray() { - return false; + return hasProperty(this, "array"); // NOI18N } diff -r d49769e4f783 -r ac05de5a8786 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 11:52:38 2013 +0100 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Mon Jan 14 18:21:48 2013 +0100 @@ -6,6 +6,20 @@ for(var i = 0; i < this.length; i++) this[i] = null; return this; }; +Array.prototype.arrtype = function(sig) { + this.jvmName = sig; + 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; +}; Array.prototype.clone__Ljava_lang_Object_2 = function() { var s = this.length; var ret = new Array(s); diff -r d49769e4f783 -r ac05de5a8786 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 14 11:52:38 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 14 18:21:48 2013 +0100 @@ -908,20 +908,42 @@ break; } case opc_newarray: - ++i; // skip type of array - emit(out, "@2 = new Array(@1).fillNulls();", - smapper.popI(), smapper.pushA()); + int atype = readByte(byteCodes, ++i); + String jvmType; + switch (atype) { + case 4: jvmType = "[Z"; break; + case 5: jvmType = "[C"; break; + case 6: jvmType = "[F"; break; + case 7: jvmType = "[D"; break; + case 8: jvmType = "[B"; break; + case 9: jvmType = "[S"; break; + case 10: jvmType = "[I"; break; + case 11: jvmType = "[J"; break; + default: throw new IllegalStateException("Array type: " + atype); + } + emit(out, "@2 = new Array(@1).fillNulls().arrtype('@3');", + smapper.popI(), smapper.pushA(), jvmType); break; - case opc_anewarray: - i += 2; // skip type of array - emit(out, "@2 = new Array(@1).fillNulls();", - smapper.popI(), smapper.pushA()); + case opc_anewarray: { + int type = readIntArg(byteCodes, i); + i += 2; + String typeName = jc.getClassName(type); + if (typeName.startsWith("[")) { + typeName = "[" + typeName; + } else { + typeName = "[L" + typeName + ";"; + } + emit(out, "@2 = new Array(@1).fillNulls().arrtype('@3');", + smapper.popI(), smapper.pushA(), typeName); break; + } case opc_multianewarray: { + int type = readIntArg(byteCodes, i); i += 2; + String typeName = jc.getClassName(type); int dim = readByte(byteCodes, ++i); out.append("{ var a0 = new Array(").append(smapper.popI()) - .append(").fillNulls();"); + .append(").fillNulls().arrtype('").append(typeName).append("');"); for (int d = 1; d < dim; d++) { out.append("\n var l" + d).append(" = ") .append(smapper.popI()).append(';'); diff -r d49769e4f783 -r ac05de5a8786 vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Mon Jan 14 11:52:38 2013 +0100 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Mon Jan 14 18:21:48 2013 +0100 @@ -90,6 +90,35 @@ return (Integer)plus.invoke(null, 2, 3); } + @Compare public String classGetNameForByte() { + return byte.class.getName(); + } + @Compare public String classGetNameForBaseObject() { + return newObject().getClass().getName(); + } + @Compare public String classGetNameForJavaObject() { + return new Object().getClass().getName(); + } + @Compare public String classGetNameForObjectArray() { + return (new Object[3]).getClass().getName(); + } + @Compare public String classGetNameForSimpleIntArray() { + return (new int[3]).getClass().getName(); + } + @Compare public boolean sameClassGetNameForSimpleCharArray() { + return (new char[3]).getClass() == (new char[34]).getClass(); + } + @Compare public String classGetNameForMultiIntArray() { + return (new int[3][4][5][6][7][8][9]).getClass().getName(); + } + @Compare public String classGetNameForMultiStringArray() { + return (new String[3][4][5][6][7][8][9]).getClass().getName(); + } + + @Compare public boolean isArray() { + return new Object[0].getClass().isArray(); + } + @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;") private static String[] sort(String[] arr, int len) { List list = Arrays.asList(arr).subList(0, len); @@ -97,6 +126,11 @@ return list.toArray(new String[0]); } + @JavaScriptBody(args = {}, body = "return new Object();") + private static Object newObject() { + return new Object(); + } + @Factory public static Object[] create() { return VMTest.create(ReflectionTest.class);