org.omegahat.Environment.Compile
Class DynamicCompiler

java.lang.Object
  |
  +--org.omegahat.Environment.Compile.DynamicCompiler
All Implemented Interfaces:
jas.RuntimeConstants
Direct Known Subclasses:
EvaluableInterfaceGenerator

public class DynamicCompiler
extends java.lang.Object
implements jas.RuntimeConstants

Basic class providing high-level methods for the Jas associated with the dynamic compilation of classes used in Omegahat for use with interpreted method dispatching and interpreted (function/expression) listeners.


Field Summary
static int BOTH
           
protected  jas.ClassEnv classDef
          The low-level Jas object representing this class definition, its methods and fields.
protected  java.lang.String className
          The simple name of the class being defined
protected  boolean debug
          Flag controlling whether debugging information is displayed during the construction of the byte-code for the new class.
static int GET
           
protected  java.io.File output
          Name of the file to which the byte-code for the newly generated class should be written
protected  java.lang.String packageName
          The name of the package in which this new class is being defined.
static int SET
           
protected  java.lang.String superClassName
          The name of the base class from which the new class is derived, defaulting to Object.
 
Fields inherited from interface jas.RuntimeConstants
ACC_ABSTRACT, ACC_FINAL, ACC_INTERFACE, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_SUPER, ACC_SYNCHRONIZED, ACC_TRANSIENT, ACC_VOLATILE, CONSTANT_CLASS, CONSTANT_DOUBLE, CONSTANT_FIELD, CONSTANT_FLOAT, CONSTANT_INTEGER, CONSTANT_INTERFACEMETHOD, CONSTANT_LONG, CONSTANT_METHOD, CONSTANT_NAMEANDTYPE, CONSTANT_STRING, CONSTANT_UNICODE, CONSTANT_UTF8, JAVA_MAGIC, JAVA_MINOR_VERSION, JAVA_VERSION, opc_aaload, opc_aastore, opc_aconst_null, opc_aload, opc_aload_0, opc_aload_1, opc_aload_2, opc_aload_3, opc_anewarray, opc_areturn, opc_arraylength, opc_astore, opc_astore_0, opc_astore_1, opc_astore_2, opc_astore_3, opc_athrow, opc_baload, opc_bastore, opc_bipush, opc_breakpoint, opc_caload, opc_castore, opc_checkcast, opc_d2f, opc_d2i, opc_d2l, opc_dadd, opc_daload, opc_dastore, opc_dcmpg, opc_dcmpl, opc_dconst_0, opc_dconst_1, opc_ddiv, opc_dead, opc_dload, opc_dload_0, opc_dload_1, opc_dload_2, opc_dload_3, opc_dmul, opc_dneg, opc_drem, opc_dreturn, opc_dstore, opc_dstore_0, opc_dstore_1, opc_dstore_2, opc_dstore_3, opc_dsub, opc_dup, opc_dup_x1, opc_dup_x2, opc_dup2, opc_dup2_x1, opc_dup2_x2, opc_f2d, opc_f2i, opc_f2l, opc_fadd, opc_faload, opc_fastore, opc_fcmpg, opc_fcmpl, opc_fconst_0, opc_fconst_1, opc_fconst_2, opc_fdiv, opc_fload, opc_fload_0, opc_fload_1, opc_fload_2, opc_fload_3, opc_fmul, opc_fneg, opc_frem, opc_freturn, opc_fstore, opc_fstore_0, opc_fstore_1, opc_fstore_2, opc_fstore_3, opc_fsub, opc_getfield, opc_getstatic, opc_goto, opc_goto_w, opc_i2b, opc_i2c, opc_i2d, opc_i2f, opc_i2l, opc_i2s, opc_iadd, opc_iaload, opc_iand, opc_iastore, opc_iconst_0, opc_iconst_1, opc_iconst_2, opc_iconst_3, opc_iconst_4, opc_iconst_5, opc_iconst_m1, opc_idiv, opc_if_acmpeq, opc_if_acmpne, opc_if_icmpeq, opc_if_icmpge, opc_if_icmpgt, opc_if_icmple, opc_if_icmplt, opc_if_icmpne, opc_ifeq, opc_ifge, opc_ifgt, opc_ifle, opc_iflt, opc_ifne, opc_ifnonnull, opc_ifnull, opc_iinc, opc_iload, opc_iload_0, opc_iload_1, opc_iload_2, opc_iload_3, opc_imul, opc_ineg, opc_instanceof, opc_int2byte, opc_int2char, opc_int2short, opc_invokeinterface, opc_invokenonvirtual, opc_invokespecial, opc_invokestatic, opc_invokevirtual, opc_ior, opc_irem, opc_ireturn, opc_ishl, opc_ishr, opc_istore, opc_istore_0, opc_istore_1, opc_istore_2, opc_istore_3, opc_isub, opc_iushr, opc_ixor, opc_jsr, opc_jsr_w, opc_l2d, opc_l2f, opc_l2i, opc_label, opc_ladd, opc_laload, opc_land, opc_lastore, opc_lcmp, opc_lconst_0, opc_lconst_1, opc_ldc, opc_ldc_w, opc_ldc2_w, opc_ldiv, opc_lload, opc_lload_0, opc_lload_1, opc_lload_2, opc_lload_3, opc_lmul, opc_lneg, opc_lookupswitch, opc_lor, opc_lrem, opc_lreturn, opc_lshl, opc_lshr, opc_lstore, opc_lstore_0, opc_lstore_1, opc_lstore_2, opc_lstore_3, opc_lsub, opc_lushr, opc_lxor, opc_monitorenter, opc_monitorexit, opc_multianewarray, opc_new, opc_newarray, opc_nop, opc_pop, opc_pop2, opc_putfield, opc_putstatic, opc_ret, opc_return, opc_saload, opc_sastore, opc_sipush, opc_swap, opc_tableswitch, opc_try, opc_wide, opc_xxxunusedxxx, opcLengths, opcNames, T_BOOLEAN, T_BYTE, T_CHAR, T_CLASS, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT
 
