mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
WASM: add support for Enum.valueOf and Class.isEnum
This commit is contained in:
parent
d09affce85
commit
3ad16e80c7
|
@ -111,7 +111,7 @@ public class TClass<T> extends TObject implements TAnnotatedElement {
|
|||
}
|
||||
|
||||
public boolean isEnum() {
|
||||
return platformClass.getMetadata().isEnum();
|
||||
return Platform.isEnum(platformClass);
|
||||
}
|
||||
|
||||
public TClass<?> getComponentType() {
|
||||
|
|
|
@ -18,11 +18,6 @@ package org.teavm.classlib.java.lang;
|
|||
import org.teavm.classlib.java.io.TSerializable;
|
||||
import org.teavm.interop.Rename;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
* @param <E> type of enum.
|
||||
*/
|
||||
public abstract class TEnum<E extends TEnum<E>> extends TObject implements TComparable<E>, TSerializable {
|
||||
private TString name;
|
||||
private int ordinal;
|
||||
|
|
|
@ -107,10 +107,8 @@ public class BinaryWriter {
|
|||
public byte[] getData() {
|
||||
byte[] result = new byte[address];
|
||||
int offset = 0;
|
||||
int index = 0;
|
||||
for (DataValue value : values) {
|
||||
offset = writeData(result, offset, value);
|
||||
++index;
|
||||
}
|
||||
return Arrays.copyOf(result, offset);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ public class WasmClassGenerator {
|
|||
DataPrimitives.ADDRESS, /* array type */
|
||||
DataPrimitives.INT, /* isInstance function */
|
||||
DataPrimitives.ADDRESS, /* parent */
|
||||
DataPrimitives.ADDRESS, /* enum values */
|
||||
DataPrimitives.ADDRESS /* layout */);
|
||||
private IntegerArray staticGcRoots = new IntegerArray(1);
|
||||
private int staticGcRootsAddress;
|
||||
|
@ -86,7 +87,8 @@ public class WasmClassGenerator {
|
|||
private static final int CLASS_ARRAY_TYPE = 7;
|
||||
private static final int CLASS_IS_INSTANCE = 8;
|
||||
private static final int CLASS_PARENT = 9;
|
||||
private static final int CLASS_LAYOUT = 10;
|
||||
private static final int CLASS_ENUM_VALUES = 10;
|
||||
private static final int CLASS_LAYOUT = 11;
|
||||
|
||||
public WasmClassGenerator(ClassReaderSource classSource, VirtualTableProvider vtableProvider,
|
||||
TagRegistry tagRegistry, BinaryWriter binaryWriter) {
|
||||
|
@ -193,6 +195,7 @@ public class WasmClassGenerator {
|
|||
: 0;
|
||||
|
||||
String name = ((ValueType.Object) binaryData.type).getClassName();
|
||||
int flags = 0;
|
||||
|
||||
VirtualTable vtable = vtableProvider.lookup(name);
|
||||
int vtableSize = vtable != null ? vtable.getEntries().size() : 0;
|
||||
|
@ -238,9 +241,34 @@ public class WasmClassGenerator {
|
|||
staticGcRoots.add(binaryData.fieldLayout.get(field.getFieldName()));
|
||||
}
|
||||
|
||||
ClassReader cls = classSource.get(name);
|
||||
if (cls != null && cls.hasModifier(ElementModifier.ENUM)) {
|
||||
header.setAddress(CLASS_ENUM_VALUES, generateEnumValues(cls, binaryData));
|
||||
flags |= RuntimeClass.ENUM;
|
||||
}
|
||||
|
||||
header.setInt(CLASS_FLAGS, flags);
|
||||
|
||||
return vtable != null ? wrapper : header;
|
||||
}
|
||||
|
||||
private int generateEnumValues(ClassReader cls, ClassBinaryData binaryData) {
|
||||
FieldReader[] fields = cls.getFields().stream()
|
||||
.filter(field -> field.hasModifier(ElementModifier.ENUM))
|
||||
.toArray(FieldReader[]::new);
|
||||
DataValue sizeValue = DataPrimitives.ADDRESS.createValue();
|
||||
sizeValue.setAddress(0, fields.length);
|
||||
int valuesAddress = binaryWriter.append(sizeValue);
|
||||
|
||||
for (FieldReader field : fields) {
|
||||
DataValue fieldRefValue = DataPrimitives.ADDRESS.createValue();
|
||||
fieldRefValue.setAddress(0, binaryData.fieldLayout.get(field.getName()));
|
||||
binaryWriter.append(fieldRefValue);
|
||||
}
|
||||
|
||||
return valuesAddress;
|
||||
}
|
||||
|
||||
private List<FieldReference> getReferenceFields(ClassReader cls) {
|
||||
return cls.getFields().stream()
|
||||
.filter(field -> !field.hasModifier(ElementModifier.STATIC))
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.teavm.interop.Unmanaged;
|
|||
public class RuntimeClass extends RuntimeJavaObject {
|
||||
public static final int INITIALIZED = 1;
|
||||
public static final int PRIMITIVE = 2;
|
||||
public static final int ENUM = 4;
|
||||
|
||||
public int size;
|
||||
public int flags;
|
||||
|
@ -31,6 +32,7 @@ public class RuntimeClass extends RuntimeJavaObject {
|
|||
public RuntimeClass arrayType;
|
||||
public IsSupertypeFunction isSupertypeOf;
|
||||
public RuntimeClass parent;
|
||||
public Address enumValues;
|
||||
public Address layout;
|
||||
|
||||
@Unmanaged
|
||||
|
|
|
@ -19,7 +19,9 @@ import java.lang.annotation.Annotation;
|
|||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||
import org.teavm.dependency.PluggableDependency;
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.DelegateTo;
|
||||
import org.teavm.interop.Unmanaged;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.browser.Window;
|
||||
|
@ -49,6 +51,7 @@ public final class Platform {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Unmanaged
|
||||
private static boolean isInstanceLowLevel(RuntimeClass self, RuntimeObject object) {
|
||||
return isAssignableLowLevel(RuntimeClass.getClass(object), self);
|
||||
}
|
||||
|
@ -71,6 +74,7 @@ public final class Platform {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Unmanaged
|
||||
private static boolean isAssignableLowLevel(RuntimeClass from, RuntimeClass to) {
|
||||
return to.isSupertypeOf.apply(from);
|
||||
}
|
||||
|
@ -119,8 +123,44 @@ public final class Platform {
|
|||
|
||||
@GeneratedBy(PlatformGenerator.class)
|
||||
@PluggableDependency(PlatformGenerator.class)
|
||||
@DelegateTo("getEnumConstantsLowLevel")
|
||||
public static native Enum<?>[] getEnumConstants(PlatformClass cls);
|
||||
|
||||
private static Enum<?>[] getEnumConstantsLowLevel(PlatformClass cls) {
|
||||
int size = getEnumConstantsSize(cls);
|
||||
if (size < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Enum<?>[] constants = new Enum<?>[size];
|
||||
fillEnumConstants(cls, constants);
|
||||
return constants;
|
||||
}
|
||||
|
||||
@DelegateTo("getEnumConstantsSizeImpl")
|
||||
private static native int getEnumConstantsSize(PlatformClass cls);
|
||||
|
||||
@Unmanaged
|
||||
private static int getEnumConstantsSizeImpl(RuntimeClass cls) {
|
||||
Address enumValues = cls.enumValues;
|
||||
if (enumValues == null) {
|
||||
return -1;
|
||||
}
|
||||
return enumValues.getAddress().toInt();
|
||||
}
|
||||
|
||||
@DelegateTo("fillEnumConstantsImpl")
|
||||
private static native void fillEnumConstants(PlatformClass cls, Enum<?>[] array);
|
||||
|
||||
@Unmanaged
|
||||
private static void fillEnumConstantsImpl(RuntimeClass cls, Address[] array) {
|
||||
Address enumValues = cls.enumValues;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
enumValues = enumValues.add(Address.sizeOf());
|
||||
array[i] = enumValues.getAddress().getAddress();
|
||||
}
|
||||
}
|
||||
|
||||
@GeneratedBy(PlatformGenerator.class)
|
||||
@PluggableDependency(PlatformGenerator.class)
|
||||
public static native Annotation[] getAnnotations(PlatformClass cls);
|
||||
|
@ -158,16 +198,28 @@ public final class Platform {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Unmanaged
|
||||
private static boolean isPrimitiveLowLevel(RuntimeClass cls) {
|
||||
return (cls.flags & RuntimeClass.PRIMITIVE) != 0;
|
||||
}
|
||||
|
||||
@DelegateTo("isEnumLowLevel")
|
||||
public static boolean isEnum(PlatformClass cls) {
|
||||
return cls.getMetadata().isEnum();
|
||||
}
|
||||
|
||||
@Unmanaged
|
||||
private static boolean isEnumLowLevel(RuntimeClass cls) {
|
||||
return (cls.flags & RuntimeClass.ENUM) != 0;
|
||||
}
|
||||
|
||||
@DelegateTo("getArrayItemLowLevel")
|
||||
public static PlatformClass getArrayItem(PlatformClass cls) {
|
||||
return cls.getMetadata().getArrayItem();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Unmanaged
|
||||
private static RuntimeClass getArrayItemLowLevel(RuntimeClass cls) {
|
||||
return cls.itemType;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user