More reflection for arrays. getClass() and isArray() work.
1.1 --- a/emul/src/main/java/java/lang/Class.java Mon Jan 14 11:52:38 2013 +0100
1.2 +++ b/emul/src/main/java/java/lang/Class.java Mon Jan 14 18:21:48 2013 +0100
1.3 @@ -330,7 +330,7 @@
1.4 * @since JDK1.1
1.5 */
1.6 public boolean isArray() {
1.7 - return false;
1.8 + return hasProperty(this, "array"); // NOI18N
1.9 }
1.10
1.11
2.1 --- a/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Mon Jan 14 11:52:38 2013 +0100
2.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Mon Jan 14 18:21:48 2013 +0100
2.3 @@ -6,6 +6,20 @@
2.4 for(var i = 0; i < this.length; i++) this[i] = null;
2.5 return this;
2.6 };
2.7 +Array.prototype.arrtype = function(sig) {
2.8 + this.jvmName = sig;
2.9 + return this;
2.10 +};
2.11 +Array.prototype.getClass__Ljava_lang_Class_2 = function() {
2.12 + var c = Array[this.jvmName];
2.13 + if (c) return c;
2.14 + c = vm.java_lang_Class(true);
2.15 + c.jvmName = this.jvmName;
2.16 + c.superclass = vm.java_lang_Object(false).$class;
2.17 + c.array = true;
2.18 + Array[this.jvmName] = c;
2.19 + return c;
2.20 +};
2.21 Array.prototype.clone__Ljava_lang_Object_2 = function() {
2.22 var s = this.length;
2.23 var ret = new Array(s);
3.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 14 11:52:38 2013 +0100
3.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 14 18:21:48 2013 +0100
3.3 @@ -908,20 +908,42 @@
3.4 break;
3.5 }
3.6 case opc_newarray:
3.7 - ++i; // skip type of array
3.8 - emit(out, "@2 = new Array(@1).fillNulls();",
3.9 - smapper.popI(), smapper.pushA());
3.10 + int atype = readByte(byteCodes, ++i);
3.11 + String jvmType;
3.12 + switch (atype) {
3.13 + case 4: jvmType = "[Z"; break;
3.14 + case 5: jvmType = "[C"; break;
3.15 + case 6: jvmType = "[F"; break;
3.16 + case 7: jvmType = "[D"; break;
3.17 + case 8: jvmType = "[B"; break;
3.18 + case 9: jvmType = "[S"; break;
3.19 + case 10: jvmType = "[I"; break;
3.20 + case 11: jvmType = "[J"; break;
3.21 + default: throw new IllegalStateException("Array type: " + atype);
3.22 + }
3.23 + emit(out, "@2 = new Array(@1).fillNulls().arrtype('@3');",
3.24 + smapper.popI(), smapper.pushA(), jvmType);
3.25 break;
3.26 - case opc_anewarray:
3.27 - i += 2; // skip type of array
3.28 - emit(out, "@2 = new Array(@1).fillNulls();",
3.29 - smapper.popI(), smapper.pushA());
3.30 + case opc_anewarray: {
3.31 + int type = readIntArg(byteCodes, i);
3.32 + i += 2;
3.33 + String typeName = jc.getClassName(type);
3.34 + if (typeName.startsWith("[")) {
3.35 + typeName = "[" + typeName;
3.36 + } else {
3.37 + typeName = "[L" + typeName + ";";
3.38 + }
3.39 + emit(out, "@2 = new Array(@1).fillNulls().arrtype('@3');",
3.40 + smapper.popI(), smapper.pushA(), typeName);
3.41 break;
3.42 + }
3.43 case opc_multianewarray: {
3.44 + int type = readIntArg(byteCodes, i);
3.45 i += 2;
3.46 + String typeName = jc.getClassName(type);
3.47 int dim = readByte(byteCodes, ++i);
3.48 out.append("{ var a0 = new Array(").append(smapper.popI())
3.49 - .append(").fillNulls();");
3.50 + .append(").fillNulls().arrtype('").append(typeName).append("');");
3.51 for (int d = 1; d < dim; d++) {
3.52 out.append("\n var l" + d).append(" = ")
3.53 .append(smapper.popI()).append(';');
4.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Mon Jan 14 11:52:38 2013 +0100
4.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Mon Jan 14 18:21:48 2013 +0100
4.3 @@ -90,6 +90,35 @@
4.4 return (Integer)plus.invoke(null, 2, 3);
4.5 }
4.6
4.7 + @Compare public String classGetNameForByte() {
4.8 + return byte.class.getName();
4.9 + }
4.10 + @Compare public String classGetNameForBaseObject() {
4.11 + return newObject().getClass().getName();
4.12 + }
4.13 + @Compare public String classGetNameForJavaObject() {
4.14 + return new Object().getClass().getName();
4.15 + }
4.16 + @Compare public String classGetNameForObjectArray() {
4.17 + return (new Object[3]).getClass().getName();
4.18 + }
4.19 + @Compare public String classGetNameForSimpleIntArray() {
4.20 + return (new int[3]).getClass().getName();
4.21 + }
4.22 + @Compare public boolean sameClassGetNameForSimpleCharArray() {
4.23 + return (new char[3]).getClass() == (new char[34]).getClass();
4.24 + }
4.25 + @Compare public String classGetNameForMultiIntArray() {
4.26 + return (new int[3][4][5][6][7][8][9]).getClass().getName();
4.27 + }
4.28 + @Compare public String classGetNameForMultiStringArray() {
4.29 + return (new String[3][4][5][6][7][8][9]).getClass().getName();
4.30 + }
4.31 +
4.32 + @Compare public boolean isArray() {
4.33 + return new Object[0].getClass().isArray();
4.34 + }
4.35 +
4.36 @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;")
4.37 private static String[] sort(String[] arr, int len) {
4.38 List<String> list = Arrays.asList(arr).subList(0, len);
4.39 @@ -97,6 +126,11 @@
4.40 return list.toArray(new String[0]);
4.41 }
4.42
4.43 + @JavaScriptBody(args = {}, body = "return new Object();")
4.44 + private static Object newObject() {
4.45 + return new Object();
4.46 + }
4.47 +
4.48 @Factory
4.49 public static Object[] create() {
4.50 return VMTest.create(ReflectionTest.class);