Add support of WASM in TeaVMTool and CLI

This commit is contained in:
Alexey Andreev 2016-08-19 14:48:45 +03:00
parent 35b59ed916
commit b83c33bcc6
3 changed files with 59 additions and 9 deletions

View File

@ -21,6 +21,7 @@ import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import org.apache.commons.cli.*; import org.apache.commons.cli.*;
import org.teavm.tooling.RuntimeCopyOperation; import org.teavm.tooling.RuntimeCopyOperation;
import org.teavm.tooling.TeaVMTargetType;
import org.teavm.tooling.TeaVMTool; import org.teavm.tooling.TeaVMTool;
import org.teavm.tooling.TeaVMToolException; import org.teavm.tooling.TeaVMToolException;
import org.teavm.vm.TeaVMPhase; import org.teavm.vm.TeaVMPhase;
@ -39,6 +40,11 @@ public final class TeaVMRunner {
@SuppressWarnings("static-access") @SuppressWarnings("static-access")
public static void main(String[] args) { public static void main(String[] args) {
Options options = new Options(); Options options = new Options();
options.addOption(OptionBuilder
.withArgName("target")
.hasArg()
.withDescription("target type (javascript/js, webassembly/wasm)")
.create('t'));
options.addOption(OptionBuilder options.addOption(OptionBuilder
.withArgName("directory") .withArgName("directory")
.hasArg() .hasArg()
@ -108,6 +114,18 @@ public final class TeaVMRunner {
} }
TeaVMTool tool = new TeaVMTool(); TeaVMTool tool = new TeaVMTool();
if (commandLine.hasOption("t")) {
switch (commandLine.getOptionValue('t').toLowerCase()) {
case "javascript":
case "js":
tool.setTargetType(TeaVMTargetType.JAVASCRIPT);
break;
case "webassembly":
case "wasm":
tool.setTargetType(TeaVMTargetType.WEBASSEMBLY);
break;
}
}
if (commandLine.hasOption("d")) { if (commandLine.hasOption("d")) {
tool.setTargetDirectory(new File(commandLine.getOptionValue("d"))); tool.setTargetDirectory(new File(commandLine.getOptionValue("d")));
} }

View File

@ -16,5 +16,6 @@
package org.teavm.tooling; package org.teavm.tooling;
public enum TeaVMTargetType { public enum TeaVMTargetType {
JAVASCRIPT JAVASCRIPT,
WEBASSEMBLY
} }

View File

@ -64,11 +64,12 @@ import org.teavm.vm.TeaVMEntryPoint;
import org.teavm.vm.TeaVMProgressListener; import org.teavm.vm.TeaVMProgressListener;
import org.teavm.vm.TeaVMTarget; import org.teavm.vm.TeaVMTarget;
import org.teavm.vm.spi.AbstractRendererListener; import org.teavm.vm.spi.AbstractRendererListener;
import org.teavm.wasm.WasmTarget;
public class TeaVMTool implements BaseTeaVMTool { public class TeaVMTool implements BaseTeaVMTool {
private File targetDirectory = new File("."); private File targetDirectory = new File(".");
private TeaVMTargetType targetType = TeaVMTargetType.JAVASCRIPT; private TeaVMTargetType targetType = TeaVMTargetType.JAVASCRIPT;
private String targetFileName = "classes.js"; private String targetFileName = "";
private boolean minifying = true; private boolean minifying = true;
private String mainClass; private String mainClass;
private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE; private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE;
@ -95,6 +96,7 @@ public class TeaVMTool implements BaseTeaVMTool {
private List<SourceFileProvider> sourceFileProviders = new ArrayList<>(); private List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
private DebugInformationBuilder debugEmitter; private DebugInformationBuilder debugEmitter;
private JavaScriptTarget javaScriptTarget; private JavaScriptTarget javaScriptTarget;
private WasmTarget webAssemblyTarget;
public File getTargetDirectory() { public File getTargetDirectory() {
return targetDirectory; return targetDirectory;
@ -217,6 +219,14 @@ public class TeaVMTool implements BaseTeaVMTool {
this.log = log; this.log = log;
} }
public TeaVMTargetType getTargetType() {
return targetType;
}
public void setTargetType(TeaVMTargetType targetType) {
this.targetType = targetType;
}
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
return classLoader; return classLoader;
} }
@ -287,6 +297,8 @@ public class TeaVMTool implements BaseTeaVMTool {
switch (targetType) { switch (targetType) {
case JAVASCRIPT: case JAVASCRIPT:
return prepareJavaScriptTarget(); return prepareJavaScriptTarget();
case WEBASSEMBLY:
return prepareWebAssemblyTarget();
} }
throw new IllegalStateException("Unknown target type: " + targetType); throw new IllegalStateException("Unknown target type: " + targetType);
} }
@ -295,7 +307,7 @@ public class TeaVMTool implements BaseTeaVMTool {
javaScriptTarget = new JavaScriptTarget(); javaScriptTarget = new JavaScriptTarget();
javaScriptTarget.setMinifying(minifying); javaScriptTarget.setMinifying(minifying);
DebugInformationBuilder debugEmitter = debugInformationGenerated || sourceMapsFileGenerated debugEmitter = debugInformationGenerated || sourceMapsFileGenerated
? new DebugInformationBuilder() : null; ? new DebugInformationBuilder() : null;
javaScriptTarget.setDebugEmitter(debugEmitter); javaScriptTarget.setDebugEmitter(debugEmitter);
@ -306,6 +318,11 @@ public class TeaVMTool implements BaseTeaVMTool {
return javaScriptTarget; return javaScriptTarget;
} }
private WasmTarget prepareWebAssemblyTarget() {
webAssemblyTarget = new WasmTarget();
return webAssemblyTarget;
}
public void generate() throws TeaVMToolException { public void generate() throws TeaVMToolException {
try { try {
cancelled = false; cancelled = false;
@ -378,7 +395,7 @@ public class TeaVMTool implements BaseTeaVMTool {
} }
targetDirectory.mkdirs(); targetDirectory.mkdirs();
try (OutputStream output = new BufferedOutputStream( try (OutputStream output = new BufferedOutputStream(
new FileOutputStream(new File(targetDirectory, targetFileName)), 65536)) { new FileOutputStream(new File(targetDirectory, getResolvedTargetFileName())), 65536)) {
Writer writer = new OutputStreamWriter(output, "UTF-8"); Writer writer = new OutputStreamWriter(output, "UTF-8");
if (runtime == RuntimeCopyOperation.MERGED) { if (runtime == RuntimeCopyOperation.MERGED) {
javaScriptTarget.add(runtimeInjector); javaScriptTarget.add(runtimeInjector);
@ -417,10 +434,24 @@ public class TeaVMTool implements BaseTeaVMTool {
} }
} }
} catch (IOException e) { } catch (IOException e) {
throw new TeaVMToolException("IO error occured", e); throw new TeaVMToolException("IO error occurred", e);
} }
} }
private String getResolvedTargetFileName() {
if (targetFileName.isEmpty()) {
switch (targetType) {
case JAVASCRIPT:
return "classes.js";
case WEBASSEMBLY:
return "classes.wast";
default:
return "classes";
}
}
return targetFileName;
}
private void additionalJavaScriptOutput(Writer writer) throws IOException { private void additionalJavaScriptOutput(Writer writer) throws IOException {
if (mainClass != null) { if (mainClass != null) {
writer.append("main = $rt_mainStarter(main);\n"); writer.append("main = $rt_mainStarter(main);\n");
@ -430,7 +461,7 @@ public class TeaVMTool implements BaseTeaVMTool {
assert debugEmitter != null; assert debugEmitter != null;
DebugInformation debugInfo = debugEmitter.getDebugInformation(); DebugInformation debugInfo = debugEmitter.getDebugInformation();
try (OutputStream debugInfoOut = new FileOutputStream(new File(targetDirectory, try (OutputStream debugInfoOut = new FileOutputStream(new File(targetDirectory,
targetFileName + ".teavmdbg"))) { getResolvedTargetFileName() + ".teavmdbg"))) {
debugInfo.write(debugInfoOut); debugInfo.write(debugInfoOut);
} }
log.info("Debug information successfully written"); log.info("Debug information successfully written");
@ -438,11 +469,11 @@ public class TeaVMTool implements BaseTeaVMTool {
if (sourceMapsFileGenerated) { if (sourceMapsFileGenerated) {
assert debugEmitter != null; assert debugEmitter != null;
DebugInformation debugInfo = debugEmitter.getDebugInformation(); DebugInformation debugInfo = debugEmitter.getDebugInformation();
String sourceMapsFileName = targetFileName + ".map"; String sourceMapsFileName = getResolvedTargetFileName() + ".map";
writer.append("\n//# sourceMappingURL=").append(sourceMapsFileName); writer.append("\n//# sourceMappingURL=").append(sourceMapsFileName);
try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream( try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(
new File(targetDirectory, sourceMapsFileName)), "UTF-8")) { new File(targetDirectory, sourceMapsFileName)), "UTF-8")) {
debugInfo.writeAsSourceMaps(sourceMapsOut, "src", targetFileName); debugInfo.writeAsSourceMaps(sourceMapsOut, "src", getResolvedTargetFileName());
} }
log.info("Source maps successfully written"); log.info("Source maps successfully written");
} }
@ -458,7 +489,7 @@ public class TeaVMTool implements BaseTeaVMTool {
String text; String text;
try (Reader reader = new InputStreamReader(classLoader.getResourceAsStream( try (Reader reader = new InputStreamReader(classLoader.getResourceAsStream(
"org/teavm/tooling/main.html"), "UTF-8")) { "org/teavm/tooling/main.html"), "UTF-8")) {
text = IOUtils.toString(reader).replace("${classes.js}", targetFileName); text = IOUtils.toString(reader).replace("${classes.js}", getResolvedTargetFileName());
} }
File mainPageFile = new File(targetDirectory, "main.html"); File mainPageFile = new File(targetDirectory, "main.html");
try (Writer mainPageWriter = new OutputStreamWriter(new FileOutputStream(mainPageFile), "UTF-8")) { try (Writer mainPageWriter = new OutputStreamWriter(new FileOutputStream(mainPageFile), "UTF-8")) {