I am working on my assignment in which I'm supposed to modify a class file using BCEL to print certain information when a getfield operation is called.
That includes printing a String if the value of referenced field is greater than 30.
The issue I'm having is creating the if condition.
Currently what I have is
instructionList.append(InstructionFactory.createDup(type.getSize()));
instructionList.append(new PUSH(constantPoolGen, 30));
instructionList.append(new ISUB());
instructionList.append(new IFGT(instructionList.append(instructionFactory.createPrintln(" !this value is greater than 30!"))));
First line duplicates the value that the getfield operation accesses.
The problem is the call to IFGT(). Upon execution I'm getting
Inconsistent stack height 2 != 3
I've tried printing the ISUB result and it is as expected, replacing the IFGT with a POP makes the program execute properly which leads me to belive that the last line is the issue.
Bytecode generated
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.io.IOException;
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String Hello world
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: new #5; //class Test$myobject
11: dup
12: invokespecial #6; //Method Test$myobject."<init>":()V
15: astore_1
16: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
23: ldc #69; //String Before getfield:\n Test$myobject\n char\n ftok
25: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
28: getfield #7; //Field Test$myobject.ftok:C
31: ldc #71; //String
33: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
36: dup_x1
37: pop
38: invokevirtual #75; //Method java/io/PrintStream.print:(Ljava/lang/Object;)V
41: dup
42: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
45: dup_x1
46: pop
47: invokevirtual #77; //Method java/io/PrintStream.print:(C)V
50: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
53: ldc #79; //String
55: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
58: invokevirtual #8; //Method java/io/PrintStream.println:(C)V
61: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
64: aload_1
65: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
68: ldc #81; //String Before getfield:\n Test$myobject\n int\n pok
70: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
73: getfield #9; //Field Test$myobject.pok:I
76: ldc #71; //String
78: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
81: dup_x1
82: pop
83: invokevirtual #75; //Method java/io/PrintStream.print:(Ljava/lang/Object;)V
86: dup
87: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
90: dup_x1
91: pop
92: invokevirtual #83; //Method java/io/PrintStream.print:(I)V
95: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
98: ldc #79; //String
100: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
103: dup
104: bipush 30
106: isub
107: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
110: ldc #85; //String !this value is greater than 30!
112: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
115: ifgt 107
118: invokevirtual #10; //Method java/io/PrintStream.println:(I)V
121: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
124: aload_1
125: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
128: ldc #87; //String Before getfield:\n Test$myobject\n int\n pyk
130: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
133: getfield #11; //Field Test$myobject.pyk:I
136: ldc #71; //String
138: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
141: dup_x1
142: pop
143: invokevirtual #75; //Method java/io/PrintStream.print:(Ljava/lang/Object;)V
146: dup
147: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
150: dup_x1
151: pop
152: invokevirtual #83; //Method java/io/PrintStream.print:(I)V
155: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
158: ldc #79; //String
160: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
163: dup
164: bipush 30
166: isub
167: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
170: ldc #85; //String !this value is greater than 30!
172: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
175: ifgt 167
178: invokevirtual #10; //Method java/io/PrintStream.println:(I)V
181: iconst_5
182: invokestatic #12; //Method returnint:(I)I
185: pop
186: ldc #13; //String plok
188: invokestatic #14; //Method returnstring:(Ljava/lang/String;)Ljava/lang/String;
191: pop
192: invokestatic #15; //Method nothing:()V
195: return
public static int returnint(int);
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: iload_0
4: invokevirtual #10; //Method java/io/PrintStream.println:(I)V
7: iload_0
8: ireturn
public static java.lang.String returnstring(java.lang.String);
Code:
0: aload_0
1: areturn
public static void nothing();
Code:
0: return
}
I've tried googling for answers but unfortunatelly I haven't found anything.