All Packages Class Hierarchy This Package Previous Next Index
Class gnu.jel.ExpressionImage
java.lang.Object
|
+----gnu.jel.ExpressionImage
- public class ExpressionImage
- extends Object
This class is responsible for generating valid Java class files based on
a sequence of calls to it's methods (asm_XXXX family of methods). This
assembler tries to do more things than other java assemblers do.
It keeps track of types in Java stack and automatically chooses which
java bytecodes should be generated to perform a given operation on
types in stack.
Anyway, it is not general purpose Java assembler, it is specifically JEL
oriented. Currently this assembler does not provide direct access to Java
control transfer instructions.
This class is designed to be the part of a bigger package. This means
it will silently generate wrong bytecodes. ;) BUT, if You compile it with
debugging ON (see boolean gnu.jel.debug.Debug.enabled) it should
warn You about all possible wrong things it does. If there are more
assertions to be made, please submit Your patches to metlov@fzu.cz.
- Author:
- Konstantin L. Metlov (metlov@fzu.cz)
- See Also:
- enabled
-
BI_AN
- Denotes the AND binary operation.
-
BI_DI
- Denotes the DIVIDE binary operation.
-
BI_EQ
- Denotes binary comparizon for equality
-
BI_GE
- Denotes binary comparizon for "greater or equal"
-
BI_GT
- Denotes binary comparizon for "greater"
-
BI_LE
- Denotes binary comparizon for "less or equal"
-
BI_LS
- Denotes binary left shift
-
BI_LT
- Denotes binary comparizon for "less"
-
BI_MI
- Denotes the MINUS binary operation.
-
BI_MU
- Denotes the MULTIPLY binary operation.
-
BI_NE
- Denotes binary comparizon for inequality
-
BI_OR
- Denotes the OR binary operation.
-
BI_PL
- Denotes the PLUS binary operation.
-
BI_RE
- Denotes the REMAINDER binary operation.
-
BI_RSS
- Denotes binary right signed shift
-
BI_RUS
- Denotes binary right unsigned shift
-
BI_XO
- Denotes the XOR binary operation.
-
binaryNames
- Names of binary operations by ID in the readable form.
-
binarySymbols
- Symbols of binary operations by ID in the readable form.
-
LOG_AN
- Denotes logical conjunction operator
-
LOG_NO
- Denotes logical complement operator
-
LOG_OR
- Denotes logical disjunction operator
-
logicalNames
- Names of logical operations by ID in the readable form.
-
logicalSymbols
- Symbols of logical operations by ID in the readable form.
-
primitiveTypeNames
- Names of the primitive types by ID in readable form.
-
primitiveTypes
- Classes of the primitive types by ID
-
UN_NE
- Denotes the unary NEGATION operation.
-
UN_NO
- Denotes the unary bitwise complement operation.
-
unaryNames
- Names of unary operations by ID in the readable form.
-
unarySymbols
- Symbols of unary operations by ID in the readable form.
-
ExpressionImage()
- Constructs and initializes empty expression image.
-
asm_binary(int)
- Generates code to perform given binary operation.
-
asm_binary_param(int)
- Denotes that the first parameter for the given binary OP is now in stack.
-
asm_branch_end()
- Finishes generation of code for conditional.
-
asm_branch_start_false()
- Continues generation of code for conditional.
-
asm_branch_start_true()
- Starts generation of code for conditional.
-
asm_convert(Class)
- Converts current top of the java stack to the given class type.
-
asm_func_call()
- Finishes generation of call to a function.
-
asm_func_param()
- Denotes that the next parameter for the current function is now in stack.
-
asm_func_start(Method, int)
- Starts generation of code for the method call.
-
asm_load_object(Object)
- Generates code to load given object constant into Java stack.
-
asm_load_primitive(Object)
- Generates code to load given constant of a primitive type.
-
asm_logical_binary(int)
- Generates code to perform given logical binary operation.
-
asm_logical_binary_param(int)
- Denotes the first parameter for the given logical binary OP is
now in stack.
-
asm_logical_block()
- This function starts a group of logical subexpressions.
-
asm_logical_unblock_not()
- This function finishes a group of logical subexpressions with inversion.
-
asm_return()
- Finishes construction of expression by generating code to return a value.
-
asm_throw_return()
- Finishes construction of expression by generating code to throw exception.
-
asm_unary(int)
- Generates code to perform given unary operation on the value in stack.
-
canConvert(Class, Class)
- Tests is this assembler can generate code to convert from from one type to another even with possible loss of the information.
-
canConvertByWidening(Class, Class)
- Tests is this assembler can generate code to convert from
from one type to another without loss of the information.
-
canGenerateBinary(int, Class, Class)
- Used to test if this assembler can generate given binary operation.
-
canGenerateUnary(int, Class)
- Used to test if this assembler can generate given unary operation.
-
getBinaryPromoted(Class, Class)
- Performs binary numeric promotion of types.
-
getBits()
- Returns compiled expression represented by ExpressionBits object.
-
getExpression()
- Constructs a new instance of this expression.
-
getImage()
- Used to get the binary image of the class.
-
getSignature(Class)
- Computes the signature of the given class.
-
getSignature(Constructor)
- Computes signature of the given constructor.
-
getSignature(Method)
- Computes signature of the given method.
-
getUnaryPromoted(Class)
- Performs unary numeric promotion of types.
-
isPromotionBinary(int)
- Checks if the binary numeric promotion is required for the operation.
-
main(String[])
- Performs unitary test of the code generator.
-
test(Tester)
- Performs unitary test of the code generator.
BI_PL
public static final int BI_PL
- Denotes the PLUS binary operation.
BI_MI
public static final int BI_MI
- Denotes the MINUS binary operation.
BI_MU
public static final int BI_MU
- Denotes the MULTIPLY binary operation.
BI_DI
public static final int BI_DI
- Denotes the DIVIDE binary operation.
BI_RE
public static final int BI_RE
- Denotes the REMAINDER binary operation.
BI_AN
public static final int BI_AN
- Denotes the AND binary operation.
BI_OR
public static final int BI_OR
- Denotes the OR binary operation.
BI_XO
public static final int BI_XO
- Denotes the XOR binary operation.
BI_EQ
public static final int BI_EQ
- Denotes binary comparizon for equality
BI_NE
public static final int BI_NE
- Denotes binary comparizon for inequality
BI_LT
public static final int BI_LT
- Denotes binary comparizon for "less"
BI_GE
public static final int BI_GE
- Denotes binary comparizon for "greater or equal"
BI_GT
public static final int BI_GT
- Denotes binary comparizon for "greater"
BI_LE
public static final int BI_LE
- Denotes binary comparizon for "less or equal"
BI_LS
public static final int BI_LS
- Denotes binary left shift
BI_RSS
public static final int BI_RSS
- Denotes binary right signed shift
BI_RUS
public static final int BI_RUS
- Denotes binary right unsigned shift
binaryNames
public static final String binaryNames[]
- Names of binary operations by ID in the readable form.
binarySymbols
public static final String binarySymbols[]
- Symbols of binary operations by ID in the readable form.
LOG_AN
public static final int LOG_AN
- Denotes logical conjunction operator
LOG_OR
public static final int LOG_OR
- Denotes logical disjunction operator
LOG_NO
public static final int LOG_NO
- Denotes logical complement operator
logicalNames
public static final String logicalNames[]
- Names of logical operations by ID in the readable form.
logicalSymbols
public static final String logicalSymbols[]
- Symbols of logical operations by ID in the readable form.
UN_NE
public static final int UN_NE
- Denotes the unary NEGATION operation.
UN_NO
public static final int UN_NO
- Denotes the unary bitwise complement operation.
unaryNames
public static final String unaryNames[]
- Names of unary operations by ID in the readable form.
unarySymbols
public static final String unarySymbols[]
- Symbols of unary operations by ID in the readable form.
primitiveTypes
public static final Class primitiveTypes[]
- Classes of the primitive types by ID
primitiveTypeNames
public static final String primitiveTypeNames[]
- Names of the primitive types by ID in readable form.
ExpressionImage
public ExpressionImage()
- Constructs and initializes empty expression image.
Immediately after the construction of the expression a number of
code generating methods can be issued:
asm_load_primitive(...)
asm_binary_param(..)
...
The code generation should be finished by one of the return methods:
asm_return();
asm_throw_return();
Before any return method is called, the code generation is assumed
to be in progress and methods, attempting to get class representation
(getImage) or instantiate the class (getExpression) will fail assertion.
After the code generation is finished and one of return methods is
called methods, attempting to modify the class (i.e.
asm_load_primitive(...)...) will fail. This is done to ensure
integrity of generated classes.
Constants of the type object are allowed in the generated expressions.
(If You don't know in java the constants are residing in the constant
pool and it is impossible to store constants of general Object type
other than java.lang.String there. This assembler overcomes this
limitation and allows to use other _NON-MUTABLE_ objects as constants.
More information is provided in the description of
asm_load_object
method.
- See Also:
- asm_load_object, asm_load_primitive, asm_binary, asm_convert, asm_func_call, asm_logical_binary, asm_logical_unblock_not, asm_unary, asm_return, asm_throw_return
isPromotionBinary
public static final boolean isPromotionBinary(int binary_op)
- Checks if the binary numeric promotion is required for the operation.
Used to check whether given binary operation requires binary or
unary numeric promotion (see JLS 5.6.1) of it's operands.
- Parameters:
- binary_op - is one of BI_XXX constants.
- Returns:
- true if binary numeric promotion is required false if unary
numeric promotion is required.
getSignature
public static String getSignature(Method m)
- Computes signature of the given method.
The signature of the method(Method descriptor) is the string and
it's format is described in the paragraph 4.3.3 of the Java VM
specification (ISBN 0-201-63451-1).
This utility method can be used outside of the JEL package
it does not involve any JEL specific assumptions and should follow
JVM Specification precisely.
- Parameters:
- m - is the method to compute the sugnature of.
- Returns:
- the method sugnature.
getSignature
public static String getSignature(Constructor c)
- Computes signature of the given constructor.
- Parameters:
- m - is the method to compute the sugnature of.
- Returns:
- the method sugnature.
- See Also:
- getSignature
getSignature
public static String getSignature(Class cls)
- Computes the signature of the given class.
The signature of the class (Field descriptor) is the string and
it's format is described in the paragraph 4.3.2 of the Java VM
specification (ISBN 0-201-63451-1).
The same can be done using java.lang.Class.getName() by
converting it's result into the "historical form".
This utility method can be used outside of the JEL package
it does not involve any JEL specific assumptions and should follow
JVM Specification precisely.
- Parameters:
- cls - is the class to compute the sgnature of. Can be primitive or
array type.
- Returns:
- the class signature.
getBits
public ExpressionBits getBits()
- Returns compiled expression represented by ExpressionBits object.
This function should be called after the code generation had
finished.
The only case You'll want to get gnu.jel.ExpressionBits
class instead of instantiated and ready to run
gnu.jel.CompiledExpression subclass is when You intend to write
expression to a persistent storage and run it in other JVM session.
- Returns:
- ready to be serialized ExpressionBits object.
getImage
public byte[] getImage()
- Used to get the binary image of the class.
This function returns bytecode of generated expression in a Java
classfile format. It is for debugging purposes only. Use ExpressionBits
if You want to store expression into a stream (file).
- Returns:
- a binary class representation.
getExpression
public CompiledExpression getExpression()
- Constructs a new instance of this expression.
This function returns ready to run instance of
gnu.jel.CompiledExpression subclass.
- Returns:
- a CompiledExpression instance or null if there was a error.
asm_load_object
public void asm_load_object(Object o)
- Generates code to load given object constant into Java stack.
Constants of type object, other than instances of
java.lang.String are not directly supported by Java Virtual
Machine. This means there is no way to reinstantiate those object
based on the information in the Java class file alone.
To overcome this limitation an array of such objects is created and
only integer index into this "object constants" array is compiled into a
class file. The drawback is that the generated class file can not be run
without proper object constants array supplied. This means bytecode alone
does not represent compiled program anymore.
To simplify storage of expressions an ExpressionBits class is
introduced which holds both bytecode and object constants, allowing to
easily store them together in a stream.
CONCLUSION : if Your class uses this function for objects other than
Strings You _must_ use ExpressionBits to store compiled bytecode.
- Parameters:
- o - is the object to load.
- See Also:
- ExpressionBits
asm_load_primitive
public void asm_load_primitive(Object o)
- Generates code to load given constant of a primitive type.
For example, to load double constant 1.0D into
the Java stack one has to call :
asm_load_primitive(new Double(1.0)).
- Parameters:
- o - is the value of a constant of primitive type, wrapped into
corresponding reflection object.
canConvert
public static boolean canConvert(Class t1,
Class t2)
- Tests is this assembler can generate code to convert from from one type to another even with possible loss of the information.
Both widening and narrowing conversions are supported by the
assembler, this function reports all supported conversions.
There are thoughts about support wrapping/unwrapping conversions
(i.e. double <--> java.lang.Double) as described in the Java Reflection
Specification. Currently these are not supported.
- Parameters:
- t1 - is the type You want to convert from.
- t2 - is the type You want to convert to.
- Returns:
- true is the corresponding conversion is supported.
canConvertByWidening
public static boolean canConvertByWidening(Class t1,
Class t2)
- Tests is this assembler can generate code to convert from
from one type to another without loss of the information.
Both widening and narrowing conversions are supported by the
assembler itself, this function reports widening conversions only.
- Parameters:
- t1 - is the type You want to convert from.
- t2 - is the type You want to convert to.
- Returns:
- true is the corresponding widening conversion is supported.
asm_convert
public boolean asm_convert(Class type)
- Converts current top of the java stack to the given class type.
- Parameters:
- type - is the type to convert to, can be primitive.
- Returns:
- true if conversion was made, false if types incompatible.
getBinaryPromoted
public static Class getBinaryPromoted(Class c1,
Class c2)
- Performs binary numeric promotion of types.
Promotion is done according to the Java Language Specification
(paragraph 5.6.2). Both parameters should be Java primitive types.
- Parameters:
- c1 - first type
- c2 - second type
- Returns:
- Class (primitive type reflection), representing
the binary promoted type, null if can't promote.
getUnaryPromoted
public static Class getUnaryPromoted(Class c)
- Performs unary numeric promotion of types.
Promotion is done according to the Java Language Specification
(paragraph 5.6.1). Both parameters should be Java primitive numeric types.
- Parameters:
- c - the type to promote
- Returns:
- Class (primitive type reflection), representing
unary promoted type, null if can't promote.
canGenerateUnary
public static boolean canGenerateUnary(int op,
Class type)
- Used to test if this assembler can generate given unary operation.
- Parameters:
- is - the code of operation (UN_NE).
- type - is the type of the operand.
- Returns:
- if the code for such operation can be generated.
asm_unary
public void asm_unary(int o)
- Generates code to perform given unary operation on the value in stack.
Unary operations can be performed on the primitive
Java types only.
If operation can not be supported for the given type
this method returns false and generates nothing.
- Parameters:
- o - type of operation to perform, one of NE
canGenerateBinary
public static boolean canGenerateBinary(int op,
Class t1,
Class t2)
- Used to test if this assembler can generate given binary operation.
- Parameters:
- is - the code of operation (BI_PL,BI_MI,BI_MU ...).
- t1 - is the type of the first operand.
- t2 - is the type of the second operand.
- Returns:
- if the code for such operation can be generated.
asm_binary
public void asm_binary(int o)
- Generates code to perform given binary operation.
Method canGenerateBinary(..) should be used to determine
if the binary operation can be generated for particular types of data.
The pattern to generate binary operations with this code generator
is following :
1. Calculate the first operand.
2. asm_binary_param( BI_XXX )
3. Calculate the second operand.
4. asm_binary( BI_XXX )
If operation can not be supported due to incompatible types of
operands this method returns false and generates nothing.
- Parameters:
- o - type of operation to perform, one of BI_XXX
- See Also:
- canGenerateBinary, asm_binary_param
asm_func_start
public void asm_func_start(Method f,
int id)
- Starts generation of code for the method call.
Method can be static or virtual. See the descrition of
asm_func_call for more details.
- Parameters:
- f - is the method to call.
- id - is the number of the function in the array of the
instances of objects implementing the function (for virtual
methods only).
- See Also:
- asm_func_call
asm_func_param
public void asm_func_param()
- Denotes that the next parameter for the current function is now in stack.
Actually, this method generates code to convert the value currently
on top of Java stack to the next formal parameter type
of a current function.
- Returns:
- false if types are incompatible.
- See Also:
- asm_func_start
asm_func_call
public void asm_func_call()
- Finishes generation of call to a function.
Call to this method should be followed zero or more asm_func_param()
calls which would transform parameters on top of the stack to be
compatible with the function input (each additioal call will process
the next formal parameter).
The pattern to generate the function call is the following
1. asm_func_start(...);
2. Calculate the first parameter.
3. asm_func_param();
4. Calculate the second parameter.
5. asm_func_param();
.... so on ...
6 Calculate the last parameter.
7. asm_func_param();
8. asm_func_call();
Correctness of id parameter can not be checked by the code
generator !!! Be careful, runtime error will be generated if it's
incorrect.
- See Also:
- asm_func_param, asm_func_start
asm_branch_start_true
public void asm_branch_start_true()
- Starts generation of code for conditional.
Starts the branch,
corresponding to the case when previous logical was "true".
expression.
The pattern to generate an "if" operator or ?: conditional is
the following :
1. Calculate condition
2. asm_branch_start_true()
3. Generate code for the "true" branch
4. asm_branch_start_false()
5. Generate code for the "false" branch
6. asm_branch_end()
Note that the code for "true" branch should be generated BEFORE
the code for the current branch. This limitation may be removed in a
future.
asm_branch_start_false
public void asm_branch_start_false()
- Continues generation of code for conditional.
- See Also:
- asm_branch_start_true
asm_branch_end
public void asm_branch_end()
- Finishes generation of code for conditional.
- See Also:
- asm_branch_start_true
asm_binary_param
public void asm_binary_param(int opc)
- Denotes that the first parameter for the given binary OP is now in stack.
- Parameters:
- op - type of operation to perform, one of BI_XXX
- See Also:
- asm_binary
asm_logical_binary_param
public void asm_logical_binary_param(int opc)
- Denotes the first parameter for the given logical binary OP is
now in stack.
- Parameters:
- opc - is the code of the logical binary operation (LOG_AN,LOG_OR)
- See Also:
- asm_logical_binary
asm_logical_binary
public void asm_logical_binary(int opc)
- Generates code to perform given logical binary operation.
The logical binary operations are either logical and (LOG_AN) or
logical or (LOG_OR).
The following pattern should be followed in order to evaluate
logical expressions :
1. Calculate the first operand (should be boolean).
2. asm_logical_binary_param( | )
3. Calculate the second operand (should be boolean).
4. asm_logical_binary( | )
- Parameters:
- opc - is the code of the logical binary operation (LOG_AN,LOG_OR)
asm_logical_block
public void asm_logical_block()
- This function starts a group of logical subexpressions.
- See Also:
- asm_logical_unblock_not
asm_logical_unblock_not
public void asm_logical_unblock_not()
- This function finishes a group of logical subexpressions with inversion.
For example, to calculate "!(..something..)" it is
needed to call :
asm_logical_block()
....
calculate something manipulating with other methods of this code generator
....
asm_logical_unblock_not();
After the above block the state of this codegenerator will correspond
to the boolean result of the logical not operator on something.
asm_return
public void asm_return()
- Finishes construction of expression by generating code to return a value.
Code to return to a caller a quantity on top of the Java stack is
generated.
asm_throw_return
public void asm_throw_return()
- Finishes construction of expression by generating code to throw exception.
Object on top of the Java stack (which should be instance of
java.lang.Throwable) is thrown.
main
public static void main(String args[])
- Performs unitary test of the code generator.
- Parameters:
- args - ignored.
test
public static void test(Tester t)
- Performs unitary test of the code generator.
Used if all package is being tested and not just codegen.
- Parameters:
- t - Tester to report test results.
All Packages Class Hierarchy This Package Previous Next Index