mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-27 01:30:35 +08:00
wasm gc: add support to Gradle plugin
This commit is contained in:
parent
10805ed0dd
commit
9fa88a15da
@ -39,6 +39,9 @@ teavm {
|
||||
outputDir = layout.buildDirectory.dir("libs/wasi").get().asFile
|
||||
relativePathInOutputDir = ""
|
||||
}
|
||||
wasmGC {
|
||||
addedToWebApp = true
|
||||
}
|
||||
all {
|
||||
mainClass = "org.teavm.samples.pi.PiCalculator"
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
<ul>
|
||||
<li><a href="js.html">JavaScript</a></li>
|
||||
<li><a href="wasm.html">WebAssembly</a></li>
|
||||
<li><a href="wasm-gc.html">WebAssembly GC</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
62
samples/pi/src/main/webapp/wasm-gc.html
Normal file
62
samples/pi/src/main/webapp/wasm-gc.html
Normal file
@ -0,0 +1,62 @@
|
||||
<!--
|
||||
Copyright 2014 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.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>PI calculator example</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<script type="text/javascript" charset="utf-8" src="teavm/stdout.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="wasm-gc/pi.wasm-runtime.js"></script>
|
||||
<style>
|
||||
#stdout {
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
margin-top: 1em;
|
||||
}
|
||||
</style>
|
||||
<script type="application/javascript">
|
||||
let runner = null;
|
||||
function init() {
|
||||
TeaVM.wasm.load("wasm-gc/pi.wasm", {
|
||||
installImports(o) {
|
||||
function putwchar(ch) {
|
||||
$rt_putStdoutCustom(String.fromCharCode(ch));
|
||||
}
|
||||
o.teavm.putcharStderr = putwchar;
|
||||
o.teavm.putcharStdout = putwchar;
|
||||
},
|
||||
}).then(teavm => {
|
||||
this.instance = teavm.instance;
|
||||
runner = n => teavm.main([n.toString()]);
|
||||
document.getElementById("run").disabled = false;
|
||||
})
|
||||
}
|
||||
function calculate() {
|
||||
var count = parseInt(document.getElementById("digit-count").value);
|
||||
runner(count);
|
||||
}
|
||||
init();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
Digit count:
|
||||
<input type="text" id="digit-count" value="1000">
|
||||
<button onclick="calculate()" id="run" disabled>Run</button>
|
||||
</div>
|
||||
<div id="stdout"></div>
|
||||
</body>
|
||||
</html>
|
@ -19,5 +19,6 @@ public enum TeaVMTargetType {
|
||||
JAVASCRIPT,
|
||||
WEBASSEMBLY,
|
||||
WEBASSEMBLY_WASI,
|
||||
WEBASSEMBLY_GC,
|
||||
C
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ import org.teavm.backend.c.generate.ShorteningFileNameProvider;
|
||||
import org.teavm.backend.c.generate.SimpleFileNameProvider;
|
||||
import org.teavm.backend.javascript.JSModuleType;
|
||||
import org.teavm.backend.javascript.JavaScriptTarget;
|
||||
import org.teavm.backend.wasm.WasmGCTarget;
|
||||
import org.teavm.backend.wasm.WasmRuntimeType;
|
||||
import org.teavm.backend.wasm.WasmTarget;
|
||||
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||
@ -336,6 +337,8 @@ public class TeaVMTool {
|
||||
return prepareWebAssemblyDefaultTarget();
|
||||
case WEBASSEMBLY_WASI:
|
||||
return prepareWebAssemblyWasiTarget();
|
||||
case WEBASSEMBLY_GC:
|
||||
return prepareWebAssemblyGCTarget();
|
||||
case C:
|
||||
return prepareCTarget();
|
||||
}
|
||||
@ -381,6 +384,13 @@ public class TeaVMTool {
|
||||
return target;
|
||||
}
|
||||
|
||||
private WasmGCTarget prepareWebAssemblyGCTarget() {
|
||||
var target = new WasmGCTarget();
|
||||
target.setObfuscated(obfuscated);
|
||||
target.setStrict(strict);
|
||||
return target;
|
||||
}
|
||||
|
||||
private CTarget prepareCTarget() {
|
||||
cTarget = new CTarget(new CNameProvider());
|
||||
cTarget.setMinHeapSize(minHeapSize);
|
||||
@ -529,6 +539,7 @@ public class TeaVMTool {
|
||||
return "classes.js";
|
||||
case WEBASSEMBLY:
|
||||
case WEBASSEMBLY_WASI:
|
||||
case WEBASSEMBLY_GC:
|
||||
return "classes.wasm";
|
||||
case C:
|
||||
return "classes.c";
|
||||
|
@ -30,11 +30,13 @@ import org.teavm.gradle.api.TeaVMExtension;
|
||||
import org.teavm.gradle.api.TeaVMJSConfiguration;
|
||||
import org.teavm.gradle.api.TeaVMWasiConfiguration;
|
||||
import org.teavm.gradle.api.TeaVMWasmConfiguration;
|
||||
import org.teavm.gradle.api.TeaVMWasmGCConfiguration;
|
||||
|
||||
class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtension {
|
||||
private TeaVMJSConfiguration js;
|
||||
private TeaVMWasmConfiguration wasm;
|
||||
private TeaVMWasiConfiguration wasi;
|
||||
private TeaVMWasmGCConfiguration wasmGC;
|
||||
private TeaVMCConfiguration c;
|
||||
private TeaVMCommonConfiguration all;
|
||||
|
||||
@ -43,11 +45,13 @@ class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtensio
|
||||
js = objectFactory.newInstance(JsConfigImpl.class);
|
||||
wasm = objectFactory.newInstance(TeaVMWasmConfiguration.class);
|
||||
wasi = objectFactory.newInstance(TeaVMWasiConfiguration.class);
|
||||
wasmGC = objectFactory.newInstance(TeaVMWasmGCConfiguration.class);
|
||||
c = objectFactory.newInstance(TeaVMCConfiguration.class);
|
||||
all = objectFactory.newInstance(TeaVMCommonConfiguration.class);
|
||||
inherit(js, all);
|
||||
inherit(wasm, all);
|
||||
inherit(wasi, all);
|
||||
inherit(wasmGC, all);
|
||||
inherit(c, all);
|
||||
setupDefaults();
|
||||
}
|
||||
@ -56,6 +60,7 @@ class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtensio
|
||||
setupJsDefaults();
|
||||
setupWasmDefaults();
|
||||
setupWasiDefaults();
|
||||
setupWasmGCDefaults();
|
||||
setupCDefaults();
|
||||
setupAllDefaults();
|
||||
}
|
||||
@ -95,6 +100,17 @@ class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtensio
|
||||
wasm.getExceptionsUsed().convention(property("wasm.exceptionsUsed").map(Boolean::parseBoolean).orElse(true));
|
||||
}
|
||||
|
||||
private void setupWasmGCDefaults() {
|
||||
wasmGC.getRelativePathInOutputDir().convention("wasm-gc");
|
||||
wasmGC.getOptimization().convention(property("wasm-gc.optimization").map(OptimizationLevel::valueOf)
|
||||
.orElse(OptimizationLevel.AGGRESSIVE));
|
||||
wasmGC.getTargetFileName().convention(project.provider(() -> project.getName() + ".wasm"));
|
||||
wasmGC.getAddedToWebApp().convention(property("wasm-gc.addedToWebApp")
|
||||
.map(Boolean::parseBoolean).orElse(false));
|
||||
wasmGC.getStrict().convention(property("wasm-gc.strict").map(Boolean::parseBoolean).orElse(true));
|
||||
wasmGC.getObfuscated().convention(property("wasm-gc.obfuscated").map(Boolean::parseBoolean).orElse(true));
|
||||
}
|
||||
|
||||
private void setupWasiDefaults() {
|
||||
wasi.getRelativePathInOutputDir().convention("wasi");
|
||||
wasi.getMinHeapSize().convention(1);
|
||||
@ -170,6 +186,21 @@ class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtensio
|
||||
action.rehydrate(getWasi(), action.getOwner(), action.getThisObject()).call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeaVMWasmGCConfiguration getWasmGC() {
|
||||
return wasmGC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wasmGC(Action<TeaVMWasmGCConfiguration> action) {
|
||||
action.execute(getWasmGC());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wasmGC(Closure<?> action) {
|
||||
action.rehydrate(getWasmGC(), action.getOwner(), action.getThisObject()).call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeaVMCConfiguration getC() {
|
||||
return c;
|
||||
|
@ -40,6 +40,7 @@ import org.teavm.gradle.config.ArtifactCoordinates;
|
||||
import org.teavm.gradle.tasks.GenerateCTask;
|
||||
import org.teavm.gradle.tasks.GenerateJavaScriptTask;
|
||||
import org.teavm.gradle.tasks.GenerateWasiTask;
|
||||
import org.teavm.gradle.tasks.GenerateWasmGCTask;
|
||||
import org.teavm.gradle.tasks.GenerateWasmTask;
|
||||
import org.teavm.gradle.tasks.JavaScriptDevServerTask;
|
||||
import org.teavm.gradle.tasks.StopJavaScriptDevServerTask;
|
||||
@ -53,6 +54,7 @@ public class TeaVMPlugin implements Plugin<Project> {
|
||||
public static final String STOP_JS_DEV_SERVER_TASK_NAME = "stopJavaScriptDevServer";
|
||||
public static final String WASM_TASK_NAME = "generateWasm";
|
||||
public static final String WASI_TASK_NAME = "generateWasi";
|
||||
public static final String WASM_GC_TASK_NAME = "generateWasmGC";
|
||||
public static final String C_TASK_NAME = "generateC";
|
||||
public static final String CONFIGURATION_NAME = "teavm";
|
||||
public static final String CLASSPATH_CONFIGURATION_NAME = "teavmClasspath";
|
||||
@ -118,6 +120,7 @@ public class TeaVMPlugin implements Plugin<Project> {
|
||||
registerStopJsDevServerTask(project);
|
||||
registerWasmTask(project, compilerConfig);
|
||||
registerWasiTask(project, compilerConfig);
|
||||
registerWasmGCTask(project, compilerConfig);
|
||||
registerCTask(project, compilerConfig);
|
||||
}
|
||||
|
||||
@ -210,6 +213,17 @@ public class TeaVMPlugin implements Plugin<Project> {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerWasmGCTask(Project project, Configuration configuration) {
|
||||
var extension = project.getExtensions().getByType(TeaVMExtension.class);
|
||||
project.getTasks().create(WASM_GC_TASK_NAME, GenerateWasmGCTask.class, task -> {
|
||||
var wasmGC = extension.getWasmGC();
|
||||
applyToTask(wasmGC, task, configuration);
|
||||
task.getTargetFileName().convention(wasmGC.getTargetFileName());
|
||||
task.getObfuscated().convention(wasmGC.getObfuscated());
|
||||
task.getStrict().convention(wasmGC.getStrict());
|
||||
});
|
||||
}
|
||||
|
||||
private void registerCTask(Project project, Configuration configuration) {
|
||||
var extension = project.getExtensions().getByType(TeaVMExtension.class);
|
||||
project.getTasks().create(C_TASK_NAME, GenerateCTask.class, task -> {
|
||||
@ -236,6 +250,7 @@ public class TeaVMPlugin implements Plugin<Project> {
|
||||
if (task.getName().equals(WarPlugin.WAR_TASK_NAME)) {
|
||||
var jsAddedToWebApp = extension.getJs().getAddedToWebApp().get();
|
||||
var wasmAddedToWebApp = extension.getWasm().getAddedToWebApp().get();
|
||||
var wasmGCAddedToWebApp = extension.getWasmGC().getAddedToWebApp().get();
|
||||
if (jsAddedToWebApp) {
|
||||
task.dependsOn(project.getTasks().named(JS_TASK_NAME));
|
||||
var outDir = extension.getJs().getOutputDir();
|
||||
@ -255,6 +270,15 @@ public class TeaVMPlugin implements Plugin<Project> {
|
||||
spec.from(project.files(outDir.map(dir -> new File(dir.getAsFile(), relPath.get()))));
|
||||
}));
|
||||
}
|
||||
if (wasmGCAddedToWebApp) {
|
||||
task.dependsOn(project.getTasks().named(WASM_GC_TASK_NAME));
|
||||
var outDir = extension.getWasmGC().getOutputDir();
|
||||
var relPath = extension.getWasmGC().getRelativePathInOutputDir();
|
||||
task.with(project.copySpec(spec -> {
|
||||
spec.into(relPath);
|
||||
spec.from(project.files(outDir.map(dir -> new File(dir.getAsFile(), relPath.get()))));
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -38,6 +38,12 @@ public interface TeaVMExtension extends TeaVMBaseExtension {
|
||||
|
||||
void wasi(@DelegatesTo(TeaVMWasiConfiguration.class) Closure<?> action);
|
||||
|
||||
TeaVMWasmGCConfiguration getWasmGC();
|
||||
|
||||
void wasmGC(Action<TeaVMWasmGCConfiguration> action);
|
||||
|
||||
void wasmGC(@DelegatesTo(TeaVMWasmGCConfiguration.class) Closure<?> action);
|
||||
|
||||
TeaVMCConfiguration getC();
|
||||
|
||||
void c(Action<TeaVMCConfiguration> action);
|
||||
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.teavm.gradle.api;
|
||||
|
||||
import org.gradle.api.provider.Property;
|
||||
|
||||
public interface TeaVMWasmGCConfiguration extends TeaVMCommonConfiguration, TeaVMWebConfiguration {
|
||||
Property<Boolean> getObfuscated();
|
||||
|
||||
Property<Boolean> getStrict();
|
||||
|
||||
Property<String> getTargetFileName();
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.gradle.tasks;
|
||||
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.teavm.tooling.TeaVMTargetType;
|
||||
import org.teavm.tooling.builder.BuildStrategy;
|
||||
|
||||
public abstract class GenerateWasmGCTask extends TeaVMTask {
|
||||
private static final int MB = 1024 * 1024;
|
||||
|
||||
public GenerateWasmGCTask() {
|
||||
getStrict().convention(true);
|
||||
getObfuscated().convention(true);
|
||||
}
|
||||
|
||||
@Input
|
||||
public abstract Property<Boolean> getStrict();
|
||||
|
||||
@Input
|
||||
public abstract Property<Boolean> getObfuscated();
|
||||
|
||||
@Override
|
||||
protected void setupBuilder(BuildStrategy builder) {
|
||||
builder.setStrict(getStrict().get());
|
||||
builder.setObfuscated(getObfuscated().get());
|
||||
builder.setTargetType(TeaVMTargetType.WEBASSEMBLY_GC);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user