org.apache.derby.impl.services.bytecode
Class BCMethod

java.lang.Object
  extended byorg.apache.derby.impl.services.bytecode.BCMethod
All Implemented Interfaces:
MethodBuilder

public class BCMethod
extends java.lang.Object
implements MethodBuilder

MethodBuilder is used to piece together a method when building a java class definition.

When a method is first created, it has:

MethodBuilder implementations are required to supply a way for Statements and Expressions to give them code. Most typically, they may have a stream to which their contents writes the code that is of the type to satisfy what the contents represent. MethodBuilder implementations also have to have a way to supply ClassBuilders with their code, that satisfies the type of class builder they are implemented with. This is implementation-dependent, so ClassBuilders, MethodBuilders, Statements, and Expressions all have to be of the same implementation in order to interact to generate a class.

Method Builder implementation for generating bytecode.


Field Summary
(package private)  BCClass cb
           
private  Conditional condition
           
private  int currentVarNum
           
private  int maxStack
           
protected  ClassHolder modClass
           
(package private)  CodeChunk myCode
           
protected  ClassMember myEntry
           
private static byte[] newArrayElementTypeMap
          this array maps the BCExpr vm_* constants 0..6 to the expected VM type constants for the newarray instruction.
protected  BCLocalField[] parameters
           
private  int stackDepth
           
private  int stackTypeOffset
           
private  Type[] stackTypes
           
private  int statementNum
           
(package private) static byte T_BOOLEAN
           
protected  java.util.Vector thrownExceptions
           
 
Constructor Summary
(package private) BCMethod(ClassBuilder cb, java.lang.String returnType, java.lang.String methodName, int modifiers, java.lang.String[] parms, BCJava factory)
           
 
Method Summary
 void addThrownException(java.lang.String exceptionClass)
          a throwable can be added to the end of the list of thrownExceptions.
 int callMethod(java.lang.Object methodDescriptor)
          Call a method previously described by describeMethod().
 int callMethod(short opcode, java.lang.String declaringClass, java.lang.String methodName, java.lang.String returnType, int numArgs)
          Call a method.
 void callSuper()
          Call super().
 void cast(java.lang.String className)
          Cast the top stack value.
 void complete()
          when the method has had all of its parameters and thrown exceptions defined, and its statement block has been completed, it can be completed and its class file information generated.
 void completeConditional()
          Complete the a ?
 void conditionalIf()
          Initiate a sequence that corresponds to the Java language ' value ?
private  void conditionalIf(short opcode)
           
 void conditionalIfNull()
          Initiate a sequence that corresponds to the Java language 'ref == null ?
(package private)  ClassHolder constantPool()
          In their giveCode methods, the parts of the method body will want to get to the constant pool to add their constants.
 java.lang.Object describeMethod(short opcode, java.lang.String declaringClass, java.lang.String methodName, java.lang.String returnType)
          Return an object that efficiently (to the implementation) describes a zero-argument method and can be used with the single argument callMethod().
 void dup()
          Duplicate the top value on the stack.
 void endStatement()
          End a statement.
 void getArrayElement(int element)
          Pop an array refrence off the stack and push an element from that array.
 void getField(LocalField field)
          Push the contents of the local field onto the stack.
private  void getField(short opcode, java.lang.String declaringClass, java.lang.String fieldName, java.lang.String fieldType)
           
 void getField(java.lang.String declaringClass, java.lang.String fieldName, java.lang.String fieldType)
          Push the contents of the described field onto the stack.
 java.lang.String getName()
          return the name of the method.
 void getParameter(int id)
          Push a parameter value.
 void getStaticField(java.lang.String declaringClass, java.lang.String fieldName, java.lang.String fieldType)
          Push the contents of the described static field onto the stack.
private  void growStack(int size, Type type)
           
private  void growStack(Type type)
           
 void isInstanceOf(java.lang.String className)
          Pop the top stack value and push a boolean that is the result of an instanceof check on the popped reference.
 void methodReturn()
          Return from a method, optionally with a value.
private  Type popStack()
           
 void push(boolean value)
          Push a boolean constant onto the stack Stack ... => ...
 void push(byte value)
          Push a byte constant onto the stack Stack ... => ...
 void push(double value)
          Push a double constant onto the stack Stack ... => ...
 void push(float value)
          Push a float constant onto the stack Stack ... => ...
 void push(int value)
          Push a int constant onto the stack Stack ... => ...
