Package org.spongepowered.asm.util

## Class Locals

- java.lang.Object
- - org.spongepowered.asm.util.Locals

    public final class Locals
    extends java.lang.Object

Utility methods for working with local variables using ASM

### Nested Class Summary

Nested Classes
`static class` `Locals.Settings` Settings for `getLocalsAt` containing the tunable options for the algorithm.
`static class` `Locals.SyntheticLocalVariableNode` A local variable entry added by mixin itself, eg.

### Method Summary

All Methods Static Methods Concrete Methods
`static int` `computeFrameSize​(org.objectweb.asm.tree.FrameNode frameNode, int initialFrameSize)` Compute the size required to accomodate the entries described by the supplied frame node
`static java.util.List<org.objectweb.asm.tree.LocalVariableNode>` `generateLocalVariableTable​(org.objectweb.asm.tree.ClassNode classNode, org.objectweb.asm.tree.MethodNode method)` Use ASM Analyzer to generate the local variable table for the specified method
`static java.lang.String` `getFrameTypeName​(java.lang.Object frameEntry)` Debug function to return printable name of a frame entry
`static java.util.List<org.objectweb.asm.tree.LocalVariableNode>` `getGeneratedLocalVariableTable​(org.objectweb.asm.tree.ClassNode classNode, org.objectweb.asm.tree.MethodNode method)` Gets the generated the local variable table for the specified method.
`static org.objectweb.asm.tree.LocalVariableNode[]` `getInitialMethodLocals​(org.objectweb.asm.tree.MethodNode method, org.objectweb.asm.tree.ClassNode classNode, int fabricCompatibility)` Constructs the initial local variable frame for a method, containing only "this" (if non-static) and the method parameters with their actual names extracted from the LVT when available.

`static org.objectweb.asm.tree.LocalVariableNode[]`

`getInitialMethodLocals​(org.objectweb.asm.tree.MethodNode method, org.objectweb.asm.tree.ClassNode classNode, int fabricCompatibility, boolean fallbackToLvIndex)`

Constructs the initial local variable frame for a method, containing only "this" (if non-static) and the method parameters with their actual names extracted from the LVT when available.

`static org.objectweb.asm.tree.LocalVariableNode[]` `getLocalsAt​(org.objectweb.asm.tree.ClassNode classNode, org.objectweb.asm.tree.MethodNode method, org.objectweb.asm.tree.AbstractInsnNode node, int fabricCompatibility)` Attempts to identify available locals at an arbitrary point in the bytecode specified by node.
`static org.objectweb.asm.tree.LocalVariableNode[]` `getLocalsAt​(org.objectweb.asm.tree.ClassNode classNode, org.objectweb.asm.tree.MethodNode method, org.objectweb.asm.tree.AbstractInsnNode node, Locals.Settings settings)` Attempts to identify available locals at an arbitrary point in the bytecode specified by node.
`static org.objectweb.asm.tree.LocalVariableNode` `getLocalVariableAt​(org.objectweb.asm.tree.ClassNode classNode, org.objectweb.asm.tree.MethodNode method, org.objectweb.asm.tree.AbstractInsnNode node, int var)` Attempts to locate the appropriate entry in the local variable table for the specified local variable index at the location specified by node.
`static java.util.List<org.objectweb.asm.tree.LocalVariableNode>` `getLocalVariableTable​(org.objectweb.asm.tree.ClassNode classNode, org.objectweb.asm.tree.MethodNode method)` Fetches or generates the local variable table for the specified method.
`static void` `loadLocals​(org.objectweb.asm.Type[] locals, org.objectweb.asm.tree.InsnList insns, int pos, int limit)` Injects appropriate LOAD opcodes into the supplied InsnList for each entry in the supplied locals array starting at pos

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Method Detail

#### getInitialMethodLocals

    public static org.objectweb.asm.tree.LocalVariableNode[] getInitialMethodLocals​(org.objectweb.asm.tree.MethodNode method,
                                                                                    org.objectweb.asm.tree.ClassNode classNode,
                                                                                    int fabricCompatibility)

Constructs the initial local variable frame for a method, containing only "this" (if non-static) and the method parameters with their actual names extracted from the LVT when available.

