Package org.codehaus.janino

# Class CodeContext

java.lang.Object
org.codehaus.janino.CodeContext

public class CodeContext extends Object
The context of the compilation of a function (constructor or method). Manages generation of byte code, the exception table, generation of line number tables, allocation of local variables, determining of stack size and local variable table size and flow analysis.

## Nested Class Summary

Nested Classes
Modifier and Type
Class
Description
`final class`
`CodeContext.BasicBlock`
This `CodeContext.Offset` marks the first byte of a "basic block" in the sense of JLS 17 "4.10.1 Verification by Type Checking": The intent is that a stack map frame must appear at the beginning of each basic block in a method.
`static interface`
`CodeContext.FixUp`
A throw-in interface that marks `CodeContext.Offset`s as "fix-ups": During the execution of `fixUp()`, all "fix-ups" are invoked and can do last touches to the code attribute.
`class`
`CodeContext.Inserter`
A class that implements an insertion point into a "Code" attribute.
`class`
`CodeContext.LineNumberOffset`
An `CodeContext.Offset` who's sole purpose is to later create a 'LineNumberTable' attribute.
`class`
`CodeContext.Offset`
A class that represents an offset within a "Code" attribute.

## Constructor Summary

Constructors
Constructor
Description
`CodeContext(ClassFile classFile)`
Creates an empty "Code" attribute.

## Method Summary