private  void push(int value, Type type)
           
 void push(long value)
          Push a long constant onto the stack Stack ... => ...
 void push(short value)
          Push a short constant onto the stack Stack ... => ...
 void push(java.lang.String value)
          Push a String constant onto the stack Stack ... => ...
 void pushNewArray(java.lang.String className, int size)
          Create an array instance Stack ... => ...
 void pushNewComplete(int numArgs)
          Complete the sequence that was started with pushNewStart().
 void pushNewStart(java.lang.String className)
          Initiate a sequence that calls a constructor, equivalent to the new operator in Java.
 void pushNull(java.lang.String type)
          Push a typed null onto the stack Stack ... => ...
 void pushThis()
          Push this onto the stack.
 void putField(LocalField field)
          Upon entry the top word(s) on the stack is the value to be put into the field.
 void putField(java.lang.String fieldName, java.lang.String fieldType)
          Pop the top stack value and store it in the instance field of this class.
 void putField(java.lang.String declaringClass, java.lang.String fieldName, java.lang.String fieldType)
          Pop the top stack value and store it in the field.
private  void putField(Type fieldType, int cpi)
           
 void setArrayElement(int element)
          Pop an array reference off the stack, store a value in the array at the passed in offset.
 void startElseCode()
          Complete the true code path of a ?
 boolean statementNumHitLimit(int noStatementsAdded)
          Tell if statement number in this method builder hits limit.
 void swap()
          Swap the top two values on the stack.
 void upCast(java.lang.String className)
          Upcast the top stack value.
private  Type vmNameDeclaringClass(java.lang.String declaringClass)
           
protected  void writeExceptions()
          sets exceptionBytes to the attribute_info needed for a method's Exceptions attribute.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

cb

final BCClass cb

modClass

protected final ClassHolder modClass

parameters

protected BCLocalField[] parameters

thrownExceptions

protected java.util.Vector thrownExceptions

myCode

final CodeChunk myCode

myEntry

protected ClassMember myEntry

currentVarNum

private int currentVarNum

statementNum

private int statementNum

stackTypes

private Type[] stackTypes

stackTypeOffset

private int stackTypeOffset

maxStack

private int maxStack

stackDepth

private int stackDepth

condition

private Conditional condition

newArrayElementTypeMap

private static final byte[] newArrayElementTypeMap
this array maps the BCExpr vm_* constants 0..6 to the expected VM type constants for the newarray instruction.

Because boolean was mapped to integer for general instructions, it will have to be specially matched and mapped to its value directly (4).


T_BOOLEAN

static final byte T_BOOLEAN
See Also:
Constant Field Values
Constructor Detail

BCMethod

BCMethod(ClassBuilder cb,
         java.lang.String returnType,
         java.lang.String methodName,
         int modifiers,
         java.lang.String[] parms,
         BCJava factory)
Method Detail

getName

public java.lang.String getName()
Description copied from interface: MethodBuilder
return the name of the method.

Specified by:
getName in interface MethodBuilder

getParameter

public void getParameter(int id)
Description copied from interface: MethodBuilder
Push a parameter value.
                Stack ...  =>
                      ...,param_value
                

Specified by:
getParameter in interface MethodBuilder
Parameters:
id - position of the parameter (zero based).

addThrownException

public void addThrownException(java.lang.String exceptionClass)
a throwable can be added to the end of the list of thrownExceptions.

Specified by:
addThrownException in interface MethodBuilder

complete

public void complete()
when the method has had all of its parameters and thrown exceptions defined, and its statement block has been completed, it can be completed and its class file information generated.

further alterations of the method will not be reflected in the code generated for it.

Specified by:
complete in interface MethodBuilder

constantPool

ClassHolder constantPool()
In their giveCode methods, the parts of the method body will want to get to the constant pool to add their constants. We really only want them treating it like a constant pool inclusion mechanism, we could write a wrapper to limit it to that.


writeExceptions

protected void writeExceptions()
sets exceptionBytes to the attribute_info needed for a method's Exceptions attribute. The ClassUtilities take care of the header 6 bytes for us, so they are not included here. See The Java Virtual Machine Specification Section 4.7.5, Exceptions attribute.


growStack

