korat.instrumentation
Class ArrayGenerator

java.lang.Object
  extended by korat.instrumentation.ArrayGenerator

public class ArrayGenerator
extends Object

ArrayGenerator is used to generate Korat Array classes. They are used during the instrumentation, as a suitable replacement for standard array classes.

Korat Arrays implement IKoratArray interface, that can distinguish them among other classes.

The template for Korat Array classes is the given in following methods, which do parts of instrumentation. Parameters that are changed for each different type of arrays are printed in bold. Here, the interface is listed:

 public class static class Korat_Array_Type implements IKoratArray {
 
      static class Korat_Array_Type_Element_Setter extends Setter {...}
      static class Korat_Array_Type_Length_Setter extends Setter {...}
      
      korat.testing.ITester tester;
      
      Type[] values;
      int[] values_ids;
      
      int length;
      int length_id;

      public Korat_Array_Type (int maxSize);
      public setTester(korat.testing.ITester tester);
      
      public Setter get_element_setter(int position, int field_id);
      public Type get(int index);
      public void set(int position, Korat_Array_Type newValue);
      public Object [] getValues();
      
      public Setter get_length_setter(int field_id);
      public int getLength(int index);
      public void setLength(int newValue);
      
      // + methods that implement IKoratTouchable (if required)
 }
 
ArrayGenerator is initialized with type of array for which a KoratArray

Author:
Sasa Misailovic
See Also:
IKoratArray, IInstrumenter, createArrayElementMethods(CtClass), createArrayElementSetter(CtClass), createInitializers(CtClass), createFields(CtClass), createLengthMethods(CtClass), createLengthSetter(CtClass)

Field Summary
private static String _ELEMENT_SETTER
           
static String _LENGTH_SETTER
           
static String ARRAY_FULLNAME_PREFIX
           
private  CtClass arrayType
           
private  String className
           
private  CtClass componentType
           
private  ClassPool cp
           
(package private) static Map<String,Class> generatedClasses
           
static String GET_ELEMENT_SETTER_METHOD_NAME
           
static String GET_LENGTH_SETTER_METHOD_NAME
           
private static CtClass indexType
           
private  boolean TRACE
           
 
Constructor Summary
ArrayGenerator(Class arrayType)
           
ArrayGenerator(CtClass arrayType)
          Creates korat array for the given type of array, which is represented as javassist CtClass.
 
Method Summary
protected  String addTrace(String msg)
          Used to show debug messages inside the generated classes This instrumentation is applied only if trace flag is set.
protected  void createArrayElementMethods(CtClass clz)
          Creates methods for KoratArray class, that manipulate array values.
protected  CtClass createArrayElementSetter(CtClass clz)
          Creates setter classes for array values (elements of values array).
protected  void createFields(CtClass clz)
          Generates fields for the KoratArray classes.
protected  void createInitializers(CtClass clz)
          Creates constructor and initializer for the KoratArray.
protected  void createLengthMethods(CtClass clz)
          Creates methods for KoratArray class, that manipulate array length.
protected  CtClass createLengthSetter(CtClass clz)
          Creates setter classes for array length.
protected  CtClass[] generateKoratArray()
          Generates the CtClass object, representing the Korat Array and all its inner classes
 Class<?> getArrayClass()
          Gets the the class file for korat array.
 String getArrayClassName()
           
static String getArrayClassName(String componentName)
           
 CtClass getArrayCtClass()
           
 CtClass[] getArrayCtClasses()
          Gets CtArrayClass [] containing korat array at position [0] and all its inner classes, if created for the first time
private  String getPrimitiveClassCounterpart(String primitiveClassName)
          Returns name of the wrapper class corresponding to the primitive type
protected  void implementIKoratTouchableInterface(CtClass clz)
          Implements IKoratTouchable interface by creating one field and two methods, specified by this interface //*actual field and method names may be different boolean koratTouched; public void __korat__touch__initialize() { if (!
protected  void setImplementedInterfaces(CtClass clz)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_ELEMENT_SETTER

private static final String _ELEMENT_SETTER
See Also:
Constant Field Values

_LENGTH_SETTER

public static final String _LENGTH_SETTER
See Also:
Constant Field Values

ARRAY_FULLNAME_PREFIX

public static final String ARRAY_FULLNAME_PREFIX
See Also:
Constant Field Values

GET_LENGTH_SETTER_METHOD_NAME

