Package com.saxonica.ee.bytecode.util
Class CompilerService
- java.lang.Object
-
- com.saxonica.ee.bytecode.util.CompilerService
-
- All Implemented Interfaces:
ICompilerService
public class CompilerService extends java.lang.Object implements ICompilerService
Controlling/service class for compilation of expressions to Java bytecode
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
CompilerService.GeneratedClassInfo
class
CompilerService.GeneratedExpression
sub-class GeneratedExpression - used to keep track of ExpressionCompiler classes that need to generate a methodstatic class
CompilerService.StaticSubClasses
static class
CompilerService.StaticVariableInfo
-
Field Summary
Fields Modifier and Type Field Description java.util.HashMap<com.saxonica.ee.bytecode.util.CompilerService.ObjectIdentityWrapper,CompilerService.StaticSubClasses>
cClassMap
int
mostRecentLineNumber
static int
tracePoint
-
Constructor Summary
Constructors Constructor Description CompilerService(Configuration config, HostLanguage hostLanguage)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addNewMethod(ExpressionCompiler ec, Expression e)
The methods adds theCompilerService.StaticVariableInfo
allocateStaticVariableInfo(java.lang.Object value)
Create a StaticVariableInfo containing the information needed to allow a static reference to a given object to be added as a static field in the currently-being-compiled classvoid
checkMaxClassesLimit()
AtomicTypeValidator
compileAtomicValidator(UserAtomicType type, ConversionRules rules)
Make a validator for user-defined atomic typesvoid
compileToBoolean(Expression expr)
Generate bytecode to evaluate an expression leaving a boolean on the stack.CompiledExpression
compileToByteCode(Expression expr, java.lang.String objectName, int evaluationModes)
Compile a top-level expression to bytecode, and return the resulting expressionvoid
compileToItem(Expression expr)
Generate bytecode to evaluate an expression leaving either an Item or null on the stack (null indicating that the expression evaluated to an empty sequence).void
compileToIterator(Expression expr)
Generate bytecode to evaluate an expression leaving a SequenceIterator on the stackvoid
compileToPrimitive(Expression expr, java.lang.Class<?> c)
Generate bytecode to evaluate an expression leaving a primitive on the stack.void
compileToPrimitive(Expression expr, java.lang.Class<?> requiredClass, OnEmpty onEmpty)
Compile an expression that returns a singleton (or empty) result of type xs:double, xs:float, xs:string, xs:untypedAtomic.void
compileToPush(Expression expr)
Generate bytecode to evaluate an expression by writing events to the current Outputter (leaving nothing on the stack at execution time)void
compileToSequence(Expression expression)
Compile code to evaluate a variable reference, or any other expresssion, leaving a Sequence on the stackjava.io.PrintWriter
createPrintWriter(java.lang.String filename)
void
generateDynamicError(java.lang.String message, java.lang.String errorCode, javax.xml.transform.SourceLocator locator, boolean isTypeError)
Generate code to throw an XPathException.void
generateGetContext()
Generate code to load the current XPathContext, leaving it on the top of the stackvoid
generateGetOutputter()
Generate code to load the current Outputter, leaving it on the top of the stackvoid
generateParameterizedDynamicError(MessageBuilder builder, java.lang.String errorCode, javax.xml.transform.SourceLocator locator, boolean isTypeError)
Generate code to throw an XPath Exception.java.lang.Class<?>
getCompiledClass(Expression expr)
Configuration
getConfiguration()
Get the Configuration used by this CompilerServiceCompilerService.GeneratedClassInfo
getCurrentClass()
Generator
getCurrentGenerator()
GeneratedMethodInfo
getCurrentMethod()
java.util.Stack<GeneratedMethodInfo>
getCurrentMethods()
int
getFlags()
Get the flag options used by the ClassWriterHostLanguage
getHostLanguage()
ExpressionCompiler
getNamedExpressionCompiler(java.lang.String name)
static int
getUniqueNumber()
Get a unique number which is different from any other number allocated by a call on this method, for the same CompilerService instancevoid
initNewMethod(Generator ga, boolean holdReceiverAsLocal)
Initialize context information for a new method.boolean
isDebugByteCode()
boolean
isDisplayByteCode()
boolean
isInRangeForInt(Expression exp)
boolean
isInRangeForLong(Expression exp)
static boolean
isLanguagePrimitiveType(AtomicType targetType)
org.objectweb.asm.ClassVisitor
makeAnnotatedTraceClassVisitor(org.objectweb.asm.ClassVisitor cv, java.lang.String className)
Make a class visitor for displaying bytecodejava.lang.Class<?>
makeClass(org.objectweb.asm.ClassWriter writer, java.lang.String className)
Having written the bytecode for all the methods for a class, create the Class itself so it can be usedjava.lang.String
makeValidJavaName(java.lang.String name)
Given a candidate Java name, make it into a valid Java name by removing surplus white spaces and truncating it to a maximum of 256 characters if length is greater than 256 characters.void
popCurrentMethodInfo()
void
popOutputterInfo()
Generate code to reinstate the previous current receiver by popping it from the receiver stack.void
pushNewClassInfo(java.lang.String className, java.lang.Class<?> superclass, org.objectweb.asm.ClassWriter cw)
void
pushNewMethodInfo(Generator ga, boolean contextIsArgument, int contextVariablePosition, int outputterVariablePosition)
void
pushNewOutputterInfo(Generator ga)
Generate code to set a new current Outputter on the top of the receiver stack.void
setCompiledClass(Expression expr, java.lang.Class<?> clss)
-
-
-
Field Detail
-
tracePoint
public static int tracePoint
-
mostRecentLineNumber
public int mostRecentLineNumber
-
cClassMap
public java.util.HashMap<com.saxonica.ee.bytecode.util.CompilerService.ObjectIdentityWrapper,CompilerService.StaticSubClasses> cClassMap
-
-
Constructor Detail
-
CompilerService
public CompilerService(Configuration config, HostLanguage hostLanguage)
-
-
Method Detail
-
isLanguagePrimitiveType
public static boolean isLanguagePrimitiveType(AtomicType targetType)
-
isDisplayByteCode
public boolean isDisplayByteCode()
-
isDebugByteCode
public boolean isDebugByteCode()
-
getHostLanguage
public HostLanguage getHostLanguage()
-
createPrintWriter
public java.io.PrintWriter createPrintWriter(java.lang.String filename)
-
getNamedExpressionCompiler
public ExpressionCompiler getNamedExpressionCompiler(java.lang.String name)
-
addNewMethod
public void addNewMethod(ExpressionCompiler ec, Expression e)
The methods adds the- Parameters:
ec
- - The ExpressionCompiler that needs to generate a methode
- - The expression represented by the Expressioncompiler
-
compileToSequence
public void compileToSequence(Expression expression) throws CannotCompileException
Compile code to evaluate a variable reference, or any other expresssion, leaving a Sequence on the stack- Parameters:
expression
- the expression to be compiled- Throws:
CannotCompileException
- if the expression cannot be compiled
-
getCompiledClass
public java.lang.Class<?> getCompiledClass(Expression expr)
-
setCompiledClass
public void setCompiledClass(Expression expr, java.lang.Class<?> clss)
-
getUniqueNumber
public static int getUniqueNumber()
Get a unique number which is different from any other number allocated by a call on this method, for the same CompilerService instance- Returns:
- a unique number
-
pushNewOutputterInfo
public void pushNewOutputterInfo(Generator ga)
Generate code to set a new current Outputter on the top of the receiver stack.Runtime precondition: the new Outputter is on the top of the bytecode stack
Runtime postcondition: the new Outputter is now the current receiver; the previous current receiver has been added to the receiver stack. The top entry from the bytecode stack has been consumed.
- Parameters:
ga
- the code generator
-
popOutputterInfo
public void popOutputterInfo()
Generate code to reinstate the previous current receiver by popping it from the receiver stack.Runtime precondition: there is a non-empty receiver stack
Runtime postcondition: the top entry in the receiver stack has been removed from the receiver stack and is now the current receiver.
-
pushNewMethodInfo
public void pushNewMethodInfo(Generator ga, boolean contextIsArgument, int contextVariablePosition, int outputterVariablePosition)
-
initNewMethod
public void initNewMethod(Generator ga, boolean holdReceiverAsLocal)
Initialize context information for a new method. On entry, the XPathContext object must be on the top of stack.- Parameters:
ga
- the code generatorholdReceiverAsLocal
- true if a local variable on the bytecode stack is to be allocated to hold the current receiver; if false, the receiver is obtained via the context when required
-
pushNewClassInfo
public void pushNewClassInfo(java.lang.String className, java.lang.Class<?> superclass, org.objectweb.asm.ClassWriter cw)
-
getCurrentMethods
public java.util.Stack<GeneratedMethodInfo> getCurrentMethods()
-
getCurrentMethod
public GeneratedMethodInfo getCurrentMethod()
-
getCurrentClass
public CompilerService.GeneratedClassInfo getCurrentClass()
-
getConfiguration
public Configuration getConfiguration()
Get the Configuration used by this CompilerService- Returns:
- the Saxon Configuration
-
getFlags
public int getFlags()
Get the flag options used by the ClassWriter- Returns:
- the flags set
-
compileToByteCode
public CompiledExpression compileToByteCode(Expression expr, java.lang.String objectName, int evaluationModes) throws CannotCompileException
Compile a top-level expression to bytecode, and return the resulting expression- Parameters:
expr
- The expression to be compiledobjectName
- The name of the object (e.g. function) being compiledevaluationModes
- The evaluation modes for which code is generated. Currently a subset ofExpression.PROCESS_METHOD
,Expression.ITERATE_METHOD
,Expression.EVALUATE_METHOD
. If no code is generated for a given evaluation method, the fallback implementation from the superclass is used.- Returns:
- The compiled expression if compilation was possible; otherwise null
- Throws:
CannotCompileException
-
compileToIterator
public void compileToIterator(Expression expr) throws CannotCompileException
Generate bytecode to evaluate an expression leaving a SequenceIterator on the stack- Parameters:
expr
- the expression to be evaluated- Throws:
CannotCompileException
- if the expression cannot be compiled
-
compileToPush
public void compileToPush(Expression expr) throws CannotCompileException
Generate bytecode to evaluate an expression by writing events to the current Outputter (leaving nothing on the stack at execution time)- Parameters:
expr
- the expression to be evaluated- Throws:
CannotCompileException
- if the expression cannot be compiled
-
compileToItem
public void compileToItem(Expression expr) throws CannotCompileException
Generate bytecode to evaluate an expression leaving either an Item or null on the stack (null indicating that the expression evaluated to an empty sequence).- Parameters:
expr
- the expression to be evaluated- Throws:
CannotCompileException
- if the expression cannot be compiled
-
compileToBoolean
public void compileToBoolean(Expression expr) throws CannotCompileException
Generate bytecode to evaluate an expression leaving a boolean on the stack. The boolean represents the effective boolean value of the result of the evaluation. This method must be implemented for all expressions except where it is statically known that the expression has no effective boolean value- Parameters:
expr
- the expression to be evaluated- Throws:
CannotCompileException
- if the expression cannot be compiled
-
compileToPrimitive
public void compileToPrimitive(Expression expr, java.lang.Class<?> c) throws CannotCompileException
Generate bytecode to evaluate an expression leaving a primitive on the stack. The primitive represents the effective value of the result of the evaluation.- Parameters:
expr
- the expression to be evaluated- Throws:
CannotCompileException
- if the expression cannot be compiled
-
isInRangeForInt
public boolean isInRangeForInt(Expression exp)
-
isInRangeForLong
public boolean isInRangeForLong(Expression exp)
-
compileToPrimitive
public void compileToPrimitive(Expression expr, java.lang.Class<?> requiredClass, OnEmpty onEmpty) throws CannotCompileException
Compile an expression that returns a singleton (or empty) result of type xs:double, xs:float, xs:string, xs:untypedAtomic. An ExpressionCompiler must support this method if the expression is known statically to return one of these types. The code generated will leave an "unboxed" result on the bytecode stack: specifically a double, a float, a String or CharSequence.- Parameters:
expr
- the expression to be compiledrequiredClass
- the required class. For an expression with static type xs:double, this will be Double.TYPE; for xs:float it will be Float.TYPE; for xs:string and xs:untypedAtomic it may be either String.class or UnicodeString.class. The expression compiler MUST generate code that leaves this class of value on the top of the bytecode stack. For an expression whose static type is xs:integer, the requiredClass may be Integer.TYPE or Long.TYPE, provided that either (a) the expression is known always to deliver a value in the range of an int or long respectively, or (b) that any other value would exceed system limits in the context where it is used (for example, if it is used as an index into a sequence then it cannot exceed a 32-bit integer). All expressions that have a static type of xs:integer must therefore implement this method.onEmpty
- action to be taken when the expression returns an empty result.- Throws:
CannotCompileException
- if the expression cannot be compiled
-
getCurrentGenerator
public Generator getCurrentGenerator()
-
popCurrentMethodInfo
public void popCurrentMethodInfo()
-
generateGetContext
public void generateGetContext()
Generate code to load the current XPathContext, leaving it on the top of the stack
-
generateGetOutputter
public void generateGetOutputter()
Generate code to load the current Outputter, leaving it on the top of the stack
-
generateDynamicError
public void generateDynamicError(java.lang.String message, java.lang.String errorCode, javax.xml.transform.SourceLocator locator, boolean isTypeError)
Generate code to throw an XPathException. This can only be used if all properties of the exception including the message are known statically.- Parameters:
message
- the error messageerrorCode
- the (local part of the) error code to be generatedlocator
- the location in the source code where the error occursisTypeError
- true if this is a type error
-
generateParameterizedDynamicError
public void generateParameterizedDynamicError(MessageBuilder builder, java.lang.String errorCode, javax.xml.transform.SourceLocator locator, boolean isTypeError)
Generate code to throw an XPath Exception. The message is constructed at runtime using the MessageBuilder.- Parameters:
builder
- the error message builder. This generates code to build the error message at run-time and leave it on the stackerrorCode
- the (local part of the) error code to be generatedlocator
- the location in the source code where the error occursisTypeError
- true if this is a type error
-
makeClass
public java.lang.Class<?> makeClass(org.objectweb.asm.ClassWriter writer, java.lang.String className)
Having written the bytecode for all the methods for a class, create the Class itself so it can be used- Parameters:
writer
- the writer that was used to create the classclassName
- the name of the class- Returns:
- the constructed Class object
-
allocateStaticVariableInfo
public CompilerService.StaticVariableInfo allocateStaticVariableInfo(java.lang.Object value)
Create a StaticVariableInfo containing the information needed to allow a static reference to a given object to be added as a static field in the currently-being-compiled class- Parameters:
value
- the object to be referenced- Returns:
- a StaticVariableInfo object, which will have been queued for later addition to the class
-
makeValidJavaName
public java.lang.String makeValidJavaName(java.lang.String name)
Given a candidate Java name, make it into a valid Java name by removing surplus white spaces and truncating it to a maximum of 256 characters if length is greater than 256 characters.- Parameters:
name
- a candidate Java name- Returns:
- a valid Java name
-
makeAnnotatedTraceClassVisitor
public org.objectweb.asm.ClassVisitor makeAnnotatedTraceClassVisitor(org.objectweb.asm.ClassVisitor cv, java.lang.String className)
Make a class visitor for displaying bytecode- Parameters:
cv
- the class visitor
-
compileAtomicValidator
public AtomicTypeValidator compileAtomicValidator(UserAtomicType type, ConversionRules rules) throws CannotCompileException
Make a validator for user-defined atomic types- Parameters:
type
- the user-defined atomic type for which a validator is requiredrules
- the conversion rules to be used by the validator- Returns:
- a custom implementation of
AtomicTypeValidator
specialised to this atomic type - Throws:
CannotCompileException
- if bytecode generation for this type is not possible for any reason
-
checkMaxClassesLimit
public void checkMaxClassesLimit() throws CannotCompileException
- Throws:
CannotCompileException
-
-