Class ClassGenerator
java.lang.Object
org.jfuncmachine.compiler.classgen.ClassGenerator
Generates classes from ClassDef structures.
A single ClassDef structure can result in multiple classes being generated if
the class contains any lambdas. This class can write the generated classes to
an output directory, return them as an array of GeneratedClass structures containing
class names and byte arrays, or it can immediate load the classes and make them
available.
-
Field Summary
FieldsModifier and TypeFieldDescriptionA class loader that can be used to immediately load defined classes.The current class being generated.The current method being generated.The class that emits Java instructions for the method.ClassDef[]The classes currently being generated.final ClassGeneratorOptionsThe options used for class generation. -
Constructor Summary
ConstructorsConstructorDescriptionCreates a new class generator using the default options.ClassGenerator(ClassGeneratorOptions options) Creates a new class generator with the specified options. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddLocalVariable(org.objectweb.asm.tree.LocalVariableNode node) Adds a definition of a local variable that is being used by the current method.voidaddMethodToGenerate(MethodDef method) Add a method that needs to be generated.voidaddTryCatch(org.objectweb.asm.tree.TryCatchBlockNode node) Adds a try-catch block definition that is being generated by the current method.allocateLambda(FunctionType type) Allocates a new lambda interface with a unique name.allocateLambdaInt(FunctionType functionType) Allocates a lambda interface name for the given function type and saves it in a map of interfaces.Converts a dot-separated class name into a slash-separated oneConverts a dot-separated class name into a slash-separated oneConverts a dot-separated class name into a slash-separated oneclassSignature(ClassDef classDef) Returns a class signature name for a class (L + class signature + ;)voidGenerates all the classes resulting from the given array of ClassDef objects and writes them to the specified directory.voidGenerates all the classes resulting from the given ClassDef object and writes them to the specified directory.voidgenerateAndLoad(ClassDef classDef) Generates all the classes resulting from the given ClassDef object and loads them into the current Java VM.voidgenerateAndLoad(ClassDef[] classDefs) Generates all the classes resulting from the given array of ClassDef objects and loads them into the current Java VM.voidgenerateAndLoad(ClassDef classDef, String outputDirectory) Generates all the classes resulting from the given ClassDef object and loads them into the current Java VM.generateClassBytes(ClassDef classDef) Generates all the classes resulting from the given ClassDef object and returns them as an array of GeneratedClass objects which contain the class name and class bytes.generateClassBytes(ClassDef[] classDefs) Generates all the classes resulting from the given array of ClassDef objects and returns them as an array of GeneratedClass objects which contain the class name and class bytes.Generates the bytecode for a lambda interface.getLoadedClass(String className) Returns a class previously loaded by the internal classloader.getTypeDescriptor(Type type) Return a JVM type descriptor for a given type.invokeMethod(String className, MethodDef methodDef, Object... args) Generates a temporary containing class with a specific name and invokes the method defined by the method def with the given arguments.invokeMethod(ClassDef classDef, String methodName, Object... args) Invokes a specific method defined in the given class definition with the given arguments.invokeMethod(MethodDef methodDef, Object... args) Generates a temporary containing class and invokes the method defined by the method def with the given arguments.lambdaInDyDescriptor(Type[] parameterTypes, String className) Creates a method descriptor specifically used to describe a lambda to the invokesynamic instruction.lambdaMethodDescriptor(Type[] capturedParameterTypes, Type[] parameterTypes, Type returnType) Returns a descriptor of a lambda's method type, which includes the lambda's declared parameters as well as any local variables captured by the lambda.lambdaReturnDescriptor(MethodDef methodDef, String lambdaInterfaceName) Generates a method descritor for a method that returns a lambda.methodDescriptor(Expression[] arguments, Type returnType) Creates a method descriptor from an array of expressions that represent the method parameters, and the method's return type.methodDescriptor(MethodDef methodDef) Creates a method descriptor for the given method definition.methodDescriptor(Type[] parameterTypes, Type returnType) Creates a method descriptor from the given parameter types and return type.voidwriteClasses(GeneratedClass[] classes, String outputDirectory) Writes an array of generated class files to the specified output directory.
-
Field Details
-
options
The options used for class generation. -
currentClass
The current class being generated. -
currentMethod
The current method being generated. -
instGen
The class that emits Java instructions for the method. -
classLoader
A class loader that can be used to immediately load defined classes. -
newClassDefinitions
The classes currently being generated. Because the generator sometimes needs to look up classes to check for compatibility between objects or to see if a method has been compiled with tail-call optimization, it may be necessary to examine the definitions of classes that are currently being generated since the class files may not have been generated yet.
-
-
Constructor Details
-
ClassGenerator
public ClassGenerator()Creates a new class generator using the default options. -
ClassGenerator
Creates a new class generator with the specified options.- Parameters:
options- An instance of ClassGenerator options.- See Also:
-
-
Method Details
-
generate
Generates all the classes resulting from the given array of ClassDef objects and writes them to the specified directory. Keep in mind that if a ClassDef file contains a lambda expression, it can result in more than one class definition being generated, since lambdas require an interface definition.- Parameters:
classes- The class definitions of the classes to be generated.outputDirectory- The name of the directory where the .class files should be written.- Throws:
IOException- If there is an exception writing the class files
-
generate
Generates all the classes resulting from the given ClassDef object and writes them to the specified directory. Keep in mind that if a ClassDef file contains a lambda expression, it can result in more than one class definition being generated, since lambdas require an interface definition.- Parameters:
classDef- The class definition to be generatedoutputDirectory- The name of the directory where the .class files should be written.- Throws:
IOException- If there is an exception writing the class files
-
generateClassBytes
Generates all the classes resulting from the given array of ClassDef objects and returns them as an array of GeneratedClass objects which contain the class name and class bytes. Keep in mind that if a class file contains a lambda expression, it can result in more than one class definition being generated, since lambdas require an interface definition.- Parameters:
classDefs- The class definitions of the classDefs to be generated.- Returns:
- An array of GeneratedClass objects containing the class bytes for each class
- See Also:
-
generateClassBytes
Generates all the classes resulting from the given ClassDef object and returns them as an array of GeneratedClass objects which contain the class name and class bytes. Keep in mind that if a ClassDef file contains a lambda expression, it can result in more than one class definition being generated, since lambdas require an interface definition.- Parameters:
classDef- The class definition to be generated.- Returns:
- An array of GeneratedClass objects containing the class bytes for each class
- See Also:
-
generateAndLoad
Generates all the classes resulting from the given array of ClassDef objects and loads them into the current Java VM. Keep in mind that if a ClassDef file contains a lambda expression, it can result in more than one class definition being generated, since lambdas require an interface definition.- Parameters:
classDefs- The class definitions of the classes to be generated.
-
generateAndLoad
Generates all the classes resulting from the given ClassDef object and loads them into the current Java VM. Keep in mind that if a ClassDef file contains a lambda expression, it can result in more than one class definition being generated, since lambdas require an interface definition.- Parameters:
classDef- The class definitions of the classes to be generated.
-
generateAndLoad
Generates all the classes resulting from the given ClassDef object and loads them into the current Java VM. Keep in mind that if a ClassDef file contains a lambda expression, it can result in more than one class definition being generated, since lambdas require an interface definition.- Parameters:
classDef- The class definitions of the classes to be generated.outputDirectory- The name of the directory where the .class files should be written.- Throws:
IOException- If there is an exception writing the class files
-
invokeMethod
Generates a temporary containing class and invokes the method defined by the method def with the given arguments.- Parameters:
methodDef- The definition of the method to executeargs- The method arguments- Returns:
- The method return value
-
invokeMethod
Generates a temporary containing class with a specific name and invokes the method defined by the method def with the given arguments.- Parameters:
className- The name of the temporary class to generatemethodDef- The definition of the method to executeargs- The method arguments- Returns:
- The method return value
-
invokeMethod
Invokes a specific method defined in the given class definition with the given arguments.- Parameters:
classDef- The class definition containing the method to executemethodName- The name of the method to executeargs- The method arguments- Returns:
- The method return value
-
writeClasses
Writes an array of generated class files to the specified output directory.- Parameters:
classes- The classes to writeoutputDirectory- The destination output directory- Throws:
IOException- If there is an exception writing the class files
-
generateLambdaInterface
Generates the bytecode for a lambda interface.- Parameters:
info- A descriptor for the lambda interface and its single method- Returns:
- A GeneratedClass containing the bytecode and the class name
-
addMethodToGenerate
Add a method that needs to be generated. This is usually done by the method generation when there is a lambda- Parameters:
method- The method to be genrated
-
addLocalVariable
public void addLocalVariable(org.objectweb.asm.tree.LocalVariableNode node) Adds a definition of a local variable that is being used by the current method.- Parameters:
node- A node describing the local variable
-
addTryCatch
public void addTryCatch(org.objectweb.asm.tree.TryCatchBlockNode node) Adds a try-catch block definition that is being generated by the current method.- Parameters:
node- A node describing a try-catch block
-
allocateLambdaInt
Allocates a lambda interface name for the given function type and saves it in a map of interfaces.- Parameters:
functionType- The type of the single method in the interface- Returns:
- A descriptor describing the interface
-
allocateLambda
Allocates a new lambda interface with a unique name.- Parameters:
type- The type of the lambda method- Returns:
- A descriptor describing the lambda
-
className
Converts a dot-separated class name into a slash-separated one- Parameters:
classDef- The class definition containing the package name and class name- Returns:
- A slash-separated class name
-
className
Converts a dot-separated class name into a slash-separated one- Parameters:
packageName- The package name of the classname- The name of the class- Returns:
- A slash-separated class name
-
className
Converts a dot-separated class name into a slash-separated one- Parameters:
name- A class name presumably containing both a package and class name- Returns:
- A slash-separated class name
-
classSignature
Returns a class signature name for a class (L + class signature + ;)- Parameters:
classDef- The class definition to get the signature name for- Returns:
- The signature of the class
-
methodDescriptor
Creates a method descriptor for the given method definition. The descriptor encodes the types of the method parameters as well as the return type as per the JVM spec. For example: A method that takes a string and an integer as parameters and returns void would be encoded as: (Ljava/lang/String;I)V- Parameters:
methodDef- The definition of the method to generate the descriptor for- Returns:
- A string descriptor encoding the types according to the JVM spec
-
lambdaReturnDescriptor
Generates a method descritor for a method that returns a lambda.- Parameters:
methodDef- The definition of the methodlambdaInterfaceName- The type of interface being returned- Returns:
- A string descriptor of the method according to the JVM spec
-
methodDescriptor
Creates a method descriptor from an array of expressions that represent the method parameters, and the method's return type.- Parameters:
arguments- An array of expressions that represent the methods parametersreturnType- The return type of the method- Returns:
- A string descriptor of the method according to the JVM spec
-
methodDescriptor
Creates a method descriptor from the given parameter types and return type.- Parameters:
parameterTypes- An array describing the types of the method's parametersreturnType- The return type of the method- Returns:
- A string descriptor of the method according to the JVM spec
-
lambdaInDyDescriptor
Creates a method descriptor specifically used to describe a lambda to the invokesynamic instruction.- Parameters:
parameterTypes- The types of the method's parametersclassName- The class name of the lambda's interface- Returns:
- A string descriptor of the lambda according to the JVM spec
-
lambdaMethodDescriptor
public String lambdaMethodDescriptor(Type[] capturedParameterTypes, Type[] parameterTypes, Type returnType) Returns a descriptor of a lambda's method type, which includes the lambda's declared parameters as well as any local variables captured by the lambda.- Parameters:
capturedParameterTypes- The types of the variables captured by the lambdaparameterTypes- The types of the methods declared parametersreturnType- The return type of the lambda- Returns:
- A string descriptor of the lambda according to the JVM spec
-
getTypeDescriptor
Return a JVM type descriptor for a given type. This is done here instead of inside the Type interface in order to handle the FunctionType correctly.- Parameters:
type- The type to return the descriptor for- Returns:
- A JVM type descriptor for the given type
-
getLoadedClass
Returns a class previously loaded by the internal classloader.- Parameters:
className- The fully-qualified name of the class to return- Returns:
- The class if it was loaded, or null if there is no class with that name
-