Wasm: initial WASI support

This commit is contained in:
Alexey Andreev 2022-11-06 11:53:52 +01:00
parent d5cdd740f5
commit 1ca2c75e1c
22 changed files with 503 additions and 45 deletions

View File

@ -16,7 +16,9 @@
package org.teavm.classlib.impl.console;
import org.teavm.backend.c.intrinsic.RuntimeInclude;
import org.teavm.backend.wasm.runtime.WasmSupport;
import org.teavm.classlib.PlatformDetector;
import org.teavm.interop.Address;
import org.teavm.interop.Import;
import org.teavm.interop.Unmanaged;
import org.teavm.jso.JSBody;
@ -25,30 +27,36 @@ public final class Console {
private Console() {
}
public static void writeStderr(int b) {
public static void writeStderr(byte[] data, int off, int len) {
if (PlatformDetector.isC()) {
writeC(b);
for (int i = 0; i < len; ++i) {
byte b = data[i + off];
writeC(b & 0xFF);
}
} else if (PlatformDetector.isWebAssembly()) {
writeWasm(b);
WasmSupport.putCharsStderr(Address.ofData(data).add(off), len);
} else {
writeJs(b);
for (int i = 0; i < len; ++i) {
byte b = data[i + off];
writeJs(b & 0xFF);
}
}
}
public static void writeStdout(int b) {
public static void writeStdout(byte[] data, int off, int len) {
if (PlatformDetector.isC()) {
writeC(b);
for (int i = 0; i < len; ++i) {
byte b = data[i + off];
writeC(b & 0xFF);
}
} else if (PlatformDetector.isWebAssembly()) {
writeWasm(b);
WasmSupport.putCharsStdout(Address.ofData(data).add(off), len);
} else {
writeJsStdout(b);
for (int i = 0; i < len; ++i) {
byte b = data[i + off];
writeJs(b & 0xFF);
}
}
public static void writeStdout(String s) {
for (int i = 0; i < s.length(); ++i) {
writeStderr(s.charAt(i));
}
}
@JSBody(params = "b", script = "$rt_putStderr(b);")
@ -57,9 +65,6 @@ public final class Console {
@JSBody(params = "b", script = "$rt_putStdout(b);")
private static native void writeJsStdout(int b);
@Import(name = "putwchar", module = "teavm")
private static native void writeWasm(int b);
@Unmanaged
@Import(name = "teavm_logchar")
@RuntimeInclude("log.h")

View File

@ -0,0 +1,32 @@
/*
* Copyright 2022 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.classlib.impl.console;
import java.io.IOException;
import java.io.OutputStream;
public abstract class ConsoleOutputStream extends OutputStream {
private byte[] buffer = new byte[1];
@Override
public void write(int b) throws IOException {
buffer[0] = (byte) b;
write(buffer);
}
@Override
public abstract void write(byte[] b, int off, int len) throws IOException;
}

View File

@ -16,16 +16,15 @@
package org.teavm.classlib.impl.console;
import java.io.IOException;
import java.io.OutputStream;
public class StderrOutputStream extends OutputStream {
public class StderrOutputStream extends ConsoleOutputStream {
public static final StderrOutputStream INSTANCE = new StderrOutputStream();
private StderrOutputStream() {
}
@Override
public void write(int b) throws IOException {
Console.writeStderr(b);
public void write(byte[] b, int off, int len) throws IOException {
Console.writeStderr(b, off, len);
}
}

View File

@ -16,16 +16,15 @@
package org.teavm.classlib.impl.console;
import java.io.IOException;
import java.io.OutputStream;
public class StdoutOutputStream extends OutputStream {
public class StdoutOutputStream extends ConsoleOutputStream {
public static final StdoutOutputStream INSTANCE = new StdoutOutputStream();
private StdoutOutputStream() {
}
@Override
public void write(int b) throws IOException {
Console.writeStdout(b);
public void write(byte[] b, int off, int len) throws IOException {
Console.writeStdout(b, off, len);
}
}

View File

@ -19,6 +19,7 @@ import java.util.Enumeration;
import java.util.Properties;
import org.teavm.backend.c.intrinsic.RuntimeInclude;
import org.teavm.backend.javascript.spi.GeneratedBy;
import org.teavm.backend.wasm.runtime.WasmSupport;
import org.teavm.classlib.PlatformDetector;
import org.teavm.classlib.fs.VirtualFileSystemProvider;
import org.teavm.classlib.fs.c.CFileSystem;
@ -144,15 +145,12 @@ public final class TSystem extends TObject {
private static long currentTimeMillisLowLevel() {
if (PlatformDetector.isWebAssembly()) {
return (long) currentTimeMillisWasm();
return WasmSupport.currentTimeMillis();
} else {
return (long) currentTimeMillisC();
return currentTimeMillisC();
}
}
@Import(name = "currentTimeMillis", module = "teavm")
private static native double currentTimeMillisWasm();
@Import(name = "teavm_currentTimeMillis")
@RuntimeInclude("time.h")
private static native long currentTimeMillisC();

View File

@ -20,4 +20,6 @@ import org.teavm.vm.spi.TeaVMHostExtension;
public interface TeaVMWasmHost extends TeaVMHostExtension {
void add(WasmIntrinsicFactory intrinsicFactory);
WasmRuntimeType getRuntimeType();
}

View File

@ -15,8 +15,8 @@
*/
package org.teavm.backend.wasm;
import org.teavm.backend.wasm.runtime.WasmSupport;
import org.teavm.interop.Address;
import org.teavm.interop.Import;
import org.teavm.interop.StaticInit;
import org.teavm.interop.Unmanaged;
@ -60,8 +60,9 @@ public final class WasmHeap {
public static native void growMemory(int amount);
@Import(name = "init", module = "teavmHeapTrace")
private static native void initHeapTrace(int maxHeap);
private static void initHeapTrace(int maxHeap) {
WasmSupport.initHeapTrace(maxHeap);
}
public static void initHeap(Address start, int minHeap, int maxHeap, int stackSize) {
initHeapTrace(maxHeap);

View File

@ -15,8 +15,8 @@
*/
package org.teavm.backend.wasm;
import org.teavm.backend.wasm.runtime.WasmSupport;
import org.teavm.interop.Address;
import org.teavm.interop.Import;
import org.teavm.interop.StaticInit;
import org.teavm.interop.Unmanaged;
import org.teavm.runtime.RuntimeObject;
@ -84,17 +84,21 @@ public final class WasmRuntime {
return value;
}
@Import(name = "print", module = "spectest")
public static native void print(int a);
public static void print(int a) {
WasmSupport.print(a);
}
@Import(name = "logString", module = "teavm")
public static native void printString(String s);
public static void printString(String s) {
WasmSupport.printString(s);
}
@Import(name = "logInt", module = "teavm")
public static native void printInt(int i);
public static void printInt(int i) {
WasmSupport.printInt(i);
}
@Import(name = "logOutOfMemory", module = "teavm")
public static native void printOutOfMemory();
public static void printOutOfMemory() {
WasmSupport.printOutOfMemory();
}
public static void fillZero(Address address, int count) {
fill(address, (byte) 0, count);

View File

@ -0,0 +1,21 @@
/*
* Copyright 2022 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.backend.wasm;
public enum WasmRuntimeType {
TEAVM,
WASI
}

View File

@ -106,6 +106,7 @@ import org.teavm.backend.wasm.render.WasmCRenderer;
import org.teavm.backend.wasm.render.WasmRenderer;
import org.teavm.backend.wasm.transformation.IndirectCallTraceTransformation;
import org.teavm.backend.wasm.transformation.MemoryAccessTraceTransformation;
import org.teavm.backend.wasm.transformation.WasiSupportClassTransformer;
import org.teavm.common.ServiceRepository;
import org.teavm.dependency.ClassDependency;
import org.teavm.dependency.DependencyAnalyzer;
@ -199,6 +200,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
private boolean obfuscated;
private Set<MethodReference> asyncMethods;
private boolean hasThreads;
private WasmRuntimeType runtimeType = WasmRuntimeType.TEAVM;
@Override
public void setController(TeaVMTargetController controller) {
@ -233,6 +235,9 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
List<ClassHolderTransformer> transformers = new ArrayList<>();
transformers.add(new ClassPatch());
transformers.add(new WasmDependencyListener());
if (runtimeType == WasmRuntimeType.WASI) {
transformers.add(new WasiSupportClassTransformer());
}
return transformers;
}
@ -291,6 +296,15 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
this.obfuscated = obfuscated;
}
public void setRuntimeType(WasmRuntimeType runtimeType) {
this.runtimeType = runtimeType;
}
@Override
public WasmRuntimeType getRuntimeType() {
return runtimeType;
}
@Override
public void contributeDependencies(DependencyAnalyzer dependencyAnalyzer) {
for (Class<?> type : Arrays.asList(int.class, long.class, float.class, double.class)) {
@ -502,6 +516,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
module.add(initFunction);
module.setStartFunction(initFunction);
module.add(createStartFunction(names));
module.add(createStartCallerFunction());
for (String functionName : classGenerator.getFunctionTable()) {
WasmFunction function = module.getFunctions().get(functionName);
@ -553,6 +568,17 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
return function;
}
private WasmFunction createStartCallerFunction() {
WasmFunction function = new WasmFunction("teavm_call_start");
function.setExportName("_start");
WasmCall call = new WasmCall("teavm_start");
call.getArguments().add(new WasmInt32Constant(0));
function.getBody().add(call);
return function;
}
private class IntrinsicFactoryContext implements WasmIntrinsicFactoryContext {
@Override
public ClassReaderSource getClassSource() {

View File

@ -0,0 +1,33 @@
/*
* Copyright 2022 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.backend.wasm.runtime;
import org.teavm.interop.Address;
public final class WasiBuffer {
private static byte[] argBuffer = new byte[256];
private WasiBuffer() {
}
public static int getBufferSize() {
return argBuffer.length;
}
public static Address getBuffer() {
return Address.ofData(argBuffer);
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright 2022 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.backend.wasm.runtime;
import org.teavm.backend.wasm.wasi.IOVec;
import org.teavm.backend.wasm.wasi.LongResult;
import org.teavm.backend.wasm.wasi.SizeResult;
import org.teavm.backend.wasm.wasi.Wasi;
import org.teavm.interop.Address;
import org.teavm.interop.Structure;
import org.teavm.interop.Unmanaged;
@Unmanaged
public class WasiSupport {
private WasiSupport() {
}
@Unmanaged
public static void putCharsStdout(Address address, int count) {
putChars(1, address, count);
}
@Unmanaged
public static void putCharsStderr(Address address, int count) {
putChars(2, address, count);
}
@Unmanaged
public static void putChars(int fd, Address address, int count) {
Address argsAddress = WasiBuffer.getBuffer();
IOVec ioVec = argsAddress.toStructure();
SizeResult result = argsAddress.add(Structure.sizeOf(IOVec.class)).toStructure();
ioVec.buffer = address;
ioVec.bufferLength = count;
Wasi.fdWrite(fd, ioVec, 1, result);
}
@Unmanaged
public static long currentTimeMillis() {
Address argsAddress = WasiBuffer.getBuffer();
LongResult result = argsAddress.toStructure();
Wasi.clockTimeGet(Wasi.CLOCKID_REALTIME, 10, result);
return result.value;
}
@Unmanaged
public static void printString(String s) {
int charsInChunk = 128;
int offsetInBuffer = 128;
Address buffer = WasiBuffer.getBuffer().add(offsetInBuffer);
for (int i = 0; i < s.length(); i += charsInChunk) {
int end = Math.min(s.length(), i + charsInChunk);
int count = end - i;
for (int j = 0; j < count; ++j) {
buffer.add(offsetInBuffer + j).putByte((byte) s.charAt(j));
}
putCharsStderr(buffer, count);
}
}
@Unmanaged
public static void printInt(int i) {
int count = 0;
Address buffer = WasiBuffer.getBuffer().add(WasiBuffer.getBufferSize());
do {
++count;
buffer = buffer.add(-1);
buffer.putByte((byte) ((i % 10) + (int) '0'));
i /= 10;
} while (i > 0);
putCharsStderr(buffer, count);
}
@Unmanaged
public static void printOutOfMemory() {
printString("Out of memory");
}
@Unmanaged
public static void initHeapTrace(int maxHeap) {
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2022 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.backend.wasm.runtime;
import org.teavm.interop.Address;
import org.teavm.interop.Import;
public class WasmSupport {
private WasmSupport() {
}
@Import(name = "putwcharsOut", module = "teavm")
public static native void putCharsStderr(Address address, int count);
@Import(name = "putwcharsErr", module = "teavm")
public static native void putCharsStdout(Address address, int count);
public static long currentTimeMillis() {
return (long) currentTimeMillisImpl();
}
@Import(name = "currentTimeMillis", module = "teavm")
private static native double currentTimeMillisImpl();
@Import(name = "print", module = "spectest")
public static native void print(int a);
@Import(name = "logString", module = "teavm")
public static native void printString(String s);
@Import(name = "logInt", module = "teavm")
public static native void printInt(int i);
@Import(name = "logOutOfMemory", module = "teavm")
public static native void printOutOfMemory();
@Import(name = "init", module = "teavmHeapTrace")
public static native void initHeapTrace(int maxHeap);
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2022 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.backend.wasm.transformation;
import org.teavm.backend.wasm.runtime.WasiSupport;
import org.teavm.backend.wasm.runtime.WasmSupport;
import org.teavm.model.ClassHierarchy;
import org.teavm.model.ClassHolder;
import org.teavm.model.ClassHolderTransformer;
import org.teavm.model.ClassHolderTransformerContext;
import org.teavm.model.ClassReader;
import org.teavm.model.ElementModifier;
import org.teavm.model.MethodHolder;
import org.teavm.model.MethodReader;
import org.teavm.model.ValueType;
import org.teavm.model.emit.ProgramEmitter;
import org.teavm.model.emit.ValueEmitter;
public class WasiSupportClassTransformer implements ClassHolderTransformer {
@Override
public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) {
if (cls.getName().equals(WasmSupport.class.getName())) {
transformWasm(cls, context.getHierarchy());
}
}
private void transformWasm(ClassHolder cls, ClassHierarchy classHierarchy) {
ClassReader sourceCls = classHierarchy.getClassSource().get(WasiSupport.class.getName());
for (MethodHolder method : cls.getMethods()) {
MethodReader sourceMethod = sourceCls.getMethod(method.getDescriptor());
if (sourceMethod != null) {
if (method.hasModifier(ElementModifier.NATIVE)) {
method.getModifiers().remove(ElementModifier.NATIVE);
}
ProgramEmitter pe = ProgramEmitter.create(method, classHierarchy);
ValueEmitter[] args = new ValueEmitter[method.parameterCount()];
for (int i = 0; i < args.length; ++i) {
args[i] = pe.var(i + 1, method.parameterType(i));
}
ValueEmitter result = pe.invoke(sourceMethod.getReference(), args);
if (method.getResultType() != ValueType.VOID) {
result.returnValue();
} else {
pe.exit();
}
}
}
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright 2022 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.backend.wasm.wasi;
import org.teavm.interop.Address;
import org.teavm.interop.Structure;
public class IOVec extends Structure {
public Address buffer;
public int bufferLength;
}

View File

@ -0,0 +1,22 @@
/*
* Copyright 2022 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.backend.wasm.wasi;
import org.teavm.interop.Structure;
public class LongResult extends Structure {
public long value;
}

View File

@ -0,0 +1,22 @@
/*
* Copyright 2022 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.backend.wasm.wasi;
import org.teavm.interop.Structure;
public class SizeResult extends Structure {
public int value;
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2022 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.backend.wasm.wasi;
import org.teavm.interop.Import;
public final class Wasi {
public static final int CLOCKID_REALTIME = 0;
private Wasi() {
}
@Import(name = "fd_write", module = "wasi_snapshot_preview1")
public static native short fdWrite(int fd, IOVec vectors, int vectorsCont, SizeResult result);
@Import(name = "clock_time_get", module = "wasi_snapshot_preview1")
public static native short clockTimeGet(int clockId, long precision, LongResult result);
}

View File

@ -31,6 +31,14 @@ TeaVM.wasm = function() {
lineBuffer += String.fromCharCode(charCode);
}
}
function putwchars(buffer, count) {
let instance = controller.instance;
let memory = instance.exports.memory.buffer;
for (let i = 0; i < count; ++i) {
// TODO: support UTF-8
putwchar(memory[buffer++]);
}
}
function towlower(code) {
return String.fromCharCode(code).toLowerCase().charCodeAt(0);
}
@ -90,7 +98,8 @@ TeaVM.wasm = function() {
teavm_getNaN: function() { return NaN; },
isinf: function(n) { return !isFinite(n) },
isfinite: isFinite,
putwchar: putwchar,
putwcharsOut: (chars, count) => putwchars(controller, chars, count),
putwcharsErr: (chars, count) => putwchars(controller, chars, count),
towlower: towlower,
towupper: towupper,
getNativeOffset: getNativeOffset,

View File

@ -58,7 +58,7 @@ public final class TeaVMRunner {
options.addOption(Option.builder("t")
.argName("target")
.hasArg()
.desc("target type (javascript/js, webassembly/wasm, C)")
.desc("target type (javascript/js, webassembly/wasm, webassembly-wasi/wasm-wasi/wasi, C)")
.build());
options.addOption(Option.builder("d")
.argName("directory")
@ -220,6 +220,11 @@ public final class TeaVMRunner {
case "wasm":
tool.setTargetType(TeaVMTargetType.WEBASSEMBLY);
break;
case "webassembly-wasi":
case "wasm-wasi":
case "wasi":
tool.setTargetType(TeaVMTargetType.WEBASSEMBLY);
break;
case "c":
tool.setTargetType(TeaVMTargetType.C);
break;

View File

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

View File

@ -37,6 +37,7 @@ import org.teavm.backend.c.generate.CNameProvider;
import org.teavm.backend.c.generate.ShorteningFileNameProvider;
import org.teavm.backend.c.generate.SimpleFileNameProvider;
import org.teavm.backend.javascript.JavaScriptTarget;
import org.teavm.backend.wasm.WasmRuntimeType;
import org.teavm.backend.wasm.WasmTarget;
import org.teavm.backend.wasm.render.WasmBinaryVersion;
import org.teavm.cache.AlwaysStaleCacheStatus;
@ -315,7 +316,9 @@ public class TeaVMTool {
case JAVASCRIPT:
return prepareJavaScriptTarget();
case WEBASSEMBLY:
return prepareWebAssemblyTarget();
return prepareWebAssemblyDefaultTarget();
case WEBASSEMBLY_WASI:
return prepareWebAssemblyWasiTarget();
case C:
return prepareCTarget();
}
@ -347,6 +350,18 @@ public class TeaVMTool {
return webAssemblyTarget;
}
private WasmTarget prepareWebAssemblyDefaultTarget() {
WasmTarget target = prepareWebAssemblyTarget();
target.setRuntimeType(WasmRuntimeType.TEAVM);
return target;
}
private WasmTarget prepareWebAssemblyWasiTarget() {
WasmTarget target = prepareWebAssemblyTarget();
target.setRuntimeType(WasmRuntimeType.WASI);
return target;
}
private CTarget prepareCTarget() {
cTarget = new CTarget(new CNameProvider());
cTarget.setMinHeapSize(minHeapSize);