rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 17 Jan 2017 07:04:06 +0100
changeset 1985 cd1cc103a03c
parent 1787 ea12a3bb4b33
permissions -rw-r--r--
Implementation of ClassValue for bck2brwsr
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012-2015 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.ByteArrayOutputStream;
    23 import java.io.IOException;
    24 import java.io.OutputStream;
    25 import java.io.PrintStream;
    26 import java.util.ArrayList;
    27 import java.util.Collections;
    28 import java.util.List;
    29 import org.apidesign.bck2brwsr.core.ExtraJavaScript;
    30 
    31 /**
    32  *
    33  * @author Jaroslav Tulach <jtulach@netbeans.org>
    34  */
    35 @ExtraJavaScript(processByteCode = false, resource="")
    36 final class ClosureWrapper extends CommandLineRunner {
    37     private static final String[] ARGS = { 
    38         "--compilation_level", 
    39         "SIMPLE_OPTIMIZATIONS", 
    40         "--output_wrapper", "(function() {%output%})(this);",
    41         "--js", "bck2brwsr-raw.js" 
    42         //, "--debug"
    43         //, "--formatting", "PRETTY_PRINT"
    44     };
    45 
    46     private final Bck2Brwsr config;
    47 
    48     private String compiledCode;
    49     private String externsCode;
    50 
    51     private ClosureWrapper(Appendable out,
    52                            String compilationLevel, Bck2Brwsr config, PrintStream err) {
    53         super(
    54             generateArguments(compilationLevel),
    55             new PrintStream(new APS(out)), err
    56         );
    57         this.config = config;
    58     }
    59 
    60     @Override
    61     protected List<SourceFile> createInputs(List<String> files, boolean allowStdIn) throws FlagUsageException, IOException {
    62         if (files.size() != 1 || !"bck2brwsr-raw.js".equals(files.get(0))) {
    63             throw new IOException("Unexpected files: " + files);
    64         }
    65         return Collections.nCopies(
    66                    1,
    67                    SourceFile.fromGenerator(
    68                        "bck2brwsr-raw.js",
    69                        new SourceFile.Generator() {
    70                            @Override
    71                            public String getCode() {
    72                                return getCompiledCode();
    73                            }
    74                        }));
    75     }
    76 
    77 
    78     @Override
    79     protected List<SourceFile> createExterns()
    80             throws FlagUsageException, IOException {
    81         final List<SourceFile> externsFiles =
    82                 new ArrayList<SourceFile>(super.createExterns());
    83 
    84         externsFiles.add(
    85                 SourceFile.fromGenerator(
    86                         "bck2brwsr_externs.js",
    87                         new SourceFile.Generator() {
    88                             @Override
    89                             public String getCode() {
    90                                 return getExternsCode();
    91                             }
    92                         }));
    93         return externsFiles;
    94     }
    95 
    96     private String getCompiledCode() {
    97         if (compiledCode == null) {
    98             StringBuilder sb = new StringBuilder();
    99             try {
   100                 VM.compile(sb, config);
   101                 compiledCode = sb.toString();
   102             } catch (IOException ex) {
   103                 compiledCode = ex.getMessage();
   104             }
   105         }
   106         return compiledCode;
   107     }
   108 
   109     private String getExternsCode() {
   110         if (externsCode == null) {
   111             // need compiled code at this point
   112             getCompiledCode();
   113 
   114             final StringBuilder sb = new StringBuilder("function RAW() {};\n");
   115             for (final String extern: FIXED_EXTERNS) {
   116                 sb.append("RAW.prototype.").append(extern).append(";\n");
   117             }
   118             externsCode = sb.toString();
   119         }
   120         return externsCode;
   121     }
   122 
   123     private static final class APS extends OutputStream {
   124         private final Appendable out;
   125 
   126         public APS(Appendable out) {
   127             this.out = out;
   128         }
   129         @Override
   130         public void write(int b) throws IOException {
   131             out.append((char)b);
   132         }
   133     }
   134 
   135     private static String[] generateArguments(String compilationLevel) {
   136         String[] finalArgs = ARGS.clone();
   137         finalArgs[1] = compilationLevel;
   138 
   139         return finalArgs;
   140     }
   141 
   142     static int produceTo(Appendable output,
   143         ObfuscationLevel obfuscationLevel,
   144         Bck2Brwsr config
   145     ) throws IOException {
   146         ByteArrayOutputStream out = new ByteArrayOutputStream();
   147         PrintStream err = new PrintStream(out);
   148         final ClosureWrapper cw = new ClosureWrapper(output,
   149             (obfuscationLevel == ObfuscationLevel.FULL) ? "ADVANCED_OPTIMIZATIONS" : "SIMPLE_OPTIMIZATIONS",
   150             config, err
   151         );
   152         try {
   153             return cw.doRun();
   154         } catch (FlagUsageException ex) {
   155             throw new IOException(out.toString(), ex);
   156         }
   157     }
   158 
   159     private static final String[] FIXED_EXTERNS = {
   160         "bck2brwsr",
   161         "bck2BrwsrThrwrbl",
   162         "register",
   163         "$class",
   164         "anno",
   165         "array",
   166         "access",
   167         "cls",
   168         "vm",
   169         "loadClass",
   170         "loadBytes",
   171         "jvmName",
   172         "primitive",
   173         "superclass",
   174         "cnstr",
   175         "add32",
   176         "sub32",
   177         "mul32",
   178         "neg32",
   179         "toInt8",
   180         "toInt16",
   181         "next32",
   182         "high32",
   183         "toInt32",
   184         "toFP",
   185         "toLong",
   186         "toJS",
   187         "toExactString",
   188         "add64",
   189         "sub64",
   190         "mul64",
   191         "and64",
   192         "or64",
   193         "xor64",
   194         "shl64",
   195         "shr64",
   196         "ushr64",
   197         "compare",
   198         "compare64",
   199         "neg64",
   200         "div32",
   201         "mod32",
   202         "div64",
   203         "mod64",
   204         "at",
   205         "cons__V",
   206         "getClass__Ljava_lang_Class_2",
   207         "clone__Ljava_lang_Object_2"
   208             
   209         //
   210         // workarounding export errors in ko4j @ 1.0
   211         //
   212             
   213         , "observable"
   214         , "notify"
   215         , "valueHasMutated"
   216     };
   217 }