Modifier and Type
Method
Description
`void`
`addExceptionTableEntry(CodeContext.Offset startPc, CodeContext.Offset endPc, CodeContext.Offset handlerPc, String catchTypeFd)`
Adds another entry to the "exception_table" of this code attribute (see JVMS 4.7.3).
`void`
`addLineNumberOffset(int lineNumber)`
`short`
`allocateLocalVariable(short size)`
Allocates space for a local variable of the given size (1 or 2) on the local variable array.
`Java.LocalVariableSlot`
`allocateLocalVariable(short size, String name, IType type)`
Allocates space for a local variable of the given size (1 or 2) on the local variable array.
`CodeContext.Inserter`
`currentInserter()`
`void`
`fixUpAndRelocate()`
Fixes up all of the offsets and relocate() all relocatables.
`List<Java.LocalVariableSlot>`
`getAllLocalVars()`
`ClassFile`
`getClassFile()`
The `ClassFile` this context is related to.
`int`
`makeSpace(int size)`
Inserts size NUL bytes at the current inserter's offset, advances the current inserter's offset by size, creates `CodeContext.LineNumberOffset`s as necessary, and returns the current inserter's original offset (the offset of the first NUL byte that was inserted).
`CodeContext.Offset`
`newBasicBlock()`
`ClassFile.CodeAttribute`
`newCodeAttribute(int initialLocalsCount, boolean debugLines, boolean debugVars)`
`CodeContext.Inserter`
`newInserter()`
Allocates an `CodeContext.Inserter`, set it to the current offset, and inserts it before the current offset.
`protected ClassFile.LocalVariableTableAttribute`
`newLocalVariableTableAttribute()`
`CodeContext.Offset`
`newOffset()`
Creates and inserts an `CodeContext.Offset` at the current inserter's current position.
`boolean`
`peekNullOperand()`
`boolean`
`peekObjectOperand()`
`ClassFile.StackMapTableAttribute.VerificationTypeInfo`
`peekOperand()`
`void`
`popInserter()`
Replaces the current `CodeContext.Inserter` with the remembered one (see `pushInserter(CodeContext.Inserter)`).
`void`
`popIntOperand()`
Asserts that the top operand is an `integer_variable_info` and pops it.
`ClassFile.StackMapTableAttribute.VerificationTypeInfo`
`popIntOrLongOperand()`
Asserts that the top operand is an `int_variable_info` or `long_variable_info`, then pops and returns it.
`void`
`popLongOperand()`
Asserts that the top operand is a `long_variable_info` and pops it.
`void`
`popNullOperand()`
`String`
`popObjectOperand()`
Asserts that the top operand is an `object_variable_info`, and pops it.
`ClassFile.StackMapTableAttribute.VerificationTypeInfo`
`popObjectOrUninitializedOrUninitializedThisOperand()`
Asserts that the top operand is an `object_variable_info`, `uninitialized_variable_info` or `uninitializedThis_variable_info`, and pops it.
`ClassFile.StackMapTableAttribute.VerificationTypeInfo`
`popOperand()`
Pops one entry from the current inserter's operand stack.
`void`
`popOperand(String expectedFd)`
Pops the top operand, asserts that it is an `integer_variable_info`, `long_variable_info`, `float_variable_info`, `double_variable_info` or `variable_object_info`, and asserts that it matches the given field descriptor.
`void`
`popOperand(ClassFile.StackMapTableAttribute.VerificationTypeInfo expected)`
Pops the top entry from the operand stack and assert that it equals expected.
`void`
`popOperandAssignableTo(String declaredFd)`
`void`
`popReferenceOperand()`
Asserts that the top operand is an `object_variable_info` or a `null_variable_info` and pops it.
`void`
`popUninitializedThisOperand()`
Asserts that the top operand is an `uninitializedThis_variable_info` and pops it.
`void`
`popUninitializedVariableOperand()`
Asserts that the top operand is an `uninitialized_variable_info` and pops it.
`void`
`pushDoubleOperand()`
`void`
`pushFloatOperand()`
`void`
`pushInserter(CodeContext.Inserter ins)`
Remembers the current `CodeContext.Inserter`, then replaces it with the new one.
`void`
`pushIntOperand()`
`void`
`pushLongOperand()`
`void`
`pushNullOperand()`
`void`
`pushObjectOperand(String fieldDescriptor)`
`void`
`pushOperand(String fieldDescriptor)`
Pushes one `object_variable_info`, `integer_variable_info`, `double_variable_info`, `float_variable_info` or `long_variable_info` entry onto the current inserter's operand stack.
`void`
`pushOperand(ClassFile.StackMapTableAttribute.VerificationTypeInfo topOperand)`
`void`
`pushTopOperand()`
`void`
`pushUninitializedOperand()`
`void`
`pushUninitializedThisOperand()`
`void`
`removeCode(CodeContext.Offset from, CodeContext.Offset to)`
Removes all code between from and to.
`void`
`restoreLocalVariables()`
Restores the previous size of the local variables array.
`List<Java.LocalVariableSlot>`
`saveLocalVariables()`
Remembers the current size of the local variables array.
`String`
`toString()`
`void`
`write(byte b1)`
Inserts a byte at the current insertion position.
`void`
`write(byte[] b)`
Inserts a sequence of bytes at the current insertion position.
`void`
`write(byte b1, byte b2)`
Inserts bytes at the current insertion position.
`void`
`write(byte b1, byte b2, byte b3)`
Inserts bytes at the current insertion position.
`void`
`write(byte b1, byte b2, byte b3, byte b4)`
Inserts bytes at the current insertion position.
`void`
`write(byte b1, byte b2, byte b3, byte b4, byte b5)`
Inserts bytes at the current insertion position.
`void`
`writeBranch(int opcode, CodeContext.Offset dst)`
Generates a "branch" instruction.
`void`
`writeOffset(CodeContext.Offset src, CodeContext.Offset dst)`
Writes a four-byte offset (as it is used in TABLESWITCH and LOOKUPSWITCH) into this code context.
`void`
`writeShort(int v)`

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

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

## Constructor Details

### CodeContext

public CodeContext(ClassFile classFile)
Creates an empty "Code" attribute.

## Method Details

### getClassFile

public ClassFile getClassFile()
The `ClassFile` this context is related to.

### allocateLocalVariable

public short allocateLocalVariable(short size)
Allocates space for a local variable of the given size (1 or 2) on the local variable array.

As a side effect, the "max_locals" field of the "Code" attribute is updated.

The only way to deallocate local variables is to `saveLocalVariables()` and later `restoreLocalVariables()`.

Parameters:
  `size` - The number of slots to allocate (1 or 2)
Returns:
  The slot index of the allocated variable

### allocateLocalVariable

public Java.LocalVariableSlot allocateLocalVariable(short size, @Nullable String name, @Nullable IType type)
Allocates space for a local variable of the given size (1 or 2) on the local variable array. As a side effect, the "max_locals" field of the "Code" attribute is updated.

The only way to deallocate local variables is to `saveLocalVariables()` and later `restoreLocalVariables()`.

