mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: produce better names for declarations, generate locals in names section
This commit is contained in:
parent
10c3731c43
commit
7324e99e6a
|
@ -85,7 +85,7 @@ public class WasmGCModuleGenerator {
|
||||||
var function = declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
var function = declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
||||||
WasmGCSupport.class, "createStringArray", int.class, String[].class));
|
WasmGCSupport.class, "createStringArray", int.class, String[].class));
|
||||||
var caller = new WasmFunction(function.getType());
|
var caller = new WasmFunction(function.getType());
|
||||||
var sizeLocal = new WasmLocal(WasmType.INT32);
|
var sizeLocal = new WasmLocal(WasmType.INT32, "length");
|
||||||
caller.add(sizeLocal);
|
caller.add(sizeLocal);
|
||||||
caller.getBody().add(callInitializer());
|
caller.getBody().add(callInitializer());
|
||||||
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(sizeLocal))));
|
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(sizeLocal))));
|
||||||
|
@ -98,8 +98,8 @@ public class WasmGCModuleGenerator {
|
||||||
StringBuilder.class, "append", char.class, StringBuilder.class));
|
StringBuilder.class, "append", char.class, StringBuilder.class));
|
||||||
var stringBuilderType = declarationsGenerator.typeMapper().mapType(ValueType.parse(StringBuilder.class));
|
var stringBuilderType = declarationsGenerator.typeMapper().mapType(ValueType.parse(StringBuilder.class));
|
||||||
var caller = new WasmFunction(declarationsGenerator.functionTypes.of(null, stringBuilderType, WasmType.INT32));
|
var caller = new WasmFunction(declarationsGenerator.functionTypes.of(null, stringBuilderType, WasmType.INT32));
|
||||||
var stringBuilderLocal = new WasmLocal(stringBuilderType);
|
var stringBuilderLocal = new WasmLocal(stringBuilderType, "stringBuilder");
|
||||||
var codeLocal = new WasmLocal(WasmType.INT32);
|
var codeLocal = new WasmLocal(WasmType.INT32, "charCode");
|
||||||
caller.add(stringBuilderLocal);
|
caller.add(stringBuilderLocal);
|
||||||
caller.add(codeLocal);
|
caller.add(codeLocal);
|
||||||
caller.getBody().add(callInitializer());
|
caller.getBody().add(callInitializer());
|
||||||
|
@ -116,7 +116,7 @@ public class WasmGCModuleGenerator {
|
||||||
var stringBuilderType = declarationsGenerator.typeMapper().mapType(ValueType.parse(StringBuilder.class));
|
var stringBuilderType = declarationsGenerator.typeMapper().mapType(ValueType.parse(StringBuilder.class));
|
||||||
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
||||||
var caller = new WasmFunction(declarationsGenerator.functionTypes.of(stringType, stringBuilderType));
|
var caller = new WasmFunction(declarationsGenerator.functionTypes.of(stringType, stringBuilderType));
|
||||||
var stringBuilderLocal = new WasmLocal(stringBuilderType);
|
var stringBuilderLocal = new WasmLocal(stringBuilderType, "stringBuilder");
|
||||||
caller.add(stringBuilderLocal);
|
caller.add(stringBuilderLocal);
|
||||||
caller.getBody().add(callInitializer());
|
caller.getBody().add(callInitializer());
|
||||||
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(stringBuilderLocal))));
|
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(stringBuilderLocal))));
|
||||||
|
@ -130,9 +130,9 @@ public class WasmGCModuleGenerator {
|
||||||
var stringArrayType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String[].class));
|
var stringArrayType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String[].class));
|
||||||
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
||||||
var caller = new WasmFunction(function.getType());
|
var caller = new WasmFunction(function.getType());
|
||||||
var arrayLocal = new WasmLocal(stringArrayType);
|
var arrayLocal = new WasmLocal(stringArrayType, "array");
|
||||||
var indexLocal = new WasmLocal(WasmType.INT32);
|
var indexLocal = new WasmLocal(WasmType.INT32, "index");
|
||||||
var valueLocal = new WasmLocal(stringType);
|
var valueLocal = new WasmLocal(stringType, "string");
|
||||||
caller.add(arrayLocal);
|
caller.add(arrayLocal);
|
||||||
caller.add(indexLocal);
|
caller.add(indexLocal);
|
||||||
caller.add(valueLocal);
|
caller.add(valueLocal);
|
||||||
|
@ -148,7 +148,7 @@ public class WasmGCModuleGenerator {
|
||||||
String.class, "length", int.class));
|
String.class, "length", int.class));
|
||||||
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
||||||
var caller = new WasmFunction(function.getType());
|
var caller = new WasmFunction(function.getType());
|
||||||
var stringLocal = new WasmLocal(stringType);
|
var stringLocal = new WasmLocal(stringType, "string");
|
||||||
caller.add(stringLocal);
|
caller.add(stringLocal);
|
||||||
caller.getBody().add(callInitializer());
|
caller.getBody().add(callInitializer());
|
||||||
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(stringLocal))));
|
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(stringLocal))));
|
||||||
|
@ -161,8 +161,8 @@ public class WasmGCModuleGenerator {
|
||||||
String.class, "charAt", int.class, char.class));
|
String.class, "charAt", int.class, char.class));
|
||||||
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
||||||
var caller = new WasmFunction(function.getType());
|
var caller = new WasmFunction(function.getType());
|
||||||
var stringLocal = new WasmLocal(stringType);
|
var stringLocal = new WasmLocal(stringType, "string");
|
||||||
var indexLocal = new WasmLocal(WasmType.INT32);
|
var indexLocal = new WasmLocal(WasmType.INT32, "index");
|
||||||
caller.add(stringLocal);
|
caller.add(stringLocal);
|
||||||
caller.add(indexLocal);
|
caller.add(indexLocal);
|
||||||
caller.getBody().add(callInitializer());
|
caller.getBody().add(callInitializer());
|
||||||
|
@ -180,7 +180,7 @@ public class WasmGCModuleGenerator {
|
||||||
initializer = new WasmFunction(functionType);
|
initializer = new WasmFunction(functionType);
|
||||||
initializer.setReferenced(true);
|
initializer.setReferenced(true);
|
||||||
declarationsGenerator.module.functions.add(initializer);
|
declarationsGenerator.module.functions.add(initializer);
|
||||||
initializerRef = new WasmGlobal("teavm_initializer", functionType.getReference(),
|
initializerRef = new WasmGlobal("teavm@initializer", functionType.getReference(),
|
||||||
new WasmFunctionReference(initializer));
|
new WasmFunctionReference(initializer));
|
||||||
declarationsGenerator.module.globals.add(initializerRef);
|
declarationsGenerator.module.globals.add(initializerRef);
|
||||||
initializer.getBody().add(new WasmSetGlobal(initializerRef,
|
initializer.getBody().add(new WasmSetGlobal(initializerRef,
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.util.function.Predicate;
|
||||||
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
||||||
import org.teavm.backend.wasm.generate.WasmNameProvider;
|
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassGenerator;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassGenerator;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCSupertypeFunctionProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCSupertypeFunctionProvider;
|
||||||
|
@ -61,7 +60,7 @@ public class WasmGCDeclarationsGenerator {
|
||||||
hierarchy = new ClassHierarchy(classes);
|
hierarchy = new ClassHierarchy(classes);
|
||||||
var virtualTables = createVirtualTableProvider(classes, isVirtual);
|
var virtualTables = createVirtualTableProvider(classes, isVirtual);
|
||||||
functionTypes = new WasmFunctionTypes(module);
|
functionTypes = new WasmFunctionTypes(module);
|
||||||
var names = new WasmNameProvider();
|
var names = new WasmGCNameProvider();
|
||||||
methodGenerator = new WasmGCMethodGenerator(
|
methodGenerator = new WasmGCMethodGenerator(
|
||||||
module,
|
module,
|
||||||
hierarchy,
|
hierarchy,
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* 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.generate.gc;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
|
import org.teavm.model.MethodDescriptor;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
public class WasmGCNameProvider {
|
||||||
|
private Set<String> occupiedTopLevelNames = new HashSet<>();
|
||||||
|
private Set<String> occupiedStructNames = new HashSet<>();
|
||||||
|
|
||||||
|
private Map<MethodDescriptor, String> virtualMethodNames = new HashMap<>();
|
||||||
|
private Map<FieldReference, String> memberFieldNames = new HashMap<>();
|
||||||
|
|
||||||
|
public String topLevel(String name) {
|
||||||
|
return pickUnoccupied(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String structureField(String name) {
|
||||||
|
return pickUnoccupied(name, occupiedStructNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String forVirtualMethod(MethodDescriptor method) {
|
||||||
|
return virtualMethodNames.computeIfAbsent(method,
|
||||||
|
k -> pickUnoccupied(sanitize(k.getName()), occupiedStructNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String forMemberField(FieldReference field) {
|
||||||
|
return memberFieldNames.computeIfAbsent(field,
|
||||||
|
k -> pickUnoccupied(sanitize(field.getFieldName()), occupiedStructNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String suggestForMethod(MethodReference method) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(sanitize(method.getClassName()));
|
||||||
|
sb.append("::");
|
||||||
|
sb.append(sanitize(method.getName()));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String suggestForStaticField(FieldReference field) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(sanitize(field.getClassName()));
|
||||||
|
sb.append('#');
|
||||||
|
sb.append(sanitize(field.getFieldName()));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String suggestForClass(String className) {
|
||||||
|
return sanitize(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String suggestForType(ValueType type) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
suggestForType(type, sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void suggestForType(ValueType type, StringBuilder sb) {
|
||||||
|
if (type instanceof ValueType.Object) {
|
||||||
|
sb.append(suggestForClass(((ValueType.Object) type).getClassName()));
|
||||||
|
} else if (type instanceof ValueType.Array) {
|
||||||
|
sb.append("Array<");
|
||||||
|
suggestForType(((ValueType.Array) type).getItemType(), sb);
|
||||||
|
sb.append(">");
|
||||||
|
} else {
|
||||||
|
sb.append("&").append(type.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String sanitize(String name) {
|
||||||
|
char[] chars = null;
|
||||||
|
var i = 0;
|
||||||
|
for (; i < name.length(); ++i) {
|
||||||
|
var c = name.charAt(i);
|
||||||
|
if (!isIdentifierPart(c)) {
|
||||||
|
chars = new char[name.length()];
|
||||||
|
name.getChars(0, i, chars, 0);
|
||||||
|
chars[i++] = '_';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (chars == null) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
for (; i < name.length(); ++i) {
|
||||||
|
var c = name.charAt(i);
|
||||||
|
chars[i] = isIdentifierPart(c) ? c : '_';
|
||||||
|
}
|
||||||
|
return new String(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isIdentifierPart(char c) {
|
||||||
|
switch (c) {
|
||||||
|
case '!':
|
||||||
|
case '#':
|
||||||
|
case '$':
|
||||||
|
case '%':
|
||||||
|
case '&':
|
||||||
|
case '`':
|
||||||
|
case '*':
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '.':
|
||||||
|
case '/':
|
||||||
|
case ':':
|
||||||
|
case '<':
|
||||||
|
case '=':
|
||||||
|
case '>':
|
||||||
|
case '?':
|
||||||
|
case '@':
|
||||||
|
case '\\':
|
||||||
|
case '^':
|
||||||
|
case '_':
|
||||||
|
case '\'':
|
||||||
|
case '|':
|
||||||
|
case '~':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String pickUnoccupied(String name) {
|
||||||
|
return pickUnoccupied(name, occupiedTopLevelNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String pickUnoccupied(String name, Set<String> occupied) {
|
||||||
|
String result = name;
|
||||||
|
int index = 0;
|
||||||
|
while (!occupied.add(result)) {
|
||||||
|
result = name + "_" + index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,13 +25,13 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import org.teavm.backend.lowlevel.generate.NameProvider;
|
|
||||||
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTable;
|
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTable;
|
||||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableEntry;
|
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableEntry;
|
||||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.WasmGCInitializerContributor;
|
import org.teavm.backend.wasm.generate.gc.WasmGCInitializerContributor;
|
||||||
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
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.WasmField;
|
||||||
|
@ -106,12 +106,13 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
public final WasmGCStringPool strings;
|
public final WasmGCStringPool strings;
|
||||||
public final WasmGCStandardClasses standardClasses;
|
public final WasmGCStandardClasses standardClasses;
|
||||||
public final WasmGCTypeMapper typeMapper;
|
public final WasmGCTypeMapper typeMapper;
|
||||||
private final NameProvider names;
|
private final WasmGCNameProvider names;
|
||||||
private List<WasmExpression> initializerFunctionStatements = new ArrayList<>();
|
private List<WasmExpression> initializerFunctionStatements = new ArrayList<>();
|
||||||
private WasmFunction createPrimitiveClassFunction;
|
private WasmFunction createPrimitiveClassFunction;
|
||||||
private WasmFunction createArrayClassFunction;
|
private WasmFunction createArrayClassFunction;
|
||||||
private final WasmGCSupertypeFunctionGenerator supertypeGenerator;
|
private final WasmGCSupertypeFunctionGenerator supertypeGenerator;
|
||||||
private final WasmGCNewArrayFunctionGenerator newArrayGenerator;
|
private final WasmGCNewArrayFunctionGenerator newArrayGenerator;
|
||||||
|
private String arrayDataFieldName;
|
||||||
|
|
||||||
private int classTagOffset;
|
private int classTagOffset;
|
||||||
private int classFlagsOffset;
|
private int classFlagsOffset;
|
||||||
|
@ -134,7 +135,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
public WasmGCClassGenerator(WasmModule module, ClassReaderSource classSource,
|
public WasmGCClassGenerator(WasmModule module, ClassReaderSource classSource,
|
||||||
WasmFunctionTypes functionTypes, TagRegistry tagRegistry,
|
WasmFunctionTypes functionTypes, TagRegistry tagRegistry,
|
||||||
ClassMetadataRequirements metadataRequirements, WasmGCVirtualTableProvider virtualTables,
|
ClassMetadataRequirements metadataRequirements, WasmGCVirtualTableProvider virtualTables,
|
||||||
BaseWasmFunctionRepository functionProvider, NameProvider names,
|
BaseWasmFunctionRepository functionProvider, WasmGCNameProvider names,
|
||||||
ClassInitializerInfo classInitializerInfo) {
|
ClassInitializerInfo classInitializerInfo) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
|
@ -146,9 +147,9 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
this.names = names;
|
this.names = names;
|
||||||
this.classInitializerInfo = classInitializerInfo;
|
this.classInitializerInfo = classInitializerInfo;
|
||||||
standardClasses = new WasmGCStandardClasses(this);
|
standardClasses = new WasmGCStandardClasses(this);
|
||||||
strings = new WasmGCStringPool(standardClasses, module, functionProvider);
|
strings = new WasmGCStringPool(standardClasses, module, functionProvider, names);
|
||||||
supertypeGenerator = new WasmGCSupertypeFunctionGenerator(module, this, names, tagRegistry, functionTypes);
|
supertypeGenerator = new WasmGCSupertypeFunctionGenerator(module, this, names, tagRegistry, functionTypes);
|
||||||
newArrayGenerator = new WasmGCNewArrayFunctionGenerator(module, functionTypes, this);
|
newArrayGenerator = new WasmGCNewArrayFunctionGenerator(module, functionTypes, this, names);
|
||||||
typeMapper = new WasmGCTypeMapper(classSource, this, functionTypes, module);
|
typeMapper = new WasmGCTypeMapper(classSource, this, functionTypes, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +280,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (classInfo.structure == null) {
|
if (classInfo.structure == null) {
|
||||||
classInfo.structure = new WasmStructure(name != null ? names.forClass(name) : null,
|
var structName = names.topLevel(names.suggestForType(type));
|
||||||
|
classInfo.structure = new WasmStructure(structName,
|
||||||
fields -> fillFields(finalClassInfo, fields, type));
|
fields -> fillFields(finalClassInfo, fields, type));
|
||||||
module.types.add(classInfo.structure);
|
module.types.add(classInfo.structure);
|
||||||
nonInitializedStructures.add(classInfo.structure);
|
nonInitializedStructures.add(classInfo.structure);
|
||||||
|
@ -297,7 +299,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
classInfo.structure.setSupertype(standardClasses.objectClass().structure);
|
classInfo.structure.setSupertype(standardClasses.objectClass().structure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var pointerName = names.forClassInstance(type);
|
var pointerName = names.topLevel(names.suggestForType(type) + "@class");
|
||||||
classInfo.hasOwnVirtualTable = virtualTable != null && !virtualTable.getEntries().isEmpty();
|
classInfo.hasOwnVirtualTable = virtualTable != null && !virtualTable.getEntries().isEmpty();
|
||||||
WasmStructure classStructure;
|
WasmStructure classStructure;
|
||||||
if (classInfo.hasOwnVirtualTable) {
|
if (classInfo.hasOwnVirtualTable) {
|
||||||
|
@ -419,7 +421,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
if (classInitializerInfo.isDynamicInitializer(name)) {
|
if (classInitializerInfo.isDynamicInitializer(name)) {
|
||||||
if (cls != null && cls.getMethod(CLINIT_METHOD_DESC) != null) {
|
if (cls != null && cls.getMethod(CLINIT_METHOD_DESC) != null) {
|
||||||
var clinitType = functionTypes.of(null);
|
var clinitType = functionTypes.of(null);
|
||||||
classInfo.initializerPointer = new WasmGlobal(null, clinitType.getReference(),
|
var wasmName = names.topLevel(names.suggestForClass(name) + "@initializer");
|
||||||
|
classInfo.initializerPointer = new WasmGlobal(wasmName, clinitType.getReference(),
|
||||||
new WasmNullConstant(clinitType.getReference()));
|
new WasmNullConstant(clinitType.getReference()));
|
||||||
module.globals.add(classInfo.initializerPointer);
|
module.globals.add(classInfo.initializerPointer);
|
||||||
}
|
}
|
||||||
|
@ -467,10 +470,11 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
WasmStructure objectStructure) {
|
WasmStructure objectStructure) {
|
||||||
var virtualTable = virtualTables.lookup("java.lang.Object");
|
var virtualTable = virtualTables.lookup("java.lang.Object");
|
||||||
var structure = getArrayVirtualTableStructure();
|
var structure = getArrayVirtualTableStructure();
|
||||||
|
var itemType = ((ValueType.Array) type).getItemType();
|
||||||
|
|
||||||
for (var entry : virtualTable.getEntries()) {
|
for (var entry : virtualTable.getEntries()) {
|
||||||
if (entry.getMethod().getName().equals("clone")) {
|
if (entry.getMethod().getName().equals("clone")) {
|
||||||
var function = generateArrayCloneMethod(objectStructure);
|
var function = generateArrayCloneMethod(objectStructure, itemType);
|
||||||
function.setReferenced(true);
|
function.setReferenced(true);
|
||||||
var ref = new WasmFunctionReference(function);
|
var ref = new WasmFunctionReference(function);
|
||||||
var fieldIndex = virtualTableFieldOffset + entry.getIndex();
|
var fieldIndex = virtualTableFieldOffset + entry.getIndex();
|
||||||
|
@ -480,7 +484,6 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var itemType = ((ValueType.Array) type).getItemType();
|
|
||||||
var info = metadataRequirements.getInfo(type);
|
var info = metadataRequirements.getInfo(type);
|
||||||
if (info.arrayLength()) {
|
if (info.arrayLength()) {
|
||||||
var lengthFunction = getArrayLengthFunction(objectStructure);
|
var lengthFunction = getArrayLengthFunction(objectStructure);
|
||||||
|
@ -502,19 +505,20 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
var elementType = arrayType.getElementType().asUnpackedType();
|
var elementType = arrayType.getElementType().asUnpackedType();
|
||||||
if (elementType instanceof WasmType.Reference) {
|
if (elementType instanceof WasmType.Reference) {
|
||||||
if (arrayLengthObjectFunction == null) {
|
if (arrayLengthObjectFunction == null) {
|
||||||
arrayLengthObjectFunction = getArrayLengthFunction(objectStructure, arrayType);
|
arrayLengthObjectFunction = createArrayLengthFunction(objectStructure);
|
||||||
}
|
}
|
||||||
return arrayLengthObjectFunction;
|
return arrayLengthObjectFunction;
|
||||||
}
|
}
|
||||||
return getArrayLengthFunction(objectStructure, arrayType);
|
return createArrayLengthFunction(objectStructure);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WasmFunction getArrayLengthFunction(WasmStructure objectStructure, WasmArray arrayType) {
|
private WasmFunction createArrayLengthFunction(WasmStructure objectStructure) {
|
||||||
var function = new WasmFunction(functionTypes.of(WasmType.INT32, standardClasses.objectClass().getType()));
|
var function = new WasmFunction(functionTypes.of(WasmType.INT32, standardClasses.objectClass().getType()));
|
||||||
function.setReferenced(true);
|
function.setReferenced(true);
|
||||||
|
function.setName(names.topLevel("Array<*>::length"));
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
|
|
||||||
var objectLocal = new WasmLocal(standardClasses.objectClass().getType());
|
var objectLocal = new WasmLocal(standardClasses.objectClass().getType(), "object");
|
||||||
function.add(objectLocal);
|
function.add(objectLocal);
|
||||||
|
|
||||||
var castObject = new WasmCast(new WasmGetLocal(objectLocal), objectStructure.getReference());
|
var castObject = new WasmCast(new WasmGetLocal(objectLocal), objectStructure.getReference());
|
||||||
|
@ -534,6 +538,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
private WasmFunction getArrayGetObjectFunction() {
|
private WasmFunction getArrayGetObjectFunction() {
|
||||||
if (arrayGetObjectFunction == null) {
|
if (arrayGetObjectFunction == null) {
|
||||||
arrayGetObjectFunction = new WasmFunction(getArrayGetType());
|
arrayGetObjectFunction = new WasmFunction(getArrayGetType());
|
||||||
|
arrayGetObjectFunction.setName(names.topLevel("Array<" + names.suggestForClass("java.lang.Object")
|
||||||
|
+ "::get"));
|
||||||
module.functions.add(arrayGetObjectFunction);
|
module.functions.add(arrayGetObjectFunction);
|
||||||
arrayGetObjectFunction.setReferenced(true);
|
arrayGetObjectFunction.setReferenced(true);
|
||||||
|
|
||||||
|
@ -541,8 +547,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
var arrayDataTypeRef = (WasmType.CompositeReference) arrayStruct.getFields()
|
var arrayDataTypeRef = (WasmType.CompositeReference) arrayStruct.getFields()
|
||||||
.get(ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
.get(ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
||||||
var arrayDataType = (WasmArray) arrayDataTypeRef.composite;
|
var arrayDataType = (WasmArray) arrayDataTypeRef.composite;
|
||||||
var objectLocal = new WasmLocal(standardClasses.objectClass().getType());
|
var objectLocal = new WasmLocal(standardClasses.objectClass().getType(), "object");
|
||||||
var indexLocal = new WasmLocal(WasmType.INT32);
|
var indexLocal = new WasmLocal(WasmType.INT32, "index");
|
||||||
arrayGetObjectFunction.add(objectLocal);
|
arrayGetObjectFunction.add(objectLocal);
|
||||||
arrayGetObjectFunction.add(indexLocal);
|
arrayGetObjectFunction.add(indexLocal);
|
||||||
|
|
||||||
|
@ -556,6 +562,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
|
|
||||||
private WasmFunction generateArrayGetPrimitiveFunction(PrimitiveType type) {
|
private WasmFunction generateArrayGetPrimitiveFunction(PrimitiveType type) {
|
||||||
var function = new WasmFunction(getArrayGetType());
|
var function = new WasmFunction(getArrayGetType());
|
||||||
|
arrayGetObjectFunction.setName(names.topLevel("Array<" + names.suggestForType(ValueType.primitive(type))
|
||||||
|
+ ">::get"));
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
function.setReferenced(true);
|
function.setReferenced(true);
|
||||||
|
|
||||||
|
@ -563,8 +571,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
var arrayDataTypeRef = (WasmType.CompositeReference) arrayStruct.getFields()
|
var arrayDataTypeRef = (WasmType.CompositeReference) arrayStruct.getFields()
|
||||||
.get(ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
.get(ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
||||||
var arrayDataType = (WasmArray) arrayDataTypeRef.composite;
|
var arrayDataType = (WasmArray) arrayDataTypeRef.composite;
|
||||||
var objectLocal = new WasmLocal(standardClasses.objectClass().getType());
|
var objectLocal = new WasmLocal(standardClasses.objectClass().getType(), "object");
|
||||||
var indexLocal = new WasmLocal(WasmType.INT32);
|
var indexLocal = new WasmLocal(WasmType.INT32, "index");
|
||||||
function.add(objectLocal);
|
function.add(objectLocal);
|
||||||
function.add(indexLocal);
|
function.add(indexLocal);
|
||||||
|
|
||||||
|
@ -644,6 +652,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
if (!entry.getOrigin().getClassName().equals(implementor.getClassName())
|
if (!entry.getOrigin().getClassName().equals(implementor.getClassName())
|
||||||
|| expectedFunctionType != function.getType()) {
|
|| expectedFunctionType != function.getType()) {
|
||||||
var wrapperFunction = new WasmFunction(expectedFunctionType);
|
var wrapperFunction = new WasmFunction(expectedFunctionType);
|
||||||
|
wrapperFunction.setName(names.topLevel(names.suggestForMethod(implementor) + "@caller"));
|
||||||
module.functions.add(wrapperFunction);
|
module.functions.add(wrapperFunction);
|
||||||
var call = new WasmCall(function);
|
var call = new WasmCall(function);
|
||||||
var instanceParam = new WasmLocal(getClassInfo(virtualTable.getClassName()).getType());
|
var instanceParam = new WasmLocal(getClassInfo(virtualTable.getClassName()).getType());
|
||||||
|
@ -665,19 +674,20 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private WasmFunction generateArrayCloneMethod(WasmStructure objectStructure) {
|
private WasmFunction generateArrayCloneMethod(WasmStructure objectStructure, ValueType itemType) {
|
||||||
var arrayTypeRef = (WasmType.CompositeReference) objectStructure.getFields().get(
|
var arrayTypeRef = (WasmType.CompositeReference) objectStructure.getFields().get(
|
||||||
WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
||||||
var arrayType = (WasmArray) arrayTypeRef.composite;
|
var arrayType = (WasmArray) arrayTypeRef.composite;
|
||||||
|
|
||||||
var type = typeMapper.getFunctionType(standardClasses.objectClass().getType(), CLONE_METHOD_DESC, false);
|
var type = typeMapper.getFunctionType(standardClasses.objectClass().getType(), CLONE_METHOD_DESC, false);
|
||||||
var function = new WasmFunction(type);
|
var function = new WasmFunction(type);
|
||||||
|
function.setName(names.topLevel("Array<" + names.suggestForType(itemType) + ">::clone"));
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
var instanceLocal = new WasmLocal(standardClasses.objectClass().getType());
|
var instanceLocal = new WasmLocal(standardClasses.objectClass().getType(), "instance");
|
||||||
var originalLocal = new WasmLocal(objectStructure.getReference());
|
var originalLocal = new WasmLocal(objectStructure.getReference(), "original");
|
||||||
var resultLocal = new WasmLocal(objectStructure.getReference());
|
var resultLocal = new WasmLocal(objectStructure.getReference(), "result");
|
||||||
var originalDataLocal = new WasmLocal(arrayType.getReference());
|
var originalDataLocal = new WasmLocal(arrayType.getReference(), "originalData");
|
||||||
var dataCopyLocal = new WasmLocal(arrayType.getReference());
|
var dataCopyLocal = new WasmLocal(arrayType.getReference(), "resultData");
|
||||||
function.add(instanceLocal);
|
function.add(instanceLocal);
|
||||||
function.add(originalLocal);
|
function.add(originalLocal);
|
||||||
function.add(resultLocal);
|
function.add(resultLocal);
|
||||||
|
@ -712,7 +722,8 @@ 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), fields -> {
|
var wasmName = names.topLevel("Class<" + names.suggestForClass(className) + ">");
|
||||||
|
var structure = new WasmStructure(wasmName, fields -> {
|
||||||
addSystemFields(fields);
|
addSystemFields(fields);
|
||||||
fillSimpleClassFields(fields, "java.lang.Class");
|
fillSimpleClassFields(fields, "java.lang.Class");
|
||||||
addVirtualTableFields(fields, virtualTable);
|
addVirtualTableFields(fields, virtualTable);
|
||||||
|
@ -744,19 +755,22 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
@Override
|
@Override
|
||||||
public WasmStructure getArrayVirtualTableStructure() {
|
public WasmStructure getArrayVirtualTableStructure() {
|
||||||
if (arrayVirtualTableStruct == null) {
|
if (arrayVirtualTableStruct == null) {
|
||||||
arrayVirtualTableStruct = new WasmStructure(null, fields -> {
|
var wasmName = names.topLevel("Class<Array<*>>");
|
||||||
|
arrayVirtualTableStruct = new WasmStructure(wasmName, fields -> {
|
||||||
addSystemFields(fields);
|
addSystemFields(fields);
|
||||||
fillSimpleClassFields(fields, "java.lang.Class");
|
fillSimpleClassFields(fields, "java.lang.Class");
|
||||||
addVirtualTableFields(fields, virtualTables.lookup("java.lang.Object"));
|
addVirtualTableFields(fields, virtualTables.lookup("java.lang.Object"));
|
||||||
if (metadataRequirements.hasArrayLength()) {
|
if (metadataRequirements.hasArrayLength()) {
|
||||||
arrayLengthOffset = fields.size();
|
arrayLengthOffset = fields.size();
|
||||||
var arrayLengthType = getArrayLengthType();
|
var arrayLengthType = getArrayLengthType();
|
||||||
fields.add(new WasmField(arrayLengthType.getReference().asStorage()));
|
fields.add(new WasmField(arrayLengthType.getReference().asStorage(),
|
||||||
|
names.structureField("@arrayLength")));
|
||||||
}
|
}
|
||||||
if (metadataRequirements.hasArrayGet()) {
|
if (metadataRequirements.hasArrayGet()) {
|
||||||
arrayGetOffset = fields.size();
|
arrayGetOffset = fields.size();
|
||||||
var arrayGetType = getArrayGetType();
|
var arrayGetType = getArrayGetType();
|
||||||
fields.add(new WasmField(arrayGetType.getReference().asStorage()));
|
fields.add(new WasmField(arrayGetType.getReference().asStorage(),
|
||||||
|
names.structureField("@arrayGet")));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
arrayVirtualTableStruct.setSupertype(standardClasses.objectClass().getVirtualTableStructure());
|
arrayVirtualTableStruct.setSupertype(standardClasses.objectClass().getVirtualTableStructure());
|
||||||
|
@ -830,7 +844,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
|
|
||||||
var type = typeMapper.mapType(javaType);
|
var type = typeMapper.mapType(javaType);
|
||||||
var wasmInitialValue = initValue != null ? initialValue(initValue) : WasmExpression.defaultValueOfType(type);
|
var wasmInitialValue = initValue != null ? initialValue(initValue) : WasmExpression.defaultValueOfType(type);
|
||||||
var global = new WasmGlobal(names.forStaticField(fieldRef), type, wasmInitialValue);
|
var wasmName = names.topLevel(names.suggestForStaticField(fieldRef));
|
||||||
|
var global = new WasmGlobal(wasmName, type, wasmInitialValue);
|
||||||
dynamicInitialValue(global, initValue);
|
dynamicInitialValue(global, initValue);
|
||||||
module.globals.add(global);
|
module.globals.add(global);
|
||||||
|
|
||||||
|
@ -968,9 +983,18 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
} else {
|
} else {
|
||||||
wasmElementType = standardClasses.objectClass().getType().asStorage();
|
wasmElementType = standardClasses.objectClass().getType().asStorage();
|
||||||
}
|
}
|
||||||
var wasmArray = new WasmArray(null, wasmElementType);
|
var wasmArrayName = names.topLevel(names.suggestForType(classInfo.getValueType()) + "$Data");
|
||||||
|
var wasmArray = new WasmArray(wasmArrayName, wasmElementType);
|
||||||
module.types.add(wasmArray);
|
module.types.add(wasmArray);
|
||||||
classInfo.structure.getFields().add(new WasmField(wasmArray.getReference().asStorage(), "data"));
|
classInfo.structure.getFields().add(new WasmField(wasmArray.getReference().asStorage(),
|
||||||
|
arrayDataFieldName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String arrayDataFieldName() {
|
||||||
|
if (arrayDataFieldName == null) {
|
||||||
|
arrayDataFieldName = names.structureField("@data");
|
||||||
|
}
|
||||||
|
return arrayDataFieldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WasmFunction getCreatePrimitiveClassFunction() {
|
private WasmFunction getCreatePrimitiveClassFunction() {
|
||||||
|
@ -988,7 +1012,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
WasmType.INT32
|
WasmType.INT32
|
||||||
);
|
);
|
||||||
var function = new WasmFunction(functionType);
|
var function = new WasmFunction(functionType);
|
||||||
function.setName("teavm_fill_primitive_class");
|
function.setName(names.topLevel("teavm@fill_primitive_class"));
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
|
|
||||||
var targetVar = new WasmLocal(standardClasses.classClass().getType(), "target");
|
var targetVar = new WasmLocal(standardClasses.classClass().getType(), "target");
|
||||||
|
@ -1047,7 +1071,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
);
|
);
|
||||||
var function = new WasmFunction(functionType);
|
var function = new WasmFunction(functionType);
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
function.setName("teavm_fill_array_class");
|
function.setName(names.topLevel("teavm@fillArrayClass"));
|
||||||
|
|
||||||
var targetVar = new WasmLocal(standardClasses.classClass().getType(), "target");
|
var targetVar = new WasmLocal(standardClasses.classClass().getType(), "target");
|
||||||
var itemVar = new WasmLocal(standardClasses.classClass().getType(), "item");
|
var itemVar = new WasmLocal(standardClasses.classClass().getType(), "item");
|
||||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.backend.wasm.generate.gc.classes;
|
||||||
|
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
||||||
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
|
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
|
||||||
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;
|
||||||
|
@ -32,22 +33,26 @@ class WasmGCNewArrayFunctionGenerator {
|
||||||
private WasmFunctionTypes functionTypes;
|
private WasmFunctionTypes functionTypes;
|
||||||
private WasmGCClassInfoProvider classInfoProvider;
|
private WasmGCClassInfoProvider classInfoProvider;
|
||||||
private WasmFunctionType newArrayFunctionType;
|
private WasmFunctionType newArrayFunctionType;
|
||||||
|
private WasmGCNameProvider names;
|
||||||
|
|
||||||
WasmGCNewArrayFunctionGenerator(WasmModule module, WasmFunctionTypes functionTypes,
|
WasmGCNewArrayFunctionGenerator(WasmModule module, WasmFunctionTypes functionTypes,
|
||||||
WasmGCClassInfoProvider classInfoProvider) {
|
WasmGCClassInfoProvider classInfoProvider, WasmGCNameProvider names) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.functionTypes = functionTypes;
|
this.functionTypes = functionTypes;
|
||||||
this.classInfoProvider = classInfoProvider;
|
this.classInfoProvider = classInfoProvider;
|
||||||
|
this.names = names;
|
||||||
}
|
}
|
||||||
|
|
||||||
WasmFunction generateNewArrayFunction(ValueType itemType) {
|
WasmFunction generateNewArrayFunction(ValueType itemType) {
|
||||||
var function = new WasmFunction(getNewArrayFunctionType());
|
var function = new WasmFunction(getNewArrayFunctionType());
|
||||||
|
function.setName(names.topLevel("Array<" + names.suggestForType(itemType) + ">@new"));
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
var sizeLocal = new WasmLocal(WasmType.INT32);
|
var sizeLocal = new WasmLocal(WasmType.INT32, "length");
|
||||||
function.add(sizeLocal);
|
function.add(sizeLocal);
|
||||||
var tempVars = new TemporaryVariablePool(function);
|
var tempVars = new TemporaryVariablePool(function);
|
||||||
var genUtil = new WasmGCGenerationUtil(classInfoProvider, tempVars);
|
var genUtil = new WasmGCGenerationUtil(classInfoProvider, tempVars);
|
||||||
var targetVar = new WasmLocal(classInfoProvider.getClassInfo(ValueType.arrayOf(itemType)).getType());
|
var targetVar = new WasmLocal(classInfoProvider.getClassInfo(ValueType.arrayOf(itemType)).getType(),
|
||||||
|
"result");
|
||||||
function.add(targetVar);
|
function.add(targetVar);
|
||||||
genUtil.allocateArray(itemType, new WasmGetLocal(sizeLocal), null, targetVar, function.getBody());
|
genUtil.allocateArray(itemType, new WasmGetLocal(sizeLocal), null, targetVar, function.getBody());
|
||||||
function.getBody().add(new WasmReturn(new WasmGetLocal(targetVar)));
|
function.getBody().add(new WasmReturn(new WasmGetLocal(targetVar)));
|
||||||
|
|
|
@ -19,8 +19,8 @@ import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.teavm.backend.lowlevel.generate.NameProvider;
|
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
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.WasmLocal;
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
|
@ -47,7 +47,7 @@ public class WasmGCSupertypeFunctionGenerator implements WasmGCSupertypeFunction
|
||||||
private Map<ValueType, WasmFunction> functions = new HashMap<>();
|
private Map<ValueType, WasmFunction> functions = new HashMap<>();
|
||||||
private WasmModule module;
|
private WasmModule module;
|
||||||
private WasmGCClassGenerator classGenerator;
|
private WasmGCClassGenerator classGenerator;
|
||||||
private NameProvider nameProvider;
|
private WasmGCNameProvider nameProvider;
|
||||||
private TagRegistry tagRegistry;
|
private TagRegistry tagRegistry;
|
||||||
private WasmFunctionTypes functionTypes;
|
private WasmFunctionTypes functionTypes;
|
||||||
private WasmFunctionType functionType;
|
private WasmFunctionType functionType;
|
||||||
|
@ -55,7 +55,7 @@ public class WasmGCSupertypeFunctionGenerator implements WasmGCSupertypeFunction
|
||||||
WasmGCSupertypeFunctionGenerator(
|
WasmGCSupertypeFunctionGenerator(
|
||||||
WasmModule module,
|
WasmModule module,
|
||||||
WasmGCClassGenerator classGenerator,
|
WasmGCClassGenerator classGenerator,
|
||||||
NameProvider nameProvider,
|
WasmGCNameProvider nameProvider,
|
||||||
TagRegistry tagRegistry,
|
TagRegistry tagRegistry,
|
||||||
WasmFunctionTypes functionTypes
|
WasmFunctionTypes functionTypes
|
||||||
) {
|
) {
|
||||||
|
@ -78,7 +78,7 @@ public class WasmGCSupertypeFunctionGenerator implements WasmGCSupertypeFunction
|
||||||
|
|
||||||
private WasmFunction generateIsSupertypeFunction(ValueType type) {
|
private WasmFunction generateIsSupertypeFunction(ValueType type) {
|
||||||
var function = new WasmFunction(getFunctionType());
|
var function = new WasmFunction(getFunctionType());
|
||||||
function.setName(nameProvider.forSupertypeFunction(type));
|
function.setName(nameProvider.topLevel(nameProvider.suggestForType(type) + "@isSupertypes"));
|
||||||
var subtypeVar = new WasmLocal(classGenerator.standardClasses.classClass().getType(), "subtype");
|
var subtypeVar = new WasmLocal(classGenerator.standardClasses.classClass().getType(), "subtype");
|
||||||
function.add(subtypeVar);
|
function.add(subtypeVar);
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
||||||
import org.teavm.backend.wasm.generate.common.methods.BaseWasmGenerationContext;
|
import org.teavm.backend.wasm.generate.common.methods.BaseWasmGenerationContext;
|
||||||
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCStandardClasses;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCStandardClasses;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCSupertypeFunctionProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCSupertypeFunctionProvider;
|
||||||
|
@ -62,13 +63,15 @@ public class WasmGCGenerationContext implements BaseWasmGenerationContext {
|
||||||
private WasmGlobal exceptionGlobal;
|
private WasmGlobal exceptionGlobal;
|
||||||
private WasmTag exceptionTag;
|
private WasmTag exceptionTag;
|
||||||
private Map<String, Set<String>> interfaceImplementors;
|
private Map<String, Set<String>> interfaceImplementors;
|
||||||
|
private WasmGCNameProvider names;
|
||||||
|
|
||||||
public WasmGCGenerationContext(WasmModule module, WasmGCVirtualTableProvider virtualTables,
|
public WasmGCGenerationContext(WasmModule module, WasmGCVirtualTableProvider virtualTables,
|
||||||
WasmGCTypeMapper typeMapper, WasmFunctionTypes functionTypes, ListableClassReaderSource classes,
|
WasmGCTypeMapper typeMapper, WasmFunctionTypes functionTypes, ListableClassReaderSource classes,
|
||||||
ClassHierarchy hierarchy, BaseWasmFunctionRepository functions,
|
ClassHierarchy hierarchy, BaseWasmFunctionRepository functions,
|
||||||
WasmGCSupertypeFunctionProvider supertypeFunctions, WasmGCClassInfoProvider classInfoProvider,
|
WasmGCSupertypeFunctionProvider supertypeFunctions, WasmGCClassInfoProvider classInfoProvider,
|
||||||
WasmGCStandardClasses standardClasses, WasmGCStringProvider strings,
|
WasmGCStandardClasses standardClasses, WasmGCStringProvider strings,
|
||||||
WasmGCCustomGeneratorProvider customGenerators, WasmGCIntrinsicProvider intrinsics) {
|
WasmGCCustomGeneratorProvider customGenerators, WasmGCIntrinsicProvider intrinsics,
|
||||||
|
WasmGCNameProvider names) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.virtualTables = virtualTables;
|
this.virtualTables = virtualTables;
|
||||||
this.typeMapper = typeMapper;
|
this.typeMapper = typeMapper;
|
||||||
|
@ -82,6 +85,7 @@ public class WasmGCGenerationContext implements BaseWasmGenerationContext {
|
||||||
this.strings = strings;
|
this.strings = strings;
|
||||||
this.customGenerators = customGenerators;
|
this.customGenerators = customGenerators;
|
||||||
this.intrinsics = intrinsics;
|
this.intrinsics = intrinsics;
|
||||||
|
this.names = names;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmGCClassInfoProvider classInfoProvider() {
|
public WasmGCClassInfoProvider classInfoProvider() {
|
||||||
|
@ -164,7 +168,8 @@ public class WasmGCGenerationContext implements BaseWasmGenerationContext {
|
||||||
public WasmGlobal exceptionGlobal() {
|
public WasmGlobal exceptionGlobal() {
|
||||||
if (exceptionGlobal == null) {
|
if (exceptionGlobal == null) {
|
||||||
var type = classInfoProvider.getClassInfo("java.lang.Throwable").getType();
|
var type = classInfoProvider.getClassInfo("java.lang.Throwable").getType();
|
||||||
exceptionGlobal = new WasmGlobal("teavm_thrown_exception", type, new WasmNullConstant(type));
|
exceptionGlobal = new WasmGlobal(names.topLevel("teavm@thrownException"), type,
|
||||||
|
new WasmNullConstant(type));
|
||||||
module.globals.add(exceptionGlobal);
|
module.globals.add(exceptionGlobal);
|
||||||
}
|
}
|
||||||
return exceptionGlobal;
|
return exceptionGlobal;
|
||||||
|
|
|
@ -23,11 +23,11 @@ import java.util.Objects;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.teavm.ast.decompilation.Decompiler;
|
import org.teavm.ast.decompilation.Decompiler;
|
||||||
import org.teavm.backend.lowlevel.generate.NameProvider;
|
|
||||||
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.gc.WasmGCVariableCategoryProvider;
|
import org.teavm.backend.wasm.gc.WasmGCVariableCategoryProvider;
|
||||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
||||||
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCStandardClasses;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCStandardClasses;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCSupertypeFunctionProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCSupertypeFunctionProvider;
|
||||||
|
@ -63,7 +63,7 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
private ClassInitializerInfo classInitInfo;
|
private ClassInitializerInfo classInitInfo;
|
||||||
private WasmFunctionTypes functionTypes;
|
private WasmFunctionTypes functionTypes;
|
||||||
private WasmGCSupertypeFunctionProvider supertypeFunctions;
|
private WasmGCSupertypeFunctionProvider supertypeFunctions;
|
||||||
private NameProvider names;
|
private WasmGCNameProvider names;
|
||||||
private Diagnostics diagnostics;
|
private Diagnostics diagnostics;
|
||||||
private WasmGCTypeMapper typeMapper;
|
private WasmGCTypeMapper typeMapper;
|
||||||
private WasmGCCustomGeneratorProvider customGenerators;
|
private WasmGCCustomGeneratorProvider customGenerators;
|
||||||
|
@ -86,7 +86,7 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
WasmGCVirtualTableProvider virtualTables,
|
WasmGCVirtualTableProvider virtualTables,
|
||||||
ClassInitializerInfo classInitInfo,
|
ClassInitializerInfo classInitInfo,
|
||||||
WasmFunctionTypes functionTypes,
|
WasmFunctionTypes functionTypes,
|
||||||
NameProvider names,
|
WasmGCNameProvider names,
|
||||||
Diagnostics diagnostics,
|
Diagnostics diagnostics,
|
||||||
WasmGCCustomGeneratorProvider customGenerators,
|
WasmGCCustomGeneratorProvider customGenerators,
|
||||||
WasmGCIntrinsicProvider intrinsics
|
WasmGCIntrinsicProvider intrinsics
|
||||||
|
@ -149,7 +149,7 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
parameterTypes[i] = typeMapper.mapType(methodReference.parameterType(i));
|
parameterTypes[i] = typeMapper.mapType(methodReference.parameterType(i));
|
||||||
}
|
}
|
||||||
var function = new WasmFunction(functionTypes.of(returnType, parameterTypes));
|
var function = new WasmFunction(functionTypes.of(returnType, parameterTypes));
|
||||||
function.setName(names.forMethod(methodReference));
|
function.setName(names.topLevel(names.suggestForMethod(methodReference)));
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
function.setJavaMethod(methodReference);
|
function.setJavaMethod(methodReference);
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
parameterTypes[i + 1] = typeMapper.mapType(methodReference.parameterType(i));
|
parameterTypes[i + 1] = typeMapper.mapType(methodReference.parameterType(i));
|
||||||
}
|
}
|
||||||
var function = new WasmFunction(functionTypes.of(returnType, parameterTypes));
|
var function = new WasmFunction(functionTypes.of(returnType, parameterTypes));
|
||||||
function.setName(names.forMethod(methodReference));
|
function.setName(names.topLevel(names.suggestForMethod(methodReference)));
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
function.setJavaMethod(methodReference);
|
function.setJavaMethod(methodReference);
|
||||||
|
|
||||||
|
@ -304,7 +304,8 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
standardClasses,
|
standardClasses,
|
||||||
strings,
|
strings,
|
||||||
customGenerators,
|
customGenerators,
|
||||||
intrinsics
|
intrinsics,
|
||||||
|
names
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
|
@ -314,7 +315,7 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
if (dummyInitializer == null) {
|
if (dummyInitializer == null) {
|
||||||
dummyInitializer = new WasmFunction(functionTypes.of(null));
|
dummyInitializer = new WasmFunction(functionTypes.of(null));
|
||||||
dummyInitializer.getBody().add(new WasmReturn());
|
dummyInitializer.getBody().add(new WasmReturn());
|
||||||
dummyInitializer.setName("teavm_dummy_initializer");
|
dummyInitializer.setName(names.topLevel("teavm@dummyInitializer"));
|
||||||
dummyInitializer.setReferenced(true);
|
dummyInitializer.setReferenced(true);
|
||||||
module.functions.add(dummyInitializer);
|
module.functions.add(dummyInitializer);
|
||||||
}
|
}
|
||||||
|
@ -341,5 +342,10 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
public WasmGCClassInfoProvider classInfoProvider() {
|
public WasmGCClassInfoProvider classInfoProvider() {
|
||||||
return classInfoProvider;
|
return classInfoProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WasmGCNameProvider names() {
|
||||||
|
return names;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
||||||
import org.teavm.backend.wasm.generate.gc.WasmGCInitializerContributor;
|
import org.teavm.backend.wasm.generate.gc.WasmGCInitializerContributor;
|
||||||
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCStandardClasses;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCStandardClasses;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
|
@ -43,12 +44,14 @@ public class WasmGCStringPool implements WasmGCStringProvider, WasmGCInitializer
|
||||||
private Map<String, WasmGCStringConstant> stringMap = new LinkedHashMap<>();
|
private Map<String, WasmGCStringConstant> stringMap = new LinkedHashMap<>();
|
||||||
private BaseWasmFunctionRepository functionProvider;
|
private BaseWasmFunctionRepository functionProvider;
|
||||||
private WasmFunction nextCharArrayFunction;
|
private WasmFunction nextCharArrayFunction;
|
||||||
|
private WasmGCNameProvider names;
|
||||||
|
|
||||||
public WasmGCStringPool(WasmGCStandardClasses standardClasses, WasmModule module,
|
public WasmGCStringPool(WasmGCStandardClasses standardClasses, WasmModule module,
|
||||||
BaseWasmFunctionRepository functionProvider) {
|
BaseWasmFunctionRepository functionProvider, WasmGCNameProvider names) {
|
||||||
this.standardClasses = standardClasses;
|
this.standardClasses = standardClasses;
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.functionProvider = functionProvider;
|
this.functionProvider = functionProvider;
|
||||||
|
this.names = names;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -86,7 +89,9 @@ public class WasmGCStringPool implements WasmGCStringProvider, WasmGCInitializer
|
||||||
}
|
}
|
||||||
binaryWriter.writeLEB(string.length());
|
binaryWriter.writeLEB(string.length());
|
||||||
binaryWriter.writeBytes(string.getBytes(StandardCharsets.UTF_8));
|
binaryWriter.writeBytes(string.getBytes(StandardCharsets.UTF_8));
|
||||||
var globalName = "teavm_java_string_" + stringMap.size();
|
var brief = string.length() > 16 ? string.substring(0, 16) : string;
|
||||||
|
var globalName = names.topLevel("teavm@string<" + stringMap.size() + ">"
|
||||||
|
+ WasmGCNameProvider.sanitize(brief));
|
||||||
var globalType = standardClasses.stringClass().getType();
|
var globalType = standardClasses.stringClass().getType();
|
||||||
var global = new WasmGlobal(globalName, globalType, WasmExpression.defaultValueOfType(globalType));
|
var global = new WasmGlobal(globalName, globalType, WasmExpression.defaultValueOfType(globalType));
|
||||||
module.globals.add(global);
|
module.globals.add(global);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.backend.wasm.generators.gc;
|
package org.teavm.backend.wasm.generators.gc;
|
||||||
|
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCTypeMapper;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCTypeMapper;
|
||||||
import org.teavm.backend.wasm.model.WasmModule;
|
import org.teavm.backend.wasm.model.WasmModule;
|
||||||
|
@ -28,4 +29,6 @@ public interface WasmGCCustomGeneratorContext {
|
||||||
WasmGCTypeMapper typeMapper();
|
WasmGCTypeMapper typeMapper();
|
||||||
|
|
||||||
WasmGCClassInfoProvider classInfoProvider();
|
WasmGCClassInfoProvider classInfoProvider();
|
||||||
|
|
||||||
|
WasmGCNameProvider names();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,8 @@ public class WasmGCStringPoolGenerator implements WasmGCCustomGenerator {
|
||||||
@Override
|
@Override
|
||||||
public void apply(MethodReference method, WasmFunction function, WasmGCCustomGeneratorContext context) {
|
public void apply(MethodReference method, WasmFunction function, WasmGCCustomGeneratorContext context) {
|
||||||
var module = context.module();
|
var module = context.module();
|
||||||
var pointer = new WasmGlobal("teavm_string_pool_pointer", WasmType.INT32, new WasmInt32Constant(0));
|
var pointer = new WasmGlobal(context.names().topLevel("teavm@stringPoolPointer"), WasmType.INT32,
|
||||||
|
new WasmInt32Constant(0));
|
||||||
module.globals.add(pointer);
|
module.globals.add(pointer);
|
||||||
|
|
||||||
var resultLocal = new WasmLocal(WasmType.INT32);
|
var resultLocal = new WasmLocal(WasmType.INT32);
|
||||||
|
|
|
@ -71,6 +71,10 @@ public class WasmStructure extends WasmCompositeType {
|
||||||
var supplier = fieldsSupplier;
|
var supplier = fieldsSupplier;
|
||||||
fieldsSupplier = null;
|
fieldsSupplier = null;
|
||||||
supplier.accept(fieldsStorage);
|
supplier.accept(fieldsStorage);
|
||||||
|
for (var field : fieldsStorage) {
|
||||||
|
field.structure = this;
|
||||||
|
}
|
||||||
|
indexesValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -476,6 +476,30 @@ public class WasmBinaryRenderer {
|
||||||
section.writeLEB(payload.length);
|
section.writeLEB(payload.length);
|
||||||
section.writeBytes(payload);
|
section.writeBytes(payload);
|
||||||
|
|
||||||
|
var functionsWithLocalNames = module.functions.stream()
|
||||||
|
.filter(fn -> fn.getLocalVariables().stream().anyMatch(v -> v.getName() != null))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (!functionsWithLocalNames.isEmpty()) {
|
||||||
|
var subsection = new WasmBinaryWriter();
|
||||||
|
subsection.writeLEB(functionsWithLocalNames.size());
|
||||||
|
for (var function : functionsWithLocalNames) {
|
||||||
|
subsection.writeLEB(module.functions.indexOf(function));
|
||||||
|
var locals = function.getLocalVariables().stream()
|
||||||
|
.filter(t -> t.getName() != null)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
subsection.writeLEB(locals.size());
|
||||||
|
for (var local : locals) {
|
||||||
|
subsection.writeLEB(local.getIndex());
|
||||||
|
subsection.writeAsciiString(local.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = subsection.getData();
|
||||||
|
section.writeLEB(2);
|
||||||
|
section.writeLEB(payload.length);
|
||||||
|
section.writeBytes(payload);
|
||||||
|
}
|
||||||
|
|
||||||
var types = module.types.stream()
|
var types = module.types.stream()
|
||||||
.filter(t -> t.getName() != null)
|
.filter(t -> t.getName() != null)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user