Constructor Summary
DynamicCompiler()
           
DynamicCompiler(jas.ClassEnv def)
          Create a new template compiler based on the class definition from the Jas compiler classes.
DynamicCompiler(java.lang.String name)
          Construct a template compiler for the specified class name with no package and no explicit base-class.
DynamicCompiler(java.lang.String name, java.lang.String packageName)
          Create a template compiler for a class in the specified package with the given name that has no explicit base class.
DynamicCompiler(java.lang.String name, java.lang.String superClass, boolean superName)
          Create a template compiler for the class with the specified name which extends the class identified by `superClass' and has no package.
DynamicCompiler(java.lang.String name, java.lang.String packageName, java.lang.String superClass)
          Create a template compiler for a class with the given `name', in the specified package whose base or parent class is specified by name via the argument superClass
 
Method Summary
 jas.CodeAttr accessorBody(java.lang.String name, java.lang.String className, boolean set, boolean isStatic)
          Create the code for the field accessor method for the specified field-name and class, indicating whether it is the set or get version.
 jas.CodeAttr accessorBody(java.lang.String name, java.lang.String className, boolean set, boolean isStatic, jas.CodeAttr code)
          Allows the instructions to be added to an existing CodeAttr so that we can have other instructions before these.
 jas.CodeAttr addConstructor(java.lang.reflect.Constructor c)
          This methods creates the byte-code for a particular constructor object, usually obtained from the base class from which this new class is being derived.
 jas.Var addField(java.lang.String name, java.lang.Class c)
          Add a protected field to the class being defined that has the given name and has the type given the type/class.
 jas.Var addField(java.lang.String name, java.lang.Class c, short permission)
          Define a field for this new class with the specified name and type using the given Class with the specified permission controlling whether the field is static or not and public, protected or private, synchronized.
 jas.Var addField(java.lang.String name, java.lang.String className)
          Add a field to the new class with the specified name and class represented by className specified with the enclosing L and ; identifying a class.
 jas.Var addField(java.lang.String name, java.lang.String className, short permission)
          The actual method that adds the field to the new class definition with the specified name and class, with the specified permission.
 jas.Var addField(java.lang.String name, java.lang.String className, short permission, boolean accessors)
           
 jas.Var addField(jas.Var var)
          Add a field defined by the Jas Var specification, including the name, type, etc.
 boolean addFieldAccessors(java.lang.String name, java.lang.String className)
          Default method to create the two accessors methods for the given field of the specified type, being defined in this new class.
 boolean addFieldAccessors(java.lang.String name, java.lang.String className, short fieldPermission)
          Add the two methods for the field accessors for the specified field
 boolean addFieldAccessors(java.lang.String name, java.lang.String className, short fieldPermission, int which)
           
 int addInheritedConstructors()
          Method to copy all the constructors from the base class into this one, implementing each one by simply calling the parent.
 boolean addReturn(java.lang.Class returnType, jas.CodeAttr code)
           
 boolean addReturn(java.lang.Class returnType, jas.CodeAttr code, boolean doConversion)
           
 jas.ClassEnv classDef()
          Retrieve the low-level class definition for this new object, creating it if it has not previously been constructed.
 jas.ClassEnv classDef(jas.ClassEnv e)
          Specify the low-level template for this class based on the name, package and base class for this new class.
 java.lang.String className()
          The name of the class being defined.
 java.lang.String className(java.lang.Class c)
          Conversion method for mapping a class name to a simple String as is needed when completing the Jas structures to define the class.
 java.lang.String className(java.lang.Class c, boolean asClass)
          Converts a Class to an appropriate string representation for use in generating byte-code using Jas.
 java.lang.String className(java.lang.String str)
          Set the name of the class being defined.
 boolean Debug()
          Return the current value of the flag indicating whether to display debugging information in the methods that generate the byte-code for the fields and methods of the new class.
 boolean Debug(boolean val)
          Set the flag controlling whether debugging information is displayed as the code for this class is generated.
 java.io.File file()
          The default file to which the byte code should be written.
 java.io.File file(java.io.File f)
          Set the default file to which the byte-code is written persistently.
 java.lang.Class findClass(Name n)
          Resolve the class specified by the single multi-element name.
 java.lang.Class findClass(java.lang.String n)
          Resolve the class identified in the string using the usual class resolution methods of the Evaluator
 jas.ClassEnv initClassDef()
          Create the Jas defining
 int loadCode(java.lang.Class c)
          Returns the operation code for loading an object of the specified class from a local variable, handling the different types of primitives and objects.
 java.lang.String mapPrimitive(java.lang.Class c)
          Returns a string representing the primitive class identified by the Class object if it is a primitive.
 java.lang.String packageName()
          The name of the package in which the new class is being defined.
 java.lang.String packageName(java.lang.String v)
          Sets the name of the package in which the class being defined.
 short primitiveLoadOp(java.lang.Class type)
          Returns an operation code corresponding to the instruction to load an object or primitive of the specified type.
 java.lang.String primitiveToClass(java.lang.Class type)
          Utility method that converts the specified class identifying a primitive class (double, int, etc.) to its corresponding object-based class (Double, Integer, etc.) This could be implemented using the static methods of the BasicEvaluator.
 boolean returnPrimitive(java.lang.Class returnType, jas.CodeAttr code)
          Add the necessary instructions to the specified code collection in order to return a primitive value of the specified type.
 boolean returnPrimitive(java.lang.Class returnType, jas.CodeAttr code, boolean doConversion)
          Sa
 java.lang.String superClassName()
          Returns the name of the base class from which this new class inherits.
 java.lang.String superClassName(java.lang.String name)
          Defines the name of the base class from which this new class inherits.
 boolean warning(java.lang.String msg)
          Display the specified warning message in a a extensible manner, in this case simply printing it to the standard error device.
 boolean write()
          Output the generated byte-code for the newly defined class to the default File, which is taken to be the name of the class if the file is not specified.
 boolean write(java.io.DataOutputStream stream)
          Lowest level write() method which actually writes the byte code to the specified output stream.
 boolean write(java.io.File f)
          Write the byte-code for the new class to the specified File.
 boolean write(java.io.OutputStream stream)
          Write the byte-code to a stream, which may be persistent or in-memory for dynamic loading of the class.
 boolean write(java.lang.String file)
          Write the byte-code for the newly compiled class to the file identified by the specified file name.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

