After merge fixes Codegen.java

This commit is contained in:
luca9913 2023-06-24 19:20:28 +02:00
parent 124313cb16
commit 1fb431ab36
3 changed files with 29 additions and 94 deletions

View File

@ -691,16 +691,7 @@ public class Codegen {
var parameters = new ArrayList<>(lambda.captures());
parameters.addAll(lambda.params().stream().map(param -> param.type() instanceof TargetGenericType ? new MethodParameter(TargetType.Object, param.name()) : param).toList());
impl = new TargetMethod(
0, name,
lambda.block(),
new TargetMethod.Signature(
Set.of(),
parameters,
lambda.returnType() instanceof TargetGenericType ? TargetType.Object : lambda.returnType()
),
null
);
impl = new TargetMethod(0, name, lambda.block(), new TargetMethod.Signature(Set.of(), parameters, lambda.returnType() instanceof TargetGenericType ? TargetType.Object : lambda.returnType()), null);
generateMethod(impl);
lambdas.put(lambda, impl);
}
@ -729,10 +720,7 @@ public class Codegen {
for (var capture : lambda.captures())
mv.visitVarInsn(ALOAD, state.scope.get(capture.name()).index);
mv.visitInvokeDynamicInsn("apply", descriptor,
bootstrap, Type.getType(desugared), handle,
Type.getType(TargetMethod.getDescriptor(impl.signature().returnType(), lambda.params().stream().map(MethodParameter::type).toArray(TargetType[]::new)))
);
mv.visitInvokeDynamicInsn("apply", descriptor, bootstrap, Type.getType(desugared), handle, Type.getType(TargetMethod.getDescriptor(impl.signature().returnType(), lambda.params().stream().map(MethodParameter::type).toArray(TargetType[]::new))));
}
private void generate(State state, TargetExpression expr) {
@ -793,42 +781,7 @@ public class Codegen {
}
break;
}
case TargetBinaryOp op:
generateBinaryOp(state, op);
break;
case TargetUnaryOp op:
generateUnaryOp(state, op);
break;
case TargetAssign assign: {
switch (assign.left()) {
case TargetLocalVar localVar: {
generate(state, assign.right());
convertTo(state, assign.right().type(), localVar.type());
boxPrimitive(state, localVar.type());
var local = state.scope.get(localVar.name());
mv.visitInsn(DUP);
mv.visitVarInsn(ASTORE, local.index());
break;
}
case TargetFieldVar dot: {
var fieldType = dot.type();
generate(state, dot.left());
generate(state, assign.right());
convertTo(state, assign.right().type(), fieldType);
boxPrimitive(state, fieldType);
if (dot.isStatic())
mv.visitInsn(DUP);
else mv.visitInsn(DUP_X1);
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), fieldType.toSignature());
break;
}
default:
throw new CodeGenException("Invalid assignment");
}
break;
}
break;
}
case TargetBinaryOp op:
generateBinaryOp(state, op);
break;
@ -839,7 +792,8 @@ public class Codegen {
switch (assign.left()) {
case TargetLocalVar localVar: {
generate(state, assign.right());
boxPrimitive(state, assign.right().type());
convertTo(state, assign.right().type(), localVar.type());
boxPrimitive(state, localVar.type());
var local = state.scope.get(localVar.name());
mv.visitInsn(DUP);
mv.visitVarInsn(ASTORE, local.index());
@ -1024,7 +978,7 @@ public class Codegen {
mv.visitCode();
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1);
for (var param: method.signature().parameters())
for (var param : method.signature().parameters())
state.createVariable(param.name(), param.type());
generate(state, method.block());
if (method.signature().returnType() == null)
@ -1048,10 +1002,7 @@ public class Codegen {
}
public byte[] generate() {
cw.visit(V1_8, clazz.modifiers() | ACC_PUBLIC | ACC_SUPER, clazz.qualifiedName(),
generateSignature(clazz, clazz.generics()), clazz.superType() != null ? clazz.superType().getInternalName(): "java/lang/Object",
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
);
cw.visit(V1_8, clazz.modifiers() | ACC_PUBLIC | ACC_SUPER, clazz.qualifiedName(), generateSignature(clazz, clazz.generics()), clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object", clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new));
if (clazz.txGenerics() != null)
cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));

View File

@ -382,7 +382,7 @@ public class JavaTXCompiler {
SourceFile sf = source.getValue();
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(f, classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList());
for (var clazz : newClasses) {
var found = false;
for (var old : allClasses) {

View File

@ -36,29 +36,32 @@ public class TestCodegen {
Files.write(outputPath.resolve(name + ".class"), code);
}
public static Map<String, ? extends Class<?>> generateClassFiles(IByteArrayClassLoader classLoader, String... files) throws IOException, ClassNotFoundException {
var path = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/");
var filenames = Arrays.stream(files).map(filename -> Path.of(path.toString(), filename).toFile()).toList();
var compiler = new JavaTXCompiler(filenames, List.of(path.toFile(), outputPath.toFile()));
var resultSet = compiler.typeInference();
public static Map<String, ? extends Class<?>> generateClassFiles(IByteArrayClassLoader classLoader, String... files) throws IOException, ClassNotFoundException {
var path = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/");
var filenames = Arrays.stream(files).map(filename -> Path.of(path.toString(), filename).toFile()).toList();
var compiler = new JavaTXCompiler(filenames, List.of(path.toFile(), outputPath.toFile()));
var resultSet = compiler.typeInference();
var result = new HashMap<String, Class<?>>();
for (var file : filenames) {
var sourceFile = compiler.sourceFiles.get(file);
var converter = new ASTToTargetAST(resultSet, sourceFile, classLoader);
var classes = compiler.sourceFiles.get(file).getClasses();
var result = new HashMap<String, Class<?>>();
for (var file : filenames) {
var sourceFile = compiler.sourceFiles.get(file);
var converter = new ASTToTargetAST(resultSet, sourceFile, classLoader);
var classes = compiler.sourceFiles.get(file).getClasses();
result.putAll(classes.stream().map(cli -> {
try {
return generateClass(converter.convert(cli), classLoader);
} catch (IOException exception) {
throw new RuntimeException(exception);
result.putAll(classes.stream().map(cli -> {
try {
return generateClass(converter.convert(cli), classLoader);
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}).collect(Collectors.toMap(Class::getName, Function.identity())));
for (var entry : converter.auxiliaries.entrySet()) {
writeClassFile(entry.getKey(), entry.getValue());
}
}
}).collect(Collectors.toMap(Class::getName, Function.identity())));
for (var entry : converter.auxiliaries.entrySet()) {
writeClassFile(entry.getKey(), entry.getValue());
}
return result;
}
public static Class<?> generateClass(TargetClass clazz, IByteArrayClassLoader classLoader) throws IOException {
@ -200,25 +203,6 @@ public class TestCodegen {
// var fun = classLoader.loadClass(Path.of(System.getProperty("user.dir"), "src/test/java/targetast/Fun1$$.class"));
var interfaceType = TargetFunNType.fromParams(List.of(TargetType.Integer));
var mainTarget = new TargetClass(Opcodes.ACC_PUBLIC, "New");
mainTarget.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "makePoint", List.of(new MethodParameter(TargetType.Integer, "x"), new MethodParameter(TargetType.Integer, "y")), pointType, new TargetBlock(List.of(new TargetReturn(new TargetNew(pointType, List.of(new TargetLocalVar(TargetType.Integer, "x"), new TargetLocalVar(TargetType.Integer, "y")))))));
var classLoader = new ByteArrayClassLoader();
var pointClass = generateClass(pointTarget, classLoader);
var mainClass = generateClass(mainTarget, classLoader);
var point = mainClass.getDeclaredMethod("makePoint", Integer.class, Integer.class).invoke(null, 10, 20);
assertEquals(point.getClass().getDeclaredField("x").get(point), 10);
assertEquals(point.getClass().getDeclaredField("y").get(point), 20);
}
@Test
@Ignore("The lambda class is not generated because we don't call ASTToTargetAST")
public void testLambda() throws Exception {
var classLoader = new ByteArrayClassLoader();
// var fun = classLoader.loadClass(Path.of(System.getProperty("user.dir"), "src/test/java/targetast/Fun1$$.class"));
var interfaceType = new TargetFunNType(1, List.of(TargetType.Integer));
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "CGLambda");
targetClass.addConstructor(Opcodes.ACC_PUBLIC, List.of(), new TargetBlock(List.of(new TargetMethodCall(null, new TargetSuper(TargetType.Object), List.of(), TargetType.Object, "<init>", false, false))));
targetClass.addMethod(Opcodes.ACC_PUBLIC, "lambda", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(interfaceType, "by2", new TargetLambdaExpression(interfaceType, List.of(), List.of(new MethodParameter(TargetType.Integer, "num")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Mul(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "num"), new TargetLiteral.IntLiteral(2))))))), new TargetReturn(new TargetCast(TargetType.Integer, new TargetMethodCall(TargetType.Object, TargetType.Object, List.of(TargetType.Object), new TargetLocalVar(interfaceType, "by2"), List.of(new TargetLiteral.IntLiteral(10)), interfaceType, "apply", false, true))))));