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