mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: support passing arguments to main method
This commit is contained in:
parent
e61301576b
commit
73edc0cf6e
|
@ -15,20 +15,21 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm;
|
package org.teavm.backend.wasm;
|
||||||
|
|
||||||
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
|
||||||
import org.teavm.backend.wasm.generate.gc.WasmGCDeclarationsGenerator;
|
import org.teavm.backend.wasm.generate.gc.WasmGCDeclarationsGenerator;
|
||||||
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
|
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmGlobal;
|
import org.teavm.backend.wasm.model.WasmGlobal;
|
||||||
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCall;
|
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmDrop;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmFunctionReference;
|
import org.teavm.backend.wasm.model.expression.WasmFunctionReference;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmGetGlobal;
|
import org.teavm.backend.wasm.model.expression.WasmGetGlobal;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
|
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmSetGlobal;
|
import org.teavm.backend.wasm.model.expression.WasmSetGlobal;
|
||||||
|
import org.teavm.backend.wasm.runtime.WasmGCSupport;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
@ -56,25 +57,92 @@ public class WasmGCModuleGenerator {
|
||||||
public WasmFunction generateMainFunction(String entryPoint) {
|
public WasmFunction generateMainFunction(String entryPoint) {
|
||||||
var mainFunction = declarationsGenerator.functions().forStaticMethod(new MethodReference(entryPoint,
|
var mainFunction = declarationsGenerator.functions().forStaticMethod(new MethodReference(entryPoint,
|
||||||
"main", ValueType.parse(String[].class), ValueType.VOID));
|
"main", ValueType.parse(String[].class), ValueType.VOID));
|
||||||
var mainFunctionCaller = new WasmFunction(declarationsGenerator.functionTypes.of(null));
|
var stringArrayType = declarationsGenerator.typeMapper()
|
||||||
|
.mapType(ValueType.parse(String[].class));
|
||||||
|
var mainFunctionCaller = new WasmFunction(declarationsGenerator.functionTypes.of(null, stringArrayType));
|
||||||
|
var argsLocal = new WasmLocal(stringArrayType, "args");
|
||||||
declarationsGenerator.module.functions.add(mainFunctionCaller);
|
declarationsGenerator.module.functions.add(mainFunctionCaller);
|
||||||
mainFunctionCaller.getBody().add(callInitializer());
|
mainFunctionCaller.getBody().add(callInitializer());
|
||||||
|
|
||||||
var tempVars = new TemporaryVariablePool(mainFunctionCaller);
|
var callToMainFunction = new WasmCall(mainFunction, new WasmGetLocal(argsLocal));
|
||||||
var genUtil = new WasmGCGenerationUtil(declarationsGenerator.classInfoProvider(), tempVars);
|
|
||||||
var stringArrayType = declarationsGenerator.typeMapper()
|
|
||||||
.mapType(ValueType.parse(String[].class));
|
|
||||||
var arrayVar = tempVars.acquire(stringArrayType);
|
|
||||||
genUtil.allocateArray(ValueType.parse(String.class), new WasmInt32Constant(0), null,
|
|
||||||
arrayVar, mainFunctionCaller.getBody());
|
|
||||||
var callToMainFunction = new WasmCall(mainFunction, new WasmGetLocal(arrayVar));
|
|
||||||
mainFunctionCaller.getBody().add(callToMainFunction);
|
mainFunctionCaller.getBody().add(callToMainFunction);
|
||||||
mainFunctionCaller.getBody().add(new WasmReturn());
|
mainFunctionCaller.getBody().add(new WasmReturn());
|
||||||
tempVars.release(arrayVar);
|
|
||||||
|
|
||||||
return mainFunctionCaller;
|
return mainFunctionCaller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WasmFunction generateCreateStringBuilderFunction() {
|
||||||
|
var function = declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
||||||
|
WasmGCSupport.class, "createStringBuilder", StringBuilder.class));
|
||||||
|
var caller = new WasmFunction(function.getType());
|
||||||
|
caller.getBody().add(callInitializer());
|
||||||
|
caller.getBody().add(new WasmReturn(new WasmCall(function)));
|
||||||
|
declarationsGenerator.module.functions.add(caller);
|
||||||
|
return caller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WasmFunction generateCreateStringArrayFunction() {
|
||||||
|
var function = declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
||||||
|
WasmGCSupport.class, "createStringArray", int.class, String[].class));
|
||||||
|
var caller = new WasmFunction(function.getType());
|
||||||
|
var sizeLocal = new WasmLocal(WasmType.INT32);
|
||||||
|
caller.add(sizeLocal);
|
||||||
|
caller.getBody().add(callInitializer());
|
||||||
|
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(sizeLocal))));
|
||||||
|
declarationsGenerator.module.functions.add(caller);
|
||||||
|
return caller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WasmFunction generateAppendCharFunction() {
|
||||||
|
var function = declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
||||||
|
StringBuilder.class, "append", char.class, StringBuilder.class));
|
||||||
|
var stringBuilderType = declarationsGenerator.typeMapper().mapType(ValueType.parse(StringBuilder.class));
|
||||||
|
var caller = new WasmFunction(declarationsGenerator.functionTypes.of(null, stringBuilderType, WasmType.INT32));
|
||||||
|
var stringBuilderLocal = new WasmLocal(stringBuilderType);
|
||||||
|
var codeLocal = new WasmLocal(WasmType.INT32);
|
||||||
|
caller.add(stringBuilderLocal);
|
||||||
|
caller.add(codeLocal);
|
||||||
|
caller.getBody().add(callInitializer());
|
||||||
|
caller.getBody().add(new WasmDrop(new WasmCall(function, new WasmGetLocal(stringBuilderLocal),
|
||||||
|
new WasmGetLocal(codeLocal))));
|
||||||
|
caller.getBody().add(new WasmReturn());
|
||||||
|
declarationsGenerator.module.functions.add(caller);
|
||||||
|
return caller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WasmFunction generateBuildStringFunction() {
|
||||||
|
var function = declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
||||||
|
StringBuilder.class, "toString", String.class));
|
||||||
|
var stringBuilderType = declarationsGenerator.typeMapper().mapType(ValueType.parse(StringBuilder.class));
|
||||||
|
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
||||||
|
var caller = new WasmFunction(declarationsGenerator.functionTypes.of(stringType, stringBuilderType));
|
||||||
|
var stringBuilderLocal = new WasmLocal(stringBuilderType);
|
||||||
|
caller.add(stringBuilderLocal);
|
||||||
|
caller.getBody().add(callInitializer());
|
||||||
|
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(stringBuilderLocal))));
|
||||||
|
declarationsGenerator.module.functions.add(caller);
|
||||||
|
return caller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WasmFunction generateSetToStringArrayFunction() {
|
||||||
|
var function = declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
||||||
|
WasmGCSupport.class, "setToStringArray", String[].class, int.class, String.class, void.class));
|
||||||
|
var stringArrayType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String[].class));
|
||||||
|
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
||||||
|
var caller = new WasmFunction(function.getType());
|
||||||
|
var arrayLocal = new WasmLocal(stringArrayType);
|
||||||
|
var indexLocal = new WasmLocal(WasmType.INT32);
|
||||||
|
var valueLocal = new WasmLocal(stringType);
|
||||||
|
caller.add(arrayLocal);
|
||||||
|
caller.add(indexLocal);
|
||||||
|
caller.add(valueLocal);
|
||||||
|
caller.getBody().add(callInitializer());
|
||||||
|
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(arrayLocal),
|
||||||
|
new WasmGetLocal(indexLocal), new WasmGetLocal(valueLocal))));
|
||||||
|
declarationsGenerator.module.functions.add(caller);
|
||||||
|
return caller;
|
||||||
|
}
|
||||||
|
|
||||||
private void createInitializer() {
|
private void createInitializer() {
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -75,7 +75,9 @@ public class WasmGCTarget implements TeaVMTarget {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contributeDependencies(DependencyAnalyzer dependencyAnalyzer) {
|
public void contributeDependencies(DependencyAnalyzer dependencyAnalyzer) {
|
||||||
new WasmGCDependencies(dependencyAnalyzer).contribute();
|
var deps = new WasmGCDependencies(dependencyAnalyzer);
|
||||||
|
deps.contribute();
|
||||||
|
deps.contributeStandardExports();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -122,9 +124,26 @@ public class WasmGCTarget implements TeaVMTarget {
|
||||||
);
|
);
|
||||||
declarationsGenerator.setFriendlyToDebugger(controller.isFriendlyToDebugger());
|
declarationsGenerator.setFriendlyToDebugger(controller.isFriendlyToDebugger());
|
||||||
var moduleGenerator = new WasmGCModuleGenerator(declarationsGenerator);
|
var moduleGenerator = new WasmGCModuleGenerator(declarationsGenerator);
|
||||||
|
|
||||||
var mainFunction = moduleGenerator.generateMainFunction(controller.getEntryPoint());
|
var mainFunction = moduleGenerator.generateMainFunction(controller.getEntryPoint());
|
||||||
mainFunction.setExportName(controller.getEntryPointName());
|
mainFunction.setExportName(controller.getEntryPointName());
|
||||||
mainFunction.setName(controller.getEntryPointName());
|
mainFunction.setName(controller.getEntryPointName());
|
||||||
|
|
||||||
|
var stringBuilderFunction = moduleGenerator.generateCreateStringBuilderFunction();
|
||||||
|
stringBuilderFunction.setExportName("createStringBuilder");
|
||||||
|
|
||||||
|
var createStringArrayFunction = moduleGenerator.generateCreateStringArrayFunction();
|
||||||
|
createStringArrayFunction.setExportName("createStringArray");
|
||||||
|
|
||||||
|
var appendCharFunction = moduleGenerator.generateAppendCharFunction();
|
||||||
|
appendCharFunction.setExportName("appendChar");
|
||||||
|
|
||||||
|
var buildStringFunction = moduleGenerator.generateBuildStringFunction();
|
||||||
|
buildStringFunction.setExportName("buildString");
|
||||||
|
|
||||||
|
var setArrayFunction = moduleGenerator.generateSetToStringArrayFunction();
|
||||||
|
setArrayFunction.setExportName("setToStringArray");
|
||||||
|
|
||||||
moduleGenerator.generate();
|
moduleGenerator.generate();
|
||||||
adjustModuleMemory(module);
|
adjustModuleMemory(module);
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,24 @@ public class WasmGCDependencies {
|
||||||
contributeInitializerUtils();
|
contributeInitializerUtils();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void contributeStandardExports() {
|
||||||
|
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "createStringArray", int.class, String[].class))
|
||||||
|
.use();
|
||||||
|
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "createStringBuilder", StringBuilder.class))
|
||||||
|
.use();
|
||||||
|
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "setToStringArray", String[].class,
|
||||||
|
int.class, String.class, void.class))
|
||||||
|
.propagate(1, analyzer.getType("[java/lang/String;"))
|
||||||
|
.propagate(3, analyzer.getType("java.lang.String"))
|
||||||
|
.use();
|
||||||
|
analyzer.linkMethod(new MethodReference(StringBuilder.class, "append", char.class, StringBuilder.class))
|
||||||
|
.propagate(0, analyzer.getType("java.lang.StringBuilder"))
|
||||||
|
.use();
|
||||||
|
analyzer.linkMethod(new MethodReference(StringBuilder.class, "toString", String.class))
|
||||||
|
.propagate(0, analyzer.getType("java.lang.StringBuilder"))
|
||||||
|
.use();
|
||||||
|
}
|
||||||
|
|
||||||
private void contributeMathUtils() {
|
private void contributeMathUtils() {
|
||||||
for (var type : Arrays.asList(int.class, long.class, float.class, double.class)) {
|
for (var type : Arrays.asList(int.class, long.class, float.class, double.class)) {
|
||||||
var method = new MethodReference(WasmRuntime.class, "compare", type, type, int.class);
|
var method = new MethodReference(WasmRuntime.class, "compare", type, type, int.class);
|
||||||
|
|
|
@ -1105,6 +1105,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
public void visit(ReturnStatement statement) {
|
public void visit(ReturnStatement statement) {
|
||||||
if (statement.getResult() != null) {
|
if (statement.getResult() != null) {
|
||||||
acceptWithType(statement.getResult(), currentMethod.getReturnType());
|
acceptWithType(statement.getResult(), currentMethod.getReturnType());
|
||||||
|
result = forceType(result, currentMethod.getReturnType());
|
||||||
} else {
|
} else {
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
|
@ -1113,6 +1114,10 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
resultConsumer.add(wasmStatement);
|
resultConsumer.add(wasmStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected WasmExpression forceType(WasmExpression expression, ValueType type) {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InstanceOfExpr expr) {
|
public void visit(InstanceOfExpr expr) {
|
||||||
acceptWithType(expr.getExpr(), expr.getType());
|
acceptWithType(expr.getExpr(), expr.getType());
|
||||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.backend.wasm.generate.gc.methods;
|
||||||
|
|
||||||
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
|
import org.teavm.backend.wasm.gc.WasmGCMethodReturnTypes;
|
||||||
import org.teavm.backend.wasm.generate.common.methods.BaseWasmGenerationContext;
|
import org.teavm.backend.wasm.generate.common.methods.BaseWasmGenerationContext;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCStandardClasses;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCStandardClasses;
|
||||||
|
@ -48,6 +49,7 @@ public class WasmGCGenerationContext implements BaseWasmGenerationContext {
|
||||||
private WasmGCSupertypeFunctionProvider supertypeFunctions;
|
private WasmGCSupertypeFunctionProvider supertypeFunctions;
|
||||||
private WasmGCCustomGeneratorProvider customGenerators;
|
private WasmGCCustomGeneratorProvider customGenerators;
|
||||||
private WasmGCIntrinsicProvider intrinsics;
|
private WasmGCIntrinsicProvider intrinsics;
|
||||||
|
private WasmGCMethodReturnTypes returnTypes;
|
||||||
private WasmFunction npeMethod;
|
private WasmFunction npeMethod;
|
||||||
private WasmFunction aaiobeMethod;
|
private WasmFunction aaiobeMethod;
|
||||||
private WasmFunction cceMethod;
|
private WasmFunction cceMethod;
|
||||||
|
@ -59,7 +61,8 @@ public class WasmGCGenerationContext implements BaseWasmGenerationContext {
|
||||||
ClassHierarchy hierarchy, BaseWasmFunctionRepository functions,
|
ClassHierarchy hierarchy, BaseWasmFunctionRepository functions,
|
||||||
WasmGCSupertypeFunctionProvider supertypeFunctions, WasmGCClassInfoProvider classInfoProvider,
|
WasmGCSupertypeFunctionProvider supertypeFunctions, WasmGCClassInfoProvider classInfoProvider,
|
||||||
WasmGCStandardClasses standardClasses, WasmGCStringProvider strings,
|
WasmGCStandardClasses standardClasses, WasmGCStringProvider strings,
|
||||||
WasmGCCustomGeneratorProvider customGenerators, WasmGCIntrinsicProvider intrinsics) {
|
WasmGCCustomGeneratorProvider customGenerators, WasmGCIntrinsicProvider intrinsics,
|
||||||
|
WasmGCMethodReturnTypes returnTypes) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.virtualTables = virtualTables;
|
this.virtualTables = virtualTables;
|
||||||
this.typeMapper = typeMapper;
|
this.typeMapper = typeMapper;
|
||||||
|
@ -73,6 +76,7 @@ public class WasmGCGenerationContext implements BaseWasmGenerationContext {
|
||||||
this.strings = strings;
|
this.strings = strings;
|
||||||
this.customGenerators = customGenerators;
|
this.customGenerators = customGenerators;
|
||||||
this.intrinsics = intrinsics;
|
this.intrinsics = intrinsics;
|
||||||
|
this.returnTypes = returnTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmGCClassInfoProvider classInfoProvider() {
|
public WasmGCClassInfoProvider classInfoProvider() {
|
||||||
|
@ -172,4 +176,8 @@ public class WasmGCGenerationContext implements BaseWasmGenerationContext {
|
||||||
public WasmGCIntrinsicProvider intrinsics() {
|
public WasmGCIntrinsicProvider intrinsics() {
|
||||||
return intrinsics;
|
return intrinsics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WasmGCMethodReturnTypes returnTypes() {
|
||||||
|
return returnTypes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -408,6 +408,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
result = invocation(expr, null, false);
|
result = invocation(expr, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WasmExpression invocation(InvocationExpr expr, List<WasmExpression> resultConsumer, boolean willDrop) {
|
protected WasmExpression invocation(InvocationExpr expr, List<WasmExpression> resultConsumer, boolean willDrop) {
|
||||||
if (expr.getType() == InvocationType.SPECIAL || expr.getType() == InvocationType.STATIC) {
|
if (expr.getType() == InvocationType.SPECIAL || expr.getType() == InvocationType.STATIC) {
|
||||||
|
@ -435,26 +436,34 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
@Override
|
@Override
|
||||||
protected WasmExpression mapFirstArgumentForCall(WasmExpression argument, WasmFunction function,
|
protected WasmExpression mapFirstArgumentForCall(WasmExpression argument, WasmFunction function,
|
||||||
MethodReference method) {
|
MethodReference method) {
|
||||||
argument.acceptVisitor(typeInference);
|
return forceType(argument, function.getType().getParameterTypes().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WasmExpression forceType(WasmExpression expression, ValueType type) {
|
||||||
|
return forceType(expression, mapType(context.returnTypes().returnTypeOf(currentMethod)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private WasmExpression forceType(WasmExpression expression, WasmType expectedType) {
|
||||||
|
expression.acceptVisitor(typeInference);
|
||||||
var actualType = typeInference.getResult();
|
var actualType = typeInference.getResult();
|
||||||
var expectedType = function.getType().getParameterTypes().get(0);
|
|
||||||
if (actualType == expectedType || !(actualType instanceof WasmType.CompositeReference)
|
if (actualType == expectedType || !(actualType instanceof WasmType.CompositeReference)
|
||||||
|| !(expectedType instanceof WasmType.CompositeReference)) {
|
|| !(expectedType instanceof WasmType.CompositeReference)) {
|
||||||
return argument;
|
return expression;
|
||||||
}
|
}
|
||||||
var actualComposite = ((WasmType.CompositeReference) actualType).composite;
|
var actualComposite = ((WasmType.CompositeReference) actualType).composite;
|
||||||
var expectedComposite = ((WasmType.CompositeReference) expectedType).composite;
|
var expectedComposite = ((WasmType.CompositeReference) expectedType).composite;
|
||||||
if (!(actualComposite instanceof WasmStructure) || !(expectedComposite instanceof WasmStructure)) {
|
if (!(actualComposite instanceof WasmStructure) || !(expectedComposite instanceof WasmStructure)) {
|
||||||
return argument;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
var actualStruct = (WasmStructure) actualComposite;
|
var actualStruct = (WasmStructure) actualComposite;
|
||||||
var expectedStruct = (WasmStructure) expectedComposite;
|
var expectedStruct = (WasmStructure) expectedComposite;
|
||||||
if (!actualStruct.isSupertypeOf(expectedStruct)) {
|
if (!actualStruct.isSupertypeOf(expectedStruct)) {
|
||||||
return argument;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new WasmCast(argument, expectedComposite.getReference());
|
return new WasmCast(expression, expectedComposite.getReference());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -302,7 +302,8 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
standardClasses,
|
standardClasses,
|
||||||
strings,
|
strings,
|
||||||
customGenerators,
|
customGenerators,
|
||||||
intrinsics
|
intrinsics,
|
||||||
|
returnTypes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
|
|
|
@ -85,4 +85,16 @@ public class WasmGCSupport {
|
||||||
private static native byte nextByte();
|
private static native byte nextByte();
|
||||||
|
|
||||||
private static native void error();
|
private static native void error();
|
||||||
|
|
||||||
|
public static StringBuilder createStringBuilder() {
|
||||||
|
return new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] createStringArray(int size) {
|
||||||
|
return new String[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setToStringArray(String[] array, int index, String value) {
|
||||||
|
array[index] = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var TeaVM = TeaVM || {};
|
||||||
|
TeaVM.wasm = function() {
|
||||||
|
function defaults(imports) {
|
||||||
|
let stderr = "";
|
||||||
|
let stdout = "";
|
||||||
|
imports.teavm = {
|
||||||
|
putcharStderr(c) {
|
||||||
|
if (c === 10) {
|
||||||
|
console.error(stderr);
|
||||||
|
stderr = "";
|
||||||
|
} else {
|
||||||
|
stderr += String.fromCharCode(c);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
putcharStdout(c) {
|
||||||
|
if (c === 10) {
|
||||||
|
console.log(stdout);
|
||||||
|
stdout = "";
|
||||||
|
} else {
|
||||||
|
stdout += String.fromCharCode(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function load(path, options) {
|
||||||
|
if (!options) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const importObj = {};
|
||||||
|
defaults(importObj);
|
||||||
|
if (typeof options.installImports !== "undefined") {
|
||||||
|
options.installImports(importObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WebAssembly.instantiateStreaming(fetch(path), importObj).then((obj => {
|
||||||
|
let teavm = {};
|
||||||
|
teavm.main = createMain(obj.instance);
|
||||||
|
return teavm;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMain(instance) {
|
||||||
|
return args => {
|
||||||
|
if (typeof args === "undefined") {
|
||||||
|
args = [];
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let exports = instance.exports;
|
||||||
|
let javaArgs = exports.createStringArray(args.length);
|
||||||
|
for (let i = 0; i < args.length; ++i) {
|
||||||
|
let arg = args[i];
|
||||||
|
let javaArg = exports.createStringBuilder();
|
||||||
|
for (let j = 0; j < arg.length; ++j) {
|
||||||
|
exports.appendChar(javaArg, arg.charCodeAt(j));
|
||||||
|
}
|
||||||
|
exports.setToStringArray(javaArgs, i, exports.buildString(javaArg));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
exports.main(javaArgs);
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { load };
|
||||||
|
}();
|
Loading…
Reference in New Issue
Block a user