Skip to content

Commit

Permalink
Enum, it just works (Todd Face)
Browse files Browse the repository at this point in the history
  • Loading branch information
kappa-maintainer committed Nov 18, 2023
1 parent 8b92ea6 commit ca30a29
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 11 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ project(':cleanroom') {
environment 'FORGE_GROUP', project.group
environment 'FORGE_VERSION', props.new_forge_version

jvmArgs '-Djava.library.path=' + project.file('build/natives') + ' -Dmixin.debug=true'
jvmArgs jvm_arguments + ' -Djava.library.path=' + project.file('build/natives') + ' -Dmixin.debug=true'
// jvmArgs jvm_arguments

// Lazily supply the Mappings target, createSrg2Mcp.getMappings() doesn't get populated until later
Expand Down Expand Up @@ -1122,7 +1122,7 @@ project(':cleanroom') {
}

test {
jvmArgs jvm_arguments
jvmArgs jvm_arguments + compiler_jvm_arguments
}
}

Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ installer_tools_version = 1.3.0
# Libraries
asm_version = 9.6
asm_deprecated = 7.1
bouncepad_version = 0.4
lwjgl_version = 3.3.2-21-CLEANROOM
bouncepad_version = 0.4.1-kappa
lwjgl_version = 3.3.2-22-CLEANROOM

# Sets default memory used for Gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
Expand Down
59 changes: 53 additions & 6 deletions src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.cleanroommc.hackery.ReflectionHackery;
import jdk.internal.reflect.ReflectionFactory;
import org.apache.commons.lang3.ArrayUtils;
import org.lwjgl.lwjgl3ify.UnsafeHacks;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
Expand All @@ -13,12 +14,12 @@

public final class EnumHackery {

private static final ReflectionFactory factory = ReflectionFactory.getReflectionFactory();
public static final ReflectionFactory factory = ReflectionFactory.getReflectionFactory();

private static final Field class$enumConstants, class$enumConstantDirectory, class$enumVars;
private static final Method constructorAccessor$newInstance;

private static final Class[] head = {String.class, int.class};
private static final Class[] prefix = {String.class, int.class};

static {
Field constructorAccessor;
Expand Down Expand Up @@ -59,15 +60,61 @@ public static <T extends Enum<T>> T addEnumEntry(Class<T> enumClass, String enum
if (parameterTypes.length != parameterValues.length) {
throw new IllegalArgumentException("The amount of parameter types must be the same as the parameter values.");
}

try {
Constructor<T> constructor = enumClass.getDeclaredConstructor(ArrayUtils.addAll(head, parameterTypes));
Constructor<T> constructor = enumClass.getDeclaredConstructor(ArrayUtils.addAll(prefix, parameterTypes));
constructor.setAccessible(true);
MethodHandle handle = MethodHandles.lookup().unreflectConstructor(constructor);
Method m = enumClass.getMethod("values");
Object o = m.invoke(enumClass);
//System.out.println(Arrays.toString(parameterValues));
return (T) handle.invokeWithArguments(ArrayUtils.addAll(new Object[]{enumName, ((Object[])o).length}, parameterValues));
handle.invokeWithArguments(ArrayUtils.addAll(new Object[]{enumName, ((Object[])o).length}, parameterValues));

T instance = UnsafeHacks.newInstance(enumClass);
//System.out.println(Arrays.toString(Enum.class.getDeclaredFields()));

Field nameField = Enum.class.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(instance, enumName);

Field valuesField = enumClass.getDeclaredField("$VALUES");
valuesField.setAccessible(true);

Field ordinalField = Enum.class.getDeclaredField("ordinal");
ordinalField.setAccessible(true);

// we get the current Enum[]
T[] values = (T[]) valuesField.get(null);
for (int i = 0; i < values.length; i++) {
T value = values[i];
if (value.name().equals(enumName)) {
//setOrdinal(enumName, value.ordinal());
ordinalField.set(enumName, value.ordinal());
values[i] = instance;
Field[] fields = enumClass.getDeclaredFields();
for (Field field : fields) {
if (field.getName().equals(enumName)) {
UnsafeHacks.setField(field, null,instance);
}
}
return instance;
}
}

// we did not find it in the existing array, thus
// append it to the array
T[] newValues = Arrays.copyOf(values, values.length + 1);
newValues[newValues.length - 1] = instance;
UnsafeHacks.setField(valuesField, null, newValues);

int ordinal = newValues.length - 1;
ordinalField.set(instance, ordinal);
//addSwitchCase();


return instance;

} catch (Throwable e) {
System.out.println(e);
throw new RuntimeException(e);
}/*
try {
Expand Down Expand Up @@ -95,7 +142,7 @@ public static <T extends Enum<T>> T addEnumEntry(Class<T> enumClass, String enum
}*/
}

private static <T extends Enum<T>> void resetEnumRelatedCaches(Class<T> enumClass) throws ReflectiveOperationException {
public static <T extends Enum<T>> void resetEnumRelatedCaches(Class<T> enumClass) throws ReflectiveOperationException {
class$enumConstants.set(enumClass, null);
class$enumConstantDirectory.set(enumClass, null);
if (class$enumVars != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public static HorseArmorType addHorseArmor(String name, String textureLocation,
public static void setFailsafeFieldValue(Field field, @Nullable Object target, @Nullable Object value) throws Exception
{

ReflectionHackery.unsafe.putObject(ReflectionHackery.unsafe.staticFieldBase(field), ReflectionHackery.unsafe.staticFieldOffset(field), value);
ReflectionHackery.unsafe.putReference(ReflectionHackery.unsafe.staticFieldBase(field), ReflectionHackery.unsafe.staticFieldOffset(field), value);
/*
field.setAccessible(true);
ReflectionHackery.stripFieldOfFinalModifier(field);
Expand Down

0 comments on commit ca30a29

Please sign in to comment.