GET

public static int GET

SET

public static int SET

BOTH

public static int BOTH

output

protected java.io.File output
Name of the file to which the byte-code for the newly generated class should be written

className

protected java.lang.String className
The simple name of the class being defined

packageName

protected java.lang.String packageName
The name of the package in which this new class is being defined.

classDef

protected jas.ClassEnv classDef
The low-level Jas object representing this class definition, its methods and fields.

debug

protected boolean debug
Flag controlling whether debugging information is displayed during the construction of the byte-code for the new class.

superClassName

protected java.lang.String superClassName
The name of the base class from which the new class is derived, defaulting to Object.
Constructor Detail

DynamicCompiler

public DynamicCompiler()

DynamicCompiler

public DynamicCompiler(java.lang.String name)
Construct a template compiler for the specified class name with no package and no explicit base-class.
Parameters:
name - name of the class

DynamicCompiler

public DynamicCompiler(java.lang.String name,
                       java.lang.String packageName)
Create a template compiler for a class in the specified package with the given name that has no explicit base class.
Parameters:
name - name of the class being compiled.
packageName - Java package name of which the new class is a member.

DynamicCompiler

public DynamicCompiler(java.lang.String name,
                       java.lang.String packageName,
                       java.lang.String superClass)
Create a template compiler for a class with the given `name', in the specified package whose base or parent class is specified by name via the argument superClass
Parameters:
name - name of the new class
packageName - name of the package in which the new class is to be defined.

DynamicCompiler

public DynamicCompiler(java.lang.String name,
                       java.lang.String superClass,
                       boolean superName)
Create a template compiler for the class with the specified name which extends the class identified by `superClass' and has no package.
Parameters:
name - name of the new class
superClass - name of the class from which this new class inherits methods and fields

