All Packages Class Hierarchy This Package Previous Next Index
java.lang.Object | +----gnu.jel.ExpressionImage
It is not general purpose Java assembler, it is specifically JEL oriented.
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 debuging 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.
public static final int BI_PL
public static final int BI_MI
public static final int BI_MU
public static final int BI_DI
public static final int BI_RE
public static final int BI_AN
public static final int BI_OR
public static final int BI_XO
public static final String binaryNames[]
public static final String unaryNames[]
public static final int UN_NE
public static final Class primitiveTypes[]
public static final String primitiveTypeNames[]
public ExpressionImage()
The class name of the expression is generated automatically by appending successive integer numbers (incremented for each instantiated ExpressionImage) to the "gnu.jel.generated.E_". This should ensure the names of expressions are unique. The number is represented by long integer allowing to instantiate close to 10^19 expressions during the program lifetime. This means program, instantiating a new expression each second, will fail with numeric overflow in about 300000000000 years, which is big enough for most applications.
Immediately after the construction of the expression a number of code generating methods can be issued:
asm_load_primitive(...) asm_Sum(..) ...
The code generation should be finished by one of the return methods:
asm_return(); asm_ThrowReturn();
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 Object type other than java.lang.String there. This assembler overcomes this limitation by allowing to use other _NON-MUTABLE_ objects as constants. More information is provided in the description of asm_load_object method.
public static String getSignature(Method m)
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.
public static String getSignature(Class cls)
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 utilizing java.lang.Class.getName(), however that Java method do not always follow Java VM spec.... To be on the safe (controllable) side I dicided to implement this method myself.
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.
public CompiledExpression getExpression()
public void asm_load_object(Object o)
Currently only java.lang.Long and java.lang.Double can be loaded as primitive types. Other classes will load as references.
Internally, this code generator supports operations with all Java primitive types. Now, there is only single way how these other primitive types can come into the stack, namely as function return values. This will be extended in the subsequent versions allowing to load them directly using this method.
public void asm_load_primitive(Object o)
public static boolean canConvert(Class t1, Class t2)
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.
public static boolean canConvertByWidening(Class t1, Class t2)
Both widening and narrowing conversions are supported by the assembler itself, this function reports widening conversions only.
public boolean asm_convert(Class type)
public static Class getMostGeneralType(Class c1, Class c2)
Both operands for the binary OP type should be converted to the most general of them, returned by this function.
Both parameters should be Java primitive types.
public static boolean canGenerateUnary(int op, Class type)
public boolean asm_unary(int o)
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.
public static boolean canGenerateBinary(int op, Class type)
public static boolean canGenerateBinary(int op, Class t1, Class t2)
public boolean asm_binary(int o)
Binary operations can be performed on the primitive Java types only. The two numbers in Java stack have to have the same type, in order for binary operation to succeed.
If operation can not be supported due to incompatible types of operands this method returns false and generates nothing.
public void asm_func_start(Method f, int id)
Method can be static or virtual.
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 actual code for the call is generated by calling asm_func_call() method.
Function calls can be nested.
Correctness of id parameter can not be checked by the code generator !!! Be careful, runtime error will be generated if it's incorrect.
public boolean asm_func_param()
The type of the quantity on top of the Java stack should be convertible to the function required input.
Use can convert function to test for convertibility.
public boolean asm_func_call()
The stack structure should be already prepared by asm_func_start(...) and asm_func_param methods.
public void asm_return()
Number on top of the Java stack converted is returned. If it is of the primitive type it is converted to the Reflection object (i.e. double to java.lang.Double. Currently such conversion is supported for doubles and longs only.
public void asm_ThrowReturn()
Object on top of the Java stack (which should be instance of java.lang.Throwable) is thrown.
public static void main(String args[])
public static void test(Tester t)
Used if all package is being tested and not just codegen.
All Packages Class Hierarchy This Package Previous Next Index