Parameters:
  `method` - the method to construct locals for
  `classNode` - the class containing the method
  `fabricCompatibility` - the compatibility level to use
Returns:
  an array of LocalVariableNodes representing the initial method frame

#### getInitialMethodLocals

    public static org.objectweb.asm.tree.LocalVariableNode[] getInitialMethodLocals​(org.objectweb.asm.tree.MethodNode method,
                                                                                    org.objectweb.asm.tree.ClassNode classNode,
                                                                                    int fabricCompatibility,
                                                                                    boolean fallbackToLvIndex)

Constructs the initial local variable frame for a method, containing only "this" (if non-static) and the method parameters with their actual names extracted from the LVT when available.

Parameters:
  `method` - the method to construct locals for
  `classNode` - the class containing the method
  `fabricCompatibility` - the compatibility level to use
  `fallbackToLvIndex` - whether the fallback names should use the LVT index of the variable (for backwards compatibility)
Returns:
  an array of LocalVariableNodes representing the initial method frame

#### loadLocals

    public static void loadLocals​(org.objectweb.asm.Type[] locals,
                                  org.objectweb.asm.tree.InsnList insns,
                                  int pos,
                                  int limit)

Injects appropriate LOAD opcodes into the supplied InsnList for each entry in the supplied locals array starting at pos

Parameters:
  `locals` - Local types (can contain nulls for uninitialised, TOP, or RETURN values in locals)
  `insns` - Instruction List to inject into
  `pos` - Start position
  `limit` - maximum number of locals to consume

#### getLocalsAt

    public static org.objectweb.asm.tree.LocalVariableNode[] getLocalsAt​(org.objectweb.asm.tree.ClassNode classNode,
                                                                         org.objectweb.asm.tree.MethodNode method,
                                                                         org.objectweb.asm.tree.AbstractInsnNode node,
                                                                         int fabricCompatibility)

Attempts to identify available locals at an arbitrary point in the bytecode specified by node.

This method builds an approximate view of the locals available at an arbitrary point in the bytecode by examining the following features in the bytecode:

- Any available stack map frames
- STORE opcodes
- The local variable table

Inference proceeds by walking the bytecode from the start of the method looking for stack frames and STORE opcodes. When either of these is encountered, an attempt is made to cross-reference the values in the stack map or STORE opcode with the value in the local variable table which covers the code range. Stack map frames overwrite the entire simulated local variable table with their own value types, STORE opcodes overwrite only the local slot to which they pertain. Values in the simulated locals array are spaced according to their size (unlike the representation in FrameNode) and this TOP, NULL and UNINTITIALIZED_THIS opcodes will be represented as null values in the simulated frame.

This code does not currently simulate the prescribed JVM behaviour where overwriting the second slot of a DOUBLE or LONG actually invalidates the DOUBLE or LONG stored in the previous location, so we have to hope (for now) that this behaviour isn't emitted by the compiler or any upstream transformers. I may have to re-think this strategy if this situation is encountered in the wild.

Parameters:
  `classNode` - ClassNode containing the method, used to initialise the implicit "this" reference in simple methods with no stack frames
  `method` - MethodNode to explore
  `node` - Node indicating the position at which to determine the locals state. The locals will be enumerated UP TO the specified node, so bear in mind that if the specified node is itself a STORE opcode, then we will be looking at the state of the locals PRIOR to its invocation
  `fabricCompatibility` - Fabric compatibility level
Returns:
  A sparse array containing a view (hopefully) of the locals at the specified location

#### getLocalsAt

    public static org.objectweb.asm.tree.LocalVariableNode[] getLocalsAt​(org.objectweb.asm.tree.ClassNode classNode,
                                                                         org.objectweb.asm.tree.MethodNode method,
                                                                         org.objectweb.asm.tree.AbstractInsnNode node,
                                                                         Locals.Settings settings)

Attempts to identify available locals at an arbitrary point in the bytecode specified by node.

This method builds an approximate view of the locals available at an arbitrary point in the bytecode by examining the following features in the bytecode:

- Any available stack map frames
- STORE opcodes
- The local variable table

