mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: generate field names and write them to name section
This commit is contained in:
parent
29f29cea1d
commit
eb0eb1f146
|
@ -33,6 +33,7 @@ import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.generate.gc.WasmGCInitializerContributor;
|
import org.teavm.backend.wasm.generate.gc.WasmGCInitializerContributor;
|
||||||
import org.teavm.backend.wasm.generate.gc.strings.WasmGCStringPool;
|
import org.teavm.backend.wasm.generate.gc.strings.WasmGCStringPool;
|
||||||
import org.teavm.backend.wasm.model.WasmArray;
|
import org.teavm.backend.wasm.model.WasmArray;
|
||||||
|
import org.teavm.backend.wasm.model.WasmField;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmFunctionType;
|
import org.teavm.backend.wasm.model.WasmFunctionType;
|
||||||
import org.teavm.backend.wasm.model.WasmGlobal;
|
import org.teavm.backend.wasm.model.WasmGlobal;
|
||||||
|
@ -73,6 +74,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
private static final MethodDescriptor CLINIT_METHOD_DESC = new MethodDescriptor("<clinit>", ValueType.VOID);
|
private static final MethodDescriptor CLINIT_METHOD_DESC = new MethodDescriptor("<clinit>", ValueType.VOID);
|
||||||
private static final MethodDescriptor GET_CLASS_METHOD = new MethodDescriptor("getClass",
|
private static final MethodDescriptor GET_CLASS_METHOD = new MethodDescriptor("getClass",
|
||||||
ValueType.parse(Class.class));
|
ValueType.parse(Class.class));
|
||||||
|
private static final FieldReference FAKE_CLASS_FIELD = new FieldReference(Object.class.getName(), "class");
|
||||||
|
private static final FieldReference FAKE_MONITOR_FIELD = new FieldReference(Object.class.getName(), "monitor");
|
||||||
|
|
||||||
private final WasmModule module;
|
private final WasmModule module;
|
||||||
private ClassReaderSource classSource;
|
private ClassReaderSource classSource;
|
||||||
|
@ -411,7 +414,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
&& !method.equals(GET_CLASS_METHOD)) {
|
&& !method.equals(GET_CLASS_METHOD)) {
|
||||||
var fieldIndex = virtualTableFieldOffset + entry.getIndex();
|
var fieldIndex = virtualTableFieldOffset + entry.getIndex();
|
||||||
var expectedType = (WasmType.CompositeReference) structure.getFields().get(fieldIndex)
|
var expectedType = (WasmType.CompositeReference) structure.getFields().get(fieldIndex)
|
||||||
.asUnpackedType();
|
.getUnpackedType();
|
||||||
var expectedFunctionType = (WasmFunctionType) expectedType.composite;
|
var expectedFunctionType = (WasmFunctionType) expectedType.composite;
|
||||||
var function = functionProvider.forInstanceMethod(entry.getImplementor());
|
var function = functionProvider.forInstanceMethod(entry.getImplementor());
|
||||||
if (!virtualTable.getClassName().equals(entry.getImplementor().getClassName())
|
if (!virtualTable.getClassName().equals(entry.getImplementor().getClassName())
|
||||||
|
@ -444,24 +447,34 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
var structure = new WasmStructure(names.forClassClass(className));
|
var structure = new WasmStructure(names.forClassClass(className));
|
||||||
structure.setSupertype(standardClasses.classClass().getStructure());
|
structure.setSupertype(standardClasses.classClass().getStructure());
|
||||||
module.types.add(structure);
|
module.types.add(structure);
|
||||||
structure.getFields().add(standardClasses.classClass().getType().asStorage());
|
addSystemFields(structure.getFields());
|
||||||
structure.getFields().add(WasmType.Reference.ANY.asStorage());
|
|
||||||
fillSimpleClassFields(structure.getFields(), "java.lang.Class");
|
fillSimpleClassFields(structure.getFields(), "java.lang.Class");
|
||||||
addVirtualTableFields(structure, virtualTable);
|
addVirtualTableFields(structure, virtualTable);
|
||||||
return structure;
|
return structure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addSystemFields(List<WasmField> fields) {
|
||||||
|
var classField = new WasmField(standardClasses.classClass().getType().asStorage());
|
||||||
|
classField.setName(names.forMemberField(FAKE_CLASS_FIELD));
|
||||||
|
fields.add(classField);
|
||||||
|
var monitorField = new WasmField(WasmType.Reference.ANY.asStorage());
|
||||||
|
monitorField.setName(names.forMemberField(FAKE_MONITOR_FIELD));
|
||||||
|
fields.add(monitorField);
|
||||||
|
}
|
||||||
|
|
||||||
private void addVirtualTableFields(WasmStructure structure, VirtualTable virtualTable) {
|
private void addVirtualTableFields(WasmStructure structure, VirtualTable virtualTable) {
|
||||||
if (virtualTable.getParent() != null) {
|
if (virtualTable.getParent() != null) {
|
||||||
addVirtualTableFields(structure, virtualTable.getParent());
|
addVirtualTableFields(structure, virtualTable.getParent());
|
||||||
}
|
}
|
||||||
for (var methodDesc : virtualTable.getMethods()) {
|
for (var methodDesc : virtualTable.getMethods()) {
|
||||||
if (methodDesc == null) {
|
if (methodDesc == null) {
|
||||||
structure.getFields().add(WasmType.Reference.FUNC.asStorage());
|
structure.getFields().add(new WasmField(WasmType.Reference.FUNC.asStorage()));
|
||||||
} else {
|
} else {
|
||||||
var originalVirtualTable = virtualTable.findMethodContainer(methodDesc);
|
var originalVirtualTable = virtualTable.findMethodContainer(methodDesc);
|
||||||
var functionType = typeMapper.getFunctionType(originalVirtualTable.getClassName(), methodDesc, false);
|
var functionType = typeMapper.getFunctionType(originalVirtualTable.getClassName(), methodDesc, false);
|
||||||
structure.getFields().add(functionType.getReference().asStorage());
|
var field = new WasmField(functionType.getReference().asStorage());
|
||||||
|
field.setName(names.forVirtualMethod(methodDesc));
|
||||||
|
structure.getFields().add(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,8 +541,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
|
|
||||||
private void fillFields(WasmGCClassInfo classInfo, ValueType type) {
|
private void fillFields(WasmGCClassInfo classInfo, ValueType type) {
|
||||||
var fields = classInfo.structure.getFields();
|
var fields = classInfo.structure.getFields();
|
||||||
fields.add(standardClasses.classClass().getType().asStorage());
|
addSystemFields(fields);
|
||||||
fields.add(WasmType.Reference.ANY.asStorage());
|
|
||||||
if (type instanceof ValueType.Object) {
|
if (type instanceof ValueType.Object) {
|
||||||
fillClassFields(fields, ((ValueType.Object) type).getClassName());
|
fillClassFields(fields, ((ValueType.Object) type).getClassName());
|
||||||
} else if (type instanceof ValueType.Array) {
|
} else if (type instanceof ValueType.Array) {
|
||||||
|
@ -537,7 +549,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillClassFields(List<WasmStorageType> fields, String className) {
|
private void fillClassFields(List<WasmField> fields, String className) {
|
||||||
var classReader = classSource.get(className);
|
var classReader = classSource.get(className);
|
||||||
if (classReader == null || classReader.hasModifier(ElementModifier.INTERFACE)) {
|
if (classReader == null || classReader.hasModifier(ElementModifier.INTERFACE)) {
|
||||||
fillSimpleClassFields(fields, "java.lang.Object");
|
fillSimpleClassFields(fields, "java.lang.Object");
|
||||||
|
@ -546,7 +558,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillSimpleClassFields(List<WasmStorageType> fields, String className) {
|
private void fillSimpleClassFields(List<WasmField> fields, String className) {
|
||||||
var classReader = classSource.get(className);
|
var classReader = classSource.get(className);
|
||||||
if (classReader.getParent() != null) {
|
if (classReader.getParent() != null) {
|
||||||
fillClassFields(fields, classReader.getParent());
|
fillClassFields(fields, classReader.getParent());
|
||||||
|
@ -562,29 +574,37 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fieldIndexes.putIfAbsent(field.getReference(), fields.size());
|
fieldIndexes.putIfAbsent(field.getReference(), fields.size());
|
||||||
fields.add(typeMapper.mapStorageType(field.getType()));
|
var wasmField = new WasmField(typeMapper.mapStorageType(field.getType()),
|
||||||
|
names.forMemberField(field.getReference()));
|
||||||
|
fields.add(wasmField);
|
||||||
}
|
}
|
||||||
if (className.equals("java.lang.Class")) {
|
if (className.equals("java.lang.Class")) {
|
||||||
classFlagsOffset = fields.size();
|
classFlagsOffset = fields.size();
|
||||||
fields.add(WasmType.INT32.asStorage());
|
fields.add(createClassField(WasmType.INT32.asStorage(), "lowerIndex"));
|
||||||
classTagOffset = fields.size();
|
classTagOffset = fields.size();
|
||||||
fields.add(WasmType.INT32.asStorage());
|
fields.add(createClassField(WasmType.INT32.asStorage(), "upperIndex"));
|
||||||
classParentOffset = fields.size();
|
classParentOffset = fields.size();
|
||||||
fields.add(standardClasses.classClass().getType().asStorage());
|
fields.add(createClassField(standardClasses.classClass().getType().asStorage(), "parent"));
|
||||||
classArrayItemOffset = fields.size();
|
classArrayItemOffset = fields.size();
|
||||||
fields.add(standardClasses.classClass().getType().asStorage());
|
fields.add(createClassField(standardClasses.classClass().getType().asStorage(), "arrayItem"));
|
||||||
classArrayOffset = fields.size();
|
classArrayOffset = fields.size();
|
||||||
fields.add(standardClasses.classClass().getType().asStorage());
|
fields.add(createClassField(standardClasses.classClass().getType().asStorage(), "array"));
|
||||||
classSupertypeFunctionOffset = fields.size();
|
classSupertypeFunctionOffset = fields.size();
|
||||||
fields.add(supertypeGenerator.getFunctionType().getReference().asStorage());
|
fields.add(createClassField(supertypeGenerator.getFunctionType().getReference().asStorage(),
|
||||||
|
"isSupertype"));
|
||||||
classNewArrayOffset = fields.size();
|
classNewArrayOffset = fields.size();
|
||||||
fields.add(newArrayGenerator.getNewArrayFunctionType().getReference().asStorage());
|
fields.add(createClassField(newArrayGenerator.getNewArrayFunctionType().getReference().asStorage(),
|
||||||
|
"createArrayInstance"));
|
||||||
classNameOffset = fields.size();
|
classNameOffset = fields.size();
|
||||||
fields.add(standardClasses.stringClass().getType().asStorage());
|
fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "name"));
|
||||||
virtualTableFieldOffset = fields.size();
|
virtualTableFieldOffset = fields.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WasmField createClassField(WasmStorageType type, String name) {
|
||||||
|
return new WasmField(type, names.forMemberField(new FieldReference("java.lang.Class", name)));
|
||||||
|
}
|
||||||
|
|
||||||
private void fillArrayFields(WasmGCClassInfo classInfo, ValueType elementType) {
|
private void fillArrayFields(WasmGCClassInfo classInfo, ValueType elementType) {
|
||||||
WasmStorageType wasmElementType;
|
WasmStorageType wasmElementType;
|
||||||
if (elementType instanceof ValueType.Primitive) {
|
if (elementType instanceof ValueType.Primitive) {
|
||||||
|
@ -617,7 +637,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
}
|
}
|
||||||
var wasmArray = new WasmArray(null, wasmElementType);
|
var wasmArray = new WasmArray(null, wasmElementType);
|
||||||
module.types.add(wasmArray);
|
module.types.add(wasmArray);
|
||||||
classInfo.structure.getFields().add(wasmArray.getReference().asStorage());
|
classInfo.structure.getFields().add(new WasmField(wasmArray.getReference().asStorage(), "data"));
|
||||||
classInfo.array = wasmArray;
|
classInfo.array = wasmArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class WasmGCGenerationUtil {
|
||||||
|
|
||||||
var wasmArrayType = (WasmType.CompositeReference) classInfo.getStructure().getFields()
|
var wasmArrayType = (WasmType.CompositeReference) classInfo.getStructure().getFields()
|
||||||
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET)
|
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET)
|
||||||
.asUnpackedType();
|
.getUnpackedType();
|
||||||
var wasmArray = (WasmArray) wasmArrayType.composite;
|
var wasmArray = (WasmArray) wasmArrayType.composite;
|
||||||
var initArrayField = new WasmStructSet(
|
var initArrayField = new WasmStructSet(
|
||||||
classInfo.getStructure(),
|
classInfo.getStructure(),
|
||||||
|
|
|
@ -176,7 +176,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
var struct = (WasmStructure) type.composite;
|
var struct = (WasmStructure) type.composite;
|
||||||
var fieldIndex = context.classInfoProvider().getFieldIndex(field);
|
var fieldIndex = context.classInfoProvider().getFieldIndex(field);
|
||||||
|
|
||||||
accept(value, struct.getFields().get(fieldIndex).asUnpackedType());
|
accept(value, struct.getFields().get(fieldIndex).getUnpackedType());
|
||||||
var wasmValue = result;
|
var wasmValue = result;
|
||||||
|
|
||||||
var expr = new WasmStructSet(struct, target, fieldIndex, wasmValue);
|
var expr = new WasmStructSet(struct, target, fieldIndex, wasmValue);
|
||||||
|
@ -284,7 +284,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
classRef = new WasmCast(classRef, vtableStruct.getReference());
|
classRef = new WasmCast(classRef, vtableStruct.getReference());
|
||||||
|
|
||||||
var functionRef = new WasmStructGet(vtableStruct, classRef, index);
|
var functionRef = new WasmStructGet(vtableStruct, classRef, index);
|
||||||
var functionTypeRef = (WasmType.CompositeReference) vtableStruct.getFields().get(index).asUnpackedType();
|
var functionTypeRef = (WasmType.CompositeReference) vtableStruct.getFields().get(index).getUnpackedType();
|
||||||
var invoke = new WasmCallReference(functionRef, (WasmFunctionType) functionTypeRef.composite);
|
var invoke = new WasmCallReference(functionRef, (WasmFunctionType) functionTypeRef.composite);
|
||||||
WasmExpression instanceRef = new WasmGetLocal(instance);
|
WasmExpression instanceRef = new WasmGetLocal(instance);
|
||||||
var instanceType = (WasmType.CompositeReference) instance.getType();
|
var instanceType = (WasmType.CompositeReference) instance.getType();
|
||||||
|
|
|
@ -85,9 +85,9 @@ public class SystemArrayCopyIntrinsic implements WasmGCIntrinsic {
|
||||||
var wasmSize = context.generate(invocation.getArguments().get(4));
|
var wasmSize = context.generate(invocation.getArguments().get(4));
|
||||||
|
|
||||||
var wasmTargetArrayTypeRef = (WasmType.CompositeReference) wasmTargetArrayStruct.getFields()
|
var wasmTargetArrayTypeRef = (WasmType.CompositeReference) wasmTargetArrayStruct.getFields()
|
||||||
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET).asUnpackedType();
|
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
||||||
var wasmSourceArrayTypeRef = (WasmType.CompositeReference) wasmSourceArrayStruct.getFields()
|
var wasmSourceArrayTypeRef = (WasmType.CompositeReference) wasmSourceArrayStruct.getFields()
|
||||||
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET).asUnpackedType();
|
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
||||||
|
|
||||||
return new WasmArrayCopy((WasmArray) wasmTargetArrayTypeRef.composite, wasmTargetArray, wasmTargetIndex,
|
return new WasmArrayCopy((WasmArray) wasmTargetArrayTypeRef.composite, wasmTargetArray, wasmTargetIndex,
|
||||||
(WasmArray) wasmSourceArrayTypeRef.composite, wasmSourceArray, wasmSourceIndex, wasmSize);
|
(WasmArray) wasmSourceArrayTypeRef.composite, wasmSourceArray, wasmSourceIndex, wasmSize);
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 konsoletyper.
|
||||||
|
*
|
||||||
|
* 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 java.util.Objects;
|
||||||
|
|
||||||
|
public class WasmField {
|
||||||
|
WasmStructure structure;
|
||||||
|
int index;
|
||||||
|
private String name;
|
||||||
|
private WasmStorageType type;
|
||||||
|
|
||||||
|
public WasmField(WasmStorageType type, String name) {
|
||||||
|
this(type);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WasmField(WasmStorageType type) {
|
||||||
|
this.type = Objects.requireNonNull(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WasmStructure getStructure() {
|
||||||
|
return structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WasmStorageType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WasmType getUnpackedType() {
|
||||||
|
return type.asUnpackedType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(WasmStorageType type) {
|
||||||
|
this.type = Objects.requireNonNull(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
if (structure == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
structure.ensureIndexes();
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,18 +15,20 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm.model;
|
package org.teavm.backend.wasm.model;
|
||||||
|
|
||||||
|
import java.util.AbstractList;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class WasmStructure extends WasmCompositeType {
|
public class WasmStructure extends WasmCompositeType {
|
||||||
private List<WasmStorageType> fields = new ArrayList<>();
|
private List<WasmField> fieldsStorage = new ArrayList<>();
|
||||||
private WasmStructure supertype;
|
private WasmStructure supertype;
|
||||||
|
private boolean indexesValid = true;
|
||||||
|
|
||||||
public WasmStructure(String name) {
|
public WasmStructure(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<WasmStorageType> getFields() {
|
public List<WasmField> getFields() {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +50,80 @@ public class WasmStructure extends WasmCompositeType {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ensureIndexes() {
|
||||||
|
if (!indexesValid) {
|
||||||
|
indexesValid = true;
|
||||||
|
for (var i = 0; i < fieldsStorage.size(); ++i) {
|
||||||
|
fieldsStorage.get(i).index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptVisitor(WasmCompositeTypeVisitor visitor) {
|
public void acceptVisitor(WasmCompositeTypeVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<WasmField> fields = new AbstractList<WasmField>() {
|
||||||
|
@Override
|
||||||
|
public WasmField get(int index) {
|
||||||
|
return fieldsStorage.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return fieldsStorage.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int index, WasmField element) {
|
||||||
|
if (element.structure != null) {
|
||||||
|
throw new IllegalArgumentException("This field already belongs to structure");
|
||||||
|
}
|
||||||
|
element.structure = WasmStructure.this;
|
||||||
|
indexesValid = false;
|
||||||
|
fieldsStorage.add(index, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WasmField remove(int index) {
|
||||||
|
var result = fieldsStorage.remove(index);
|
||||||
|
indexesValid = false;
|
||||||
|
result.structure = null;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void removeRange(int fromIndex, int toIndex) {
|
||||||
|
var sublist = fieldsStorage.subList(fromIndex, toIndex);
|
||||||
|
for (var field : sublist) {
|
||||||
|
field.structure = null;
|
||||||
|
}
|
||||||
|
indexesValid = false;
|
||||||
|
sublist.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
for (var field : fieldsStorage) {
|
||||||
|
field.structure = null;
|
||||||
|
}
|
||||||
|
indexesValid = true;
|
||||||
|
fieldsStorage.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WasmField set(int index, WasmField element) {
|
||||||
|
if (element.structure != null) {
|
||||||
|
throw new IllegalArgumentException("This field already belongs to structure");
|
||||||
|
}
|
||||||
|
var former = fieldsStorage.set(index, element);
|
||||||
|
former.structure = null;
|
||||||
|
if (indexesValid) {
|
||||||
|
element.index = former.index;
|
||||||
|
}
|
||||||
|
element.structure = WasmStructure.this;
|
||||||
|
return former;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ final class WasmTypeGraphBuilder {
|
||||||
addEdge(type.getSupertype().getReference());
|
addEdge(type.getSupertype().getReference());
|
||||||
}
|
}
|
||||||
for (var field : type.getFields()) {
|
for (var field : type.getFields()) {
|
||||||
addEdge(field.asUnpackedType());
|
addEdge(field.getUnpackedType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ public class UnusedTypeElimination {
|
||||||
@Override
|
@Override
|
||||||
public void visit(WasmStructure type) {
|
public void visit(WasmStructure type) {
|
||||||
for (var field : type.getFields()) {
|
for (var field : type.getFields()) {
|
||||||
visit(field);
|
visit(field.getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.teavm.backend.wasm.model.WasmCustomSection;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmMemorySegment;
|
import org.teavm.backend.wasm.model.WasmMemorySegment;
|
||||||
import org.teavm.backend.wasm.model.WasmModule;
|
import org.teavm.backend.wasm.model.WasmModule;
|
||||||
|
import org.teavm.backend.wasm.model.WasmStructure;
|
||||||
import org.teavm.backend.wasm.model.WasmType;
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
|
|
||||||
public class WasmBinaryRenderer {
|
public class WasmBinaryRenderer {
|
||||||
|
@ -509,6 +510,31 @@ public class WasmBinaryRenderer {
|
||||||
section.writeBytes(payload);
|
section.writeBytes(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var typesWithNamedFields = module.types.stream()
|
||||||
|
.filter(t -> t instanceof WasmStructure)
|
||||||
|
.filter(t -> ((WasmStructure) t).getFields().stream().anyMatch(f -> f.getName() != null))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (!typesWithNamedFields.isEmpty()) {
|
||||||
|
var subsection = new WasmBinaryWriter();
|
||||||
|
subsection.writeLEB(typesWithNamedFields.size());
|
||||||
|
for (var type : typesWithNamedFields) {
|
||||||
|
subsection.writeLEB(module.types.indexOf(type));
|
||||||
|
var fields = ((WasmStructure) type).getFields().stream()
|
||||||
|
.filter(t -> t.getName() != null)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
subsection.writeLEB(fields.size());
|
||||||
|
for (var field : fields) {
|
||||||
|
subsection.writeLEB(field.getIndex());
|
||||||
|
subsection.writeAsciiString(field.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = subsection.getData();
|
||||||
|
section.writeLEB(10);
|
||||||
|
section.writeLEB(payload.length);
|
||||||
|
section.writeBytes(payload);
|
||||||
|
}
|
||||||
|
|
||||||
writeSection(SECTION_UNKNOWN, "name", section.getData());
|
writeSection(SECTION_UNKNOWN, "name", section.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class WasmCompositeTypeBinaryRenderer implements WasmCompositeTypeVisitor
|
||||||
section.writeByte(0x5F);
|
section.writeByte(0x5F);
|
||||||
section.writeLEB(type.getFields().size());
|
section.writeLEB(type.getFields().size());
|
||||||
for (var fieldType : type.getFields()) {
|
for (var fieldType : type.getFields()) {
|
||||||
writeStorageType(fieldType);
|
writeStorageType(fieldType.getType());
|
||||||
section.writeLEB(0x01); // mutable
|
section.writeLEB(0x01); // mutable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,7 +290,7 @@ public class WasmTypeInference implements WasmExpressionVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WasmStructGet expression) {
|
public void visit(WasmStructGet expression) {
|
||||||
result = expression.getType().getFields().get(expression.getFieldIndex()).asUnpackedType();
|
result = expression.getType().getFields().get(expression.getFieldIndex()).getUnpackedType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue
Block a user