As described above, each method invocation places the method's arguments and local variables in the frame. Thus any method transformers that change the number of arguments or local state of the method must modify the method's frame.
Modifying the frame is somewhat trickier than modifying the Constant Pool. In particular, the JVM specification requires that the arguments to the method appear in order at the low end of the frame, before local variables held in the frame. This means that adding a new argument to a method may displace existing local variables or even other arguments. In these cases, the transformer must update the method's instructions to redirect loads and stores from one frame location to another.
Relocating references to frame locations is simple in concept but more complex in implementation. There are twenty-five separate instruction types responsible for loading operands from the frame to the stack, and twenty-five complementary instructions for storing from the stack to the frame. Since the instruction set is strongly typed (for ease of verification), each type (integer, long, float, double, and reference) has its own family of loads and stores. Moreover, JVM load and store instructions encode their operands in any of several different ways. For example, references to frame locations 0, 1, 2, and 3 may use efficient ``shortcut'' instructions with the location encoded in the opcode. If the frame has more than 256 locations, load and store instructions that reference locations at the high end of the frame must be prefixed by a ``wide'' bytecode, indicating that the frame offset is specified as two bytes rather than one. In these cases, changing the frame offset of the operand may force a change to the opcode itself, or make it necessary to insert or delete a ``wide'' prefix. For example, the instruction could be a shortcut that references frame location 3; if the new target is location 5 then the opcode must be changed to take an explicit operand, since there is no shortcut for frame location 5. JOIE correctly generates the correct opcode and operand in the face of such changes.