From 1fb431ab36d13e905bb1badac6a7d0c7d1ac1321 Mon Sep 17 00:00:00 2001 From: luca9913 Date: Sat, 24 Jun 2023 19:20:28 +0200 Subject: [PATCH] After merge fixes Codegen.java --- .../de/dhbwstuttgart/bytecode/Codegen.java | 61 ++----------------- .../de/dhbwstuttgart/core/JavaTXCompiler.java | 2 +- src/test/java/targetast/TestCodegen.java | 60 +++++++----------- 3 files changed, 29 insertions(+), 94 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java index 9bfb029f..29699d83 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java @@ -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()))); diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index d707c07a..f2353709 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -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) { diff --git a/src/test/java/targetast/TestCodegen.java b/src/test/java/targetast/TestCodegen.java index 5fed1b8e..b1389f6e 100644 --- a/src/test/java/targetast/TestCodegen.java +++ b/src/test/java/targetast/TestCodegen.java @@ -36,29 +36,32 @@ public class TestCodegen { Files.write(outputPath.resolve(name + ".class"), code); } - public static Map> 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> 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>(); - 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>(); + 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, "", 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))))));