mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 00:04:10 -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 binaryRenderer = new WasmBinaryRenderer(binaryWriter, WasmBinaryVersion.V_0x1, obfuscated,
|
||||
null, null, null, null, WasmBinaryStatsCollector.EMPTY);
|
||||
module.prepareForRendering();
|
||||
binaryRenderer.render(module);
|
||||
var data = binaryWriter.getData();
|
||||
if (!outputName.endsWith(".wasm")) {
|
||||
|
|
|
@ -30,6 +30,10 @@ public class WasmCollection<T extends WasmEntity> implements Iterable<T> {
|
|||
WasmCollection() {
|
||||
}
|
||||
|
||||
public T get(int index) {
|
||||
return items.get(index);
|
||||
}
|
||||
|
||||
public int 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() {
|
||||
indexesInvalid = true;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.teavm.backend.wasm.model;
|
|||
public abstract class WasmCompositeType extends WasmEntity {
|
||||
private String name;
|
||||
private WasmType.CompositeReference reference;
|
||||
int indexInRecursiveType = -1;
|
||||
int recursiveTypeCount = -1;
|
||||
|
||||
WasmCompositeType(String name) {
|
||||
this.name = name;
|
||||
|
@ -34,5 +36,13 @@ public abstract class WasmCompositeType extends WasmEntity {
|
|||
return reference;
|
||||
}
|
||||
|
||||
public int getIndexInRecursiveType() {
|
||||
return indexInRecursiveType;
|
||||
}
|
||||
|
||||
public int getRecursiveTypeCount() {
|
||||
return recursiveTypeCount;
|
||||
}
|
||||
|
||||
public abstract void acceptVisitor(WasmCompositeTypeVisitor visitor);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Collections;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.teavm.common.GraphUtils;
|
||||
|
||||
public class WasmModule {
|
||||
private int minMemorySize;
|
||||
|
@ -90,4 +91,34 @@ public class WasmModule {
|
|||
public void setStartFunction(WasmFunction 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 typeRenderer = new WasmCompositeTypeBinaryRenderer(module, section);
|
||||
section.writeLEB(module.types.size());
|
||||
for (var type : module.types) {
|
||||
type.acceptVisitor(typeRenderer);
|
||||
var recTypeCount = 0;
|
||||
for (var i = 0; i < module.types.size();) {
|
||||
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());
|
||||
|
|
|
@ -30,6 +30,10 @@ public class WasmBinaryWriter {
|
|||
}
|
||||
|
||||
public void writeType(WasmType type, WasmModule module) {
|
||||
writeType(type, module, false);
|
||||
}
|
||||
|
||||
public void writeType(WasmType type, WasmModule module, boolean isRecursiveMember) {
|
||||
if (type == null) {
|
||||
writeByte(0x40);
|
||||
return;
|
||||
|
@ -55,7 +59,12 @@ public class WasmBinaryWriter {
|
|||
break;
|
||||
}
|
||||
} 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 {
|
||||
private WasmModule module;
|
||||
private WasmBinaryWriter section;
|
||||
private boolean reference;
|
||||
|
||||
public WasmCompositeTypeBinaryRenderer(WasmModule module, WasmBinaryWriter section) {
|
||||
this.module = module;
|
||||
|
@ -43,6 +44,7 @@ public class WasmCompositeTypeBinaryRenderer implements WasmCompositeTypeVisitor
|
|||
|
||||
@Override
|
||||
public void visit(WasmArray type) {
|
||||
section.writeByte(0x5E);
|
||||
writeStorageType(type.getElementType());
|
||||
section.writeLEB(0x01); // mutable
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user