Package org.apache.tapestry5.plastic
Interface InstructionBuilder
-
- All Known Implementing Classes:
InstructionBuilderImpl
public interface InstructionBuilder
Simplifies the generation of method instructions for a particular method (or constructor), allowing bytecode to be created with a friendlier API that focuses on Java type names (names as they would appear in Java source) rather than JVM descriptors or internal names. In some limited cases, types may be specified as Java Class instances as well. In addition, there is good support for primitive type boxing and unboxing. Most methods return the same instance of InstructionBuilder, allowing for a "fluid" API. More complex functionality, such as try/catch blocks, is more like a DSL (domain specific language), and is based on callbacks. This looks better in Groovy and will be more reasonable once JDK 1.8 closures are available; in the meantime, it means some deeply nested inner classes, but helps ensure that correct bytecode is generated and helps to limit the amount of bookkeeping is necessary on the part of code using InstructionBuilder.
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description InstructionBuilder
arrayLength()
Expects the top object on the stack to be an array.InstructionBuilder
boxPrimitive(String typeName)
If the type name is a primitive type, adds code to box the type into the equivalent wrapper type, using static methods on the wrapper type.InstructionBuilder
castOrUnbox(String typeName)
Casts the object on top of the stack to the indicated type.InstructionBuilder
checkcast(Class clazz)
InstructionBuilder
checkcast(String className)
Adds a check that the object on top of the stack is assignable to the indicated class.InstructionBuilder
compareSpecial(String typeName)
Special comparison logic for primitive float, double and long.InstructionBuilder
doWhile(Condition condition, WhileCallback callback)
Implements a simple loop based on a condition.InstructionBuilder
dupe()
Duplicates the top object on the stack.InstructionBuilder
dupe(int depth)
Duplicates the top object on the stack, placing the result at some depth.InstructionBuilder
dupeWide()
Duplicates a wide value (a primitive long or double).InstructionBuilder
getField(String className, String fieldName, Class fieldType)
Loads a field onto the stack.InstructionBuilder
getField(String className, String fieldName, String typeName)
Loads an instance field onto the stack.InstructionBuilder
getField(PlasticField field)
Loads an instance or static field onto the stack.InstructionBuilder
getStaticField(String className, String fieldName, Class fieldType)
Gets a static field; does not consume a value from the stack, but pushes the fields' value onto the stack.InstructionBuilder
getStaticField(String className, String fieldName, String typeName)
Gets a static field; does not consume a value from the stack, but pushes the fields' value onto the stack.InstructionBuilder
increment(LocalVariable variable)
Increments a local integer variable.InstructionBuilder
invoke(Class clazz, Class returnType, String methodName, Class... argumentTypes)
Automatically invokes an interface or virtual method.InstructionBuilder
invoke(Method method)
Automatically invokes an interface or virtual method.InstructionBuilder
invokeConstructor(Class clazz, Class... argumentTypes)
InstructionBuilder
invokeConstructor(String className, String... argumentTypes)
Invokes a constructor on a class.InstructionBuilder
invokeInterface(String interfaceName, String returnType, String methodName, String... argumentTypes)
Invokes a standard virtual method.InstructionBuilder
invokeSpecial(String containingClassName, MethodDescription description)
Invokes an instance method of a base class, or a private method of a class, using the target object and parameters already on the stack.InstructionBuilder
invokeStatic(Class clazz, Class returnType, String methodName, Class... argumentTypes)
Invokes a static method of a class.InstructionBuilder
invokeVirtual(String className, String returnType, String methodName, String... argumentTypes)
Invokes a standard virtual method.InstructionBuilder
invokeVirtual(PlasticMethod method)
InstructionBuilder
iterateArray(InstructionBuilderCallback callback)
Expects an array to be the top value on the stack.InstructionBuilder
loadArgument(int index)
Loads an argument onto the stack, using the opcode appropriate to the argument's type.InstructionBuilder
loadArguments()
Loads all arguments for the current method onto the stack; this is used when invoking a method that takes the exact same parameters (often, a super-class implementation).InstructionBuilder
loadArrayElement()
Loads a value from an array object.InstructionBuilder
loadArrayElement(int index, String elementType)
Loads a value from an array object, which must be the top element of the stack.InstructionBuilder
loadConstant(Object constant)
Loads a constant valueInstructionBuilder
loadNull()
Loads the null constant onto the stack.InstructionBuilder
loadThis()
Loads this onto the stack.InstructionBuilder
loadTypeConstant(Class type)
Loads a Java type (a Class instance) as a constant.InstructionBuilder
loadTypeConstant(String typeName)
Loads a Java type (a Class instance) as a constant.InstructionBuilder
loadVariable(LocalVariable variable)
Loads a value from a local variable and pushes it onto the stack.InstructionBuilder
newInstance(Class clazz)
A convenience version ofnewInstance(String)
used when the class is known at build time.InstructionBuilder
newInstance(String className)
Creates a new, uninitialized instance of the indicated class.InstructionBuilder
pop()
Discards the top value on the stack.InstructionBuilder
popWide()
Pops a wide value (a primitive long or double).InstructionBuilder
putField(String className, String fieldName, Class fieldType)
InstructionBuilder
putField(String className, String fieldName, String typeName)
Expects the stack to contain the instance to update, and the value to store into the field.InstructionBuilder
putStaticField(String className, String fieldName, Class fieldType)
Sets a static field; the new field value should be on top of the stack.InstructionBuilder
putStaticField(String className, String fieldName, String typeName)
Sets a static field; the new field value should be on top of the stack.InstructionBuilder
returnDefaultValue()
Returns the default value for the method, which may be null, or a specific primitive value.InstructionBuilder
returnResult()
Returns the top value on the stack.InstructionBuilder
startSwitch(int min, int max, SwitchCallback callback)
Starts a switch statement.InstructionBuilder
startTryCatch(TryCatchCallback tryCatchCallback)
Defines the start of a block that can have exception handlers and finally blocks applied.InstructionBuilder
startVariable(String type, LocalVariableCallback callback)
Starts a block where the given name is active.InstructionBuilder
storeVariable(LocalVariable variable)
Stores the value on top of the stack to a local variable (previously defined bystartVariable(String, LocalVariableCallback)
.InstructionBuilder
swap()
Swaps the top element of the stack with the next element down.InstructionBuilder
throwException()
Throws the exception on the top of the stack.InstructionBuilder
throwException(Class<? extends Throwable> exceptionType, String message)
InstructionBuilder
throwException(String className, String message)
Throws an exception with a fixed message.InstructionBuilder
unboxPrimitive(String typeName)
Unboxes a wrapper type to a primitive type if typeName is a primitive type name (the value on the stack should be the corresponding wrapper type instance).InstructionBuilder
when(Condition condition, InstructionBuilderCallback ifTrue)
Simplified version ofwhen(Condition, WhenCallback)
that simply executes the callback code when the condition is true and does nothing if the condition is false (the more general case).InstructionBuilder
when(Condition condition, WhenCallback callback)
Executes conditional code based on aCondition
.
-
-
-
Method Detail
-
returnDefaultValue
@Opcodes("ACONST_NULL, LCONST_0, FCONST_0, DCONST_0, ICONST_0, RETURN, ARETURN, IRETURN, FRETURN, LRETURN, DRETURN") InstructionBuilder returnDefaultValue()
Returns the default value for the method, which may be null, or a specific primitive value.
-
loadThis
@Opcodes("ALOAD") InstructionBuilder loadThis()
Loads this onto the stack.
-
loadNull
@Opcodes("ACONST_NULL") InstructionBuilder loadNull()
Loads the null constant onto the stack.
-
loadArgument
@Opcodes("ALOAD, ILOAD, LLOAD, FLOAD, DLOAD") InstructionBuilder loadArgument(int index)
Loads an argument onto the stack, using the opcode appropriate to the argument's type. In addition this automatically adjusts for arguments of primitive type long or double (which take up two local variable indexes, rather than one as for all other types)- Parameters:
index
- to argument (0 is the first argument, not this)
-
loadArguments
@Opcodes("ALOAD, ILOAD, LLOAD, FLOAD, DLOAD") InstructionBuilder loadArguments()
Loads all arguments for the current method onto the stack; this is used when invoking a method that takes the exact same parameters (often, a super-class implementation). A call toloadThis()
(or some other way of identifying the target method) should precede this call.
-
invokeSpecial
@Opcodes("INVOKESPECIAL") InstructionBuilder invokeSpecial(String containingClassName, MethodDescription description)
Invokes an instance method of a base class, or a private method of a class, using the target object and parameters already on the stack. Leaves the result on the stack (unless its a void method).- Parameters:
containingClassName
- class name containing the methoddescription
- describes the method name, parameters and return type
-
invokeVirtual
@Opcodes("INVOKEVIRTUAL") InstructionBuilder invokeVirtual(String className, String returnType, String methodName, String... argumentTypes)
Invokes a standard virtual method.
-
invokeVirtual
@Opcodes("INVOKEVIRTUAL") InstructionBuilder invokeVirtual(PlasticMethod method)
-
invokeInterface
@Opcodes("INVOKEINTERFACE") InstructionBuilder invokeInterface(String interfaceName, String returnType, String methodName, String... argumentTypes)
Invokes a standard virtual method.
-
invoke
@Opcodes("INVOKEVIRTUAL, INVOKEINTERFACE") InstructionBuilder invoke(Class clazz, Class returnType, String methodName, Class... argumentTypes)
Automatically invokes an interface or virtual method. Remember to useinvokeConstructor(Class, Class...)
for constructors andinvokeSpecial(String, MethodDescription)
for private methods.
-
invoke
InstructionBuilder invoke(Method method)
Automatically invokes an interface or virtual method. Remember to useinvokeConstructor(Class, Class...)
for constructors andinvokeSpecial(String, MethodDescription)
for private methods.
-
invokeStatic
@Opcodes("INVOKESTATIC") InstructionBuilder invokeStatic(Class clazz, Class returnType, String methodName, Class... argumentTypes)
Invokes a static method of a class.
-
returnResult
@Opcodes("ARETURN, IRETURN, LRETURN, FRETURN, DRETURN") InstructionBuilder returnResult()
Returns the top value on the stack. For void methods, no value should be on the stack and the method will simply return.
-
boxPrimitive
@Opcodes("INVOKESTATIC") InstructionBuilder boxPrimitive(String typeName)
If the type name is a primitive type, adds code to box the type into the equivalent wrapper type, using static methods on the wrapper type. Does nothing if the type is not primitive, or type void.
-
unboxPrimitive
@Opcodes("INVOKEVIRTUAL") InstructionBuilder unboxPrimitive(String typeName)
Unboxes a wrapper type to a primitive type if typeName is a primitive type name (the value on the stack should be the corresponding wrapper type instance). Does nothing for non-primitive types.- Parameters:
typeName
- possibly primitive type name
-
getField
@Opcodes("GETFIELD") InstructionBuilder getField(String className, String fieldName, String typeName)
Loads an instance field onto the stack. The object containing the field should already be loaded onto the stack (usually, vialoadThis()
).- Parameters:
className
- name of class containing the fieldfieldName
- name of the fieldtypeName
- type of field
-
getField
@Opcodes("GETFIELD") InstructionBuilder getField(PlasticField field)
Loads an instance or static field onto the stack. The plastic class instance containing the field should already be loaded onto the stack (usually, vialoadThis()
).- Parameters:
field
- identifies name, type and container of field to load
-
getField
@Opcodes("GETFIELD") InstructionBuilder getField(String className, String fieldName, Class fieldType)
Loads a field onto the stack. This version is used when the field type is known at build time, rather than discovered at runtime.- Parameters:
className
- name of class containing the fieldfieldName
- name of the fieldfieldType
- type of field
-
getStaticField
@Opcodes("GETSTATIC") InstructionBuilder getStaticField(String className, String fieldName, Class fieldType)
Gets a static field; does not consume a value from the stack, but pushes the fields' value onto the stack.- Parameters:
className
- name of class containing the fieldfieldName
- name of the fieldfieldType
- type of field
-
getStaticField
@Opcodes("GETSTATIC") InstructionBuilder getStaticField(String className, String fieldName, String typeName)
Gets a static field; does not consume a value from the stack, but pushes the fields' value onto the stack.- Parameters:
className
- name of class containing the fieldfieldName
- name of the fieldtypeName
- type of field
-
putStaticField
@Opcodes("PUTSTATIC") InstructionBuilder putStaticField(String className, String fieldName, Class fieldType)
Sets a static field; the new field value should be on top of the stack.- Parameters:
className
- name of class containing the fieldfieldName
- name of the fieldfieldType
- type of field
-
putStaticField
@Opcodes("PUTSTATIC") InstructionBuilder putStaticField(String className, String fieldName, String typeName)
Sets a static field; the new field value should be on top of the stack.- Parameters:
className
- name of class containing the fieldfieldName
- name of the fieldtypeName
- type of field
-
putField
@Opcodes("PUTFIELD") InstructionBuilder putField(String className, String fieldName, String typeName)
Expects the stack to contain the instance to update, and the value to store into the field.
-
putField
@Opcodes("PUTFIELD") InstructionBuilder putField(String className, String fieldName, Class fieldType)
-
loadArrayElement
@Opcodes("LDC, AALOAD") InstructionBuilder loadArrayElement(int index, String elementType)
Loads a value from an array object, which must be the top element of the stack.- Parameters:
index
- constant index into the arrayelementType
- the type name of the elements of the array Note: currently only reference types (objects and arrays) are supported, not primitives
-
loadArrayElement
@Opcodes("AALOAD") InstructionBuilder loadArrayElement()
Loads a value from an array object. The stack should have the array at depth 1, and an array index on top. Only object arrays (not arrays of primitives) are supported.
-
checkcast
@Opcodes("CHECKCAST") InstructionBuilder checkcast(String className)
Adds a check that the object on top of the stack is assignable to the indicated class.- Parameters:
className
- class to cast to
-
checkcast
@Opcodes("CHECKCAST") InstructionBuilder checkcast(Class clazz)
-
startTryCatch
InstructionBuilder startTryCatch(TryCatchCallback tryCatchCallback)
Defines the start of a block that can have exception handlers and finally blocks applied. Continue using this InstructionBuilder to define code inside the block, then call methods on the InstructionBlock to define the end of the block and set up handlers.- Parameters:
tryCatchCallback
- allows generation of try, catch, and finally clauses
-
newInstance
@Opcodes("NEW") InstructionBuilder newInstance(String className)
Creates a new, uninitialized instance of the indicated class. This should be followed by code to call the new instance's constructor.- Parameters:
className
- of class to instantiate
-
newInstance
@Opcodes("NEW") InstructionBuilder newInstance(Class clazz)
A convenience version ofnewInstance(String)
used when the class is known at build time.- Parameters:
clazz
- to instantiate
-
invokeConstructor
@Opcodes("INVOKESPECIAL") InstructionBuilder invokeConstructor(String className, String... argumentTypes)
Invokes a constructor on a class. The instance should already be on the stack, followed by the right number and type of parameters. Note that a constructor acts like a void method, so you will often follow the sequence: newInstance(), dupe(0), invokeConstructor() so that a reference to the instance is left on the stack.F- Parameters:
className
- the class containing the constructorargumentTypes
- java type names for each argument of the constructor
-
invokeConstructor
@Opcodes("INVOKESPECIAL") InstructionBuilder invokeConstructor(Class clazz, Class... argumentTypes)
-
dupe
@Opcodes("DUP, DUP_X1, DUP_X2") InstructionBuilder dupe(int depth)
Duplicates the top object on the stack, placing the result at some depth.- Parameters:
depth
- 0 (DUP), 1 (DUP_X1) or 2 (DUP_X2)
-
dupeWide
@Opcodes("DUP2") InstructionBuilder dupeWide()
Duplicates a wide value (a primitive long or double).
-
popWide
@Opcodes("POP2") InstructionBuilder popWide()
Pops a wide value (a primitive long or double).
-
dupe
@Opcodes("DUP") InstructionBuilder dupe()
Duplicates the top object on the stack. Commonly used withwhen(Condition, WhenCallback)
.- See Also:
dupe(int)
-
pop
InstructionBuilder pop()
Discards the top value on the stack. Assumes the value is a single word value: an object reference, or a small primitive) and not a double or long.
-
swap
@Opcodes("SWAP") InstructionBuilder swap()
Swaps the top element of the stack with the next element down. Note that this can cause problems if the top element on the stack is a long or double.
-
loadConstant
@Opcodes("LDC, ICONST_*, LCONST_*, FCONST_*, DCONST_*, ACONST_NULL") InstructionBuilder loadConstant(Object constant)
Loads a constant value- Parameters:
constant
- Integer, Float, Double, Long, String or null
-
loadTypeConstant
@Opcodes("LDC") InstructionBuilder loadTypeConstant(String typeName)
Loads a Java type (a Class instance) as a constant. This assumes the type name is the name of class (or array) but not a primitive type.- Parameters:
typeName
- Java class name
-
loadTypeConstant
@Opcodes("LDC") InstructionBuilder loadTypeConstant(Class type)
Loads a Java type (a Class instance) as a constant. This assumes the type name is the name of class (or array) but not a primitive type.- Parameters:
type
- Java type to load as a constant
-
castOrUnbox
@Opcodes("CHECKCAST, INVOKEVIRTUAL") InstructionBuilder castOrUnbox(String typeName)
Casts the object on top of the stack to the indicated type. For primitive types, casts to the wrapper type and invokes the appropriate unboxing static method call, leaving a primitive type value on the stack.- Parameters:
typeName
- to cast or unbox to
-
throwException
@Opcodes("NEW, DUP, LDC, INVOKESPECIAL, ATHROW") InstructionBuilder throwException(String className, String message)
Throws an exception with a fixed message. Assumes the exception class includes a constructor that takes a single string.- Parameters:
className
- name of exception class to instantiatemessage
- message (passed as first and only parameter to constructor)
-
throwException
@Opcodes("NEW, DUP, LDC, INVOKESPECIAL, ATHROW") InstructionBuilder throwException(Class<? extends Throwable> exceptionType, String message)
-
throwException
@Opcodes("ATHROW") InstructionBuilder throwException()
Throws the exception on the top of the stack.
-
startSwitch
@Opcodes("TABLESWITCH") InstructionBuilder startSwitch(int min, int max, SwitchCallback callback)
Starts a switch statement.- Parameters:
min
- the minimum value to match againstmax
- the maximum value to match against
-
startVariable
InstructionBuilder startVariable(String type, LocalVariableCallback callback)
Starts a block where the given name is active.- Parameters:
type
- type of local variablecallback
- generates code used when variable is in effect
-
storeVariable
@Opcodes("ASTORE, ISTORE, LSTORE, FSTORE, DSTORE") InstructionBuilder storeVariable(LocalVariable variable)
Stores the value on top of the stack to a local variable (previously defined bystartVariable(String, LocalVariableCallback)
.
-
loadVariable
@Opcodes("ALOAD, ILOAD, LLOAD, FLOAD, DLOAD") InstructionBuilder loadVariable(LocalVariable variable)
Loads a value from a local variable and pushes it onto the stack. The variable is defined bystartVariable(String, LocalVariableCallback)
.
-
when
@Opcodes("IFEQ, etc., GOTO") InstructionBuilder when(Condition condition, WhenCallback callback)
Executes conditional code based on aCondition
. The testing opcodes all pop the value off the stack, so this is usually preceded bydupe(0)
.- Parameters:
condition
- defines true and false casescallback
- provides code for true and false blocks- Returns:
- this builder
-
when
@Opcodes("IFEQ, etc., GOTO") InstructionBuilder when(Condition condition, InstructionBuilderCallback ifTrue)
Simplified version ofwhen(Condition, WhenCallback)
that simply executes the callback code when the condition is true and does nothing if the condition is false (the more general case). The testing opcodes all pop the value off the stack, so this is usually preceded bydupe(0)
.- Parameters:
condition
- to evaluateifTrue
- generates code for when condition is true- Returns:
- this builder
-
doWhile
@Opcodes("IFEQ, etc., GOTO") InstructionBuilder doWhile(Condition condition, WhileCallback callback)
Implements a simple loop based on a condition. First the WhileCallback.buildTest(InstructionBuilder) code is executed, then the condition is evaluated (which will consume at least the top value on the stack). When the condition is false, the loop is exited. When the condition is true, the code defined byWhileCallback.buildBody(InstructionBuilder)
is executed, and then a GOTO back to the test code.- Parameters:
condition
-callback
-- Returns:
- this builder
-
iterateArray
@Opcodes("IINC, ARRAYLENGTH, IFEQ, etc., GOTO") InstructionBuilder iterateArray(InstructionBuilderCallback callback)
Expects an array to be the top value on the stack. Iterates the array. The callback generates code that will have each successive value from the array as the top value on the stack. Creates a variable to store the loop index.- Parameters:
callback
- to invoke. The element will be the top value on the stack. The callback is responsible for removing it from the stack.- Returns:
- this builder
-
increment
@Opcodes("IINC") InstructionBuilder increment(LocalVariable variable)
Increments a local integer variable.- Returns:
- this builder
-
arrayLength
@Opcodes("ARRAYLENGTH") InstructionBuilder arrayLength()
Expects the top object on the stack to be an array. Replaces it with the length of that array.
-
compareSpecial
@Opcodes("LCMP, FCMPL, DCMPL") InstructionBuilder compareSpecial(String typeName)
Special comparison logic for primitive float, double and long. Expect two matching wide values on the stack. Reduces the two wide values to a single int value: -1, 0, or 1 depending on whether the deeper value is less than, equal to, or greater than the top value on the stack.- Parameters:
typeName
-
-
-