mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: fix some issues and implement intrinsics
* properly cast exception type on catch blocks * generate virtual table structures lazily * fix calculation of types of a.field values
This commit is contained in:
parent
4823109be5
commit
10c3731c43
|
@ -299,6 +299,8 @@ public final class TMath extends TObject {
|
||||||
return randomC();
|
return randomC();
|
||||||
} else if (PlatformDetector.isWebAssembly()) {
|
} else if (PlatformDetector.isWebAssembly()) {
|
||||||
return WasmSupport.random();
|
return WasmSupport.random();
|
||||||
|
} else if (PlatformDetector.isWebAssemblyGC()) {
|
||||||
|
return randomWasmGC();
|
||||||
} else {
|
} else {
|
||||||
return randomImpl();
|
return randomImpl();
|
||||||
}
|
}
|
||||||
|
@ -310,6 +312,9 @@ public final class TMath extends TObject {
|
||||||
@GeneratedBy(MathNativeGenerator.class)
|
@GeneratedBy(MathNativeGenerator.class)
|
||||||
private static native double randomImpl();
|
private static native double randomImpl();
|
||||||
|
|
||||||
|
@Import(module = "teavmMath", name = "random")
|
||||||
|
private static native double randomWasmGC();
|
||||||
|
|
||||||
public static int min(int a, int b) {
|
public static int min(int a, int b) {
|
||||||
return a < b ? a : b;
|
return a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
|
@ -401,6 +401,7 @@ class StatementGenerator implements InstructionVisitor {
|
||||||
if (insn.getInstance() != null) {
|
if (insn.getInstance() != null) {
|
||||||
AssignmentStatement stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()),
|
AssignmentStatement stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()),
|
||||||
Expr.qualify(Expr.var(insn.getInstance().getIndex()), insn.getField()));
|
Expr.qualify(Expr.var(insn.getInstance().getIndex()), insn.getField()));
|
||||||
|
stmt.getRightValue().setVariableIndex(insn.getReceiver().getIndex());
|
||||||
stmt.setLocation(currentLocation);
|
stmt.setLocation(currentLocation);
|
||||||
statements.add(stmt);
|
statements.add(stmt);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -175,7 +175,8 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void catchException(TextLocation location, List<WasmExpression> target, WasmLocal local) {
|
protected void catchException(TextLocation location, List<WasmExpression> target, WasmLocal local,
|
||||||
|
String exceptionClass) {
|
||||||
var call = new WasmCall(context.functions().forStaticMethod(CATCH_METHOD));
|
var call = new WasmCall(context.functions().forStaticMethod(CATCH_METHOD));
|
||||||
if (local != null) {
|
if (local != null) {
|
||||||
var save = new WasmSetLocal(local, call);
|
var save = new WasmSetLocal(local, call);
|
||||||
|
|
|
@ -1300,7 +1300,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
var catchLocal = tryCatch.getExceptionVariable() != null
|
var catchLocal = tryCatch.getExceptionVariable() != null
|
||||||
? localVar(tryCatch.getExceptionVariable())
|
? localVar(tryCatch.getExceptionVariable())
|
||||||
: null;
|
: null;
|
||||||
catchException(null, catchBlock.getBody(), catchLocal);
|
catchException(null, catchBlock.getBody(), catchLocal, tryCatch.getExceptionType());
|
||||||
visitMany(tryCatch.getHandler(), catchBlock.getBody());
|
visitMany(tryCatch.getHandler(), catchBlock.getBody());
|
||||||
if (!catchBlock.isTerminating() && catchBlock != outerCatchBlock) {
|
if (!catchBlock.isTerminating() && catchBlock != outerCatchBlock) {
|
||||||
catchBlock.getBody().add(new WasmBreak(outerCatchBlock));
|
catchBlock.getBody().add(new WasmBreak(outerCatchBlock));
|
||||||
|
@ -1313,7 +1313,8 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
|
|
||||||
protected abstract WasmExpression peekException();
|
protected abstract WasmExpression peekException();
|
||||||
|
|
||||||
protected abstract void catchException(TextLocation location, List<WasmExpression> target, WasmLocal local);
|
protected abstract void catchException(TextLocation location, List<WasmExpression> target, WasmLocal local,
|
||||||
|
String exceptionClass);
|
||||||
|
|
||||||
private void visitMany(List<Statement> statements, List<WasmExpression> target) {
|
private void visitMany(List<Statement> statements, List<WasmExpression> target) {
|
||||||
var oldTarget = resultConsumer;
|
var oldTarget = resultConsumer;
|
||||||
|
|
|
@ -129,6 +129,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
private WasmFunction arrayLengthObjectFunction;
|
private WasmFunction arrayLengthObjectFunction;
|
||||||
private WasmFunctionType arrayGetType;
|
private WasmFunctionType arrayGetType;
|
||||||
private WasmFunctionType arrayLengthType;
|
private WasmFunctionType arrayLengthType;
|
||||||
|
private List<WasmStructure> nonInitializedStructures = new ArrayList<>();
|
||||||
|
|
||||||
public WasmGCClassGenerator(WasmModule module, ClassReaderSource classSource,
|
public WasmGCClassGenerator(WasmModule module, ClassReaderSource classSource,
|
||||||
WasmFunctionTypes functionTypes, TagRegistry tagRegistry,
|
WasmFunctionTypes functionTypes, TagRegistry tagRegistry,
|
||||||
|
@ -163,10 +164,22 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
var classInfo = classInfoQueue.remove();
|
var classInfo = classInfoQueue.remove();
|
||||||
classInfo.initializer.accept(initializerFunctionStatements);
|
classInfo.initializer.accept(initializerFunctionStatements);
|
||||||
classInfo.initializer = null;
|
classInfo.initializer = null;
|
||||||
|
initStructures();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initStructures() {
|
||||||
|
if (nonInitializedStructures.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var copy = List.copyOf(nonInitializedStructures);
|
||||||
|
nonInitializedStructures.clear();
|
||||||
|
for (var structure : copy) {
|
||||||
|
structure.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contributeToInitializerDefinitions(WasmFunction function) {
|
public void contributeToInitializerDefinitions(WasmFunction function) {
|
||||||
fillVirtualTableSupertypes();
|
fillVirtualTableSupertypes();
|
||||||
|
@ -269,6 +282,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
classInfo.structure = new WasmStructure(name != null ? names.forClass(name) : null,
|
classInfo.structure = new WasmStructure(name != null ? names.forClass(name) : null,
|
||||||
fields -> fillFields(finalClassInfo, fields, type));
|
fields -> fillFields(finalClassInfo, fields, type));
|
||||||
module.types.add(classInfo.structure);
|
module.types.add(classInfo.structure);
|
||||||
|
nonInitializedStructures.add(classInfo.structure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
|
@ -698,12 +712,14 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
|
|
||||||
private WasmStructure initRegularClassStructure(String className) {
|
private WasmStructure initRegularClassStructure(String className) {
|
||||||
var virtualTable = virtualTables.lookup(className);
|
var virtualTable = virtualTables.lookup(className);
|
||||||
var structure = new WasmStructure(names.forClassClass(className));
|
var structure = new WasmStructure(names.forClassClass(className), fields -> {
|
||||||
|
addSystemFields(fields);
|
||||||
|
fillSimpleClassFields(fields, "java.lang.Class");
|
||||||
|
addVirtualTableFields(fields, virtualTable);
|
||||||
|
});
|
||||||
|
nonInitializedStructures.add(structure);
|
||||||
structure.setSupertype(standardClasses.classClass().getStructure());
|
structure.setSupertype(standardClasses.classClass().getStructure());
|
||||||
module.types.add(structure);
|
module.types.add(structure);
|
||||||
addSystemFields(structure.getFields());
|
|
||||||
fillSimpleClassFields(structure.getFields(), "java.lang.Class");
|
|
||||||
addVirtualTableFields(structure, virtualTable);
|
|
||||||
return structure;
|
return structure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,46 +732,49 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
fields.add(monitorField);
|
fields.add(monitorField);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addVirtualTableFields(WasmStructure structure, WasmGCVirtualTable virtualTable) {
|
private void addVirtualTableFields(List<WasmField> fields, WasmGCVirtualTable virtualTable) {
|
||||||
for (var entry : virtualTable.getEntries()) {
|
for (var entry : virtualTable.getEntries()) {
|
||||||
var functionType = typeMapper.getFunctionType(entry.getOrigin().getClassName(), entry.getMethod(), false);
|
var functionType = typeMapper.getFunctionType(entry.getOrigin().getClassName(), entry.getMethod(), false);
|
||||||
var field = new WasmField(functionType.getReference().asStorage());
|
var field = new WasmField(functionType.getReference().asStorage());
|
||||||
field.setName(names.forVirtualMethod(entry.getMethod()));
|
field.setName(names.forVirtualMethod(entry.getMethod()));
|
||||||
structure.getFields().add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WasmStructure getArrayVirtualTableStructure() {
|
public WasmStructure getArrayVirtualTableStructure() {
|
||||||
if (arrayVirtualTableStruct == null) {
|
if (arrayVirtualTableStruct == null) {
|
||||||
arrayVirtualTableStruct = new WasmStructure(null);
|
arrayVirtualTableStruct = new WasmStructure(null, fields -> {
|
||||||
|
addSystemFields(fields);
|
||||||
|
fillSimpleClassFields(fields, "java.lang.Class");
|
||||||
|
addVirtualTableFields(fields, virtualTables.lookup("java.lang.Object"));
|
||||||
|
if (metadataRequirements.hasArrayLength()) {
|
||||||
|
arrayLengthOffset = fields.size();
|
||||||
|
var arrayLengthType = getArrayLengthType();
|
||||||
|
fields.add(new WasmField(arrayLengthType.getReference().asStorage()));
|
||||||
|
}
|
||||||
|
if (metadataRequirements.hasArrayGet()) {
|
||||||
|
arrayGetOffset = fields.size();
|
||||||
|
var arrayGetType = getArrayGetType();
|
||||||
|
fields.add(new WasmField(arrayGetType.getReference().asStorage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
arrayVirtualTableStruct.setSupertype(standardClasses.objectClass().getVirtualTableStructure());
|
arrayVirtualTableStruct.setSupertype(standardClasses.objectClass().getVirtualTableStructure());
|
||||||
module.types.add(arrayVirtualTableStruct);
|
module.types.add(arrayVirtualTableStruct);
|
||||||
addSystemFields(arrayVirtualTableStruct.getFields());
|
nonInitializedStructures.add(arrayVirtualTableStruct);
|
||||||
fillSimpleClassFields(arrayVirtualTableStruct.getFields(), "java.lang.Class");
|
|
||||||
addVirtualTableFields(arrayVirtualTableStruct, virtualTables.lookup("java.lang.Object"));
|
|
||||||
|
|
||||||
if (metadataRequirements.hasArrayLength()) {
|
|
||||||
arrayLengthOffset = arrayVirtualTableStruct.getFields().size();
|
|
||||||
var arrayLengthType = getArrayLengthType();
|
|
||||||
arrayVirtualTableStruct.getFields().add(new WasmField(arrayLengthType.getReference().asStorage()));
|
|
||||||
}
|
|
||||||
if (metadataRequirements.hasArrayGet()) {
|
|
||||||
arrayGetOffset = arrayVirtualTableStruct.getFields().size();
|
|
||||||
var arrayGetType = getArrayGetType();
|
|
||||||
arrayVirtualTableStruct.getFields().add(new WasmField(arrayGetType.getReference().asStorage()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return arrayVirtualTableStruct;
|
return arrayVirtualTableStruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getArrayLengthOffset() {
|
public int getArrayLengthOffset() {
|
||||||
|
initStructures();
|
||||||
return arrayLengthOffset;
|
return arrayLengthOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getArrayGetOffset() {
|
public int getArrayGetOffset() {
|
||||||
|
initStructures();
|
||||||
return arrayGetOffset;
|
return arrayGetOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -372,10 +372,16 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void catchException(TextLocation location, List<WasmExpression> target, WasmLocal local) {
|
protected void catchException(TextLocation location, List<WasmExpression> target, WasmLocal local,
|
||||||
|
String exceptionClass) {
|
||||||
var type = context.classInfoProvider().getClassInfo("java.lang.Throwable").getType();
|
var type = context.classInfoProvider().getClassInfo("java.lang.Throwable").getType();
|
||||||
if (local != null) {
|
if (local != null) {
|
||||||
var save = new WasmSetLocal(local, new WasmGetGlobal(context.exceptionGlobal()));
|
WasmExpression exception = new WasmGetGlobal(context.exceptionGlobal());
|
||||||
|
if (exceptionClass != null && !exceptionClass.equals("java.lang.Throwable")) {
|
||||||
|
exception = new WasmCast(exception, context.classInfoProvider().getClassInfo(exceptionClass)
|
||||||
|
.getStructure().getReference());
|
||||||
|
}
|
||||||
|
var save = new WasmSetLocal(local, exception);
|
||||||
save.setLocation(location);
|
save.setLocation(location);
|
||||||
target.add(save);
|
target.add(save);
|
||||||
}
|
}
|
||||||
|
@ -511,6 +517,9 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
var fieldType = field.getType();
|
var fieldType = field.getType();
|
||||||
if (fieldType instanceof ValueType.Primitive) {
|
if (fieldType instanceof ValueType.Primitive) {
|
||||||
switch (((ValueType.Primitive) fieldType).getKind()) {
|
switch (((ValueType.Primitive) fieldType).getKind()) {
|
||||||
|
case BOOLEAN:
|
||||||
|
structGet.setSignedType(WasmSignedType.UNSIGNED);
|
||||||
|
break;
|
||||||
case BYTE:
|
case BYTE:
|
||||||
structGet.setSignedType(WasmSignedType.SIGNED);
|
structGet.setSignedType(WasmSignedType.SIGNED);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -35,6 +35,7 @@ public class SystemArrayCopyIntrinsic implements WasmGCIntrinsic {
|
||||||
public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
||||||
var result = tryGenerateSpecialCase(invocation, context);
|
var result = tryGenerateSpecialCase(invocation, context);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
|
tryGenerateSpecialCase(invocation, context);
|
||||||
var function = getDefaultFunction(context);
|
var function = getDefaultFunction(context);
|
||||||
result = new WasmCall(function, context.generate(invocation.getArguments().get(0)),
|
result = new WasmCall(function, context.generate(invocation.getArguments().get(0)),
|
||||||
context.generate(invocation.getArguments().get(1)),
|
context.generate(invocation.getArguments().get(1)),
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
package org.teavm.backend.wasm.transformation.gc;
|
package org.teavm.backend.wasm.transformation.gc;
|
||||||
|
|
||||||
import org.teavm.backend.wasm.runtime.WasmGCSupport;
|
import org.teavm.backend.wasm.runtime.WasmGCSupport;
|
||||||
|
import org.teavm.interop.Import;
|
||||||
import org.teavm.model.AccessLevel;
|
import org.teavm.model.AccessLevel;
|
||||||
|
import org.teavm.model.AnnotationHolder;
|
||||||
|
import org.teavm.model.AnnotationValue;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
import org.teavm.model.ClassHolderTransformerContext;
|
import org.teavm.model.ClassHolderTransformerContext;
|
||||||
|
@ -86,6 +89,12 @@ public class BaseClassesTransformation implements ClassHolderTransformer {
|
||||||
method.setProgram(null);
|
method.setProgram(null);
|
||||||
method.getModifiers().add(ElementModifier.NATIVE);
|
method.getModifiers().add(ElementModifier.NATIVE);
|
||||||
break;
|
break;
|
||||||
|
case "currentTimeMillis": {
|
||||||
|
var annotation = new AnnotationHolder(Import.class.getName());
|
||||||
|
annotation.getValues().put("module", new AnnotationValue("teavm"));
|
||||||
|
annotation.getValues().put("name", new AnnotationValue("currentTimeMillis"));
|
||||||
|
method.getAnnotations().add(annotation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,12 @@ TeaVM.wasm = function() {
|
||||||
} else {
|
} else {
|
||||||
stdout += String.fromCharCode(c);
|
stdout += String.fromCharCode(c);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
currentTimeMillis() {
|
||||||
|
return new Date().getTime();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
imports.teavmMath = Math;
|
||||||
}
|
}
|
||||||
|
|
||||||
function load(path, options) {
|
function load(path, options) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user