DynamicCompiler

public DynamicCompiler(jas.ClassEnv def)
Create a new template compiler based on the class definition from the Jas compiler classes.
Method Detail

mapPrimitive

public java.lang.String mapPrimitive(java.lang.Class c)
Returns a string representing the primitive class identified by the Class object if it is a primitive.
Returns:
String of a single letter representing the primitive class or null when the specified class does not refer to a primitive.

className

public java.lang.String className(java.lang.Class c)
Conversion method for mapping a class name to a simple String as is needed when completing the Jas structures to define the class.
Parameters:
the - Class object whose name is being sought
Returns:
a version of the class name suitable for use in the Jas methods, in the form Lpackage/name; or a single letter in the case of a class corresponding to a primitive (double, int, etc.)

className

public java.lang.String className(java.lang.Class c,
                                  boolean asClass)
Converts a Class to an appropriate string representation for use in generating byte-code using Jas. This means that primitives are mapped to single character strings and regular classes are usually wrapped with the suffix "L" and ";".
Modified so that arrays are converted as described on page 156 of the The Java Virtual Machine Specification, Second Edition by Lindholm and Yellin.
Parameters:
c - the class to be represented by a string suitable for use in byte-code generation.
asClass - flag indicating whether to wrap a class with the "L" and ";"

className

public java.lang.String className()
The name of the class being defined.

className

public java.lang.String className(java.lang.String str)
Set the name of the class being defined. This replaces the package separators with directory separators.

initClassDef

public jas.ClassEnv initClassDef()
Create the Jas defining

write

public boolean write()
Output the generated byte-code for the newly defined class to the default File, which is taken to be the name of the class if the file is not specified.
Returns:
bolean indicating success or failure.

write

public boolean write(java.lang.String file)
Write the byte-code for the newly compiled class to the file identified by the specified file name.
Parameters:
file - name of the file
Returns:
flag indicating whether the output of the byte code was successful or not.

write

public boolean write(java.io.File f)
Write the byte-code for the new class to the specified File. This is used for permanent storage, in contrast to writing to a buffer for dynamic loading during within an application or Omegahat session.
Parameters:
f - file to which byte code is written.
Returns:
success or failure of the byte-code generation and write to the file.

write

public boolean write(java.io.OutputStream stream)
Write the byte-code to a stream, which may be persistent or in-memory for dynamic loading of the class.
Parameters:
stream - output stream to which byte code is written.

write

public boolean write(java.io.DataOutputStream stream)
Lowest level write() method which actually writes the byte code to the specified output stream.

warning

public boolean warning(java.lang.String msg)
Display the specified warning message in a a extensible manner, in this case simply printing it to the standard error device.

file

public java.io.File file()
The default file to which the byte code should be written. For dynamically loaded classes, this is not used.

file

public java.io.File file(java.io.File f)
Set the default file to which the byte-code is written persistently.

classDef

public jas.ClassEnv classDef()
Retrieve the low-level class definition for this new object, creating it if it has not previously been constructed.
See Also:
initClassDef()

classDef

public jas.ClassEnv classDef(jas.ClassEnv e)
Specify the low-level template for this class based on the name, package and base class for this new class.

packageName

public java.lang.String packageName()
The name of the package in which the new class is being defined.

packageName

public java.lang.String packageName(java.lang.String v)
Sets the name of the package in which the class being defined. This replaces the package separators with directory separators.

Debug

public boolean Debug()
Return the current value of the flag indicating whether to display debugging information in the methods that generate the byte-code for the fields and methods of the new class.

Debug

public boolean Debug(boolean val)
Set the flag controlling whether debugging information is displayed as the code for this class is generated.

superClassName

public java.lang.String superClassName()
Returns the name of the base class from which this new class inherits.

superClassName

public java.lang.String superClassName(java.lang.String name)
Defines the name of the base class from which this new class inherits.

addInheritedConstructors

public int addInheritedConstructors()
Method to copy all the constructors from the base class into this one, implementing each one by simply calling the parent.

addConstructor

public jas.CodeAttr addConstructor(java.lang.reflect.Constructor c)
This methods creates the byte-code for a particular constructor object, usually obtained from the base class from which this new class is being derived. The new constructor simply calls super(a1,a2,...,ak) where ai is the parameter corresponding to the one in the base constructor, with an identical class specification.

