# HG changeset patch # User Jaroslav Tulach # Date 1359043682 -3600 # Node ID 62c327a1e23fe5a227c1ecd0d624bd720ac3334d # Parent 62dd2c7944319f3dafe06a961322a1f8660b063f isInstance, casts and isAssignableFrom for arrays diff -r 62dd2c794431 -r 62c327a1e23f emul/src/main/java/java/lang/Class.java --- a/emul/src/main/java/java/lang/Class.java Thu Jan 24 00:11:04 2013 +0100 +++ b/emul/src/main/java/java/lang/Class.java Thu Jan 24 17:08:02 2013 +0100 @@ -278,6 +278,10 @@ * @since JDK1.1 */ public boolean isInstance(Object obj) { + if (isArray()) { + return isAssignableFrom(obj.getClass()); + } + String prop = "$instOf_" + getName().replace('.', '_'); return hasProperty(obj, prop); } @@ -312,7 +316,21 @@ * null. * @since JDK1.1 */ - public native boolean isAssignableFrom(Class cls); + public boolean isAssignableFrom(Class cls) { + if (this == cls) { + return true; + } + + if (isArray()) { + final Class cmpType = cls.getComponentType(); + if (isPrimitive()) { + return this == cmpType; + } + return cmpType != null && getComponentType().isAssignableFrom(cmpType); + } + String prop = "$instOf_" + getName().replace('.', '_'); + return hasProperty(cls, prop); + } /** diff -r 62dd2c794431 -r 62c327a1e23f emul/src/main/java/java/lang/reflect/Array.java --- a/emul/src/main/java/java/lang/reflect/Array.java Thu Jan 24 00:11:04 2013 +0100 +++ b/emul/src/main/java/java/lang/reflect/Array.java Thu Jan 24 17:08:02 2013 +0100 @@ -190,7 +190,7 @@ throws IllegalArgumentException, ArrayIndexOutOfBoundsException { final Class t = array.getClass().getComponentType(); if (t.isPrimitive()) { - return Array.fromPrimitive(t, array, index); + return fromPrimitive(t, array, index); } else { return ((Object[])array)[index]; } @@ -512,7 +512,7 @@ } } - + /** * Sets the value of the indexed component of the specified array * object to the specified {@code int} value. @@ -534,7 +534,7 @@ throws IllegalArgumentException, ArrayIndexOutOfBoundsException { Class t = array.getClass().getComponentType(); if (t == Integer.TYPE) { - long[] arr = (long[]) array; + int[] arr = (int[]) array; arr[index] = i; } else { setLong(array, index, i); @@ -643,10 +643,11 @@ if (dims.length == index + 1) { return newArray(sig.length() == 2, sig, dims[index]); } - Object[] arr = (Object[]) newArray(false, sig, dims[index]); + Object arr = newArray(false, sig, dims[index]); String compsig = sig.substring(1); - for (int i = 0; i < arr.length; i++) { - arr[i] = multiNewArray(compsig, dims, index + 1); + int len = getLength(arr); + for (int i = 0; i < len; i++) { + setArray(arr, i, multiNewArray(compsig, dims, index + 1)); } return arr; } @@ -654,6 +655,9 @@ return Method.fromPrimitive(t, atArray(array, index)); } - @JavaScriptBody(args = { "array", "index" }, body = "return array[index]") + @JavaScriptBody(args = { "array", "index" }, body = "return array[index];") private static native Object atArray(Object array, int index); + + @JavaScriptBody(args = { "array", "index", "v" }, body = "array[index] = v;") + private static native Object setArray(Object array, int index, Object v); } diff -r 62dd2c794431 -r 62c327a1e23f 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 Thu Jan 24 00:11:04 2013 +0100 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Thu Jan 24 17:08:02 2013 +0100 @@ -22,5 +22,6 @@ for (var i = 0; i < s; i++) { ret[i] = this[i]; } + ret.jvmName = this.jvmName; return ret; }; diff -r 62dd2c794431 -r 62c327a1e23f vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Jan 24 00:11:04 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Jan 24 17:08:02 2013 +0100 @@ -1106,11 +1106,13 @@ int indx = readIntArg(byteCodes, i); final String type = jc.getClassName(indx); if (!type.startsWith("[")) { - // no way to check arrays right now - // XXX proper exception emit(out, "if (@1 !== null && !@1.$instOf_@2) throw {};", smapper.getA(0), type.replace('/', '_')); + } else { + emit(out, "vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@2').cast__Ljava_lang_Object_2Ljava_lang_Object_2(@1);", + smapper.getA(0), type + ); } i += 2; break; @@ -1118,9 +1120,16 @@ case opc_instanceof: { int indx = readIntArg(byteCodes, i); final String type = jc.getClassName(indx); - emit(out, "var @2 = @1.$instOf_@3 ? 1 : 0;", - smapper.popA(), smapper.pushI(), - type.replace('/', '_')); + if (!type.startsWith("[")) { + emit(out, "var @2 = @1.$instOf_@3 ? 1 : 0;", + smapper.popA(), smapper.pushI(), + type.replace('/', '_')); + } else { + emit(out, "var @2 = vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@3').isInstance__ZLjava_lang_Object_2(@1);", + smapper.popA(), smapper.pushI(), + type + ); + } i += 2; break; } diff -r 62dd2c794431 -r 62c327a1e23f vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Thu Jan 24 00:11:04 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Thu Jan 24 17:08:02 2013 +0100 @@ -98,7 +98,7 @@ "try {\n" + " new Function(script)(loader, name);\n" + "} catch (ex) {\n" + - " throw 'Cannot compile ' + ex + ' line: ' + ex.lineNumber + ' script:\\n' + script;\n" + + " throw 'Cannot compile ' + name + ' ' + ex + ' line: ' + ex.lineNumber + ' script:\\n' + script;\n" + "}\n" + "return name != null ? vm[name](instance) : null;\n" ) diff -r 62dd2c794431 -r 62c327a1e23f vm/src/test/java/org/apidesign/vm4brwsr/Array.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/Array.java Thu Jan 24 00:11:04 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Array.java Thu Jan 24 17:08:02 2013 +0100 @@ -112,6 +112,10 @@ return Object[].class.getName(); } + public static boolean instanceOfArray(Object obj) { + return obj instanceof Object[]; + } + public static int sum(int size) { int[] arr = new int[size]; return arr[0] + arr[1]; diff -r 62dd2c794431 -r 62c327a1e23f vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java Thu Jan 24 00:11:04 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java Thu Jan 24 17:08:02 2013 +0100 @@ -72,6 +72,9 @@ @Test public void verifyObjectArrayClass() throws Exception { assertExec("Returns 'Object[]'", Array.class, "objectArrayClass__Ljava_lang_String_2", Array.objectArrayClass()); } + @Test public void verifyInstanceOfArray() throws Exception { + assertExec("Returns 'false'", Array.class, "instanceOfArray__ZLjava_lang_Object_2", Double.valueOf(0), "non-array"); + } private static CharSequence codeSeq; private static Invocable code;