fix problem with new

This commit is contained in:
simon 2024-06-27 21:43:13 +02:00
parent 71df6cc1d5
commit c823894eb2
5 changed files with 121 additions and 39 deletions

View File

@ -0,0 +1,80 @@
package de.maishai.typedast;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class LoggingMethodVisitor extends MethodVisitor {
public LoggingMethodVisitor(MethodVisitor methodVisitor) {
super(Opcodes.ASM9, methodVisitor);
System.out.println("\n--- Visiting Method ---");
}
public static String opcodeToString(int opcode) {
for (java.lang.reflect.Field field : Opcodes.class.getDeclaredFields()) {
try {
if (field.getType() == int.class && field.getInt(null) == opcode) {
return field.getName();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return "UNKNOWN";
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
System.out.println("visitMethodInsn: " + opcodeToString(opcode) + ", " + owner + ", " + name + ", " + descriptor + ", " + isInterface);
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
}
@Override
public void visitVarInsn(int opcode, int varIndex) {
System.out.println("visitVarInsn: " + opcodeToString(opcode) + ", " + varIndex);
super.visitVarInsn(opcode, varIndex);
}
@Override
public void visitTypeInsn(int opcode, String type) {
System.out.println("visitTypeInsn: " + opcodeToString(opcode) + ", " + type);
super.visitTypeInsn(opcode, type);
}
@Override
public void visitInsn(int opcode) {
System.out.println("visitInsn: " + opcodeToString(opcode));
super.visitInsn(opcode);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor) {
System.out.println("visitMethodInsn: " + opcodeToString(opcode) + ", " + owner + ", " + name + ", " + descriptor);
super.visitMethodInsn(opcode, owner, name, descriptor);
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
System.out.println("visitFieldInsn: " + opcodeToString(opcode) + ", " + owner + ", " + name + ", " + descriptor);
super.visitFieldInsn(opcode, owner, name, descriptor);
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
System.out.println("visitMaxs: " + maxStack + ", " + maxLocals);
super.visitMaxs(maxStack, maxLocals);
}
@Override
public void visitIntInsn(int opcode, int operand) {
String opcodeString = opcode == Opcodes.BIPUSH ? "BIPUSH" : "SIPUSH";
System.out.println("visitIntInsn: " + opcodeString + ", " + operand);
super.visitIntInsn(opcode, operand);
}
@Override
public void visitLdcInsn(Object value) {
System.out.println("visitLdcInsn: " + value);
super.visitLdcInsn(value);
}
}

View File

@ -28,7 +28,12 @@ public class MethodContext {
private final Deque<Label> continueLabels = new ArrayDeque<>();
public MethodContext(ClassContext classContext, MethodVisitor mv, Type returnType) {
this.mv = mv;
// if DEBUG env variable is set, log all method calls
if (System.getenv("DEBUG") != null) {
this.mv = new LoggingMethodVisitor(mv);
} else {
this.mv = mv;
}
this.classContext = classContext;
this.returnType = returnType;
registerVariable("this", classContext.getType());

View File

@ -88,7 +88,7 @@ public class TypedAssignment implements TypedStatement {
@Override
public void codeGen(MethodContext ctx) {
if(value instanceof TypedNew || value instanceof TypedMethodCall) {
if(value instanceof TypedMethodCall) {
value.codeGen(ctx);
getOwnerChain(ctx);
} else {

View File

@ -71,6 +71,7 @@ public class TypedNew implements TypedExpression, TypedStatement {
}
String descriptor = CodeGenUtils.generateDescriptor(args.stream().map(TypedExpression::getType).toList(), Type.VOID);
ctx.getMv().visitMethodInsn(Opcodes.INVOKESPECIAL, type.getReference(), "<init>", descriptor, false);
ctx.popStack();
LOGGER.log(Level.FINEST, "INVOKESPECIAL {0} <init> {1}", new Object[]{type.getReference(), descriptor});
for (int i = 0; i < args.size(); i++) {
ctx.popStack();

View File

@ -7,52 +7,50 @@ import testResources.CodeGen.BytecodeTestUtil;
import java.util.List;
public class ByteCode_ClassObjects {
class ByteCode_ClassObjects {
private BytecodeTestUtil util;
private BytecodeTestUtil util;
@BeforeEach
public void setUp() {
try {
util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/ClassObjects.java"), "ClassObjects");
} catch (Exception e) {
throw new RuntimeException(e);
}
@BeforeEach
public void setUp() {
try {
util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/ClassObjects.java"), "ClassObjects");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testConstructorCount() {
void testConstructorCount() {
Assertions.assertEquals(2, util.getConstructorCount());
}
@Test
public void testConstructor1() {
void testConstructor1() {
Assertions.assertEquals("ClassObjects", util.getConstructorNames().get(0));
Assertions.assertEquals(0, util.getConstructorParameterCount(0));
}
@Test
public void testConstructor2() {
void testConstructor2() {
Assertions.assertEquals("ClassObjects", util.getConstructorNames().get(1));
Assertions.assertEquals(1, util.getConstructorParameterCount(1));
}
@Test
public void testMethodCount() {
void testMethodCount() {
Assertions.assertEquals(1, util.getMethodCount());
}
@Test
public void testMethodNames() {
void testMethodNames() {
Assertions.assertEquals("objectsMethod", util.getMethodNames().get(0));
}
@Test
public void testMethodReturnType() {
void testMethodReturnType() {
try {
Assertions.assertEquals("void", util.getMethodReturnType("objectsMethod", new Class<?>[]{}));
} catch (Exception e) {
@ -61,7 +59,7 @@ public class ByteCode_ClassObjects {
}
@Test
public void testMethodParameters() {
void testMethodParameters() {
try {
Assertions.assertEquals(0, util.getMethodParameterCount("objectsMethod", new Class<?>[]{}));
} catch (Exception e) {
@ -70,28 +68,27 @@ public class ByteCode_ClassObjects {
}
@Test
public void testFieldCount() {
void testFieldCount() {
Assertions.assertEquals(3, util.getFieldCount());
}
@Test
public void testFieldNames() {
void testFieldNames() {
Assertions.assertEquals("object", util.getFieldNames().get(0));
Assertions.assertEquals("objectWithValue", util.getFieldNames().get(1));
Assertions.assertEquals("integerValue", util.getFieldNames().get(2));
}
@Test
public void testFieldTypes() {
void testFieldTypes() {
Assertions.assertEquals("ClassObjects", util.getFieldTypes().get(0));
Assertions.assertEquals("ClassObjects", util.getFieldTypes().get(1));
Assertions.assertEquals("int", util.getFieldTypes().get(2));
}
@Test
public void testFieldValues() {
void testFieldValues() {
try {
Assertions.assertNull(util.getFieldValue("object"));
Assertions.assertNull(util.getFieldValue("objectWithValue"));
@ -102,47 +99,46 @@ public class ByteCode_ClassObjects {
}
@Test
public void testInvokeConstructor1() {
void testInvokeConstructor1() {
try {
Object constructor1ReturnValue = util.invokeConstructor(new Class<?>[]{}, new Object[]{});
Assertions.assertEquals(constructor1ReturnValue.getClass().getName(), "ClassObjects");
Assertions.assertNull(util.getFieldValueOfObject(constructor1ReturnValue,"object"));
Assertions.assertEquals("ClassObjects", constructor1ReturnValue.getClass().getName());
Assertions.assertNull(util.getFieldValueOfObject(constructor1ReturnValue, "object"));
Assertions.assertNull(util.getFieldValueOfObject(constructor1ReturnValue, "objectWithValue"));
Assertions.assertEquals(0,
(int) util.getFieldValueOfObject(constructor1ReturnValue,"integerValue"));
(int) util.getFieldValueOfObject(constructor1ReturnValue, "integerValue"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testInvokeConstructor2() {
void testInvokeConstructor2() {
try {
Object constructor2ReturnValue = util.invokeConstructor(new Class<?>[]{int.class}, new Object[]{2});
Assertions.assertEquals(constructor2ReturnValue.getClass().getName(), "ClassObjects");
Assertions.assertEquals("ClassObjects", constructor2ReturnValue.getClass().getName());
Assertions.assertNull(util.getFieldValueOfObject(constructor2ReturnValue, "object"));
Assertions.assertNull(util.getFieldValueOfObject(constructor2ReturnValue, "objectWithValue"));
Assertions.assertEquals(2,
(int) util.getFieldValueOfObject(constructor2ReturnValue,"integerValue"));
(int) util.getFieldValueOfObject(constructor2ReturnValue, "integerValue"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testInvokeMethod() {
void testInvokeMethod() {
try {
Object fieldObject = util.getFieldValue("object");
Object fieldObjectWithValue = util.getFieldValue("objectWithValue");
int fieldIntegerValue = (int) util.getFieldValue("integerValue");
util.invokeMethod("objectsMethod", new Class<?>[]{}, new Object[]{});
Assertions.assertEquals(0, (int) util.getFieldValue("integerValue"));
util.invokeMethod("objectsMethod", null);
Assertions.assertNotSame(util.getFieldValue("object"), fieldObject);
Assertions.assertEquals(util.getFieldValue("object").getClass().getName(), "ClassObjects");
Assertions.assertEquals("ClassObjects", util.getFieldValue("object").getClass().getName());
Assertions.assertNotSame(util.getFieldValue("objectWithValue"), fieldObjectWithValue);
Assertions.assertEquals(util.getFieldValue("objectWithValue").getClass().getName(), "ClassObjects");
Assertions.assertEquals((int) util.getFieldValue("integerValue"), fieldIntegerValue);
Assertions.assertEquals("ClassObjects", util.getFieldValue("objectWithValue").getClass().getName());
Assertions.assertEquals(2, (int) util.getFieldValue("integerValue"));
} catch (Exception e) {
throw new RuntimeException(e);
}