# HG changeset patch # User Jaroslav Tulach # Date 1355931817 -3600 # Node ID 002b7c3d5157253a41379d0f23571eec4ec4ff8a # Parent fd38bdad7fb556270d5e4c2770f3df8cfa1040db Reflective calls on methods that return int diff -r fd38bdad7fb5 -r 002b7c3d5157 emul/src/main/java/java/lang/Class.java --- a/emul/src/main/java/java/lang/Class.java Tue Dec 18 16:04:37 2012 +0100 +++ b/emul/src/main/java/java/lang/Class.java Wed Dec 19 16:43:37 2012 +0100 @@ -330,6 +330,10 @@ * @see java.lang.Void#TYPE * @since JDK1.1 */ + @JavaScriptBody(args = "self", body = + "if (self.primitive) return true;" + + "else return false;" + ) public native boolean isPrimitive(); /** @@ -1093,6 +1097,7 @@ @JavaScriptBody(args = "type", body = "" + "var c = vm.java_lang_Class(true);" + "c.jvmName = type;" + + "c.primitive = true;" + "return c;" ) native static Class getPrimitiveClass(String type); diff -r fd38bdad7fb5 -r 002b7c3d5157 emul/src/main/java/java/lang/reflect/Method.java --- a/emul/src/main/java/java/lang/reflect/Method.java Tue Dec 18 16:04:37 2012 +0100 +++ b/emul/src/main/java/java/lang/reflect/Method.java Wed Dec 19 16:43:37 2012 +0100 @@ -137,7 +137,24 @@ * @return the return type for the method this object represents */ public Class getReturnType() { - throw new UnsupportedOperationException(); + switch (sig.charAt(0)) { + 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 'L': try { + int up = sig.indexOf("_2"); + String type = sig.substring(1, up); + return Class.forName(type); + } catch (ClassNotFoundException ex) { + // should not happen + } + } + throw new UnsupportedOperationException(sig); } /** @@ -488,17 +505,33 @@ * @exception ExceptionInInitializerError if the initialization * provoked by this method fails. */ + public Object invoke(Object obj, Object... args) + throws IllegalAccessException, IllegalArgumentException, + InvocationTargetException + { + Object res = invoke0(this, obj, args); + if (getReturnType().isPrimitive()) { + res = fromPrimitive(getReturnType(), res); + } + return res; + } + @JavaScriptBody(args = { "method", "self", "args" }, body = "if (args.length > 0) throw 'unsupported now';" + "return method.fld_data(self);" ) - public Object invoke(Object obj, Object... args) - throws IllegalAccessException, IllegalArgumentException, - InvocationTargetException - { - throw new UnsupportedOperationException(); + private static native Object invoke0(Method m, Object self, Object[] args); + + private static Object fromPrimitive(Class type, Object o) { + if (type == Integer.TYPE) { + return fromInteger(o); + } + return o; } - + + @JavaScriptBody(args = "o", body = "return vm.java_lang_Integer(false).valueOf__Ljava_lang_Integer_2I(o);") + private static native Integer fromInteger(Object o); + /** * Returns {@code true} if this method is a bridge * method; returns {@code false} otherwise. diff -r fd38bdad7fb5 -r 002b7c3d5157 vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Tue Dec 18 16:04:37 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Wed Dec 19 16:43:37 2012 +0100 @@ -101,6 +101,12 @@ "java.io.IOException", false, "name" ); } + @Test public void primitiveReturnType() throws Exception { + assertExec("Tries to get an integer via reflection", Classes.class, + "primitiveType__Ljava_lang_String_2", + Classes.primitiveType() + ); + } @Test public void javaAnnotatedMethod() throws Exception { assertEquals(Classes.reflectiveMethodCall(false, null), "java.io.IOException", "Calls the name() method via reflection"); } diff -r fd38bdad7fb5 -r 002b7c3d5157 vm/src/test/java/org/apidesign/vm4brwsr/Classes.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Tue Dec 18 16:04:37 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Wed Dec 19 16:43:37 2012 +0100 @@ -92,6 +92,14 @@ return Integer.TYPE.getName(); } + public static int primitive() { + return 1; + } + + public static String primitiveType() throws Exception { + return reflectiveMethodCall(false, "primitive").getClass().getName(); + } + @JavaScriptBody(args = "msg", body = "throw msg;") private static native void thrw(String msg);