# HG changeset patch # User Jaroslav Tulach # Date 1348075745 -7200 # Node ID 282828609b8622ae297ec9ac3f1ccc442a51412f # Parent eca88b77b986ce8bd4aa1ff68deebbc3306af79c Support for invoking virtual methods diff -r eca88b77b986 -r 282828609b86 nb-configuration.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nb-configuration.xml Wed Sep 19 19:29:05 2012 +0200 @@ -0,0 +1,18 @@ + + + + + + all + + diff -r eca88b77b986 -r 282828609b86 src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java --- a/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Wed Sep 19 18:53:16 2012 +0200 +++ b/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Wed Sep 19 19:29:05 2012 +0200 @@ -71,7 +71,7 @@ out.append("() {"); for (Method m : jc.getMethods()) { if (!m.isStatic()) { - + compiler.generateMethodReference(m); } } for (Variable v : jc.getVariables()) { @@ -113,6 +113,13 @@ out.append("}"); } + private void generateMethodReference(Method m) throws IOException { + final String name = findMethodName(m); + out.append("\n this.").append(name).append(" = ") + .append(jc.getName().getExternalName().replace('.', '_')) + .append('_').append(name).append(";"); + } + private void generateInstanceMethod(Method m) throws IOException { out.append("\nfunction ").append( jc.getName().getExternalName().replace('.', '_') @@ -361,6 +368,9 @@ i += 2; break; } + case bc_invokevirtual: + i = invokeVirtualMethod(byteCodes, i); + break; case bc_invokespecial: i = invokeStaticMethod(byteCodes, i, false); break; @@ -561,4 +571,35 @@ i += 2; return i; } + private int invokeVirtualMethod(byte[] byteCodes, int i) + throws IOException { + int methodIndex = readIntArg(byteCodes, i); + CPMethodInfo mi = (CPMethodInfo) jc.getConstantPool().get(methodIndex); + boolean[] hasReturn = { false }; + int[] cnt = { 0 }; + String mn = findMethodName(mi, cnt, hasReturn); + out.append("{ "); + for (int j = cnt[0] - 1; j >= 0; j--) { + out.append("var v" + j).append(" = stack.pop(); "); + } + out.append("var self = stack.pop(); "); + if (hasReturn[0]) { + out.append("stack.push("); + } + out.append("self."); + out.append(mn); + out.append('('); + out.append("self"); + for (int j = 0; j < cnt[0]; j++) { + out.append(", "); + out.append("v" + j); + } + out.append(")"); + if (hasReturn[0]) { + out.append(")"); + } + out.append("; }"); + i += 2; + return i; + } } diff -r eca88b77b986 -r 282828609b86 src/test/java/org/apidesign/java4browser/Instance.java --- a/src/test/java/org/apidesign/java4browser/Instance.java Wed Sep 19 18:53:16 2012 +0200 +++ b/src/test/java/org/apidesign/java4browser/Instance.java Wed Sep 19 19:29:05 2012 +0200 @@ -42,4 +42,9 @@ i.b = (byte)0x09; return (i.i - i.b) * i.d; } + public static byte virtualBytes() { + Instance i = new Instance(); + i.setByte((byte)0x0a); + return i.getByte(); + } } diff -r eca88b77b986 -r 282828609b86 src/test/java/org/apidesign/java4browser/InstanceTest.java --- a/src/test/java/org/apidesign/java4browser/InstanceTest.java Wed Sep 19 18:53:16 2012 +0200 +++ b/src/test/java/org/apidesign/java4browser/InstanceTest.java Wed Sep 19 19:29:05 2012 +0200 @@ -35,6 +35,13 @@ Double.valueOf(3.3) ); } + @Test public void verifyInstanceMethods() throws Exception { + assertExec( + "Should be ten", + "org_apidesign_java4browser_Instance_virtualBytesB", + Double.valueOf(10) + ); + } private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception { StringBuilder sb = new StringBuilder();