private void growStack(int size,
                       Type type)

growStack

private void growStack(Type type)

popStack

private Type popStack()

pushThis

public void pushThis()
Description copied from interface: MethodBuilder
Push this onto the stack.
                Stack ...  =>
                      ...,this_ref
                

Specified by:
pushThis in interface MethodBuilder

push

public void push(byte value)
Description copied from interface: MethodBuilder
Push a byte constant onto the stack
                Stack ...  =>
                      ...,byte_value
                

Specified by:
push in interface MethodBuilder

push

public void push(boolean value)
Description copied from interface: MethodBuilder
Push a boolean constant onto the stack
                Stack ...  =>
                      ...,boolean_value
                

Specified by:
push in interface MethodBuilder

push

public void push(short value)
Description copied from interface: MethodBuilder
Push a short constant onto the stack
                Stack ...  =>
                      ...,short_value
                

Specified by:
push in interface MethodBuilder

push

public void push(int value)
Description copied from interface: MethodBuilder
Push a int constant onto the stack
                Stack ...  =>
                      ...,int_value
                

Specified by:
push in interface MethodBuilder

dup

public void dup()
Description copied from interface: MethodBuilder
Duplicate the top value on the stack.
                Stack ...,value =>
                      ...,value,value
                

Specified by:
dup in interface MethodBuilder

swap

public void swap()
Description copied from interface: MethodBuilder
Swap the top two values on the stack.
                Stack ...,valueA,valueB =>
                      ...,valueB,valueA
                

Specified by:
swap in interface MethodBuilder

push

private void push(int value,
                  Type type)

push

public void push(long value)
Description copied from interface: MethodBuilder
Push a long constant onto the stack
                Stack ...  =>
                      ...,long_value
                

Specified by:
push in interface MethodBuilder

push

public void push(float value)
Description copied from interface: MethodBuilder
Push a float constant onto the stack
                Stack ...  =>
                      ...,float_value
                

Specified by:
push in interface MethodBuilder

push

public void push(double value)
Description copied from interface: MethodBuilder
Push a double constant onto the stack
                Stack ...  =>
                      ...,double_value
                

Specified by:
push in interface MethodBuilder

push

public void push(java.lang.String value)
Description copied from interface: MethodBuilder
Push a String constant onto the stack
                Stack ...  =>
                      ...,String_value
                

Specified by:
push in interface MethodBuilder

methodReturn

public void methodReturn()
Description copied from interface: MethodBuilder
Return from a method, optionally with a value. Must only be called if zero or one item exists on the stack. If the stack contains a single value then that is popped and used as the returned value.
                Stack value =>
                      :empty:
                or

                Stack :empty: =>
                      :empty:

                
.

Specified by:
methodReturn in interface MethodBuilder

describeMethod

public java.lang.Object describeMethod(short opcode,
                                       java.lang.String declaringClass,
                                       java.lang.String methodName,
                                       java.lang.String returnType)
Description copied from interface: MethodBuilder
Return an object that efficiently (to the implementation) describes a zero-argument method and can be used with the single argument callMethod(). Descriptions for the parameters to this method are the same as the five argument callMethod(). This allows the caller to cache frequently used methods. The returned object is only valid for use by this MethodBuilder.
This call does not affect the Stack.

Specified by:
describeMethod in interface MethodBuilder

callMethod

public int callMethod(java.lang.Object methodDescriptor)
Description copied from interface: MethodBuilder
Call a method previously described by describeMethod().
                static methods

                Stack ...,value* => [numArgs number of values will be popped]
                      ...,return_value [void methods will not push a value]

                non-static methods

                Stack ...,ref,value* => [numArgs number of values will be popped]
                      ...,return_value [void methods will not push a value]
                

Specified by:
callMethod in interface MethodBuilder

callMethod

public int callMethod(short opcode,
                      java.lang.String declaringClass,
                      java.lang.String methodName,
                      java.lang.String returnType,
                      int numArgs)
Description copied from interface: MethodBuilder
Call a method. The instance (receiver or reference) for non-static methods must be pushed by the caller. The instance (for non-static) and the arguments are popped of the stack, and the return value (if any) is pushed onto the stack.
The type needs to be one of:
                static methods

                Stack ...,value* => [numArgs number of values will be popped]
                      ...,return_value [void methods will not push a value]

                non-static methods

                Stack ...,ref,value* => [numArgs number of values will be popped]
                      ...,return_value [void methods will not push a value]
                

