Top Description Inners Fields Constructors Methods
bsh

public Class ClassGeneratorUtil

extends Object
implements bsh.org.objectweb.asm.Constants
Class Inheritance
Imports
bsh.org.objectweb.asm.*, bsh.org.objectweb.asm.Type, java.lang.reflect.*, java.util.ArrayList, .List, java.io.*

ClassGeneratorUtil utilizes the ASM (www.objectweb.org) bytecode generator by Eric Bruneton in order to generate class "stubs" for BeanShell at runtime.

Stub classes contain all of the fields of a BeanShell scripted class as well as two "callback" references to BeanShell namespaces: one for static methods and one for instance methods. Methods of the class are delegators which invoke corresponding methods on either the static or instance bsh object and then unpack and return the results. The static namespace utilizes a static import to delegate variable access to the class' static fields. The instance namespace utilizes a dynamic import (i.e. mixin) to delegate variable access to the class' instance variables.

Constructors for the class delegate to the static initInstance() method of ClassGeneratorUtil to initialize new instances of the object. initInstance() invokes the instance intializer code (init vars and instance blocks) and then delegates to the corresponding scripted constructor method in the instance namespace. Constructors contain special switch logic which allows the BeanShell to control the calling of alternate constructors (this() or super() references) at runtime.

Specially named superclass delegator methods are also generated in order to allow BeanShell to access overridden methods of the superclass (which reflection does not normally allow).

Author
Pat Niemeyer

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static class
ClassGeneratorUtil.ConstructorArgs

A ConstructorArgs object holds evaluated arguments for a constructor call as well as the index of a possible alternate selector to invoke.

Field Summary

Modifier and TypeField and Description
pack-priv static final String
BSHCONSTRUCTORS

The bsh static namespace variable that holds the constructor methods

pack-priv static final String
BSHINIT

The bsh static namespace variable name of the instance initializer

pack-priv static final String
BSHSTATIC

The name of the static field holding the reference to the bsh static This (the callback namespace for static methods)

pack-priv static final String
BSHSUPER

The prefix for the name of the super delegate methods.

pack-priv static final String
BSHTHIS

The name of the instance field holding the reference to the bsh instance This (the callback namespace for instance methods)

pack-priv Modifiers
pack-priv String
pack-priv NameSpace
pack-priv DelayedEvalBshMethod[]
pack-priv static final int
DEFAULTCONSTRUCTOR

The switch branch number for the default constructor.

pack-priv String
fqClassName

fully qualified class name (with package) e.g. foo/bar/Blah

pack-priv Class<T>[]
pack-priv boolean
pack-priv DelayedEvalBshMethod[]
pack-priv static final String
pack-priv Class<T>
pack-priv String
pack-priv Constructor<T>[]
pack-priv Variable[]

Constructor Summary

AccessConstructor and Description
public
ClassGeneratorUtil(Modifiers classModifiers, String className, String
e.g. "com.foo.bar"
packageName
,
Class<T> superClass, Class<T>[] interfaces, Variable[] vars, DelayedEvalBshMethod[] bshmethods, NameSpace classStaticNameSpace, boolean isInterface)

Method Summary

Modifier and TypeMethod and Description
pack-priv boolean
classContainsMethod(Class<T> clas, String methodName, String[] paramTypes)

private static String
descriptorToClassName(String s)

If a non-array object type, remove the prefix "L" and suffix ";".

pack-priv static void
doSwitchBranch(int index, String targetClassName, String[] paramTypes, bsh.org.objectweb.asm.Label endLabel, bsh.org.objectweb.asm.Label[] labels, int consArgsVar, bsh.org.objectweb.asm.CodeVisitor cv)

public byte[]
generateClass()

Generate the class bytecode for this class.

pack-priv void
generateConstructor(int index, String[] paramTypes, int modifiers, bsh.org.objectweb.asm.ClassWriter cw)

Generate a constructor.

pack-priv void
generateConstructorSwitch(int consIndex, int argsVar, int consArgsVar, bsh.org.objectweb.asm.CodeVisitor cv)

Generate a switch with a branch for each possible alternate constructor.

pack-priv static void
generateField(String fieldName, String type, int modifiers, bsh.org.objectweb.asm.ClassWriter cw)

