diff --git a/settings.gradle.kts b/settings.gradle.kts index 7c56260d8..f95772560 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -50,6 +50,7 @@ include("tools:idea") include("tools:maven:plugin") include("tools:maven:webapp") include("tools:classlib-comparison-gen") +include("tools:wasm-disassembly") include("tests") include("extras-slf4j") diff --git a/tests/src/test/java/org/teavm/jso/core/test/JSSymbolTest.java b/tests/src/test/java/org/teavm/jso/core/test/JSSymbolTest.java index 439e44925..1a764c5ac 100644 --- a/tests/src/test/java/org/teavm/jso/core/test/JSSymbolTest.java +++ b/tests/src/test/java/org/teavm/jso/core/test/JSSymbolTest.java @@ -26,11 +26,14 @@ import org.teavm.jso.core.JSObjects; import org.teavm.jso.core.JSString; import org.teavm.jso.core.JSSymbol; import org.teavm.jso.core.JSUndefined; +import org.teavm.junit.OnlyPlatform; import org.teavm.junit.SkipJVM; import org.teavm.junit.TeaVMTestRunner; +import org.teavm.junit.TestPlatform; @RunWith(TeaVMTestRunner.class) @SkipJVM +@OnlyPlatform({ TestPlatform.JAVASCRIPT, TestPlatform.WEBASSEMBLY_GC }) public class JSSymbolTest { @Test public void getWorks() { diff --git a/tools/wasm-disassembly/build.gradle.kts b/tools/wasm-disassembly/build.gradle.kts new file mode 100644 index 000000000..274097eeb --- /dev/null +++ b/tools/wasm-disassembly/build.gradle.kts @@ -0,0 +1,70 @@ +/* + * Copyright 2024 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + `java-library` +} + +configurations { + val teavmCompile = create("teavmCompile") + compileClasspath.configure { + extendsFrom(teavmCompile) + } + create("wasm") +} + +dependencies { + compileOnly(project(":jso:apis")) + "teavmCompile"(project(":classlib")) + "teavmCompile"(project(":tools:core")) +} + +val generateWasm by tasks.register("generateWasm") { + outputs.dir(layout.buildDirectory.dir("webapp-out")) + dependsOn(tasks.classes) + classpath += configurations["teavmCompile"] + classpath += java.sourceSets.main.get().output.classesDirs + mainClass = "org.teavm.tooling.wasm.disassembly.Compiler" + args( + "org.teavm.tooling.wasm.disassembly.DisassemblerTool", + layout.buildDirectory.dir("webapp-out").get().asFile.absolutePath, + "disassembler.wasm" + ) +} + +val copyHtml by tasks.register("copyHtml") { + outputs.dir(layout.buildDirectory.dir("webapp-out")) + from(sourceSets.getByName("main").resources.srcDirs) + into(layout.buildDirectory.dir("webapp-out")) +} + +val copyRuntime by tasks.register("copyRuntime") { + outputs.dir(layout.buildDirectory.dir("webapp-out")) + dependsOn(configurations["teavmCompile"]) + from(providers.provider { + configurations["teavmCompile"].map { zipTree(it) } + }) + into(layout.buildDirectory.dir("webapp-out")) + include("**/wasm-gc-runtime.js") + includeEmptyDirs = false + eachFile { + path = name + } +} + +tasks.assemble.configure { + dependsOn(copyHtml, generateWasm, copyRuntime) +} \ No newline at end of file diff --git a/tools/wasm-disassembly/src/main/java/org.teavm.tooling.wasm.disassembly/Compiler.java b/tools/wasm-disassembly/src/main/java/org.teavm.tooling.wasm.disassembly/Compiler.java new file mode 100644 index 000000000..3863dd25e --- /dev/null +++ b/tools/wasm-disassembly/src/main/java/org.teavm.tooling.wasm.disassembly/Compiler.java @@ -0,0 +1,47 @@ +/* + * Copyright 2023 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.tooling.wasm.disassembly; + +import java.io.File; +import org.teavm.tooling.ConsoleTeaVMToolLog; +import org.teavm.tooling.TeaVMProblemRenderer; +import org.teavm.tooling.TeaVMTargetType; +import org.teavm.tooling.TeaVMTool; +import org.teavm.tooling.TeaVMToolException; +import org.teavm.vm.TeaVMOptimizationLevel; + +public final class Compiler { + private Compiler() { + } + + public static void main(String[] args) throws TeaVMToolException { + var tool = new TeaVMTool(); + var log = new ConsoleTeaVMToolLog(false); + tool.setTargetType(TeaVMTargetType.WEBASSEMBLY_GC); + tool.setMainClass(args[0]); + tool.setTargetDirectory(new File(args[1])); + tool.setTargetFileName(args[2]); + tool.setObfuscated(true); + tool.setOptimizationLevel(TeaVMOptimizationLevel.ADVANCED); + tool.setStrict(false); + + tool.generate(); + TeaVMProblemRenderer.describeProblems(tool.getDependencyInfo().getCallGraph(), tool.getProblemProvider(), log); + if (!tool.getProblemProvider().getSevereProblems().isEmpty()) { + System.exit(1); + } + } +} diff --git a/tools/wasm-disassembly/src/main/java/org.teavm.tooling.wasm.disassembly/DisassemblerTool.java b/tools/wasm-disassembly/src/main/java/org.teavm.tooling.wasm.disassembly/DisassemblerTool.java new file mode 100644 index 000000000..0c62e0e66 --- /dev/null +++ b/tools/wasm-disassembly/src/main/java/org.teavm.tooling.wasm.disassembly/DisassemblerTool.java @@ -0,0 +1,49 @@ +/* + * Copyright 2024 konsoletyper. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.tooling.wasm.disassembly; + +import java.io.PrintWriter; +import java.io.StringWriter; +import org.teavm.backend.wasm.disasm.Disassembler; +import org.teavm.backend.wasm.disasm.DisassemblyHTMLWriter; +import org.teavm.backend.wasm.disasm.DisassemblyWriter; +import org.teavm.jso.JSExport; + +public class DisassemblerTool { + private DisassemblerTool() { + } + + @JSExport + public static String disassemble(byte[] data) { + var out = new StringWriter(); + var writer = new PrintWriter(out); + var htmlWriter = new DisassemblyHTMLWriter(writer) { + @Override + public DisassemblyWriter prologue() { + return this; + } + + @Override + public DisassemblyWriter epilogue() { + return this; + } + }; + htmlWriter.setWithAddress(true); + var disassembler = new Disassembler(htmlWriter); + disassembler.disassemble(data); + return out.toString(); + } +} diff --git a/tools/wasm-disassembly/src/main/resources/index.html b/tools/wasm-disassembly/src/main/resources/index.html new file mode 100644 index 000000000..cbce66a2b --- /dev/null +++ b/tools/wasm-disassembly/src/main/resources/index.html @@ -0,0 +1,58 @@ + + + + + + TeaVM WebAssembly disassembler + + + + +

Please, note that this is not full disassembler, it only supports subset of WebAssembly + used by TeaVM.

+
+ +
+
+    
+ + + \ No newline at end of file