rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java
author Lubomir Nerad <lubomir.nerad@oracle.com>
Mon, 06 May 2013 11:57:29 +0200
branchclosure
changeset 1083 9d6130cb464f
parent 1029 b1fe994d4267
child 1086 2ac4283ee209
permissions -rw-r--r--
Removed ObfuscationDelegate
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.vm4brwsr;
    19 
    20 import com.google.javascript.jscomp.CommandLineRunner;
    21 import com.google.javascript.jscomp.SourceFile;
    22 import java.io.IOException;
    23 import java.io.OutputStream;
    24 import java.io.PrintStream;
    25 import java.util.ArrayList;
    26 import java.util.Collections;
    27 import java.util.List;
    28 import org.apidesign.bck2brwsr.core.ExtraJavaScript;
    29 
    30 /**
    31  *
    32  * @author Jaroslav Tulach <jtulach@netbeans.org>
    33  */
    34 @ExtraJavaScript(processByteCode = false, resource="")
    35 final class ClosureWrapper extends CommandLineRunner {
    36     private static final String[] ARGS = { "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--js", "bck2brwsr-raw.js" /*, "--debug", "--formatting", "PRETTY_PRINT" */ };
    37 
    38     private final Bck2Brwsr.Resources res;
    39     private final StringArray classes;
    40 
    41     private String compiledCode;
    42     private String externsCode;
    43 
    44     private ClosureWrapper(Appendable out, 
    45                            String compilationLevel,
    46                            Bck2Brwsr.Resources res, StringArray classes) {
    47         super(
    48             generateArguments(compilationLevel),
    49             new PrintStream(new APS(out)), System.err
    50         );
    51         this.res = res;
    52         this.classes = classes;
    53     }
    54 
    55     @Override
    56     protected List<SourceFile> createInputs(List<String> files, boolean allowStdIn) throws FlagUsageException, IOException {
    57         if (files.size() != 1 || !"bck2brwsr-raw.js".equals(files.get(0))) {
    58             throw new IOException("Unexpected files: " + files);
    59         }
    60         return Collections.nCopies(
    61                    1,
    62                    SourceFile.fromGenerator(
    63                        "bck2brwsr-raw.js",
    64                        new SourceFile.Generator() {
    65                            @Override
    66                            public String getCode() {
    67                                return getCompiledCode();
    68                            }
    69                        }));
    70     }
    71 
    72 
    73     @Override
    74     protected List<SourceFile> createExterns()
    75             throws FlagUsageException, IOException {
    76         final List<SourceFile> externsFiles =
    77                 new ArrayList<SourceFile>(super.createExterns());
    78 
    79         externsFiles.add(
    80                 SourceFile.fromGenerator(
    81                         "bck2brwsr_externs.js",
    82                         new SourceFile.Generator() {
    83                             @Override
    84                             public String getCode() {
    85                                 return getExternsCode();
    86                             }
    87                         }));
    88         return externsFiles;
    89     }
    90 
    91     private String getCompiledCode() {
    92         if (compiledCode == null) {
    93             StringBuilder sb = new StringBuilder();
    94             try {
    95                 VM.compileStandalone(res, sb, classes);
    96                 compiledCode = sb.toString();
    97             } catch (IOException ex) {
    98                 compiledCode = ex.getMessage();
    99             }
   100         }
   101         return compiledCode;
   102     }
   103 
   104     private String getExternsCode() {
   105         if (externsCode == null) {
   106             // need compiled code at this point
   107             getCompiledCode();
   108 
   109             final StringBuilder sb = new StringBuilder("function RAW() {};\n");
   110             for (final String extern: FIXED_EXTERNS) {
   111                 sb.append("RAW.prototype.").append(extern).append(";\n");
   112             }
   113             externsCode = sb.toString();
   114         }
   115         return externsCode;
   116     }
   117 
   118     private static final class APS extends OutputStream {
   119         private final Appendable out;
   120 
   121         public APS(Appendable out) {
   122             this.out = out;
   123         }
   124         @Override
   125         public void write(int b) throws IOException {
   126             out.append((char)b);
   127         }
   128     }
   129 
   130     private static String[] generateArguments(String compilationLevel) {
   131         String[] finalArgs = ARGS.clone();
   132         finalArgs[1] = compilationLevel;
   133 
   134         return finalArgs;
   135     }
   136 
   137     static int produceTo(Appendable w, ObfuscationLevel obfuscationLevel, Bck2Brwsr.Resources resources, StringArray arr) throws IOException {
   138         ClosureWrapper cw = create(w, obfuscationLevel, resources, arr);
   139         try {
   140             return cw.doRun();
   141         } catch (FlagUsageException ex) {
   142             throw new IOException(ex);
   143         }
   144     }
   145 
   146     private static ClosureWrapper create(Appendable w,
   147                                          ObfuscationLevel obfuscationLevel,
   148                                          Bck2Brwsr.Resources resources,
   149                                          StringArray arr) {
   150         switch (obfuscationLevel) {
   151             case MINIMAL:
   152                 return new ClosureWrapper(w, "SIMPLE_OPTIMIZATIONS",
   153                                           resources, arr);
   154 
   155             case FULL:
   156                 return new ClosureWrapper(w, "ADVANCED_OPTIMIZATIONS",
   157                                           resources, arr);
   158             default:
   159                 throw new IllegalArgumentException(
   160                         "Unsupported level: " + obfuscationLevel);
   161         }
   162     }
   163 
   164     private static final String[] FIXED_EXTERNS = {
   165         "bck2brwsr",
   166         "$class",
   167         "anno",
   168         "array",
   169         "access",
   170         "cls",
   171         "vm",
   172         "loadClass",
   173         "loadBytes",
   174         "jvmName",
   175         "primitive",
   176         "superclass",
   177         "cnstr",
   178         "add32",
   179         "sub32",
   180         "mul32",
   181         "neg32",
   182         "toInt8",
   183         "toInt16",
   184         "next32",
   185         "high32",
   186         "toInt32",
   187         "toFP",
   188         "toLong",
   189         "toExactString",
   190         "add64",
   191         "sub64",
   192         "mul64",
   193         "and64",
   194         "or64",
   195         "xor64",
   196         "shl64",
   197         "shr64",
   198         "ushr64",
   199         "compare64",
   200         "neg64",
   201         "div32",
   202         "mod32",
   203         "div64",
   204         "mod64",
   205         "at",
   206         "getClass__Ljava_lang_Class_2",
   207         "clone__Ljava_lang_Object_2"
   208     };
   209 }