mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-21 16:04:09 -08:00
wasm gc: implement enum constants
This commit is contained in:
parent
8184c46bae
commit
2d8556d0a2
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.classlib.impl.reflection;
|
||||
|
||||
import org.teavm.interop.NoSideEffects;
|
||||
|
||||
public final class ClassSupport {
|
||||
private ClassSupport() {
|
||||
}
|
||||
|
||||
@NoSideEffects
|
||||
public static native Enum<?>[] getEnumConstants(Class<?> cls);
|
||||
}
|
|
@ -29,6 +29,7 @@ import java.util.Set;
|
|||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||
import org.teavm.classlib.PlatformDetector;
|
||||
import org.teavm.classlib.impl.reflection.ClassSupport;
|
||||
import org.teavm.classlib.impl.reflection.Flags;
|
||||
import org.teavm.classlib.impl.reflection.JSClass;
|
||||
import org.teavm.classlib.impl.reflection.JSField;
|
||||
|
@ -692,8 +693,12 @@ public final class TClass<T> extends TObject implements TAnnotatedElement, TType
|
|||
if (!isEnum()) {
|
||||
return null;
|
||||
}
|
||||
Platform.initClass(platformClass);
|
||||
return (T[]) Platform.getEnumConstants(platformClass).clone();
|
||||
if (PlatformDetector.isWebAssemblyGC()) {
|
||||
return (T[]) ClassSupport.getEnumConstants((Class<?>) (Object) this);
|
||||
} else {
|
||||
Platform.initClass(platformClass);
|
||||
return (T[]) Platform.getEnumConstants(platformClass).clone();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.teavm.classlib.java.util;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import org.teavm.classlib.PlatformDetector;
|
||||
import org.teavm.classlib.impl.reflection.ClassSupport;
|
||||
import org.teavm.classlib.java.lang.TClass;
|
||||
import org.teavm.platform.Platform;
|
||||
import org.teavm.platform.PlatformClass;
|
||||
|
@ -43,9 +45,13 @@ class TGenericEnumSet<E extends Enum<E>> extends TEnumSet<E> {
|
|||
}
|
||||
|
||||
static Enum<?>[] getConstants(Class<?> cls) {
|
||||
PlatformClass platformClass = ((TClass<?>) (Object) cls).getPlatformClass();
|
||||
Platform.initClass(platformClass);
|
||||
return Platform.getEnumConstants(platformClass);
|
||||
if (PlatformDetector.isWebAssemblyGC()) {
|
||||
return ClassSupport.getEnumConstants(cls);
|
||||
} else {
|
||||
PlatformClass platformClass = ((TClass<?>) (Object) cls).getPlatformClass();
|
||||
Platform.initClass(platformClass);
|
||||
return Platform.getEnumConstants(platformClass);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -98,8 +98,8 @@ public class WasmGCDependencies {
|
|||
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "aiiobe", ArrayIndexOutOfBoundsException.class))
|
||||
.use();
|
||||
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "cce", ClassCastException.class)).use();
|
||||
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "throwCloneNotSupportedException",
|
||||
void.class)).use();
|
||||
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "defaultClone", Object.class,
|
||||
Object.class)).use();
|
||||
}
|
||||
|
||||
private void contributeInitializerUtils() {
|
||||
|
|
|
@ -31,8 +31,10 @@ import org.teavm.backend.wasm.WasmFunctionTypes;
|
|||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTable;
|
||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableEntry;
|
||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
||||
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
||||
import org.teavm.backend.wasm.generate.gc.WasmGCInitializerContributor;
|
||||
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
|
||||
import org.teavm.backend.wasm.generate.gc.strings.WasmGCStringPool;
|
||||
import org.teavm.backend.wasm.model.WasmArray;
|
||||
import org.teavm.backend.wasm.model.WasmField;
|
||||
|
@ -48,7 +50,9 @@ import org.teavm.backend.wasm.model.expression.WasmArrayCopy;
|
|||
import org.teavm.backend.wasm.model.expression.WasmArrayGet;
|
||||
import org.teavm.backend.wasm.model.expression.WasmArrayLength;
|
||||
import org.teavm.backend.wasm.model.expression.WasmArrayNewDefault;
|
||||
import org.teavm.backend.wasm.model.expression.WasmBlock;
|
||||
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
||||
import org.teavm.backend.wasm.model.expression.WasmCast;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.backend.wasm.model.expression.WasmFloat32Constant;
|
||||
|
@ -72,6 +76,7 @@ import org.teavm.backend.wasm.model.expression.WasmStructNewDefault;
|
|||
import org.teavm.backend.wasm.model.expression.WasmStructSet;
|
||||
import org.teavm.backend.wasm.runtime.WasmGCSupport;
|
||||
import org.teavm.model.ClassHierarchy;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.FieldReference;
|
||||
|
@ -131,6 +136,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
private int classSupertypeFunctionOffset;
|
||||
private int classEnclosingClassOffset;
|
||||
private int virtualTableFieldOffset;
|
||||
private int enumConstantsFunctionOffset;
|
||||
private int arrayLengthOffset = -1;
|
||||
private int arrayGetOffset = -1;
|
||||
private int cloneOffset = -1;
|
||||
|
@ -140,6 +146,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
private WasmFunctionType arrayGetType;
|
||||
private WasmFunctionType arrayLengthType;
|
||||
private List<WasmStructure> nonInitializedStructures = new ArrayList<>();
|
||||
private WasmArray objectArrayType;
|
||||
private WasmArray enumConstantArray;
|
||||
|
||||
public WasmGCClassGenerator(WasmModule module, ClassReaderSource classSource,
|
||||
ClassHierarchy hierarchy,
|
||||
|
@ -494,11 +502,15 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
cloneFunction = generateCloneFunction(classInfo, name);
|
||||
} else {
|
||||
cloneFunction = functionProvider.forStaticMethod(new MethodReference(
|
||||
WasmGCSupport.class, "throwCloneNotSupportedException", void.class));
|
||||
WasmGCSupport.class, "defaultClone", Object.class, Object.class));
|
||||
}
|
||||
cloneFunction.setReferenced(true);
|
||||
target.add(setClassField(classInfo, cloneOffset, new WasmFunctionReference(cloneFunction)));
|
||||
}
|
||||
if (metadataReq.enumConstants() && cls.hasModifier(ElementModifier.ENUM)) {
|
||||
target.add(setClassField(classInfo, enumConstantsFunctionOffset,
|
||||
new WasmFunctionReference(createEnumConstantsFunction(classInfo, cls))));
|
||||
}
|
||||
}
|
||||
if (virtualTable != null && virtualTable.isConcrete()) {
|
||||
fillVirtualTableMethods(target, classStructure, classInfo.pointer, virtualTable);
|
||||
|
@ -881,6 +893,11 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
return arrayGetOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnumConstantsFunctionOffset() {
|
||||
return enumConstantsFunctionOffset;
|
||||
}
|
||||
|
||||
private void initArrayClass(WasmGCClassInfo classInfo, ValueType.Array type) {
|
||||
classInfo.initializer = target -> {
|
||||
var itemTypeInfo = getClassInfo(type.getItemType());
|
||||
|
@ -1047,6 +1064,13 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
cloneOffset = fields.size();
|
||||
fields.add(createClassField(functionTypes.of(standardClasses.objectClass().getType(),
|
||||
standardClasses.objectClass().getType()).getReference().asStorage(), "clone"));
|
||||
fields.add(createClassField(WasmType.INT32.asStorage(), "enumConstantCount"));
|
||||
if (metadataRequirements.hasEnumConstants()) {
|
||||
enumConstantsFunctionOffset = fields.size();
|
||||
var enumArrayType = getClassInfo(ValueType.arrayOf(ValueType.object("java.lang.Enum"))).getType();
|
||||
var enumConstantsType = functionTypes.of(enumArrayType);
|
||||
fields.add(createClassField(enumConstantsType.getReference().asStorage(), "getEnumConstants"));
|
||||
}
|
||||
virtualTableFieldOffset = fields.size();
|
||||
}
|
||||
}
|
||||
|
@ -1057,6 +1081,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
|
||||
private void fillArrayFields(WasmGCClassInfo classInfo, ValueType elementType) {
|
||||
WasmStorageType wasmElementType;
|
||||
WasmArray wasmArray;
|
||||
if (elementType instanceof ValueType.Primitive) {
|
||||
switch (((ValueType.Primitive) elementType).getKind()) {
|
||||
case BOOLEAN:
|
||||
|
@ -1082,12 +1107,21 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
var wasmArrayName = names.topLevel(names.suggestForType(classInfo.getValueType()) + "$Data");
|
||||
wasmArray = new WasmArray(wasmArrayName, wasmElementType);
|
||||
module.types.add(wasmArray);
|
||||
} else {
|
||||
wasmElementType = standardClasses.objectClass().getType().asStorage();
|
||||
wasmArray = objectArrayType;
|
||||
if (wasmArray == null) {
|
||||
var wasmArrayName = names.topLevel(names.suggestForType(ValueType.arrayOf(
|
||||
ValueType.object("java.lang.Object"))) + "$Data");
|
||||
wasmArray = new WasmArray(wasmArrayName, wasmElementType);
|
||||
module.types.add(wasmArray);
|
||||
objectArrayType = wasmArray;
|
||||
}
|
||||
}
|
||||
var wasmArrayName = names.topLevel(names.suggestForType(classInfo.getValueType()) + "$Data");
|
||||
var wasmArray = new WasmArray(wasmArrayName, wasmElementType);
|
||||
module.types.add(wasmArray);
|
||||
|
||||
classInfo.structure.getFields().add(new WasmField(wasmArray.getReference().asStorage(),
|
||||
arrayDataFieldName()));
|
||||
}
|
||||
|
@ -1214,6 +1248,35 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
return function;
|
||||
}
|
||||
|
||||
private WasmFunction createEnumConstantsFunction(WasmGCClassInfo classInfo, ClassReader cls) {
|
||||
var enumArrayStruct = getClassInfo(ValueType.parse(Enum[].class)).structure;
|
||||
var function = new WasmFunction(functionTypes.of(enumArrayStruct.getReference()));
|
||||
function.setName(names.topLevel(cls.getName() + "@constants"));
|
||||
module.functions.add(function);
|
||||
function.setReferenced(true);
|
||||
|
||||
var fields = cls.getFields().stream()
|
||||
.filter(field -> field.hasModifier(ElementModifier.ENUM))
|
||||
.filter(field -> field.hasModifier(ElementModifier.STATIC))
|
||||
.map(field -> new WasmGetGlobal(getStaticFieldLocation(field.getReference())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (classInfo.getInitializerPointer() != null) {
|
||||
function.getBody().add(new WasmCallReference(new WasmGetGlobal(classInfo.getInitializerPointer()),
|
||||
functionTypes.of(null)));
|
||||
}
|
||||
|
||||
var tempVars = new TemporaryVariablePool(function);
|
||||
var util = new WasmGCGenerationUtil(this, tempVars);
|
||||
var local = tempVars.acquire(enumArrayStruct.getReference());
|
||||
var block = new WasmBlock(false);
|
||||
block.setType(enumArrayStruct.getReference());
|
||||
util.allocateArray(ValueType.parse(Enum.class), fields, null, null, block.getBody());
|
||||
function.getBody().add(new WasmReturn(block));
|
||||
tempVars.release(local);
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
private WasmExpression setClassField(WasmGCClassInfo classInfo, int fieldIndex, WasmExpression value) {
|
||||
return new WasmStructSet(
|
||||
|
|
|
@ -54,6 +54,8 @@ public interface WasmGCClassInfoProvider {
|
|||
|
||||
int getArrayLengthOffset();
|
||||
|
||||
int getEnumConstantsFunctionOffset();
|
||||
|
||||
int getCloneOffset();
|
||||
|
||||
default WasmGCClassInfo getClassInfo(String name) {
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
package org.teavm.backend.wasm.generate.gc.methods;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||
import org.teavm.backend.wasm.model.WasmArray;
|
||||
import org.teavm.backend.wasm.model.WasmLocal;
|
||||
import org.teavm.backend.wasm.model.WasmType;
|
||||
import org.teavm.backend.wasm.model.expression.WasmArrayNewDefault;
|
||||
import org.teavm.backend.wasm.model.expression.WasmArrayNewFixed;
|
||||
import org.teavm.backend.wasm.model.expression.WasmBlock;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.backend.wasm.model.expression.WasmGetGlobal;
|
||||
|
@ -43,6 +45,20 @@ public class WasmGCGenerationUtil {
|
|||
|
||||
public void allocateArray(ValueType itemType, WasmExpression length, TextLocation location, WasmLocal local,
|
||||
List<WasmExpression> target) {
|
||||
allocateArray(itemType, location, local, target, arrayType -> new WasmArrayNewDefault(arrayType, length));
|
||||
}
|
||||
|
||||
public void allocateArray(ValueType itemType, List<? extends WasmExpression> data, TextLocation location,
|
||||
WasmLocal local, List<WasmExpression> target) {
|
||||
allocateArray(itemType, location, local, target, arrayType -> {
|
||||
var expr = new WasmArrayNewFixed(arrayType);
|
||||
expr.getElements().addAll(data);
|
||||
return expr;
|
||||
});
|
||||
}
|
||||
|
||||
public void allocateArray(ValueType itemType, TextLocation location,
|
||||
WasmLocal local, List<WasmExpression> target, Function<WasmArray, WasmExpression> data) {
|
||||
var classInfo = classInfoProvider.getClassInfo(ValueType.arrayOf(itemType));
|
||||
var block = new WasmBlock(false);
|
||||
block.setType(classInfo.getType());
|
||||
|
@ -68,7 +84,7 @@ public class WasmGCGenerationUtil {
|
|||
classInfo.getStructure(),
|
||||
new WasmGetLocal(targetVar),
|
||||
WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET,
|
||||
new WasmArrayNewDefault(wasmArray, length)
|
||||
data.apply(wasmArray)
|
||||
);
|
||||
initArrayField.setLocation(location);
|
||||
target.add(initArrayField);
|
||||
|
|
|
@ -43,8 +43,7 @@ public class ClassIntrinsic implements WasmGCIntrinsic {
|
|||
case "getSuperclass": {
|
||||
var cls = context.generate(invocation.getArguments().get(0));
|
||||
var clsStruct = context.classInfoProvider().getClassInfo("java.lang.Class").getStructure();
|
||||
var result = new WasmStructGet(clsStruct, cls,
|
||||
context.classInfoProvider().getClassParentOffset());
|
||||
var result = new WasmStructGet(clsStruct, cls, context.classInfoProvider().getClassParentOffset());
|
||||
result.setLocation(invocation.getLocation());
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.intrinsics.gc;
|
||||
|
||||
import org.teavm.ast.InvocationExpr;
|
||||
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.backend.wasm.model.expression.WasmStructGet;
|
||||
import org.teavm.model.ValueType;
|
||||
|
||||
public class ClassSupportIntrinsic implements WasmGCIntrinsic {
|
||||
@Override
|
||||
public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
||||
var enumArrayStruct = context.classInfoProvider().getClassInfo(ValueType.arrayOf(
|
||||
ValueType.object("java.lang.Enum"))).getStructure();
|
||||
var clsStruct = context.classInfoProvider().getClassInfo("java.lang.Class").getStructure();
|
||||
var cls = context.generate(invocation.getArguments().get(0));
|
||||
var fieldIndex = context.classInfoProvider().getEnumConstantsFunctionOffset();
|
||||
var functionRef = new WasmStructGet(clsStruct, cls, fieldIndex);
|
||||
return new WasmCallReference(functionRef, context.functionTypes().of(enumArrayStruct.getReference()));
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ public class WasmGCIntrinsics implements WasmGCIntrinsicProvider {
|
|||
fillWasmRuntime();
|
||||
fillObject();
|
||||
fillClass();
|
||||
fillClassSupport();
|
||||
fillSystem();
|
||||
fillLongAndInteger();
|
||||
fillFloat();
|
||||
|
@ -89,6 +90,13 @@ public class WasmGCIntrinsics implements WasmGCIntrinsicProvider {
|
|||
add(new MethodReference(Class.class, "setSimpleNameCache", Class.class, String.class, void.class), intrinsic);
|
||||
}
|
||||
|
||||
private void fillClassSupport() {
|
||||
var intrinsic = new ClassSupportIntrinsic();
|
||||
add(new MethodReference("org.teavm.classlib.impl.reflection.ClassSupport",
|
||||
"getEnumConstants", ValueType.object("java.lang.Class"),
|
||||
ValueType.arrayOf(ValueType.object("java.lang.Enum"))), intrinsic);
|
||||
}
|
||||
|
||||
private void fillSystem() {
|
||||
add(new MethodReference(System.class, "arraycopy", Object.class, int.class, Object.class,
|
||||
int.class, int.class, void.class), new SystemArrayCopyIntrinsic());
|
||||
|
|
|
@ -35,7 +35,7 @@ public class WasmGCSupport {
|
|||
return new ClassCastException();
|
||||
}
|
||||
|
||||
public static void throwCloneNotSupportedException() throws CloneNotSupportedException {
|
||||
public static Object defaultClone(Object value) throws CloneNotSupportedException {
|
||||
throw new CloneNotSupportedException();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package org.teavm.model.analysis;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.teavm.dependency.DependencyInfo;
|
||||
|
@ -45,6 +46,7 @@ public class ClassMetadataRequirements {
|
|||
private Map<ValueType, ClassInfo> requirements = new HashMap<>();
|
||||
private boolean hasArrayGet;
|
||||
private boolean hasArrayLength;
|
||||
private boolean hasEnumConstants;
|
||||
|
||||
public ClassMetadataRequirements(DependencyInfo dependencyInfo) {
|
||||
MethodDependencyInfo getNameMethod = dependencyInfo.getMethod(GET_NAME_METHOD);
|
||||
|
@ -128,6 +130,22 @@ public class ClassMetadataRequirements {
|
|||
requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).cloneMethod = true;
|
||||
}
|
||||
}
|
||||
|
||||
var enumConstants = Arrays.asList(
|
||||
dependencyInfo.getMethod(new MethodReference("org.teavm.platform.Platform", "getEnumConstants",
|
||||
ValueType.object("org.teavm.platform.PlatformClass"), ValueType.parse(Enum[].class))),
|
||||
dependencyInfo.getMethod(new MethodReference("org.teavm.classlib.impl.reflection.ClassSupport",
|
||||
"getEnumConstants", ValueType.parse(Class.class), ValueType.parse(Enum[].class)))
|
||||
);
|
||||
for (var enumConstantsDep : enumConstants) {
|
||||
if (enumConstantsDep != null) {
|
||||
hasEnumConstants = true;
|
||||
var classNames = enumConstantsDep.getVariable(1).getClassValueNode().getTypes();
|
||||
for (var className : classNames) {
|
||||
requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).enumConstants = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Info getInfo(String className) {
|
||||
|
@ -150,6 +168,10 @@ public class ClassMetadataRequirements {
|
|||
return hasArrayLength;
|
||||
}
|
||||
|
||||
public boolean hasEnumConstants() {
|
||||
return hasEnumConstants;
|
||||
}
|
||||
|
||||
private void addClassesRequiringName(Map<ValueType, ClassInfo> target, String[] source) {
|
||||
for (String typeName : source) {
|
||||
target.computeIfAbsent(decodeType(typeName), k -> new ClassInfo()).name = true;
|
||||
|
@ -177,6 +199,7 @@ public class ClassMetadataRequirements {
|
|||
boolean arrayLength;
|
||||
boolean arrayGet;
|
||||
boolean cloneMethod;
|
||||
boolean enumConstants;
|
||||
|
||||
@Override
|
||||
public boolean name() {
|
||||
|
@ -227,6 +250,11 @@ public class ClassMetadataRequirements {
|
|||
public boolean cloneMethod() {
|
||||
return cloneMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enumConstants() {
|
||||
return enumConstants;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Info {
|
||||
|
@ -249,5 +277,7 @@ public class ClassMetadataRequirements {
|
|||
boolean arrayGet();
|
||||
|
||||
boolean cloneMethod();
|
||||
|
||||
boolean enumConstants();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public class EnumDependencySupport extends AbstractDependencyListener {
|
|||
|
||||
@Override
|
||||
public void methodReached(DependencyAgent agent, MethodDependency method) {
|
||||
if (method.getReference().getClassName().equals(Platform.class.getName())
|
||||
if (isEnumSupportClass(method.getMethod().getOwnerName())
|
||||
&& method.getReference().getName().equals("getEnumConstants")) {
|
||||
allEnums.connect(method.getResult().getArrayItem());
|
||||
final MethodReference ref = method.getReference();
|
||||
|
@ -66,4 +66,9 @@ public class EnumDependencySupport extends AbstractDependencyListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEnumSupportClass(String className) {
|
||||
return className.equals(Platform.class.getName())
|
||||
|| className.endsWith("org.teavm.classlib.impl.reflection.ClassSupport");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user