Convert FunNGenerator to class with static methods instead of using a singleton

This commit is contained in:
Vic Nightfall 2022-11-14 15:44:31 +01:00
parent 15e94111d4
commit 83b735716f
4 changed files with 20 additions and 71 deletions

View File

@ -23,28 +23,21 @@ import static org.objectweb.asm.Opcodes.*;
* @since Studienarbeit Type Erasure
* @author etiennezink
*/
public class FunNGenerator implements FunNUtilities{
private static final FunNGenerator funNGenerator = new FunNGenerator();
public static FunNGenerator getInstance(){
return funNGenerator;
}
public class FunNGenerator {
private static final String argumentGenericBase = "T";
private static final String returnGeneric = "R";
private static final String methodName = "apply";
private final int bytecodeVersion = V1_8;
private static final int bytecodeVersion = V1_8;
private final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
private final String objectSignature = applySignature(TargetType.Object);
private static final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
private static final String objectSignature = applySignature(TargetType.Object);
private String applyDescriptor(TargetType a) { return a.toDescriptor(); }
private String applySignature(TargetType a) { return a.toSignature(); }
private String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("L%s;", applyDescriptor(a)); }
private static String applyDescriptor(TargetType a) { return a.toDescriptor(); }
private static String applySignature(TargetType a) { return a.toSignature(); }
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("L%s;", applyDescriptor(a)); }
@Override
public byte[] generateSuperBytecode(int numberArguments) {
public static byte[] generateSuperBytecode(int numberArguments) {
StringBuilder superFunNClassSignature = new StringBuilder("<");
StringBuilder superFunNMethodSignature = new StringBuilder("(");
StringBuilder superFunNMethodDescriptor = new StringBuilder("(");
@ -67,13 +60,11 @@ public class FunNGenerator implements FunNUtilities{
return classWriter.toByteArray();
}
@Override
public String getSuperClassName(int numberArguments) {
public static String getSuperClassName(int numberArguments) {
return String.format("Fun%d$$", numberArguments);
}
@Override
public byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType) {
public static byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType) {
List<TargetType> parameters = Stream
.concat(argumentTypes.stream(), Stream.of(returnType))
.collect(Collectors.toList());
@ -98,39 +89,34 @@ public class FunNGenerator implements FunNUtilities{
return classWriter.toByteArray();
}
@Override
public String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
return String.format("Fun%d$$%s%s",
argumentTypes.size(),
argumentTypes
.stream()
.map(this::applyNameDescriptor)
.map(FunNGenerator::applyNameDescriptor)
.collect(Collectors.joining()),
applyNameDescriptor(returnType))
.replace('/', '$')
.replace(";", "$_$");
}
@Override
public String getSpecializedDescriptor(List<TargetType> argumentTypes, TargetType returnType) {
public static String getSpecializedDescriptor(List<TargetType> argumentTypes, TargetType returnType) {
return applyDescriptor(new TargetRefType(getSpecializedClassName(argumentTypes, returnType)));
}
@Override
public String getSpecializedSignature(List<TargetType> argumentTypes, TargetType returnType) {
public static String getSpecializedSignature(List<TargetType> argumentTypes, TargetType returnType) {
return applySignature(new TargetRefType(getSpecializedClassName(argumentTypes, returnType)));
}
@Override
public List<TargetType> getArguments(List<TargetType> list) {
public static List<TargetType> getArguments(List<TargetType> list) {
return list
.stream()
.limit(Math.max(0, list.size() - 1))
.collect(Collectors.toList());
}
@Override
public TargetType getReturnType(List<TargetType> list) {
public static TargetType getReturnType(List<TargetType> list) {
if(list.size() == 0)
throw new IndexOutOfBoundsException();
return list.get(list.size() - 1);

View File

@ -1,35 +0,0 @@
package de.dhbwstuttgart.bytecode.funN;
import de.dhbwstuttgart.target.tree.type.TargetType;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
public interface FunNUtilities {
byte[] generateSuperBytecode(int numberArguments);
String getSuperClassName(int numberArguments);
byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType);
String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType);
String getSpecializedDescriptor(List<TargetType> argumentTypes, TargetType returnType);
String getSpecializedSignature(List<TargetType> argumentTypes, TargetType returnType);
List<TargetType> getArguments(List<TargetType> list);
TargetType getReturnType(List<TargetType> list);
@Deprecated
public static boolean writeClassFile(String className, byte[] bytecode, File directory) {
try (FileOutputStream output = new FileOutputStream(new File(directory , className + ".class"))){
output.write(bytecode);
output.flush();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

View File

@ -675,17 +675,16 @@ public class ASTToTargetAST {
var params = refType.getParaList().stream().map(ASTToTargetAST.this::convert).toList();
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
var gen = FunNGenerator.getInstance();
var className = gen.getSpecializedClassName(gen.getArguments(params), gen.getReturnType(params));
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
if (!usedFunNSuperTypes.contains(params.size())) {
usedFunNSuperTypes.add(params.size());
var code = gen.generateSuperBytecode(params.size() - 1);
var code = FunNGenerator.generateSuperBytecode(params.size() - 1);
var clazz = classLoader.loadClass(code);
auxiliaries.put(clazz.getName(), code);
}
if (!usedFunN.contains(className)) {
usedFunN.add(className);
var code = gen.generateSpecializedBytecode(gen.getArguments(params), gen.getReturnType(params));
var code = FunNGenerator.generateSpecializedBytecode(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
var clazz = classLoader.loadClass(code);
auxiliaries.put(clazz.getName(), code);
}

View File

@ -9,8 +9,7 @@ public record TargetFunNType(int N, List<TargetType> params) implements TargetSp
@Override
public String getInternalName() {
var gen = FunNGenerator.getInstance();
return gen.getSpecializedClassName(gen.getArguments(params), gen.getReturnType(params));
return FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
}
@Override