Class MethodContext
This context tracks:
- Variable to slot mappings
- Temp variable source tracking
- IR labels to JVM labels
- Local variable debug metadata
- Scope boundaries
- Field type descriptors
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionintAllocate the next variable slot and increment the counter.voidboundBeforeDeclaration(String variableName) Record that a local's value has just been bound before its declaration (a catch handler storing the caught exception), so the declaration that follows must keep it rather than null-initialise it.currentDeclaration(String variableName) The declaration a name currently refers to, or null if it has none.voiddeclareLocal(LocalVariableInfo declaration) THE record of a local's declaration for the LocalVariableTable: every declaration gets its own entry.booleandeclaresAgain(String variableName) THE rule for whether a REFERENCE (a local's declaration) must null-initialise the local's slot.voidendDeclarationsIn(String scopeId, org.objectweb.asm.Label endLabel) Record a SCOPE_EXIT: every current declaration registered in that scope ends here.Get the field descriptor map (maps "this.fieldName" to JVM descriptor).Get the IR label to JVM label mapping.Every declaration of a local (parameters included), in declaration order.The operation-level (method-wide) scope id, or null if none was recorded.Get the scope boundaries map.Get the temp variable source tracking map.The receiver ('this') descriptor for an instance method (e.g.Get the variable to slot mapping.Get the variable type map (maps variable name to primitive type or null for objects).voidmarkOperationScopeIfAbsent(String scopeId) Record the operation-level (method-wide) scope on the FIRST SCOPE_ENTER — the outermost scope, which spans the whole method and is where parameters are live from.voidregisterParameter(LocalVariableInfo parameter) Pre-register a parameter for the LocalVariableTable (before any instruction is processed).voidsetThisTypeDescriptor(String descriptor) Record the receiver descriptor for an instance method — enables the slot-0thisLocalVariableTable entry.
-
Constructor Details
-
MethodContext
public MethodContext()
-
-
Method Details
-
getVariableMap
-
getTempSourceMap
Get the temp variable source tracking map. -
getLabelMap
-
declareLocal
THE record of a local's declaration for the LocalVariableTable: every declaration gets its own entry.A name's slot is shared by all its declarations in one method (see
declaresAgain(String)), but each declaration is a different variable - sibling if/else blocks, sequential loops and tries may each declarevalue, even of different types. Keyed by name, only the LAST declaration reached the table and a debugger standing in an earlier block could not see its local. Each declaration is now appended and becomes the name's CURRENT declaration, which later SCOPE_REGISTER / SCOPE_EXIT apply to; the earlier one keeps the end it was given by its own scope's exit, so the ranges do not overlap.The one exception is a parameter pre-registered by
registerParameter(LocalVariableInfo): the IR's own declaration of it replaces that registration in place. -
registerParameter
Pre-register a parameter for the LocalVariableTable (before any instruction is processed). -
currentDeclaration
The declaration a name currently refers to, or null if it has none. -
endDeclarationsIn
Record a SCOPE_EXIT: every current declaration registered in that scope ends here. A declaration a later one of the same name has replaced is not current, so it keeps its own (earlier) end. -
getLocalVariableDeclarations
Every declaration of a local (parameters included), in declaration order. -
getScopeMap
-
getFieldDescriptorMap
-
getVariableTypeMap
-
declaresAgain
THE rule for whether a REFERENCE (a local's declaration) must null-initialise the local's slot.A local's slot is keyed by its NAME, so every declaration of the same name in one method - a later sequential scope, a sibling if/else block, another loop body, a body the back end emits more than once (a for-range's three direction copies) - shares one slot. Each declaration is a NEW variable and must define the slot again: skipping it leaves whatever the slot held on the incoming paths ('top' after a join where one path never stored it, or the earlier declaration's type), and anything that reads the slot before the new declaration's first store - the generated close of a try resource on its handler path, a returning variable after a finally merge - fails JVM verification (VerifyError).
The only names that must NOT be null-initialised are those whose value is bound BEFORE their declaration: a parameter (pre-registered in the variable map, never declared here) and a catch handler's exception variable (stored by the handler, see
boundBeforeDeclaration(String)).- Returns:
- true if the declaration must null-initialise the slot (recording that it did)
-
boundBeforeDeclaration
Record that a local's value has just been bound before its declaration (a catch handler storing the caught exception), so the declaration that follows must keep it rather than null-initialise it. -
allocateNextSlot
public int allocateNextSlot()Allocate the next variable slot and increment the counter. -
markOperationScopeIfAbsent
Record the operation-level (method-wide) scope on the FIRST SCOPE_ENTER — the outermost scope, which spans the whole method and is where parameters are live from. Later (nested control-flow) SCOPE_ENTERs do not overwrite it. B.1: letsDebugInfoGeneratorpick the real method-wide scope for parameters instead of an arbitraryfindFirst()over the scope map. -
getOperationScopeId
The operation-level (method-wide) scope id, or null if none was recorded. -
getThisTypeDescriptor
The receiver ('this') descriptor for an instance method (e.g."Lfoo/Bar;"), or null for a static method. When set,DebugInfoGeneratoremits the slot-0thisLocalVariableTable entry. -
setThisTypeDescriptor
Record the receiver descriptor for an instance method — enables the slot-0thisLocalVariableTable entry. Leave unset (null) for static methods.
-