rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
changeset 883 8c14a9f0c232
parent 864 8ece59d31fcf
parent 880 32eb44c74e1e
child 962 787578f33c21
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Mar 20 21:24:36 2013 +0100
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Mon Mar 25 13:33:03 2013 +0100
     1.3 @@ -28,9 +28,16 @@
     1.4  abstract class ByteCodeToJavaScript {
     1.5      private ClassData jc;
     1.6      final Appendable out;
     1.7 +    final ObfuscationDelegate obfuscationDelegate;
     1.8  
     1.9      protected ByteCodeToJavaScript(Appendable out) {
    1.10 +        this(out, ObfuscationDelegate.NULL);
    1.11 +    }
    1.12 +
    1.13 +    protected ByteCodeToJavaScript(
    1.14 +            Appendable out, ObfuscationDelegate obfuscationDelegate) {
    1.15          this.out = out;
    1.16 +        this.obfuscationDelegate = obfuscationDelegate;
    1.17      }
    1.18      
    1.19      /* Collects additional required resources.
    1.20 @@ -58,7 +65,9 @@
    1.21      /* protected */ String accessClass(String classOperation) {
    1.22          return classOperation;
    1.23      }
    1.24 -    
    1.25 +
    1.26 +    abstract String getVMObject();
    1.27 +
    1.28      /** Prints out a debug message. 
    1.29       * 
    1.30       * @param msg the message
    1.31 @@ -92,7 +101,9 @@
    1.32              "resource", "processByteCode"
    1.33          );
    1.34          if (arr != null) {
    1.35 -            requireScript(arr[0]);
    1.36 +            if (!arr[0].isEmpty()) {
    1.37 +                requireScript(arr[0]);
    1.38 +            }
    1.39              if ("0".equals(arr[1])) {
    1.40                  return null;
    1.41              }
    1.42 @@ -104,7 +115,8 @@
    1.43          StringArray toInitilize = new StringArray();
    1.44          final String className = className(jc);
    1.45          out.append("\n\n").append(assignClass(className));
    1.46 -        out.append("function CLS() {");
    1.47 +        out.append("function ").append(className).append("() {");
    1.48 +        out.append("\n  var CLS = ").append(className).append(';');
    1.49          out.append("\n  if (!CLS.$class) {");
    1.50          if (proto == null) {
    1.51              String sc = jc.getSuperClassName(); // with _
    1.52 @@ -136,6 +148,8 @@
    1.53                      append(className).append('_').append(v.getName())
    1.54                     .append("; };");
    1.55              }
    1.56 +
    1.57 +            obfuscationDelegate.exportField(out, "c", "_" + v.getName(), v);
    1.58          }
    1.59          for (MethodData m : jc.getMethods()) {
    1.60              byte[] onlyArr = m.findAnnotationData(true);
    1.61 @@ -150,33 +164,39 @@
    1.62                  }
    1.63                  continue;
    1.64              }
    1.65 -            String prefix;
    1.66 +            String destObject;
    1.67              String mn;
    1.68 +            out.append("\n    ");
    1.69              if (m.isStatic()) {
    1.70 -                prefix = "\n    c.";
    1.71 -                mn = generateStaticMethod(prefix, m, toInitilize);
    1.72 +                destObject = "c";
    1.73 +                mn = generateStaticMethod(destObject, m, toInitilize);
    1.74              } else {
    1.75                  if (m.isConstructor()) {
    1.76 -                    prefix = "\n    CLS.";
    1.77 -                    mn = generateInstanceMethod(prefix, m);
    1.78 +                    destObject = "CLS";
    1.79 +                    mn = generateInstanceMethod(destObject, m);
    1.80                  } else {
    1.81 -                    prefix = "\n    c.";
    1.82 -                    mn = generateInstanceMethod(prefix, m);
    1.83 +                    destObject = "c";
    1.84 +                    mn = generateInstanceMethod(destObject, m);
    1.85                  }
    1.86              }
    1.87 +            obfuscationDelegate.exportMethod(out, destObject, mn, m);
    1.88              byte[] runAnno = m.findAnnotationData(false);
    1.89              if (runAnno != null) {
    1.90 -                out.append(prefix).append(mn).append(".anno = {");
    1.91 +                out.append("\n    ").append(destObject).append(".").append(mn).append(".anno = {");
    1.92                  generateAnno(jc, out, runAnno);
    1.93                  out.append("\n    };");
    1.94              }
    1.95 -            out.append(prefix).append(mn).append(".access = " + m.getAccess()).append(";");
    1.96 -            out.append(prefix).append(mn).append(".cls = CLS;");
    1.97 +            out.append("\n    ").append(destObject).append(".").append(mn).append(".access = " + m.getAccess()).append(";");
    1.98 +            out.append("\n    ").append(destObject).append(".").append(mn).append(".cls = CLS;");
    1.99          }
   1.100          out.append("\n    c.constructor = CLS;");
   1.101 -        out.append("\n    c.$instOf_").append(className).append(" = true;");
   1.102 +        String instOfName = "$instOf_" + className;
   1.103 +        out.append("\n    c.").append(instOfName).append(" = true;");
   1.104 +        obfuscationDelegate.exportJSProperty(out, "c", instOfName);
   1.105          for (String superInterface : jc.getSuperInterfaces()) {
   1.106 -            out.append("\n    c.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
   1.107 +            instOfName = "$instOf_" + superInterface.replace('/', '_');
   1.108 +            out.append("\n    c.").append(instOfName).append(" = true;");
   1.109 +            obfuscationDelegate.exportJSProperty(out, "c", instOfName);
   1.110          }
   1.111          out.append("\n    CLS.$class = 'temp';");
   1.112          out.append("\n    CLS.$class = ");
   1.113 @@ -222,14 +242,17 @@
   1.114          out.append("\n  }");
   1.115          out.append("\n  return arguments[0] ? new CLS() : CLS.prototype;");
   1.116          out.append("\n};");
   1.117 +
   1.118 +        obfuscationDelegate.exportClass(out, getVMObject(), className, jc);
   1.119 +
   1.120  //        StringBuilder sb = new StringBuilder();
   1.121  //        for (String init : toInitilize.toArray()) {
   1.122  //            sb.append("\n").append(init).append("();");
   1.123  //        }
   1.124          return "";
   1.125      }
   1.126 -    private String generateStaticMethod(String prefix, MethodData m, StringArray toInitilize) throws IOException {
   1.127 -        String jsb = javaScriptBody(prefix, m, true);
   1.128 +    private String generateStaticMethod(String destObject, MethodData m, StringArray toInitilize) throws IOException {
   1.129 +        String jsb = javaScriptBody(destObject, m, true);
   1.130          if (jsb != null) {
   1.131              return jsb;
   1.132          }
   1.133 @@ -237,28 +260,28 @@
   1.134          if (mn.equals("class__V")) {
   1.135              toInitilize.add(accessClass(className(jc)) + "(false)." + mn);
   1.136          }
   1.137 -        generateMethod(prefix, mn, m);
   1.138 +        generateMethod(destObject, mn, m);
   1.139          return mn;
   1.140      }
   1.141  
   1.142 -    private String generateInstanceMethod(String prefix, MethodData m) throws IOException {
   1.143 -        String jsb = javaScriptBody(prefix, m, false);
   1.144 +    private String generateInstanceMethod(String destObject, MethodData m) throws IOException {
   1.145 +        String jsb = javaScriptBody(destObject, m, false);
   1.146          if (jsb != null) {
   1.147              return jsb;
   1.148          }
   1.149          final String mn = findMethodName(m, new StringBuilder());
   1.150 -        generateMethod(prefix, mn, m);
   1.151 +        generateMethod(destObject, mn, m);
   1.152          return mn;
   1.153      }
   1.154  
   1.155 -    private void generateMethod(String prefix, String name, MethodData m)
   1.156 +    private void generateMethod(String destObject, String name, MethodData m)
   1.157              throws IOException {
   1.158          final StackMapIterator stackMapIterator = m.createStackMapIterator();
   1.159          TrapDataIterator trap = m.getTrapDataIterator();
   1.160          final LocalsMapper lmapper =
   1.161                  new LocalsMapper(stackMapIterator.getArguments());
   1.162  
   1.163 -        out.append(prefix).append(name).append(" = function(");
   1.164 +        out.append(destObject).append(".").append(name).append(" = function(");
   1.165          lmapper.outputArguments(out, m.isStatic());
   1.166          out.append(") {").append("\n");
   1.167  
   1.168 @@ -1546,7 +1569,7 @@
   1.169          return s;
   1.170      }
   1.171  
   1.172 -    private String javaScriptBody(String prefix, MethodData m, boolean isStatic) throws IOException {
   1.173 +    private String javaScriptBody(String destObject, MethodData m, boolean isStatic) throws IOException {
   1.174          byte[] arr = m.findAnnotationData(true);
   1.175          if (arr == null) {
   1.176              return null;
   1.177 @@ -1581,7 +1604,7 @@
   1.178          }
   1.179          StringBuilder cnt = new StringBuilder();
   1.180          final String mn = findMethodName(m, cnt);
   1.181 -        out.append(prefix).append(mn);
   1.182 +        out.append(destObject).append(".").append(mn);
   1.183          out.append(" = function(");
   1.184          String space = "";
   1.185          int index = 0;