The type of the arguments to the methods must exactly match the declared types of the parameters to the methods. If a argument is of the incorrect type the caller must up cast it or down cast it.

Specified by:
callMethod in interface MethodBuilder
Parameters:
opcode - type of method invocation
declaringClass - Class or interface the method is declared in. If it is a non-static method call then if declaringClass is null, the declared type is taken to be the type of the reference that will be popped.
methodName - name of the method
returnType - class name or primitive type (including "void") of the return type of the method, can not be null.
numArgs - number of arguments to the method (can be 0).

vmNameDeclaringClass

private Type vmNameDeclaringClass(java.lang.String declaringClass)

callSuper

public void callSuper()
Description copied from interface: MethodBuilder
Call super(). Caller must only add this to a constructor.

                Stack ... =>
                      ... 
                

Specified by:
callSuper in interface MethodBuilder

pushNewStart

public void pushNewStart(java.lang.String className)
Description copied from interface: MethodBuilder
Initiate a sequence that calls a constructor, equivalent to the new operator in Java. After this call, the caller must push any arguments and then complete the construction with a call to pushNewComplete(). Only arguments to the constructor can be pushed onto the stack between the pushNewStart() and pushNewComplete() method calls.
                Stack ... => [unchanged]
                      ...
                

Specified by:
pushNewStart in interface MethodBuilder
Parameters:
className - class name of object to be created.

pushNewComplete

public void pushNewComplete(int numArgs)
Description copied from interface: MethodBuilder
Complete the sequence that was started with pushNewStart(). Pop the arguments to the constructor and push the reference to the newly created object.
                Stack ...,value* => [numArgs number of values will be popped]
                      ...,new_ref
                

Specified by:
pushNewComplete in interface MethodBuilder
Parameters:
numArgs - number of arguments to the constructor (can be 0).

upCast

public void upCast(java.lang.String className)
Description copied from interface: MethodBuilder
Upcast the top stack value. This is used for correct method resolution by upcasting method parameters. It does not put any casting code into the byte code stream. Can only be used for refrences.
                Stack ...,ref =>
                      ...,ref
                

Specified by:
upCast in interface MethodBuilder

cast

public void cast(java.lang.String className)
Description copied from interface: MethodBuilder
Cast the top stack value. Correctly down-casts a reference or casts a primitive type (e.g. int to short).
                Stack ...,value =>
                      ...,cast_value
                

Specified by:
cast in interface MethodBuilder
Parameters:
className - type (primitive, interface or class) to cast to.

isInstanceOf

public void isInstanceOf(java.lang.String className)
Description copied from interface: MethodBuilder
Pop the top stack value and push a boolean that is the result of an instanceof check on the popped reference.
                Stack ...,ref =>
                      ...,boolean_value
                
.

Specified by:
isInstanceOf in interface MethodBuilder

pushNull

public void pushNull(java.lang.String type)
Description copied from interface: MethodBuilder
Push a typed null onto the stack
                Stack ...  =>
                      ...,null
                

Specified by:
pushNull in interface MethodBuilder

getField

public void getField(LocalField field)
Description copied from interface: MethodBuilder
Push the contents of the local field onto the stack. This call pushes the this instance required to access the field itself.
                Stack ...  =>
                      ...,field_value
                

Specified by:
getField in interface MethodBuilder

getField

public void getField(java.lang.String declaringClass,
                     java.lang.String fieldName,
                     java.lang.String fieldType)
Description copied from interface: MethodBuilder
Push the contents of the described field onto the stack. This call requires the instance (reference) to be pushed by the caller.
                Stack ...,field_ref  =>
                      ...,field_value
                

Specified by:
getField in interface MethodBuilder

getStaticField

public void getStaticField(java.lang.String declaringClass,
                           java.lang.String fieldName,
                           java.lang.String fieldType)
Push the contents of the described static field onto the stack.

Specified by:
getStaticField in interface MethodBuilder

getField

private void getField(short opcode,
                      java.lang.String declaringClass,
                      java.lang.String fieldName,
                      java.lang.String fieldType)

putField

public void putField(LocalField field)
Upon entry the top word(s) on the stack is the value to be put into the field. Ie. we have
                word
                