Inference proceeds by walking the bytecode from the start of the method looking for stack frames and STORE opcodes. When either of these is encountered, an attempt is made to cross-reference the values in the stack map or STORE opcode with the value in the local variable table which covers the code range. Stack map frames overwrite the entire simulated local variable table with their own value types, STORE opcodes overwrite only the local slot to which they pertain. Values in the simulated locals array are spaced according to their size (unlike the representation in FrameNode) and this TOP, NULL and UNINTITIALIZED_THIS opcodes will be represented as null values in the simulated frame.

This code does not currently simulate the prescribed JVM behaviour where overwriting the second slot of a DOUBLE or LONG actually invalidates the DOUBLE or LONG stored in the previous location, so we have to hope (for now) that this behaviour isn't emitted by the compiler or any upstream transformers. I may have to re-think this strategy if this situation is encountered in the wild.

Parameters:
  `classNode` - ClassNode containing the method, used to initialise the implicit "this" reference in simple methods with no stack frames
  `method` - MethodNode to explore
  `node` - Node indicating the position at which to determine the locals state. The locals will be enumerated UP TO the specified node, so bear in mind that if the specified node is itself a STORE opcode, then we will be looking at the state of the locals PRIOR to its invocation
  `settings` - Tunable settings for the state machine
Returns:
  A sparse array containing a view (hopefully) of the locals at the specified location

#### getLocalVariableAt

    public static org.objectweb.asm.tree.LocalVariableNode getLocalVariableAt​(org.objectweb.asm.tree.ClassNode classNode,
                                                                              org.objectweb.asm.tree.MethodNode method,
                                                                              org.objectweb.asm.tree.AbstractInsnNode node,
                                                                              int var)

Attempts to locate the appropriate entry in the local variable table for the specified local variable index at the location specified by node.

Parameters:
  `classNode` - Containing class
  `method` - Method
  `node` - Instruction defining the location to get the local variable table at
  `var` - Local variable index
Returns:
  a LocalVariableNode containing information about the local variable at the specified location in the specified local slot

#### getLocalVariableTable

    public static java.util.List<org.objectweb.asm.tree.LocalVariableNode> getLocalVariableTable​(org.objectweb.asm.tree.ClassNode classNode,
                                                                                                 org.objectweb.asm.tree.MethodNode method)

Fetches or generates the local variable table for the specified method. Since Mojang strip the local variable table as part of the obfuscation process, we need to generate the local variable table when running obfuscated. We cache the generated tables so that we only need to do the relatively expensive calculation once per method we encounter.

Parameters:
  `classNode` - Containing class
  `method` - Method
Returns:
  local variable table

#### getGeneratedLocalVariableTable

    public static java.util.List<org.objectweb.asm.tree.LocalVariableNode> getGeneratedLocalVariableTable​(org.objectweb.asm.tree.ClassNode classNode,
                                                                                                          org.objectweb.asm.tree.MethodNode method)

Gets the generated the local variable table for the specified method.

Parameters:
  `classNode` - Containing class
  `method` - Method
Returns:
  generated local variable table

#### generateLocalVariableTable

    public static java.util.List<org.objectweb.asm.tree.LocalVariableNode> generateLocalVariableTable​(org.objectweb.asm.tree.ClassNode classNode,
                                                                                                      org.objectweb.asm.tree.MethodNode method)

Use ASM Analyzer to generate the local variable table for the specified method

Parameters:
  `classNode` - Containing class
  `method` - Method
Returns:
  generated local variable table

#### computeFrameSize

    public static int computeFrameSize​(org.objectweb.asm.tree.FrameNode frameNode,
                                       int initialFrameSize)

Compute the size required to accomodate the entries described by the supplied frame node

Parameters:
  `frameNode` - frame node with locals to compute
  `initialFrameSize` - Method initial frame size
Returns:
  size of frame node locals

#### getFrameTypeName

    public static java.lang.String getFrameTypeName​(java.lang.Object frameEntry)

Debug function to return printable name of a frame entry

Parameters:
  `frameEntry` - Frame entry
Returns:
  string representation of the supplied frame entry