rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 27 Apr 2014 22:40:17 +0200
branchclosure
changeset 1493 234fea368401
parent 1491 4a1398eff4fb
child 1513 ba912ef24b27
permissions -rw-r--r--
Initial infrastructure to export resources
     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 config;
    39 
    40     private String compiledCode;
    41     private String externsCode;
    42 
    43     private ClosureWrapper(Appendable out,
    44                            String compilationLevel, Bck2Brwsr config) {
    45         super(
    46             generateArguments(compilationLevel),
    47             new PrintStream(new APS(out)), System.err
    48         );
    49         this.config = config;
    50     }
    51 
    52     @Override
    53     protected List<SourceFile> createInputs(List<String> files, boolean allowStdIn) throws FlagUsageException, IOException {
    54         if (files.size() != 1 || !"bck2brwsr-raw.js".equals(files.get(0))) {
    55             throw new IOException("Unexpected files: " + files);
    56         }
    57         return Collections.nCopies(
    58                    1,
    59                    SourceFile.fromGenerator(
    60                        "bck2brwsr-raw.js",
    61                        new SourceFile.Generator() {
    62                            @Override
    63                            public String getCode() {
    64                                return getCompiledCode();
    65                            }
    66                        }));
    67     }
    68 
    69 
    70     @Override
    71     protected List<SourceFile> createExterns()
    72             throws FlagUsageException, IOException {
    73         final List<SourceFile> externsFiles =
    74                 new ArrayList<SourceFile>(super.createExterns());
    75 
    76         externsFiles.add(
    77                 SourceFile.fromGenerator(
    78                         "bck2brwsr_externs.js",
    79                         new SourceFile.Generator() {
    80                             @Override
    81                             public String getCode() {
    82                                 return getExternsCode();
    83                             }
    84                         }));
    85         return externsFiles;
    86     }
    87 
    88     private String getCompiledCode() {
    89         if (compiledCode == null) {
    90             StringBuilder sb = new StringBuilder();
    91             try {
    92                 VM.compile(sb, config);
    93                 compiledCode = sb.toString();
    94             } catch (IOException ex) {
    95                 compiledCode = ex.getMessage();
    96             }
    97         }
    98         return compiledCode;
    99     }
   100 
   101     private String getExternsCode() {
   102         if (externsCode == null) {
   103             // need compiled code at this point
   104             getCompiledCode();
   105 
   106             final StringBuilder sb = new StringBuilder("function RAW() {};\n");
   107             for (final String extern: FIXED_EXTERNS) {
   108                 sb.append("RAW.prototype.").append(extern).append(";\n");
   109             }
   110             externsCode = sb.toString();
   111         }
   112         return externsCode;
   113     }
   114 
   115     private static final class APS extends OutputStream {
   116         private final Appendable out;
   117 
   118         public APS(Appendable out) {
   119             this.out = out;
   120         }
   121         @Override
   122         public void write(int b) throws IOException {
   123             out.append((char)b);
   124         }
   125     }
   126 
   127     private static String[] generateArguments(String compilationLevel) {
   128         String[] finalArgs = ARGS.clone();
   129         finalArgs[1] = compilationLevel;
   130 
   131         return finalArgs;
   132     }
   133 
   134     static int produceTo(Appendable output,
   135         ObfuscationLevel obfuscationLevel,
   136         Bck2Brwsr config
   137     ) throws IOException {
   138         final ClosureWrapper cw =
   139                 new ClosureWrapper(output,
   140                                    (obfuscationLevel == ObfuscationLevel.FULL)
   141                                            ? "ADVANCED_OPTIMIZATIONS"
   142                                            : "SIMPLE_OPTIMIZATIONS",
   143                                    config);
   144         try {
   145             return cw.doRun();
   146         } catch (FlagUsageException ex) {
   147             throw new IOException(ex);
   148         }
   149     }
   150 
   151     private static final String[] FIXED_EXTERNS = {
   152         "bck2brwsr",
   153         "bck2BrwsrCnvrt",
   154         "registerExtension",
   155         "$class",
   156         "anno",
   157         "array",
   158         "access",
   159         "cls",
   160         "vm",
   161         "loadClass",
   162         "loadBytes",
   163         "jvmName",
   164         "primitive",
   165         "superclass",
   166         "cnstr",
   167         "add32",
   168         "sub32",
   169         "mul32",
   170         "neg32",
   171         "toInt8",
   172         "toInt16",
   173         "next32",
   174         "high32",
   175         "toInt32",
   176         "toFP",
   177         "toLong",
   178         "toExactString",
   179         "add64",
   180         "sub64",
   181         "mul64",
   182         "and64",
   183         "or64",
   184         "xor64",
   185         "shl64",
   186         "shr64",
   187         "ushr64",
   188         "compare64",
   189         "neg64",
   190         "div32",
   191         "mod32",
   192         "div64",
   193         "mod64",
   194         "at",
   195         "getClass__Ljava_lang_Class_2",
   196         "clone__Ljava_lang_Object_2"
   197     };
   198 }