Parameters:
  `size` - Number of slots to use (1 or 2)
  `name` - The variable name; if `null`, then the variable won't be written to the LocalVariableTable
  `type` - The variable type; if the name is not null, then the type is needed to write to the LocalVariableTable

### saveLocalVariables

public List<Java.LocalVariableSlot> saveLocalVariables()
Remembers the current size of the local variables array.

### restoreLocalVariables

public void restoreLocalVariables()
Restores the previous size of the local variables array. This MUST to be called for every call to saveLocalVariables as it closes the variable extent for all the active local variables in the current block.

### newCodeAttribute

public ClassFile.CodeAttribute newCodeAttribute(int initialLocalsCount, boolean debugLines, boolean debugVars)

Parameters:
  `initialLocalsCount` - The number of parameters, plus one iff there is a "this" parameter

### newLocalVariableTableAttribute

@Nullable protected ClassFile.LocalVariableTableAttribute newLocalVariableTableAttribute()

Returns:
  A `ClassFile.LocalVariableTableAttribute` for this `CodeContext`

### fixUpAndRelocate

public void fixUpAndRelocate()
Fixes up all of the offsets and relocate() all relocatables.

### write

public void write(byte[] b)
Inserts a sequence of bytes at the current insertion position. Creates `CodeContext.LineNumberOffset`s as necessary.

### write

public void write(byte b1)
Inserts a byte at the current insertion position. Creates `CodeContext.LineNumberOffset`s as necessary.

This method is an optimization to avoid allocating small byte[] and ease GC load.

### write

public void write(byte b1, byte b2)
Inserts bytes at the current insertion position. Creates `CodeContext.LineNumberOffset`s as necessary.

This method is an optimization to avoid allocating small byte[] and ease GC load.

### write

public void write(byte b1, byte b2, byte b3)
Inserts bytes at the current insertion position. Creates `CodeContext.LineNumberOffset`s as necessary.

This method is an optimization to avoid allocating small byte[] and ease GC load.

### write

public void write(byte b1, byte b2, byte b3, byte b4)
Inserts bytes at the current insertion position. Creates `CodeContext.LineNumberOffset`s as necessary.

This method is an optimization to avoid allocating small byte[] and ease GC load.

### write

public void write(byte b1, byte b2, byte b3, byte b4, byte b5)
Inserts bytes at the current insertion position. Creates `CodeContext.LineNumberOffset`s as necessary.

This method is an optimization to avoid allocating small byte[] and ease GC load.

### addLineNumberOffset

public void addLineNumberOffset(int lineNumber)

### makeSpace

public int makeSpace(int size)
Inserts size NUL bytes at the current inserter's offset, advances the current inserter's offset by size, creates `CodeContext.LineNumberOffset`s as necessary, and returns the current inserter's original offset (the offset of the first NUL byte that was inserted).

Because the class file format does not support line numbers greater than 65535, these are treated as 65535.

Parameters:
  `size` - The number of NUL bytes to inject
Returns:
  The offset of the first inserted byte

### writeShort

public void writeShort(int v)

### writeBranch

public void writeBranch(int opcode, CodeContext.Offset dst)
Generates a "branch" instruction.

Parameters:
  `opcode` - One of `Opcode.GOTO`, `Opcode.JSR` and `Opcode.IF*`
  `dst` - Where to branch

### writeOffset

public void writeOffset(CodeContext.Offset src, CodeContext.Offset dst)
Writes a four-byte offset (as it is used in TABLESWITCH and LOOKUPSWITCH) into this code context.

### newOffset

public CodeContext.Offset newOffset()
Creates and inserts an `CodeContext.Offset` at the current inserter's current position.

### newBasicBlock

public CodeContext.Offset newBasicBlock()

### newInserter

public CodeContext.Inserter newInserter()
Allocates an `CodeContext.Inserter`, set it to the current offset, and inserts it before the current offset.

In clear text, this means that you can continue writing to the "Code" attribute, then `pushInserter(CodeContext.Inserter)` the `CodeContext.Inserter`, then write again (which inserts bytes into the "Code" attribute at the previously remembered position), and then `popInserter()`.

### currentInserter

public CodeContext.Inserter currentInserter()

Returns:
  The current inserter

### pushInserter

public void pushInserter(CodeContext.Inserter ins)
Remembers the current `CodeContext.Inserter`, then replaces it with the new one.

