| java.lang.Object bsh.ClassGeneratorUtil
ClassGeneratorUtil | public class ClassGeneratorUtil implements Constants(Code) | | 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).
TODO: We have hooks for generating static initializer code, now used
to save persistent class stubs. This must be extended to accomodate
general static initializer blocks.
author: Pat Niemeyer |
Inner Class :public static class ConstructorArgs | |
Method Summary | |
static boolean | classContainsMethod(Class clas, String methodName, String[] paramTypes) | static void | doSwitchBranch(int index, String targetClassName, String[] paramTypes, Label endLabel, Label[] labels, int consArgsVar, CodeVisitor cv) | public byte[] | generateClass(boolean generateInitCode) Generate the class bytecode for this class. | void | generateConstructor(int index, String[] paramTypes, int modifiers, ClassWriter cw) Generate a constructor. | void | generateConstructorSwitch(int consIndex, int argsVar, int consArgsVar, CodeVisitor cv) Generate a switch with a branch for each possible alternate
constructor. | static void | generateField(String fieldName, String type, int modifiers, ClassWriter cw) Generate a field - static or instance. | static void | generateMethod(String className, String fqClassName, String methodName, String returnType, String[] paramTypes, int modifiers, ClassWriter cw) Generate a delegate method - static or instance. | public static void | generateParameterReifierCode(String[] paramTypes, boolean isStatic, CodeVisitor cv) Generates the code to reify the arguments of the given method. | static void | generatePlainReturnCode(String returnType, CodeVisitor cv) | public static void | generateReturnCode(String returnType, CodeVisitor cv) Generates the code to unreify the result of the given method. | void | generateStaticInitializer(ClassWriter cw) | static void | generateSuperDelegateMethod(String superClassName, String methodName, String returnType, String[] paramTypes, int modifiers, ClassWriter cw) Generate a superclass method delegate accessor method. | static int | getASMModifiers(Modifiers modifiers) Translate bsh.Modifiers into ASM modifier bitflags. | static This | getClassInstanceThis(Object instance, String className) Get the instance bsh namespace field from the object instance. | static This | getClassStaticThis(Class clas, String className) Get the static bsh namespace field from the class. | public static ConstructorArgs | getConstructorArgs(String superClassName, This classStaticThis, Object[] consArgs, int index) This method is called by the **generated class** during construction.
Evaluate the arguments (if any) for the constructor specified by
the constructor index. | static String | getMethodDescriptor(String returnType, String[] paramTypes) | static String[] | getTypeDescriptors(Class[] cparams) | public static void | initInstance(Object instance, String className, Object[] args) This method is called from the **generated class** constructor to
evaluate the instance initializer (instance blocks and loosely typed
statements) and then the scripted constructor,
in the instance namespace. | public static void | initStatic(Class genClass) The class is "cold" (detached with no live interpreter static
This reference) try to start a new interpreter and source the
script backing it.
We pass in both the fq class name and the static This ref here just
to minimize the generated code. | public void | initStaticNameSpace(NameSpace classStaticNameSpace, BSHBlock instanceInitBlock) This method provides a hook for the class generator implementation to
store additional information in the class's bsh static namespace. | public static void | startInterpreterForClass(Class genClass) Attempt to load a script named for the class: e.g. |
BSHCONSTRUCTORS | final static String BSHCONSTRUCTORS(Code) | | The bsh static namespace variable that holds the constructor methods
|
BSHINIT | final static String BSHINIT(Code) | | The name of the instance initializer in the bsh static class namespace.
The instance initializer contains instance blocks and loose code, etc.
|
BSHSTATIC | final static String BSHSTATIC(Code) | | The name of the static field holding the reference to the bsh
static This (the callback namespace for static methods)
|
BSHSUPER | final static String BSHSUPER(Code) | | The prefix for the name of the super delegate methods. e.g.
_bshSuperfoo() is equivalent to super.foo()
|
BSHTHIS | final static String BSHTHIS(Code) | | The name of the instance field holding the reference to the bsh
instance This (the callback namespace for instance methods)
|
DEFAULTCONSTRUCTOR | final static int DEFAULTCONSTRUCTOR(Code) | | The switch branch number for the default constructor.
The value -1 will cause the default branch to be taken.
|
fqClassName | String fqClassName(Code) | | fully qualified class name (with package) e.g. foo/bar/Blah
|
isInterface | boolean isInterface(Code) | | |
generateClass | public byte[] generateClass(boolean generateInitCode)(Code) | | Generate the class bytecode for this class.
|
generateConstructor | void generateConstructor(int index, String[] paramTypes, int modifiers, ClassWriter cw)(Code) | | Generate a constructor.
|
generateConstructorSwitch | void generateConstructorSwitch(int consIndex, int argsVar, int consArgsVar, CodeVisitor cv)(Code) | | 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.
|
generateField | static void generateField(String fieldName, String type, int modifiers, ClassWriter cw)(Code) | | Generate a field - static or instance.
|
generateMethod | static void generateMethod(String className, String fqClassName, String methodName, String returnType, String[] paramTypes, int modifiers, ClassWriter cw)(Code) | | 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.
|
generateParameterReifierCode | public static void generateParameterReifierCode(String[] paramTypes, boolean isStatic, CodeVisitor cv)(Code) | | 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.
author: Eric Bruneton author: Pat Niemeyer Parameters: cv - the code visitor to be used to generate the bytecode. Parameters: isStatic - the enclosing methods is static |
generatePlainReturnCode | static void generatePlainReturnCode(String returnType, CodeVisitor cv)(Code) | | Generate return code for a normal bytecode
|
generateReturnCode | public static void generateReturnCode(String returnType, CodeVisitor cv)(Code) | | 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 - the code visitor to be used to generate the bytecode. author: Eric Bruneton author: Pat Niemeyer |
generateStaticInitializer | void generateStaticInitializer(ClassWriter cw)(Code) | | Generate the static initializer for the class
|
generateSuperDelegateMethod | static void generateSuperDelegateMethod(String superClassName, String methodName, String returnType, String[] paramTypes, int modifiers, ClassWriter cw)(Code) | | 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).
|
getASMModifiers | static int getASMModifiers(Modifiers modifiers)(Code) | | Translate bsh.Modifiers into ASM modifier bitflags.
|
getClassInstanceThis | static This getClassInstanceThis(Object instance, String className)(Code) | | Get the instance bsh namespace field from the object instance.
the class instance This object or null if the object has notbeen initialized. |
getClassStaticThis | static This getClassStaticThis(Class clas, String className)(Code) | | Get the static bsh namespace field from the class.
Parameters: className - may be the name of clas itself or a superclass of clas. |
getConstructorArgs | public static ConstructorArgs getConstructorArgs(String superClassName, This classStaticThis, Object[] consArgs, int index)(Code) | | This method is called by the **generated class** during construction.
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 - the arguments to the constructor. These are necessary inthe evaluation of the alt constructor args. e.g. Foo(a) { super(a); } the ConstructorArgs object containing a constructor selectorand evaluated arguments for the alternate constructor |
initInstance | public static void initInstance(Object instance, String className, Object[] args)(Code) | | This method is called from the **generated class** constructor to
evaluate the instance initializer (instance blocks and loosely typed
statements) and then the scripted constructor,
in the instance namespace. These activities happen in the bsh script
but have side effects in the generated stub class (imported instance
and static variables may be initialized).
|
initStatic | public static void initStatic(Class genClass)(Code) | | The class is "cold" (detached with no live interpreter static
This reference) try to start a new interpreter and source the
script backing it.
We pass in both the fq class name and the static This ref here just
to minimize the generated code. All we really do here is a simple
if condition for now.
|
initStaticNameSpace | public void initStaticNameSpace(NameSpace classStaticNameSpace, BSHBlock instanceInitBlock)(Code) | | This method provides a hook for the class generator implementation to
store additional information in the class's bsh static namespace.
Currently this is used to store an array of consructors corresponding
to the constructor switch in the generated class.
This method must be called to initialize the static space even if we
are using a previously generated class.
|
startInterpreterForClass | public static void startInterpreterForClass(Class genClass)(Code) | | 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.
The only interact that this method has with the process is to initially
cache the correct class in the class manager for the interpreter to
insure that it is found and associated with the scripted body.
|
|
|