org.codehaus.janino

Class 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
interfaceCodeContext.FixUp
A throw-in interface that marks Offsets as "fix-ups": During the execution of CodeContext, all "fix-ups" are invoked and can do last touches to the code attribute.
classCodeContext.Inserter
A class that implements an insertion point into a "Code" attribute.
classCodeContext.LineNumberOffset
classCodeContext.Offset
A class that represents an offset within a "Code" attribute.
Constructor Summary
CodeContext(ClassFile classFile)
Create an empty "Code" attribute.
Method Summary
voidaddExceptionTableEntry(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).
shortallocateLocalVariable(short size)
Allocate space for a local variable of the given size (1 or 2) on the local variable array.
CodeContext.InsertercurrentInserter()
voidfixUpAndRelocate()
fixUp() all of the offsets and relocate() all relocatables
voidflowAnalysis(String functionName)
Checks the code for consistency; updates the "maxStack" member.
ClassFilegetClassFile()
voidmakeSpace(short lineNumber, int size)
Add space for size bytes at current offset.
CodeContext.InserternewInserter()
Allocate an Inserter, set it to the current offset, and insert it before the current offset.
CodeContext.OffsetnewOffset()
voidpopInserter()
Replace the current Inserter with the remembered one (see pushInserter).
voidpushInserter(CodeContext.Inserter ins)
Remember the current Inserter, then replace it with the new one.
voidrestoreLocalVariables()
Restore the previous size of the local variables array.
voidsaveLocalVariables()
Remember the current size of the local variables array.
protected voidstoreCodeAttributeBody(DataOutputStream dos, short lineNumberTableAttributeNameIndex)
voidwrite(short lineNumber, byte[] b)
Inserts a sequence of bytes at the current insertion position.
voidwrite(short lineNumber, byte b1)
Inserts a byte at the current insertion position.
voidwrite(short lineNumber, byte b1, byte b2)
Inserts bytes at the current insertion position.
voidwrite(short lineNumber, byte b1, byte b2, byte b3)
Inserts bytes at the current insertion position.
voidwrite(short lineNumber, byte b1, byte b2, byte b3, byte b4)
Inserts bytes at the current insertion position.
voidwriteBranch(short lineNumber, int opcode, CodeContext.Offset dst)
voidwriteOffset(short lineNumber, CodeContext.Offset src, CodeContext.Offset dst)
voidwriteShort(short lineNumber, int v)

Constructor Detail

CodeContext

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

Method Detail

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: startPC endPC handlerPC catchTypeFD

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.

currentInserter

public CodeContext.Inserter currentInserter()

fixUpAndRelocate

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

flowAnalysis

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

getClassFile

public ClassFile getClassFile()

makeSpace

public void makeSpace(short lineNumber, int size)
Add space for size bytes at current offset. Creates LineNumberOffsets as necessary.

Parameters: lineNumber The line number that corresponds to the byte code, or -1 size The size in bytes to inject

newInserter

public CodeContext.Inserter newInserter()
Allocate an 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 the Inserter, then write again (which inserts bytes into the "Code" attribute at the previously remembered position), and then popInserter.

newOffset

public CodeContext.Offset newOffset()

popInserter

public void popInserter()
Replace the current Inserter with the remembered one (see pushInserter).

pushInserter

public void pushInserter(CodeContext.Inserter ins)
Remember the current Inserter, then replace it with the new one.

restoreLocalVariables

public void restoreLocalVariables()
Restore the previous size of the local variables array.

saveLocalVariables

public void saveLocalVariables()
Remember the current size of the local variables array.

storeCodeAttributeBody

protected void storeCodeAttributeBody(DataOutputStream dos, short lineNumberTableAttributeNameIndex)

Parameters: dos lineNumberTableAttributeNameIndex 0 == don't generate a "LineNumberTable" attribute

Throws: IOException

write

public void write(short lineNumber, byte[] b)
Inserts a sequence of bytes at the current insertion position. Creates 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 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 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 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 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

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)

writeShort

public void writeShort(short lineNumber, int v)

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