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