Reputation: 390
For example, for method
public int f() {
int k = 1;
for (int i = 0; i < 10; i++) {
k += 2;
}
return k;
}
javac
generates the following bytecode:
public int f();
Code:
0: iconst_1
1: istore_1
2: iconst_0
3: istore_2
4: iload_2
5: bipush 10
7: if_icmpge 19
10: iinc 1, 2
13: iinc 2, 1
16: goto 4
19: iload_1
20: ireturn
At label 4 stack has same size (0), no matter which instruction was previous: 3 or 16.
Is that generally true for bytecode generated from java code?
Upvotes: 3
Views: 139
Reputation: 7146
For a reference to the Antimony's answer, see the JVM specification §4.9.2. Structural Constraints (thank you Holger!):
- ...
- If an instruction can be executed along several different execution paths, the operand stack must have the same depth (§2.6.2) prior to the execution of the instruction, regardless of the path taken.
In the first version of this answer, I cited §4.10.2.1. The Process of Verification by Type Inference, which is for class files that do not contain StackMapTable
attributes (version number of 49.0 or below):
... The verifier ensures that at any given point in the program, no matter what code path is taken to reach that point, all of the following are true:
- The operand stack is always the same size and contains the same types of values.
- ...
Upvotes: 4
Reputation: 39451
Yes. Bytecode verification enforces that the stack size is constant at any given instruction, regardless of control flow. (It also enforces that the types are compatible). Therefore, this is true not only of bytecode derived from compiled Java, but any valid bytecode at all.
Upvotes: 3