Generate a field - static or instance.

pack-priv static void
generateMethod(String className, String fqClassName, String methodName, String returnType, String[] paramTypes, int modifiers, bsh.org.objectweb.asm.ClassWriter cw)

Generate a delegate method - static or instance.

public static void
generateParameterReifierCode(String[] paramTypes, boolean
the enclosing methods is static
isStatic
,
final bsh.org.objectweb.asm.CodeVisitor
the code visitor to be used to generate the bytecode.
cv
)

Generates the code to reify the arguments of the given method.

pack-priv static void
generatePlainReturnCode(String returnType, bsh.org.objectweb.asm.CodeVisitor cv)

Generate return code for a normal bytecode

public static void
generateReturnCode(String returnType, bsh.org.objectweb.asm.CodeVisitor
the code visitor to be used to generate the bytecode.
cv
)

Generates the code to unreify the result of the given method.

pack-priv static void
generateSuperDelegateMethod(String superClassName, String methodName, String returnType, String[] paramTypes, int modifiers, bsh.org.objectweb.asm.ClassWriter cw)

Generate a superclass method delegate accessor method.

pack-priv static int
getASMModifiers(Modifiers modifiers)

Translate bsh.Modifiers into ASM modifier bitflags.

private static String
getBaseName(String className)

pack-priv static This

Returns:

the class instance This object or null if the object has not been initialized.
getClassInstanceThis
(Object instance, String className)

Get the instance bsh namespace field from the object instance.

pack-priv static This
getClassStaticThis(Class<T> clas, String
may be the name of clas itself or a superclass of clas.
className
)

Get the static bsh namespace field from the class.

public static ClassGeneratorUtil.ConstructorArgs

Returns:

the ConstructorArgs object containing a constructor selector and evaluated arguments for the alternate constructor
getConstructorArgs
(String superClassName, This classStaticThis, Object[]
the arguments to the constructor. These are necessary in the evaluation of the alt constructor args. e.g. Foo(a) { super(a); }
consArgs
,
int index)

Evaluate the arguments (if any) for the constructor specified by the constructor index.

pack-priv static String
getMethodDescriptor(String returnType, String[] paramTypes)

pack-priv static String[]
getTypeDescriptors(Class<T>[] cparams)

public static void
initInstance(Object instance, String className, Object[] args)

Initialize an instance of the class.

private static boolean
isPrimitive(String typeDescriptor)

Does the type descriptor string describe a primitive type?

public static void
startInterpreterForClass(Class<T> clas)

Attempt to load a script named for the class: e.g. Foo.class Foo.bsh.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

BSHCONSTRUCTORSback to summary
pack-priv static final String BSHCONSTRUCTORS

The bsh static namespace variable that holds the constructor methods

BSHINITback to summary
pack-priv static final String BSHINIT

The bsh static namespace variable name of the instance initializer

BSHSTATICback to summary
pack-priv static final String BSHSTATIC

The name of the static field holding the reference to the bsh static This (the callback namespace for static methods)

BSHSUPERback to summary
pack-priv static final String BSHSUPER

The prefix for the name of the super delegate methods. e.g. _bshSuperfoo() is equivalent to super.foo()

BSHTHISback to summary
pack-priv static final String BSHTHIS

The name of the instance field holding the reference to the bsh instance This (the callback namespace for instance methods)

classModifiersback to summary
pack-priv Modifiers classModifiers
classNameback to summary
pack-priv String className
classStaticNameSpaceback to summary
pack-priv NameSpace classStaticNameSpace
constructorsback to summary
pack-priv DelayedEvalBshMethod[] constructors
DEFAULTCONSTRUCTORback to summary
pack-priv static final int DEFAULTCONSTRUCTOR

The switch branch number for the default constructor. The value -1 will cause the default branch to be taken.

fqClassNameback to summary
pack-priv String fqClassName

fully qualified class name (with package) e.g. foo/bar/Blah

interfacesback to summary
pack-priv Class<T>[] interfaces
isInterfaceback to summary
pack-priv boolean isInterface
methodsback to summary
pack-priv DelayedEvalBshMethod[] methods
OBJECTback to summary
pack-priv static final String OBJECT
superClassback to summary
pack-priv Class<T> superClass
superClassNameback to summary
pack-priv String superClassName
superConstructorsback to summary
pack-priv Constructor<T>[] superConstructors
varsback to summary
pack-priv Variable[] vars