public static final String GET_LENGTH_SETTER_METHOD_NAME
See Also:
Constant Field Values

GET_ELEMENT_SETTER_METHOD_NAME

public static final String GET_ELEMENT_SETTER_METHOD_NAME
See Also:
Constant Field Values

generatedClasses

static Map<String,Class> generatedClasses

TRACE

private boolean TRACE

cp

private ClassPool cp

arrayType

private CtClass arrayType

componentType

private CtClass componentType

className

private String className

indexType

private static final CtClass indexType
Constructor Detail

ArrayGenerator

public ArrayGenerator(CtClass arrayType)
               throws NotFoundException
Creates korat array for the given type of array, which is represented as javassist CtClass. It must represent array type e.g. int[].class, Object[].class

Parameters:
arrayType - - Array type for which this
Throws:
NotFoundException - - given array type does not exist
See Also:
ArrayGenerator(Class)

ArrayGenerator

public ArrayGenerator(Class arrayType)
               throws NotFoundException
Throws:
NotFoundException
Method Detail

addTrace

protected String addTrace(String msg)
Used to show debug messages inside the generated classes This instrumentation is applied only if trace flag is set.

Parameters:
msg - - debug message
Returns:
string to prepend to method's source code

getArrayClassName

public String getArrayClassName()
Returns:
the class name array

getArrayClassName

public static String getArrayClassName(String componentName)
Parameters:
componentName - name of the component type
Returns:
the name of array class that corresponds to the given type of components

generateKoratArray

protected CtClass[] generateKoratArray()
                                throws CannotCompileException,
                                       NotFoundException
Generates the CtClass object, representing the Korat Array and all its inner classes

Returns:
- array of CtClasses, the first of which is the KoratArray class followed by its inner classes
Throws:
CannotCompileException
NotFoundException

setImplementedInterfaces

protected void setImplementedInterfaces(CtClass clz)

getArrayClass

public Class<?> getArrayClass()
Gets the the class file for korat array. If this Korat array hasn't been generated before, it will be generated. Otherwise it is returned from the javassist repository.

Returns:
class file for korat array
See Also:
generateKoratArray(), getArrayCtClasses()

getArrayCtClasses

public CtClass[] getArrayCtClasses()
                            throws CannotCompileException,
                                   NotFoundException
Gets CtArrayClass [] containing korat array at position [0] and all its inner classes, if created for the first time

Returns:
korat array (at position 0) and all its inner classes, if created for the first time
Throws:
NotFoundException
CannotCompileException
See Also:
getArrayClass(), generateKoratArray()

getArrayCtClass

public CtClass getArrayCtClass()
Returns:
CtClass for the KoratArray.

createFields

protected void createFields(CtClass clz)
                     throws CannotCompileException,
                            NotFoundException
Generates fields for the KoratArray classes. Fields are given in the following table.
Field Description
Type[] values represents values stored in array object
int[] values_ids represents field identifiers for corresponding values elements
int length represents the actual length of the array
int length_id represents field identifier for the length
korat.testing.ITester tester object to which the field accesses will be reported

For detailed explanation on purpose of _id fields, please see FieldInstrumenter class.

Throws:
CannotCompileException
NotFoundException
See Also:
FieldInstrumenter

createInitializers

protected void createInitializers(CtClass clz)
                           throws CannotCompileException,
                                  NotFoundException
Creates constructor and initializer for the KoratArray. Constructor prototype is the following:
      public Korat_Array_Type (int maxSize)
  
Argument maxSize represents the maximal size array object can have The body of this constructor is:
  public Korat_Array_Type (int maxSize){
    values = new Type [maxSize];  
    values_ids = new int[maxSize];  
    length = maxSize; 
    for (int i = 0; i < maxSize; i++) 
       values_ids[i] = -1;
  }
 
Method setTester allows initialization of KoratArray with arbitrary ITester object.
      public void setTester(korat.testing.ITester tester) {
         this.tester = tester;
      }
 
 

Throws:
CannotCompileException
NotFoundException

createArrayElementSetter

protected CtClass createArrayElementSetter(CtClass clz)
                                    throws NotFoundException,
                                           CannotCompileException
