mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: fix issues in generation of types, globals and some expressions
This commit is contained in:
parent
ea29208b6c
commit
87aaa0b452
|
@ -300,6 +300,11 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor {
|
|||
return new WasmInt32Constant(classGenerator.getClassPointer(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WasmExpression nullLiteral() {
|
||||
return new WasmInt32Constant(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(SubscriptExpr expr) {
|
||||
WasmExpression ptr = getArrayElementPointer(expr);
|
||||
|
|
|
@ -553,7 +553,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
|||
@Override
|
||||
public void visit(ConstantExpr expr) {
|
||||
if (expr.getValue() == null) {
|
||||
result = new WasmInt32Constant(0);
|
||||
result = nullLiteral();
|
||||
} else if (expr.getValue() instanceof Integer) {
|
||||
result = new WasmInt32Constant((Integer) expr.getValue());
|
||||
} else if (expr.getValue() instanceof Long) {
|
||||
|
@ -569,8 +569,11 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
|||
} else {
|
||||
throw new IllegalArgumentException("Constant unsupported: " + expr.getValue());
|
||||
}
|
||||
result.setLocation(expr.getLocation());
|
||||
}
|
||||
|
||||
protected abstract WasmExpression nullLiteral();
|
||||
|
||||
protected abstract WasmExpression stringLiteral(String s);
|
||||
|
||||
protected abstract WasmExpression classLiteral(ValueType type);
|
||||
|
|
|
@ -335,8 +335,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
var virtualTable = virtualTables.lookup(className);
|
||||
var structure = new WasmStructure(names.forClassClass(className));
|
||||
module.types.add(structure);
|
||||
addVirtualTableFields(structure, virtualTable);
|
||||
fillClassFields(structure.getFields(), "java.lang.Class");
|
||||
addVirtualTableFields(structure, virtualTable);
|
||||
return structure;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.backend.wasm.generate.gc.methods;
|
|||
|
||||
import java.util.List;
|
||||
import org.teavm.ast.ArrayType;
|
||||
import org.teavm.ast.BinaryExpr;
|
||||
import org.teavm.ast.Expr;
|
||||
import org.teavm.ast.InvocationExpr;
|
||||
import org.teavm.ast.QualificationExpr;
|
||||
|
@ -40,7 +41,11 @@ import org.teavm.backend.wasm.model.expression.WasmCast;
|
|||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.backend.wasm.model.expression.WasmGetGlobal;
|
||||
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
|
||||
import org.teavm.backend.wasm.model.expression.WasmIntType;
|
||||
import org.teavm.backend.wasm.model.expression.WasmIntUnary;
|
||||
import org.teavm.backend.wasm.model.expression.WasmIntUnaryOperation;
|
||||
import org.teavm.backend.wasm.model.expression.WasmNullConstant;
|
||||
import org.teavm.backend.wasm.model.expression.WasmReferencesEqual;
|
||||
import org.teavm.backend.wasm.model.expression.WasmSetGlobal;
|
||||
import org.teavm.backend.wasm.model.expression.WasmSetLocal;
|
||||
import org.teavm.backend.wasm.model.expression.WasmStructGet;
|
||||
|
@ -167,11 +172,45 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
|||
return new WasmGetGlobal(classConstant.getPointer());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WasmExpression nullLiteral() {
|
||||
return new WasmNullConstant(WasmType.Reference.STRUCT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CallSiteIdentifier generateCallSiteId(TextLocation location) {
|
||||
return new SimpleCallSite();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BinaryExpr expr) {
|
||||
if (expr.getType() == null) {
|
||||
switch (expr.getOperation()) {
|
||||
case EQUALS: {
|
||||
accept(expr.getFirstOperand());
|
||||
var first = result;
|
||||
accept(expr.getSecondOperand());
|
||||
var second = result;
|
||||
result = new WasmReferencesEqual(first, second);
|
||||
result.setLocation(expr.getLocation());
|
||||
return;
|
||||
}
|
||||
case NOT_EQUALS:
|
||||
accept(expr.getFirstOperand());
|
||||
var first = result;
|
||||
accept(expr.getSecondOperand());
|
||||
var second = result;
|
||||
result = new WasmReferencesEqual(first, second);
|
||||
result = new WasmIntUnary(WasmIntType.INT32, WasmIntUnaryOperation.EQZ, result);
|
||||
result.setLocation(expr.getLocation());
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
super.visit(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WasmExpression generateVirtualCall(WasmLocal instance, MethodReference method,
|
||||
List<WasmExpression> arguments) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Collections;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.teavm.common.Graph;
|
||||
import org.teavm.common.GraphUtils;
|
||||
|
||||
public class WasmModule {
|
||||
|
@ -93,32 +94,70 @@ public class WasmModule {
|
|||
}
|
||||
|
||||
public void prepareForRendering() {
|
||||
prepareRecursiveTypes();
|
||||
prepareTypes();
|
||||
}
|
||||
|
||||
private void prepareRecursiveTypes() {
|
||||
private void prepareTypes() {
|
||||
var typeGraph = WasmTypeGraphBuilder.buildTypeGraph(types, types.size());
|
||||
var newList = new ArrayList<WasmCompositeType>();
|
||||
var typesInScc = new boolean[types.size()];
|
||||
for (var scc : GraphUtils.findStronglyConnectedComponents(typeGraph)) {
|
||||
var sccs = GraphUtils.findStronglyConnectedComponents(typeGraph);
|
||||
var sccStartNode = new int[types.size()];
|
||||
for (var i = 0; i < sccStartNode.length; ++i) {
|
||||
sccStartNode[i] = i;
|
||||
}
|
||||
var sccsByIndex = new int[types.size()][];
|
||||
for (var scc : sccs) {
|
||||
sccsByIndex[scc[0]] = scc;
|
||||
var firstType = types.get(scc[0]);
|
||||
firstType.recursiveTypeCount = scc.length;
|
||||
for (var i = 0; i < scc.length; i++) {
|
||||
var index = scc[i];
|
||||
var type = types.get(index);
|
||||
newList.add(type);
|
||||
type.indexInRecursiveType = i;
|
||||
typesInScc[index] = true;
|
||||
sccStartNode[scc[i]] = sccStartNode[scc[0]];
|
||||
}
|
||||
}
|
||||
for (var type : types) {
|
||||
if (!typesInScc[type.index]) {
|
||||
newList.add(type);
|
||||
}
|
||||
|
||||
var sorting = new TypeSorting();
|
||||
sorting.original = types;
|
||||
sorting.graph = typeGraph;
|
||||
sorting.visited = new boolean[types.size()];
|
||||
sorting.sccMap = sccStartNode;
|
||||
sorting.sccsByIndex = sccsByIndex;
|
||||
for (var i = 0; i < types.size(); ++i) {
|
||||
sorting.visit(i);
|
||||
}
|
||||
|
||||
types.clear();
|
||||
for (var type : newList) {
|
||||
for (var type : sorting.sorted) {
|
||||
types.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TypeSorting {
|
||||
WasmCollection<WasmCompositeType> original;
|
||||
Graph graph;
|
||||
boolean[] visited;
|
||||
int[] sccMap;
|
||||
int[][] sccsByIndex;
|
||||
List<WasmCompositeType> sorted = new ArrayList<>();
|
||||
|
||||
void visit(int typeIndex) {
|
||||
typeIndex = sccMap[typeIndex];
|
||||
if (visited[typeIndex]) {
|
||||
return;
|
||||
}
|
||||
visited[typeIndex] = true;
|
||||
for (var outgoing : graph.outgoingEdges(typeIndex)) {
|
||||
visit(outgoing);
|
||||
}
|
||||
var scc = sccsByIndex[typeIndex];
|
||||
if (scc == null) {
|
||||
sorted.add(original.get(typeIndex));
|
||||
} else {
|
||||
for (var index : scc) {
|
||||
sorted.add(original.get(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ public abstract class WasmType {
|
|||
}
|
||||
}
|
||||
|
||||
public static final class SpecialReference extends WasmType {
|
||||
public static final class SpecialReference extends Reference {
|
||||
public final SpecialReferenceKind kind;
|
||||
|
||||
private SpecialReference(SpecialReferenceKind kind) {
|
||||
|
|
|
@ -38,6 +38,7 @@ public class WasmBinaryRenderer {
|
|||
private static final int SECTION_FUNCTION = 3;
|
||||
private static final int SECTION_TABLE = 4;
|
||||
private static final int SECTION_MEMORY = 5;
|
||||
private static final int SECTION_GLOBAL = 6;
|
||||
private static final int SECTION_EXPORT = 7;
|
||||
private static final int SECTION_START = 8;
|
||||
private static final int SECTION_ELEMENT = 9;
|
||||
|
@ -88,6 +89,7 @@ public class WasmBinaryRenderer {
|
|||
renderTable(module);
|
||||
renderMemory(module);
|
||||
renderTags(module);
|
||||
renderGlobals(module);
|
||||
renderExport(module);
|
||||
renderStart(module);
|
||||
renderElement(module);
|
||||
|
@ -205,6 +207,24 @@ public class WasmBinaryRenderer {
|
|||
writeSection(SECTION_MEMORY, "memory", section.getData());
|
||||
}
|
||||
|
||||
private void renderGlobals(WasmModule module) {
|
||||
if (module.globals.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var section = new WasmBinaryWriter();
|
||||
var visitor = new WasmBinaryRenderingVisitor(section, module, null, null, 0);
|
||||
section.writeLEB(module.globals.size());
|
||||
for (var global : module.globals) {
|
||||
section.writeType(global.getType(), module);
|
||||
section.writeByte(1); // mutable
|
||||
global.getInitialValue().acceptVisitor(visitor);
|
||||
section.writeByte(0x0b);
|
||||
}
|
||||
|
||||
writeSection(SECTION_GLOBAL, "global", section.getData());
|
||||
}
|
||||
|
||||
private void renderExport(WasmModule module) {
|
||||
|
||||
// https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#export-section
|
||||
|
|
|
@ -253,7 +253,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
public void visit(WasmNullConstant expression) {
|
||||
pushLocation(expression);
|
||||
writer.writeByte(0xD0);
|
||||
writeBlockType(expression.getType());
|
||||
writer.writeHeapType(expression.getType(), module);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
|
@ -1146,7 +1146,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
public void visit(WasmFunctionReference expression) {
|
||||
pushLocation(expression);
|
||||
writer.writeByte(0xd2);
|
||||
writer.writeInt32(module.functions.indexOf(expression.getFunction()));
|
||||
writer.writeLEB(module.functions.indexOf(expression.getFunction()));
|
||||
popLocation();
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,27 @@ public class WasmBinaryWriter {
|
|||
if (type instanceof WasmType.Number) {
|
||||
writeType(((WasmType.Number) type).number);
|
||||
} else if (type instanceof WasmType.SpecialReference) {
|
||||
switch (((WasmType.SpecialReference) type).kind) {
|
||||
writeSpecialHeapType(((WasmType.SpecialReference) type).kind);
|
||||
} else if (type instanceof WasmType.CompositeReference) {
|
||||
writeByte(0x63);
|
||||
var composite = ((WasmType.CompositeReference) type).composite;
|
||||
var index = module.types.indexOf(composite);
|
||||
writeSignedLEB(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeHeapType(WasmType.Reference type, WasmModule module) {
|
||||
if (type instanceof WasmType.CompositeReference) {
|
||||
var composite = ((WasmType.CompositeReference) type).composite;
|
||||
var index = module.types.indexOf(composite);
|
||||
writeSignedLEB(index);
|
||||
} else {
|
||||
writeSpecialHeapType(((WasmType.SpecialReference) type).kind);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSpecialHeapType(WasmType.SpecialReferenceKind type) {
|
||||
switch (type) {
|
||||
case ANY:
|
||||
writeByte(0x6e);
|
||||
break;
|
||||
|
@ -58,14 +78,6 @@ public class WasmBinaryWriter {
|
|||
writeByte(0x6a);
|
||||
break;
|
||||
}
|
||||
} else if (type instanceof WasmType.CompositeReference) {
|
||||
writeByte(0x63);
|
||||
var composite = ((WasmType.CompositeReference) type).composite;
|
||||
var index = isRecursiveMember
|
||||
? composite.getIndexInRecursiveType()
|
||||
: module.types.indexOf(composite);
|
||||
writeSignedLEB(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeType(WasmNumType type) {
|
||||
|
|
|
@ -75,7 +75,7 @@ public class WasmCompositeTypeBinaryRenderer implements WasmCompositeTypeVisitor
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
section.writeType(storageType.asUnpackedType(), module);
|
||||
section.writeType(storageType.asUnpackedType(), module, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user