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