Constructor Detail

ClassGeneratorUtilback to summary
public ClassGeneratorUtil(Modifiers classModifiers, String className, String packageName, Class<T> superClass, Class<T>[] interfaces, Variable[] vars, DelayedEvalBshMethod[] bshmethods, NameSpace classStaticNameSpace, boolean isInterface)
Parameters
packageName:String

e.g. "com.foo.bar"

Method Detail

classContainsMethodback to summary
pack-priv boolean classContainsMethod(Class<T> clas, String methodName, String[] paramTypes)
descriptorToClassNameback to summary
private static String descriptorToClassName(String s)

If a non-array object type, remove the prefix "L" and suffix ";".

doSwitchBranchback to summary
pack-priv static void doSwitchBranch(int index, String targetClassName, String[] paramTypes, bsh.org.objectweb.asm.Label endLabel, bsh.org.objectweb.asm.Label[] labels, int consArgsVar, bsh.org.objectweb.asm.CodeVisitor cv)
generateClassback to summary
public byte[] generateClass()

Generate the class bytecode for this class.

generateConstructorback to summary
pack-priv void generateConstructor(int index, String[] paramTypes, int modifiers, bsh.org.objectweb.asm.ClassWriter cw)

Generate a constructor.

generateConstructorSwitchback to summary
pack-priv void generateConstructorSwitch(int consIndex, int argsVar, int consArgsVar, bsh.org.objectweb.asm.CodeVisitor cv)

Generate a switch with a branch for each possible alternate constructor. This includes all superclass constructors and all constructors of this class. The default branch of this switch is the default superclass constructor.

This method also generates the code to call the static ClassGeneratorUtil getConstructorArgs() method which inspects the scripted constructor to find the alternate constructor signature (if any) and evalute the arguments at runtime. The getConstructorArgs() method returns the actual arguments as well as the index of the constructor to call.

generateFieldback to summary
pack-priv static void generateField(String fieldName, String type, int modifiers, bsh.org.objectweb.asm.ClassWriter cw)

Generate a field - static or instance.

generateMethodback to summary
pack-priv static void generateMethod(String className, String fqClassName, String methodName, String returnType, String[] paramTypes, int modifiers, bsh.org.objectweb.asm.ClassWriter cw)

Generate a delegate method - static or instance. The generated code packs the method arguments into an object array (wrapping primitive types in bsh.Primitive), invokes the static or instance namespace invokeMethod() method, and then unwraps / returns the result.

generateParameterReifierCodeback to summary
public static void generateParameterReifierCode(String[] paramTypes, boolean isStatic, final bsh.org.objectweb.asm.CodeVisitor cv)

Generates the code to reify the arguments of the given method. For a method "int m (int i, String s)", this code is the bytecode corresponding to the "new Object[] { new bsh.Primitive(i), s }" expression.

Parameters
isStatic:boolean

the enclosing methods is static

cv:bsh.org.objectweb.asm.CodeVisitor

the code visitor to be used to generate the bytecode.

Authors
Eric Bruneton, Pat Niemeyer
generatePlainReturnCodeback to summary
pack-priv static void generatePlainReturnCode(String returnType, bsh.org.objectweb.asm.CodeVisitor cv)

Generate return code for a normal bytecode

generateReturnCodeback to summary
public static void generateReturnCode(String returnType, bsh.org.objectweb.asm.CodeVisitor cv)

Generates the code to unreify the result of the given method. For a method "int m (int i, String s)", this code is the bytecode corresponding to the "((Integer)...).intValue()" expression.

Parameters
cv:bsh.org.objectweb.asm.CodeVisitor

the code visitor to be used to generate the bytecode.

Authors
Eric Bruneton, Pat Niemeyer
generateSuperDelegateMethodback to summary
pack-priv static void generateSuperDelegateMethod(String superClassName, String methodName, String returnType, String[] paramTypes, int modifiers, bsh.org.objectweb.asm.ClassWriter cw)

