mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: trying to generate types according to unclear spec
This commit is contained in:
parent
a281c19363
commit
ea29208b6c
|
@ -131,6 +131,7 @@ public class WasmGCTarget implements TeaVMTarget {
|
||||||
var binaryWriter = new WasmBinaryWriter();
|
var binaryWriter = new WasmBinaryWriter();
|
||||||
var binaryRenderer = new WasmBinaryRenderer(binaryWriter, WasmBinaryVersion.V_0x1, obfuscated,
|
var binaryRenderer = new WasmBinaryRenderer(binaryWriter, WasmBinaryVersion.V_0x1, obfuscated,
|
||||||
null, null, null, null, WasmBinaryStatsCollector.EMPTY);
|
null, null, null, null, WasmBinaryStatsCollector.EMPTY);
|
||||||
|
module.prepareForRendering();
|
||||||
binaryRenderer.render(module);
|
binaryRenderer.render(module);
|
||||||
var data = binaryWriter.getData();
|
var data = binaryWriter.getData();
|
||||||
if (!outputName.endsWith(".wasm")) {
|
if (!outputName.endsWith(".wasm")) {
|
||||||
|
|
|
@ -30,6 +30,10 @@ public class WasmCollection<T extends WasmEntity> implements Iterable<T> {
|
||||||
WasmCollection() {
|
WasmCollection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T get(int index) {
|
||||||
|
return items.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return items.size();
|
return items.size();
|
||||||
}
|
}
|
||||||
|
@ -57,6 +61,13 @@ public class WasmCollection<T extends WasmEntity> implements Iterable<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
for (var item : items) {
|
||||||
|
item.collection = null;
|
||||||
|
}
|
||||||
|
items.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void invalidateIndexes() {
|
void invalidateIndexes() {
|
||||||
indexesInvalid = true;
|
indexesInvalid = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ package org.teavm.backend.wasm.model;
|
||||||
public abstract class WasmCompositeType extends WasmEntity {
|
public abstract class WasmCompositeType extends WasmEntity {
|
||||||
private String name;
|
private String name;
|
||||||
private WasmType.CompositeReference reference;
|
private WasmType.CompositeReference reference;
|
||||||
|
int indexInRecursiveType = -1;
|
||||||
|
int recursiveTypeCount = -1;
|
||||||
|
|
||||||
WasmCompositeType(String name) {
|
WasmCompositeType(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -34,5 +36,13 @@ public abstract class WasmCompositeType extends WasmEntity {
|
||||||
return reference;
|
return reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getIndexInRecursiveType() {
|
||||||
|
return indexInRecursiveType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRecursiveTypeCount() {
|
||||||
|
return recursiveTypeCount;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void acceptVisitor(WasmCompositeTypeVisitor visitor);
|
public abstract void acceptVisitor(WasmCompositeTypeVisitor visitor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.teavm.common.GraphUtils;
|
||||||
|
|
||||||
public class WasmModule {
|
public class WasmModule {
|
||||||
private int minMemorySize;
|
private int minMemorySize;
|
||||||
|
@ -90,4 +91,34 @@ public class WasmModule {
|
||||||
public void setStartFunction(WasmFunction startFunction) {
|
public void setStartFunction(WasmFunction startFunction) {
|
||||||
this.startFunction = startFunction;
|
this.startFunction = startFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void prepareForRendering() {
|
||||||
|
prepareRecursiveTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareRecursiveTypes() {
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var type : types) {
|
||||||
|
if (!typesInScc[type.index]) {
|
||||||
|
newList.add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
types.clear();
|
||||||
|
for (var type : newList) {
|
||||||
|
types.add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* 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.backend.wasm.model;
|
||||||
|
|
||||||
|
import org.teavm.common.Graph;
|
||||||
|
import org.teavm.common.GraphBuilder;
|
||||||
|
|
||||||
|
final class WasmTypeGraphBuilder {
|
||||||
|
private WasmTypeGraphBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static Graph buildTypeGraph(Iterable<WasmCompositeType> types, int size) {
|
||||||
|
var graphBuilder = new GraphBuilder(size);
|
||||||
|
var visitor = new GraphBuilderVisitor(graphBuilder);
|
||||||
|
for (var type : types) {
|
||||||
|
visitor.currentIndex = type.index;
|
||||||
|
type.acceptVisitor(visitor);
|
||||||
|
}
|
||||||
|
return graphBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GraphBuilderVisitor implements WasmCompositeTypeVisitor {
|
||||||
|
final GraphBuilder graphBuilder;
|
||||||
|
int currentIndex;
|
||||||
|
|
||||||
|
GraphBuilderVisitor(GraphBuilder graphBuilder) {
|
||||||
|
this.graphBuilder = graphBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(WasmStructure type) {
|
||||||
|
for (var field : type.getFields()) {
|
||||||
|
addEdge(field.asUnpackedType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(WasmArray type) {
|
||||||
|
addEdge(type.getElementType().asUnpackedType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(WasmFunctionType type) {
|
||||||
|
for (var parameter : type.getParameterTypes()) {
|
||||||
|
addEdge(parameter);
|
||||||
|
}
|
||||||
|
if (type.getReturnType() != null) {
|
||||||
|
addEdge(type.getReturnType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addEdge(WasmType type) {
|
||||||
|
if (type instanceof WasmType.CompositeReference) {
|
||||||
|
var composite = ((WasmType.CompositeReference) type).composite;
|
||||||
|
graphBuilder.addEdge(currentIndex, composite.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -103,9 +103,30 @@ public class WasmBinaryRenderer {
|
||||||
var section = new WasmBinaryWriter();
|
var section = new WasmBinaryWriter();
|
||||||
|
|
||||||
var typeRenderer = new WasmCompositeTypeBinaryRenderer(module, section);
|
var typeRenderer = new WasmCompositeTypeBinaryRenderer(module, section);
|
||||||
section.writeLEB(module.types.size());
|
var recTypeCount = 0;
|
||||||
for (var type : module.types) {
|
for (var i = 0; i < module.types.size();) {
|
||||||
type.acceptVisitor(typeRenderer);
|
var type = module.types.get(i);
|
||||||
|
if (type.getRecursiveTypeCount() > 0) {
|
||||||
|
i += type.getRecursiveTypeCount();
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
recTypeCount++;
|
||||||
|
}
|
||||||
|
section.writeLEB(recTypeCount);
|
||||||
|
for (var i = 0; i < module.types.size();) {
|
||||||
|
var type = module.types.get(i);
|
||||||
|
if (type.getRecursiveTypeCount() > 0) {
|
||||||
|
section.writeByte(0x4E);
|
||||||
|
section.writeLEB(type.getRecursiveTypeCount());
|
||||||
|
for (var j = 0; j < type.getRecursiveTypeCount(); ++j) {
|
||||||
|
var subtype = module.types.get(i++);
|
||||||
|
subtype.acceptVisitor(typeRenderer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type.acceptVisitor(typeRenderer);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeSection(SECTION_TYPE, "type", section.getData());
|
writeSection(SECTION_TYPE, "type", section.getData());
|
||||||
|
|
|
@ -30,6 +30,10 @@ public class WasmBinaryWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeType(WasmType type, WasmModule module) {
|
public void writeType(WasmType type, WasmModule module) {
|
||||||
|
writeType(type, module, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeType(WasmType type, WasmModule module, boolean isRecursiveMember) {
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
writeByte(0x40);
|
writeByte(0x40);
|
||||||
return;
|
return;
|
||||||
|
@ -55,7 +59,12 @@ public class WasmBinaryWriter {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (type instanceof WasmType.CompositeReference) {
|
} else if (type instanceof WasmType.CompositeReference) {
|
||||||
writeSignedLEB(module.types.indexOf(((WasmType.CompositeReference) type).composite));
|
writeByte(0x63);
|
||||||
|
var composite = ((WasmType.CompositeReference) type).composite;
|
||||||
|
var index = isRecursiveMember
|
||||||
|
? composite.getIndexInRecursiveType()
|
||||||
|
: module.types.indexOf(composite);
|
||||||
|
writeSignedLEB(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.teavm.backend.wasm.model.WasmStructure;
|
||||||
public class WasmCompositeTypeBinaryRenderer implements WasmCompositeTypeVisitor {
|
public class WasmCompositeTypeBinaryRenderer implements WasmCompositeTypeVisitor {
|
||||||
private WasmModule module;
|
private WasmModule module;
|
||||||
private WasmBinaryWriter section;
|
private WasmBinaryWriter section;
|
||||||
|
private boolean reference;
|
||||||
|
|
||||||
public WasmCompositeTypeBinaryRenderer(WasmModule module, WasmBinaryWriter section) {
|
public WasmCompositeTypeBinaryRenderer(WasmModule module, WasmBinaryWriter section) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
|
@ -43,6 +44,7 @@ public class WasmCompositeTypeBinaryRenderer implements WasmCompositeTypeVisitor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WasmArray type) {
|
public void visit(WasmArray type) {
|
||||||
|
section.writeByte(0x5E);
|
||||||
writeStorageType(type.getElementType());
|
writeStorageType(type.getElementType());
|
||||||
section.writeLEB(0x01); // mutable
|
section.writeLEB(0x01); // mutable
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user