Creates setter classes for array values (elements of values array). Setter class is the static inner class of Korat_Array_Type
 static class _Element_Setter extends Setter{
      // pointer to the owner object of the _element_setter_class
      // this class couldn't be implemented as non static inner class
      // since javassist doesn't allow it
      Korat_Array_Type _this;    
      
      int position;   // element position inside values array
      
      _Element_Setter(KoratArray_Type owner, int pos) {
          _this = owner;
          position = pos;
      }
      
      // for primitive types only :: 
      // sets the new value, overrides the corresponding set method from Setter class
      void set(Type newValue) {
          _this.values[position] = newValue;
      }
      
      // for other types :: 
      // sets the new value, overrides the corresponding set method from Setter class      
      void set(Object newValue) {
          _this.values[position] = (Type)newValue;
      }
 }
 

Throws:
NotFoundException
CannotCompileException

createArrayElementMethods

protected void createArrayElementMethods(CtClass clz)
                                  throws CannotCompileException,
                                         NotFoundException
Creates methods for KoratArray class, that manipulate array values.
 //Used to initialize KoratArray, sets field_id for array elements, 
 //and returns corresponding setters
 public Setter get_element_setter(int position, int field_id) {
      values_ids[position] = field_id;
      return new _Element_Setter(this, position);
 }
  
 // Returns the value of the index'th element of an array
 public Type get(int index) {
      tester.notifyFieldAccess(values_ids[index]);
      return values[index];
 }
 
 // Sets the value of the array element at position position. 
 public void set(int position, Korat_Array_Type newValue) {
      if (index >= length)
          throw new IndexOutOfBoundsException();     * 
      values[position] = newValue;
 }
 
 // Returns element at position index; this is part of IKoratArray interface,
 // used by Korat internally, instead of java reflection
 public Object getValue(int index) {
      if (index >= length)
          throw new IndexOutOfBoundsException();
      // For Primitive Types:
      return new TypeWrapper values[index];
      // ---------------------
      // For other types
      return values[index];
 }
 

Throws:
CannotCompileException
NotFoundException

createLengthSetter

protected CtClass createLengthSetter(CtClass clz)
                              throws NotFoundException,
                                     CannotCompileException
Creates setter classes for array length. Setter class is the static inner class of Korat_Array_Type
 static class _Length_Setter extends Setter{
      // pointer to the owner object of the _length_setter class
      Korat_Array_Type _this;    
      
      int position;   // element position inside values array
      
      _Length_Setter(KoratArray_Type owner, int pos) {
          _this = owner;
      }
      
      // sets the new value, overrides the corresponding set method from Setter class
      void set(Type newLength) {
          _this.length = newLength;
      }
 }
 

Throws:
NotFoundException
CannotCompileException

createLengthMethods

protected void createLengthMethods(CtClass clz)
                            throws CannotCompileException
Creates methods for KoratArray class, that manipulate array length.
 //Used in initialization of KoratArray, sets field_id for array length, 
 //and returns corresponding setter
 public Setter get_length_setter(int field_id) {
      length_id = field_id;
      return new _Length_Setter(this);
 }
  
 // Returns the value of the array length
 public int getLength(int index) {
      tester.notifyFieldAccess(length_id]);
      return length;
 }
 
 // Sets the value of the array element at position position. 
 public void setLength(int newValue) {
      length = newValue;
 }
 

Throws:
CannotCompileException

implementIKoratTouchableInterface

protected void implementIKoratTouchableInterface(CtClass clz)
Implements IKoratTouchable interface by creating one field and two methods, specified by this interface
  //*actual field and method names may be different 
  
  boolean koratTouched;  
   
  public void __korat__touch__initialize() {
    if (!koratTouched)  
      return;
    
    koratTouched = false;
  }
   
  public void __korat__touch() {
    if (koratTouched)
      return;
      
    koratTouched = true;
    
    for (int i = 0; i < length; i++)
      get(i);
    getLength();
    
    for (int i = 0; i < length; i++)
      if (values[i] && values[i] instanceOf KoratTouchable)
        ((KoratTouchable) values[i]).__korat__touch();
  }
 

Parameters:
clz -
See Also:
IKoratTouchable

getPrimitiveClassCounterpart

private String getPrimitiveClassCounterpart(String primitiveClassName)
Returns name of the wrapper class corresponding to the primitive type

Parameters:
primitiveClassName - - name of primitive class (boolean, byte, char, double, float, int, long, short)
Returns:
- name of its object counterpart (Boolean, Byte, Character, Double, Float, Integer, Long, Short)