Before the call we need
                word
                this
                word
                
word2,word1 -> word2, word1, word2 So that we are left with word after the put.

Specified by:
putField in interface MethodBuilder

putField

public void putField(java.lang.String fieldName,
                     java.lang.String fieldType)
Pop the top stack value and store it in the instance field of this class.

Specified by:
putField in interface MethodBuilder

putField

private void putField(Type fieldType,
                      int cpi)

putField

public void putField(java.lang.String declaringClass,
                     java.lang.String fieldName,
                     java.lang.String fieldType)
Pop the top stack value and store it in the field. This call requires the instance to be pushed by the caller.

Specified by:
putField in interface MethodBuilder

conditionalIfNull

public void conditionalIfNull()
Description copied from interface: MethodBuilder
Initiate a sequence that corresponds to the Java language 'ref == null ? ... : ...'. The top value on the stack (a reference) is popped and compared to 'null'. If the value is null then the code following this call until the startElseCode() will be executed at runtime, otherwise the code following startElseCode() until the completeConditional() is called.
E.g.
                mb.callMethod(...); // pushes an object onto the stack
                mb.conditionalIfNull();
                  mb.push(3);
                mb.startElseCode();
                  mb.push(5);
                mb.completeConditional();
                // at this point 3 or 5 will be on the stack
                
Each path through the ?: statement must leave the stack at the same depth as the other.
                Stack ...,ref =>
                      ...
                
.

Specified by:
conditionalIfNull in interface MethodBuilder

conditionalIf

public void conditionalIf()
Description copied from interface: MethodBuilder
Initiate a sequence that corresponds to the Java language ' value ? ... : ...'. The top value on the stack must be a boolean and will be popped. If it is true then the code following this call until the startElseCode() will be executed at runtime, otherwise the code following startElseCode() until the completeConditional() is called. See conditionalIfNull() for example.
                Stack ...,boolean_value =>
                      ...
                
.

Specified by:
conditionalIf in interface MethodBuilder

conditionalIf

private void conditionalIf(short opcode)

startElseCode

public void startElseCode()
Description copied from interface: MethodBuilder
Complete the true code path of a ?: operator.

Specified by:
startElseCode in interface MethodBuilder

completeConditional

public void completeConditional()
Description copied from interface: MethodBuilder
Complete the a ?: operator which completes the false code path.

Specified by:
completeConditional in interface MethodBuilder

endStatement

public void endStatement()
Description copied from interface: MethodBuilder
End a statement. Pops the top-word of the stack, if any. Must only be called if zero or one item exists on the stack.
                Stack value =>
                      :empty:
                or

                Stack :empty: =>
                      :empty:

                
.

Specified by:
endStatement in interface MethodBuilder

getArrayElement

public void getArrayElement(int element)
Description copied from interface: MethodBuilder
Pop an array refrence off the stack and push an element from that array.
                Stack ...,array_ref =>
                      ...,value
                

Specified by:
getArrayElement in interface MethodBuilder
Parameters:
element - Offset into the array (zero based)

setArrayElement

public void setArrayElement(int element)
Description copied from interface: MethodBuilder
Pop an array reference off the stack, store a value in the array at the passed in offset.
                Stack ...,array_ref, value =>
                      ...
                

Specified by:
setArrayElement in interface MethodBuilder
Parameters:
element - Offset into the array (zero based)

pushNewArray

public void pushNewArray(java.lang.String className,
                         int size)
Create an array instance Stack ... => ...,arrayref

Specified by:
pushNewArray in interface MethodBuilder
Parameters:
className - - type of array.
size - - number of elements in the array

statementNumHitLimit

public boolean statementNumHitLimit(int noStatementsAdded)
Tell if statement number in this method builder hits limit. This method builder keeps a counter of how many statements are added to it. Caller should call this function every time it tries to add a statement to this method builder (counter is increased by 1), then the function returns whether the accumulated statement number hits a limit. The reason of doing this is that Java compiler has a limit of 64K code size for each method. We might hit this limit if an extremely long insert statement is issued, for example (see beetle 4293). Counting statement number is an approximation without too much overhead.

Specified by:
statementNumHitLimit in interface MethodBuilder


Apache Derby V10.0 Engine Documentation - Copyright © 1997,2004 The Apache Software Foundation or its licensors, as applicable.