From b83c33bcc618271fcbecba061448c18baa0ff114 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 19 Aug 2016 14:48:45 +0300 Subject: [PATCH] Add support of WASM in TeaVMTool and CLI --- .../main/java/org/teavm/cli/TeaVMRunner.java | 18 +++++++ .../org/teavm/tooling/TeaVMTargetType.java | 3 +- .../java/org/teavm/tooling/TeaVMTool.java | 47 +++++++++++++++---- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java b/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java index 1bda04d5a..761dc2efd 100644 --- a/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java +++ b/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java @@ -21,6 +21,7 @@ import java.net.URL; import java.net.URLClassLoader; import org.apache.commons.cli.*; import org.teavm.tooling.RuntimeCopyOperation; +import org.teavm.tooling.TeaVMTargetType; import org.teavm.tooling.TeaVMTool; import org.teavm.tooling.TeaVMToolException; import org.teavm.vm.TeaVMPhase; @@ -39,6 +40,11 @@ public final class TeaVMRunner { @SuppressWarnings("static-access") public static void main(String[] args) { Options options = new Options(); + options.addOption(OptionBuilder + .withArgName("target") + .hasArg() + .withDescription("target type (javascript/js, webassembly/wasm)") + .create('t')); options.addOption(OptionBuilder .withArgName("directory") .hasArg() @@ -108,6 +114,18 @@ public final class TeaVMRunner { } 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")) { tool.setTargetDirectory(new File(commandLine.getOptionValue("d"))); } diff --git a/tools/core/src/main/java/org/teavm/tooling/TeaVMTargetType.java b/tools/core/src/main/java/org/teavm/tooling/TeaVMTargetType.java index 32f774dbe..db950d0be 100644 --- a/tools/core/src/main/java/org/teavm/tooling/TeaVMTargetType.java +++ b/tools/core/src/main/java/org/teavm/tooling/TeaVMTargetType.java @@ -16,5 +16,6 @@ package org.teavm.tooling; public enum TeaVMTargetType { - JAVASCRIPT + JAVASCRIPT, + WEBASSEMBLY } diff --git a/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java b/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java index ee1e4afad..c4388d59c 100644 --- a/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java +++ b/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java @@ -64,11 +64,12 @@ import org.teavm.vm.TeaVMEntryPoint; import org.teavm.vm.TeaVMProgressListener; import org.teavm.vm.TeaVMTarget; import org.teavm.vm.spi.AbstractRendererListener; +import org.teavm.wasm.WasmTarget; public class TeaVMTool implements BaseTeaVMTool { private File targetDirectory = new File("."); private TeaVMTargetType targetType = TeaVMTargetType.JAVASCRIPT; - private String targetFileName = "classes.js"; + private String targetFileName = ""; private boolean minifying = true; private String mainClass; private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE; @@ -95,6 +96,7 @@ public class TeaVMTool implements BaseTeaVMTool { private List sourceFileProviders = new ArrayList<>(); private DebugInformationBuilder debugEmitter; private JavaScriptTarget javaScriptTarget; + private WasmTarget webAssemblyTarget; public File getTargetDirectory() { return targetDirectory; @@ -217,6 +219,14 @@ public class TeaVMTool implements BaseTeaVMTool { this.log = log; } + public TeaVMTargetType getTargetType() { + return targetType; + } + + public void setTargetType(TeaVMTargetType targetType) { + this.targetType = targetType; + } + public ClassLoader getClassLoader() { return classLoader; } @@ -287,6 +297,8 @@ public class TeaVMTool implements BaseTeaVMTool { switch (targetType) { case JAVASCRIPT: return prepareJavaScriptTarget(); + case WEBASSEMBLY: + return prepareWebAssemblyTarget(); } throw new IllegalStateException("Unknown target type: " + targetType); } @@ -295,7 +307,7 @@ public class TeaVMTool implements BaseTeaVMTool { javaScriptTarget = new JavaScriptTarget(); javaScriptTarget.setMinifying(minifying); - DebugInformationBuilder debugEmitter = debugInformationGenerated || sourceMapsFileGenerated + debugEmitter = debugInformationGenerated || sourceMapsFileGenerated ? new DebugInformationBuilder() : null; javaScriptTarget.setDebugEmitter(debugEmitter); @@ -306,6 +318,11 @@ public class TeaVMTool implements BaseTeaVMTool { return javaScriptTarget; } + private WasmTarget prepareWebAssemblyTarget() { + webAssemblyTarget = new WasmTarget(); + return webAssemblyTarget; + } + public void generate() throws TeaVMToolException { try { cancelled = false; @@ -378,7 +395,7 @@ public class TeaVMTool implements BaseTeaVMTool { } targetDirectory.mkdirs(); 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"); if (runtime == RuntimeCopyOperation.MERGED) { javaScriptTarget.add(runtimeInjector); @@ -417,10 +434,24 @@ public class TeaVMTool implements BaseTeaVMTool { } } } 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 { if (mainClass != null) { writer.append("main = $rt_mainStarter(main);\n"); @@ -430,7 +461,7 @@ public class TeaVMTool implements BaseTeaVMTool { assert debugEmitter != null; DebugInformation debugInfo = debugEmitter.getDebugInformation(); try (OutputStream debugInfoOut = new FileOutputStream(new File(targetDirectory, - targetFileName + ".teavmdbg"))) { + getResolvedTargetFileName() + ".teavmdbg"))) { debugInfo.write(debugInfoOut); } log.info("Debug information successfully written"); @@ -438,11 +469,11 @@ public class TeaVMTool implements BaseTeaVMTool { if (sourceMapsFileGenerated) { assert debugEmitter != null; DebugInformation debugInfo = debugEmitter.getDebugInformation(); - String sourceMapsFileName = targetFileName + ".map"; + String sourceMapsFileName = getResolvedTargetFileName() + ".map"; writer.append("\n//# sourceMappingURL=").append(sourceMapsFileName); try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream( new File(targetDirectory, sourceMapsFileName)), "UTF-8")) { - debugInfo.writeAsSourceMaps(sourceMapsOut, "src", targetFileName); + debugInfo.writeAsSourceMaps(sourceMapsOut, "src", getResolvedTargetFileName()); } log.info("Source maps successfully written"); } @@ -458,7 +489,7 @@ public class TeaVMTool implements BaseTeaVMTool { String text; try (Reader reader = new InputStreamReader(classLoader.getResourceAsStream( "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"); try (Writer mainPageWriter = new OutputStreamWriter(new FileOutputStream(mainPageFile), "UTF-8")) {