Generate a superclass method delegate accessor method. These methods are specially named methods which allow access to overridden methods of the superclass (which the Java reflection API normally does not allow).

getASMModifiersback to summary
pack-priv static int getASMModifiers(Modifiers modifiers)

Translate bsh.Modifiers into ASM modifier bitflags.

getBaseNameback to summary
private static String getBaseName(String className)
getClassInstanceThisback to summary
pack-priv static This getClassInstanceThis(Object instance, String className)

Get the instance bsh namespace field from the object instance.

Returns:This

the class instance This object or null if the object has not been initialized.

getClassStaticThisback to summary
pack-priv static This getClassStaticThis(Class<T> clas, String className)

Get the static bsh namespace field from the class.

Parameters
className:String

may be the name of clas itself or a superclass of clas.

getConstructorArgsback to summary
public static ClassGeneratorUtil.ConstructorArgs getConstructorArgs(String superClassName, This classStaticThis, Object[] consArgs, int index)

Evaluate the arguments (if any) for the constructor specified by the constructor index. Return the ConstructorArgs object which contains the actual arguments to the alternate constructor and also the index of that constructor for the constructor switch.

Parameters
consArgs:Object[]

the arguments to the constructor. These are necessary in the evaluation of the alt constructor args. e.g. Foo(a) { super(a); }

Returns:ClassGeneratorUtil.ConstructorArgs

the ConstructorArgs object containing a constructor selector and evaluated arguments for the alternate constructor

getMethodDescriptorback to summary
pack-priv static String getMethodDescriptor(String returnType, String[] paramTypes)
getTypeDescriptorsback to summary
pack-priv static String[] getTypeDescriptors(Class<T>[] cparams)
initInstanceback to summary
public static void initInstance(Object instance, String className, Object[] args)

Initialize an instance of the class. This method is called from the **generated class** constructor to evaluate the instance initializer and scripted constructor in the instance namespace.

isPrimitiveback to summary
private static boolean isPrimitive(String typeDescriptor)

Does the type descriptor string describe a primitive type?

startInterpreterForClassback to summary
public static void startInterpreterForClass(Class<T> clas)

Attempt to load a script named for the class: e.g. Foo.class Foo.bsh. The script is expected to (at minimum) initialize the class body. That is, it should contain the scripted class definition. This method relies on the fact that the ClassGenerator generateClass() method will detect that the generated class already exists and initialize it rather than recreating it.

bsh back to summary

public Class ClassGeneratorUtil.ConstructorArgs

extends Object
Class Inheritance

A ConstructorArgs object holds evaluated arguments for a constructor call as well as the index of a possible alternate selector to invoke. This object is used by the constructor switch.
See Also
generateConstructor(int , String [] , int , ClassWriter)

Field Summary

Modifier and TypeField and Description
pack-priv int
pack-priv Object[]
public static ClassGeneratorUtil.ConstructorArgs
DEFAULT

A ConstructorArgs which calls the default constructor

public int

Constructor Summary

AccessConstructor and Description
pack-priv
ConstructorArgs()

The index of the constructor to call.

pack-priv
ConstructorArgs(int selector, Object[] args)

Method Summary

Modifier and TypeMethod and Description
public boolean
public byte
public char
public double
public float
public int
public long
public Object
public short
pack-priv Object
next()

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

argback to summary
pack-priv int arg
argsback to summary
pack-priv Object[] args
DEFAULTback to summary
public static ClassGeneratorUtil.ConstructorArgs DEFAULT

A ConstructorArgs which calls the default constructor

selectorback to summary
public int selector

Constructor Detail

ConstructorArgsback to summary
pack-priv ConstructorArgs()

The index of the constructor to call.

ConstructorArgsback to summary
pack-priv ConstructorArgs(int selector, Object[] args)

Method Detail

getBooleanback to summary
public boolean getBoolean()
getByteback to summary
public byte getByte()
getCharback to summary
public char getChar()
getDoubleback to summary
public double getDouble()
getFloatback to summary
public float getFloat()
getIntback to summary
public int getInt()
getLongback to summary
public long getLong()
getObjectback to summary
public Object getObject()
getShortback to summary
public short getShort()
nextback to summary
pack-priv Object next()