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.
  • Constructor Details

    • CodeContext

      public CodeContext(ClassFile classFile)
      Create an empty "Code" attribute.
  • Method Details

    • getClassFile

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

      public short allocateLocalVariable(short size)
      Allocate 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, String name, IClass type)
      Allocate 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 it's null, the variable won't be written to the localvariabletable
      type - The variable type. if the name isn't null, the type is needed to write to the localvariabletable
    • saveLocalVariables

      public List saveLocalVariables()
      Remember the current size of the local variables array.
    • restoreLocalVariables

      public void restoreLocalVariables()
      Restore 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.
    • storeCodeAttributeBody

      protected void storeCodeAttributeBody(DataOutputStream dos, short lineNumberTableAttributeNameIndex, short localVariableTableAttributeNameIndex) throws IOException
      Parameters:
      dos -
      lineNumberTableAttributeNameIndex - 0 == don't generate a "LineNumberTable" attribute
      Throws:
      IOException
    • storeLocalVariableTable

      protected ClassFile.AttributeInfo storeLocalVariableTable(DataOutputStream dos, short localVariableTableAttributeNameIndex)
      Returns:
      A ClassFile.LocalVariableTableAttribute for this CodeContext
    • flowAnalysis

      public void flowAnalysis(String functionName)
      Checks the code for consistency; updates the "maxStack" member. Notice: On inconsistencies, a "RuntimeException" is thrown (KLUDGE).
    • fixUpAndRelocate

      public void fixUpAndRelocate()
      fixUp() all of the offsets and relocate() all relocatables
    • write

      public void write(short lineNumber, byte[] b)
      Inserts a sequence of bytes at the current insertion position. Creates CodeContext.LineNumberOffsets as necessary.
      Parameters:
      lineNumber - The line number that corresponds to the byte code, or -1
      b -
    • write

      public void write(short lineNumber, byte b1)
      Inserts a byte at the current insertion position. Creates CodeContext.LineNumberOffsets as necessary.

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

      Parameters:
      lineNumber - The line number that corresponds to the byte code, or -1
      b1 -
    • write

      public void write(short lineNumber, byte b1, byte b2)
      Inserts bytes at the current insertion position. Creates CodeContext.LineNumberOffsets as necessary.

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

      Parameters:
      lineNumber - The line number that corresponds to the byte code, or -1
      b1 -
      b2 -
    • write

      public void write(short lineNumber, byte b1, byte b2, byte b3)
      Inserts bytes at the current insertion position. Creates CodeContext.LineNumberOffsets as necessary.

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

      Parameters:
      lineNumber - The line number that corresponds to the byte code, or -1
      b1 -
      b2 -
      b3 -
    • write

      public void write(short lineNumber, byte b1, byte b2, byte b3, byte b4)
      Inserts bytes at the current insertion position. Creates CodeContext.LineNumberOffsets as necessary.

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

      Parameters:
      lineNumber - The line number that corresponds to the byte code, or -1
      b1 -
      b2 -
      b3 -
      b4 -
    • makeSpace

      public void makeSpace(short lineNumber, int size)
      Add space for size bytes at current offset. Creates CodeContext.LineNumberOffsets as necessary.
      Parameters:
      lineNumber - The line number that corresponds to the byte code, or -1
      size - The size in bytes to inject
    • writeShort

      public void writeShort(short lineNumber, int v)
      Parameters:
      lineNumber - The line number that corresponds to the byte code, or -1
    • writeBranch

      public void writeBranch(short lineNumber, int opcode, CodeContext.Offset dst)
      Parameters:
      lineNumber - The line number that corresponds to the byte code, or -1
    • writeOffset

      public void writeOffset(short lineNumber, 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.
    • newInserter

      public CodeContext.Inserter newInserter()
      Allocate an CodeContext.Inserter, set it to the current offset, and insert 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)
      Remember the current CodeContext.Inserter, then replace it with the new one.
    • popInserter

      public void popInserter()
      Replace 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, String catchTypeFd)
      Add another entry to the "exception_table" of this code attribute (see JVMS 4.7.3).
      Parameters:
      catchTypeFd - null == "finally" clause
    • getAllLocalVars

      public List getAllLocalVars()
      Returns:
      All the local variables that are allocated in any block in this CodeContext