primitiveLoadOp

public short primitiveLoadOp(java.lang.Class type)
Returns an operation code corresponding to the instruction to load an object or primitive of the specified type. This handles the case of two-word values that have to be handled "carefully".

findClass

public java.lang.Class findClass(Name n)
                          throws java.lang.ClassNotFoundException
Resolve the class specified by the single multi-element name. This uses the default evaluator stored in the Globals class.
Parameters:
n - the name of the class with one or more components of the Java package and class name.

findClass

public java.lang.Class findClass(java.lang.String n)
                          throws java.lang.ClassNotFoundException
Resolve the class identified in the string using the usual class resolution methods of the Evaluator

addReturn

public boolean addReturn(java.lang.Class returnType,
                         jas.CodeAttr code,
                         boolean doConversion)
                  throws jas.jasError

addReturn

public boolean addReturn(java.lang.Class returnType,
                         jas.CodeAttr code)
                  throws jas.jasError

returnPrimitive

public boolean returnPrimitive(java.lang.Class returnType,
                               jas.CodeAttr code)
                        throws jas.jasError
Add the necessary instructions to the specified code collection in order to return a primitive value of the specified type.
Parameters:
returnType - the class of the value being returned, coming from the collection of primitive classes.
code - code object containing the instructions of the method so far.
Returns:
boolean indicating whether the addition of the appropriate instructions was successful. (Very little error checking done at this point, so generally this is true.)
See Also:
#handleReturnType()

returnPrimitive

public boolean returnPrimitive(java.lang.Class returnType,
                               jas.CodeAttr code,
                               boolean doConversion)
                        throws jas.jasError
Sa

primitiveToClass

public java.lang.String primitiveToClass(java.lang.Class type)
Utility method that converts the specified class identifying a primitive class (double, int, etc.) to its corresponding object-based class (Double, Integer, etc.) This could be implemented using the static methods of the BasicEvaluator.

addField

public jas.Var addField(jas.Var var)
Add a field defined by the Jas Var specification, including the name, type, etc.

addField

public jas.Var addField(java.lang.String name,
                        java.lang.Class c)
Add a protected field to the class being defined that has the given name and has the type given the type/class. The class is converted to the appropriate named and passed to addField(String,String).

addField

public jas.Var addField(java.lang.String name,
                        java.lang.Class c,
                        short permission)
Define a field for this new class with the specified name and type using the given Class with the specified permission controlling whether the field is static or not and public, protected or private, synchronized. The specification of the permission is created by or'ing the appropriate constants from the Jas Constants class.

addField

public jas.Var addField(java.lang.String name,
                        java.lang.String className)
Add a field to the new class with the specified name and class represented by className specified with the enclosing L and ; identifying a class.

addField

public jas.Var addField(java.lang.String name,
                        java.lang.String className,
                        short permission)
The actual method that adds the field to the new class definition with the specified name and class, with the specified permission.

addField

public jas.Var addField(java.lang.String name,
                        java.lang.String className,
                        short permission,
                        boolean accessors)

addFieldAccessors

public boolean addFieldAccessors(java.lang.String name,
                                 java.lang.String className)
Default method to create the two accessors methods for the given field of the specified type, being defined in this new class.

addFieldAccessors

public boolean addFieldAccessors(java.lang.String name,
                                 java.lang.String className,
                                 short fieldPermission)
Add the two methods for the field accessors for the specified field
Parameters:
name - name of the field for which the accesors are being defined.
className - class of the field.
fieldPermission - ignored!, as the accessors are made public.

addFieldAccessors

public boolean addFieldAccessors(java.lang.String name,
                                 java.lang.String className,
                                 short fieldPermission,
                                 int which)

accessorBody

public jas.CodeAttr accessorBody(java.lang.String name,
                                 java.lang.String className,
                                 boolean set,
                                 boolean isStatic)
Create the code for the field accessor method for the specified field-name and class, indicating whether it is the set or get version. This defines the code segment
public type name() {
return(name);
}
or
public type name(type v) {
name = v;
return(name());
}

accessorBody

public jas.CodeAttr accessorBody(java.lang.String name,
                                 java.lang.String className,
                                 boolean set,
                                 boolean isStatic,
                                 jas.CodeAttr code)
Allows the instructions to be added to an existing CodeAttr so that we can have other instructions before these.

loadCode

public int loadCode(java.lang.Class c)
Returns the operation code for loading an object of the specified class from a local variable, handling the different types of primitives and objects.