rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
changeset 1242 c1097ab15f48
parent 1241 30a49f14dfc5
child 1243 c3e68a67d46d
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Jul 10 13:31:00 2013 +0200
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Thu Jul 11 20:33:19 2013 +0200
     1.3 @@ -1645,10 +1645,77 @@
     1.4              index++;
     1.5          }
     1.6          out.append(") {").append("\n");
     1.7 -        out.append(p.body);
     1.8 +        if (p.javacall) {
     1.9 +            int lastSlash = jc.getClassName().lastIndexOf('/');
    1.10 +            final String pkg = jc.getClassName().substring(0, lastSlash);
    1.11 +            out.append(mangleCallbacks(pkg, p.body));
    1.12 +            requireReference(pkg + "/$JsCallbacks$");
    1.13 +        } else {
    1.14 +            out.append(p.body);
    1.15 +        }
    1.16          out.append("\n}\n");
    1.17          return mn;
    1.18      }
    1.19 +    
    1.20 +    private static CharSequence mangleCallbacks(String pkgName, String body) {
    1.21 +        StringBuilder sb = new StringBuilder();
    1.22 +        int pos = 0;
    1.23 +        for (;;) {
    1.24 +            int next = body.indexOf(".@", pos);
    1.25 +            if (next == -1) {
    1.26 +                sb.append(body.substring(pos));
    1.27 +                return sb;
    1.28 +            }
    1.29 +            int ident = next;
    1.30 +            while (ident > 0) {
    1.31 +                if (!Character.isJavaIdentifierPart(body.charAt(--ident))) {
    1.32 +                    ident++;
    1.33 +                    break;
    1.34 +                }
    1.35 +            }
    1.36 +            String refId = body.substring(ident, next);
    1.37 +
    1.38 +            sb.append(body.substring(pos, ident));
    1.39 +
    1.40 +            int sigBeg = body.indexOf('(', next);
    1.41 +            int sigEnd = body.indexOf(')', sigBeg);
    1.42 +            int colon4 = body.indexOf("::", next);
    1.43 +            if (sigBeg == -1 || sigEnd == -1 || colon4 == -1) {
    1.44 +                throw new IllegalStateException("Malformed body " + body);
    1.45 +            }
    1.46 +            String fqn = body.substring(next + 2, colon4);
    1.47 +            String method = body.substring(colon4 + 2, sigBeg);
    1.48 +            String params = body.substring(sigBeg, sigEnd + 1);
    1.49 +
    1.50 +            int paramBeg = body.indexOf('(', sigEnd + 1);
    1.51 +            
    1.52 +            sb.append("vm.").append(pkgName.replace('/', '_')).append("_$JsCallbacks$(false)._VM().");
    1.53 +            sb.append(mangle(fqn, method, params));
    1.54 +            sb.append("(").append(refId);
    1.55 +            if (body.charAt(paramBeg + 1) != ')') {
    1.56 +                sb.append(",");
    1.57 +            }
    1.58 +            pos = paramBeg + 1;
    1.59 +        }
    1.60 +    }
    1.61 +    private static String mangle(String fqn, String method, String params) {
    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 +    }
    1.71 +
    1.72 +    private static String replace(String orig) {
    1.73 +        return orig.replace("_", "_1").
    1.74 +            replace(";", "_2").
    1.75 +            replace("[", "_3").
    1.76 +            replace('.', '_').replace('/', '_');
    1.77 +    }
    1.78 +    
    1.79      private static String className(ClassData jc) {
    1.80          //return jc.getName().getInternalName().replace('/', '_');
    1.81          return jc.getClassName().replace('/', '_');