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