### popInserter

public void popInserter()
Replaces the current `CodeContext.Inserter` with the remembered one (see `pushInserter(CodeContext.Inserter)`).

### addExceptionTableEntry

public void addExceptionTableEntry(CodeContext.Offset startPc, CodeContext.Offset endPc, CodeContext.Offset handlerPc, @Nullable String catchTypeFd)
Adds another entry to the "exception_table" of this code attribute (see JVMS 4.7.3).

Parameters:
  `catchTypeFd` - `null` means `finally` clause

### getAllLocalVars

public List<Java.LocalVariableSlot> getAllLocalVars()

Returns:
  All the local variables that are allocated in any block in this `CodeContext`

### removeCode

public void removeCode(CodeContext.Offset from, CodeContext.Offset to)
Removes all code between from and to. Also removes any `CodeContext.Relocatable`s existing in that range.

### toString

public String toString()

Overrides:
  `toString` in class `Object`

### pushOperand

public void pushOperand(String fieldDescriptor)
Pushes one `object_variable_info`, `integer_variable_info`, `double_variable_info`, `float_variable_info` or `long_variable_info` entry onto the current inserter's operand stack.

### pushTopOperand

public void pushTopOperand()

### pushIntOperand

public void pushIntOperand()

### pushLongOperand

public void pushLongOperand()

### pushFloatOperand

public void pushFloatOperand()

### pushDoubleOperand

public void pushDoubleOperand()

### pushNullOperand

public void pushNullOperand()

### pushUninitializedThisOperand

public void pushUninitializedThisOperand()

### pushUninitializedOperand

public void pushUninitializedOperand()

### pushObjectOperand

public void pushObjectOperand(String fieldDescriptor)

### pushOperand

public void pushOperand(ClassFile.StackMapTableAttribute.VerificationTypeInfo topOperand)

### peekNullOperand

public boolean peekNullOperand()

Returns:
  Whether the top operand is a `null_variable_info`

### peekObjectOperand

public boolean peekObjectOperand()

Returns:
  Whether the top operand is a `object_variable_info`

### peekOperand

public ClassFile.StackMapTableAttribute.VerificationTypeInfo peekOperand()

Returns:
  The verification type of the top operand

### popOperand

public ClassFile.StackMapTableAttribute.VerificationTypeInfo popOperand()
Pops one entry from the current inserter's operand stack.

### popOperand

public void popOperand(ClassFile.StackMapTableAttribute.VerificationTypeInfo expected)
Pops the top entry from the operand stack and assert that it equals expected.

### popOperand

public void popOperand(String expectedFd)
Pops the top operand, asserts that it is an `integer_variable_info`, `long_variable_info`, `float_variable_info`, `double_variable_info` or `variable_object_info`, and asserts that it matches the given field descriptor.

### popOperandAssignableTo

public void popOperandAssignableTo(String declaredFd)

### popIntOperand

public void popIntOperand()
Asserts that the top operand is an `integer_variable_info` and pops it.

### popLongOperand

public void popLongOperand()
Asserts that the top operand is a `long_variable_info` and pops it.

### popUninitializedThisOperand

public void popUninitializedThisOperand()
Asserts that the top operand is an `uninitializedThis_variable_info` and pops it.

### popUninitializedVariableOperand

public void popUninitializedVariableOperand()
Asserts that the top operand is an `uninitialized_variable_info` and pops it.

### popReferenceOperand

public void popReferenceOperand()
Asserts that the top operand is an `object_variable_info` or a `null_variable_info` and pops it.

### popNullOperand

public void popNullOperand()

### popObjectOperand

public String popObjectOperand()
Asserts that the top operand is an `object_variable_info`, and pops it.

Returns:
  The field descriptor of the popped object operand

### popObjectOrUninitializedOrUninitializedThisOperand

public ClassFile.StackMapTableAttribute.VerificationTypeInfo popObjectOrUninitializedOrUninitializedThisOperand()
Asserts that the top operand is an `object_variable_info`, `uninitialized_variable_info` or `uninitializedThis_variable_info`, and pops it.

### popIntOrLongOperand

public ClassFile.StackMapTableAttribute.VerificationTypeInfo popIntOrLongOperand()
Asserts that the top operand is an `int_variable_info` or `long_variable_info`, then pops and returns it.