Recognizes callback to static Java methods
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 11 Jul 2013 22:36:01 +0200
changeset 1243c3e68a67d46d
parent 1242 c1097ab15f48
child 1244 4b43ab1f72e8
Recognizes callback to static Java methods
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
rt/vm/src/test/java/org/apidesign/vm4brwsr/HtmlAnnotations.java
rt/vm/src/test/java/org/apidesign/vm4brwsr/HtmlAnnotationsTest.java
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Thu Jul 11 20:33:19 2013 +0200
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Thu Jul 11 22:36:01 2013 +0200
     1.3 @@ -1664,7 +1664,8 @@
     1.4              int next = body.indexOf(".@", pos);
     1.5              if (next == -1) {
     1.6                  sb.append(body.substring(pos));
     1.7 -                return sb;
     1.8 +                body = sb.toString();
     1.9 +                break;
    1.10              }
    1.11              int ident = next;
    1.12              while (ident > 0) {
    1.13 @@ -1690,23 +1691,63 @@
    1.14              int paramBeg = body.indexOf('(', sigEnd + 1);
    1.15              
    1.16              sb.append("vm.").append(pkgName.replace('/', '_')).append("_$JsCallbacks$(false)._VM().");
    1.17 -            sb.append(mangle(fqn, method, params));
    1.18 +            sb.append(mangle(fqn, method, params, false));
    1.19              sb.append("(").append(refId);
    1.20              if (body.charAt(paramBeg + 1) != ')') {
    1.21                  sb.append(",");
    1.22              }
    1.23              pos = paramBeg + 1;
    1.24          }
    1.25 +        sb = null;
    1.26 +        pos = 0;
    1.27 +        for (;;) {
    1.28 +            int next = body.indexOf("@", pos);
    1.29 +            if (next == -1) {
    1.30 +                if (sb == null) {
    1.31 +                    return body;
    1.32 +                }
    1.33 +                sb.append(body.substring(pos));
    1.34 +                return sb;
    1.35 +            }
    1.36 +            if (sb == null) {
    1.37 +                sb = new StringBuilder();
    1.38 +            }
    1.39 +
    1.40 +            sb.append(body.substring(pos, next));
    1.41 +
    1.42 +            int sigBeg = body.indexOf('(', next);
    1.43 +            int sigEnd = body.indexOf(')', sigBeg);
    1.44 +            int colon4 = body.indexOf("::", next);
    1.45 +            if (sigBeg == -1 || sigEnd == -1 || colon4 == -1) {
    1.46 +                throw new IllegalStateException("Malformed body " + body);
    1.47 +            }
    1.48 +            String fqn = body.substring(next + 1, colon4);
    1.49 +            String method = body.substring(colon4 + 2, sigBeg);
    1.50 +            String params = body.substring(sigBeg, sigEnd + 1);
    1.51 +
    1.52 +            int paramBeg = body.indexOf('(', sigEnd + 1);
    1.53 +            
    1.54 +            sb.append("vm.").append(pkgName.replace('/', '_')).append("_$JsCallbacks$(false)._VM().");
    1.55 +            sb.append(mangle(fqn, method, params, true));
    1.56 +            sb.append("(");
    1.57 +            pos = paramBeg + 1;
    1.58 +        }
    1.59      }
    1.60 -    private static String mangle(String fqn, String method, String params) {
    1.61 +    private static String mangle(String fqn, String method, String params, boolean isStatic) {
    1.62          if (params.startsWith("(")) {
    1.63              params = params.substring(1);
    1.64          }
    1.65          if (params.endsWith(")")) {
    1.66              params = params.substring(0, params.length() - 1);
    1.67          }
    1.68 -        return replace(fqn) + "__" + replace(method) + "____Ljava_lang_Object_2L" + 
    1.69 -            replace(fqn) + "_2" + replace(params);
    1.70 +        StringBuilder sb = new StringBuilder();
    1.71 +        final String rfqn = replace(fqn);
    1.72 +        sb.append(rfqn).append("__").append(method).append("____Ljava_lang_Object_2");
    1.73 +        if (!isStatic) {
    1.74 +            sb.append('L').append(rfqn).append("_2");
    1.75 +        }
    1.76 +        sb.append(params);
    1.77 +        return sb.toString();
    1.78      }
    1.79  
    1.80      private static String replace(String orig) {
     2.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/HtmlAnnotations.java	Thu Jul 11 20:33:19 2013 +0200
     2.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/HtmlAnnotations.java	Thu Jul 11 22:36:01 2013 +0200
     2.3 @@ -47,5 +47,7 @@
     2.4      
     2.5      @JavaScriptBody(args = { "r" }, javacall=true, body = "r.@java.lang.Runnable::run()()")
     2.6      private static native void callback(Runnable r);
     2.7 -    
     2.8 +
     2.9 +    @JavaScriptBody(args = {  }, javacall = true, body = "return @org.apidesign.vm4brwsr.HtmlAnnotations::callback()();")
    2.10 +    private static native int staticCallback();
    2.11  }
     3.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/HtmlAnnotationsTest.java	Thu Jul 11 20:33:19 2013 +0200
     3.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/HtmlAnnotationsTest.java	Thu Jul 11 22:36:01 2013 +0200
     3.3 @@ -47,6 +47,13 @@
     3.4              Double.valueOf(1)
     3.5          );
     3.6      }
     3.7 +
     3.8 +    @Test public void callStaticMethodFromJS() throws Exception {
     3.9 +        assertExec("runnable called", HtmlAnnotations.class, 
    3.10 +            "staticCallback__I",
    3.11 +            Double.valueOf(1)
    3.12 +        );
    3.13 +    }
    3.14      
    3.15      private static TestVM code;
    3.16