Package com.ibm.wala.util.ssa
Class ParameterAccessor
- java.lang.Object
-
- com.ibm.wala.util.ssa.ParameterAccessor
-
public class ParameterAccessor extends Object
Access parameters without confusion on their numbers. Depending on the representation of a method (IMethod, MethodReference) parameters are placed at a different position. Functions furthermore may have an implicit this-pointer which alters the positions again. Accessing parameters of these functions by their numbers only is error prone and leads to confusion. This class tries to leverage parameter-access. You can use this class using now numbers at all. However if you choose to use numbers this class has yet another numbering convention (jupeee): 1 is the first parameter appearing in the Selector, no matter if the Method has an implicit this. It is not zero as Java initializes new integer-arrays with zero. If you want to alter the values of the incoming parameters you may also want to use the ParameterManager which tracks the changes.- Since:
- 2013-10-19
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
ParameterAccessor.BasedOn
The Constructor used to create ParameterAccessor influences the parameter-offset.static class
ParameterAccessor.ParamerterDisposition
The kind of parameter.static class
ParameterAccessor.Parameter
The representation of a Parameter handled using a ParameterAccessor.static class
ParameterAccessor.ParameterKey
This key is identified by type and parameter number.
-
Constructor Summary
Constructors Constructor Description ParameterAccessor(IMethod method)
Read the parameters from an IMethod.ParameterAccessor(MethodReference mRef, boolean hasImplicitThis)
Reads the parameters of a MethodReference CAUTION:.ParameterAccessor(MethodReference mRef, IClassHierarchy cha)
Reads the parameters of a MethodReference CAUTION:.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description List<ParameterAccessor.Parameter>
all()
This list _excludes_ the implicit this-pointer (if any).List<ParameterAccessor.Parameter>
allExtend(TypeName tName, IClassHierarchy cha)
All parameters in the selector that are a subclass of tName (slow).List<ParameterAccessor.Parameter>
allExtend(TypeReference tRef, IClassHierarchy cha)
All parameters in the selector that are a subclass of tRef (slow).List<SSAValue>
connectThrough(ParameterAccessor callee, Set<? extends SSAValue> overrides, Set<? extends SSAValue> defaults, IClassHierarchy cha)
Assign parameters to a call based on their type.List<SSAValue>
connectThrough(ParameterAccessor callee, Set<? extends SSAValue> overrides, Set<? extends SSAValue> defaults, IClassHierarchy cha, IInstantiator instantiator, Object... instantiatorArgs)
Connects though parameters from the calling function (overridable) - CAUTION:.String
dump()
Extensive output for debugging purposes.ParameterAccessor.Parameter
firstExtends(TypeName tName, IClassHierarchy cha)
First parameter in the selector that is a subclass of tName (slow).ParameterAccessor.Parameter
firstExtends(TypeReference tRef, IClassHierarchy cha)
First parameter in the selector that is a subclass of tRef (slow).int
firstInSelector()
The SSA-Value to acces the parameter appearing first in the Descriptor with.ParameterAccessor.Parameter
firstOf(TypeName tName)
First parameter in the selector that matches _exactly_.ParameterAccessor.Parameter
firstOf(TypeReference tRef)
First parameter in the selector that matches _exactly_.int[]
forInvokeStatic(List<? extends ParameterAccessor.Parameter> args, MethodReference target, IClassHierarchy cha)
Shorthand for forInvokeStatic(final List extends Parameter> args, final ParameterAccessor target, final IClassHierarchy cha).int[]
forInvokeStatic(List<? extends SSAValue> args)
Generate the params-param for an InvokeIstruction w/o type checking.int[]
forInvokeStatic(List<? extends SSAValue> args, ParameterAccessor target, IClassHierarchy cha)
Generate the params-param for an InvokeIstruction with type checking.int[]
forInvokeVirtual(int self, List<? extends ParameterAccessor.Parameter> args, MethodReference target, IClassHierarchy cha)
Shorthand for forInvokeVirtual(final int self, final List extends Parameter> args, final ParameterAccessor target, final IClassHierarchy cha).int[]
forInvokeVirtual(int self, List<? extends SSAValue> args)
Generate the params-param for an InvokeIstruction w/o type checking.int[]
forInvokeVirtual(int self, List<? extends SSAValue> args, ParameterAccessor target, IClassHierarchy cha)
Generate the params-param for an InvokeIstruction with type checking.MethodReference
forMethod()
The method this accessor reads the parameters from.int
getFirstAfter()
The first SSA-Number after the parameters.int
getNumberOfParameters()
Number of parameters _excluding_ implicit thisParameterAccessor.Parameter
getParameter(int no)
Make an Parameter Object using a Descriptor-based numbering (starting with 1).int
getParameterNo(int no)
Return the SSA-Value to access a parameter using a Descriptor-based numbering (starting with 1).int
getParameterNo(ParameterAccessor.Parameter param)
Same as Parameter.getNumber().TypeReference
getParameterType(int no)
Prefer: getParameter(int no) or all().TypeReference
getReturnType()
Handed through to the IMethod / MethodReferenceParameterAccessor.Parameter
getThis()
Return the implicit this-pointer (or throw).ParameterAccessor.Parameter
getThisAs(TypeReference asType)
Return the implicit this-pointer as a supertype.int
getThisNo()
Return the SSA-Value of the implicit this-pointer (or throw).boolean
hasImplicitThis()
If the method has an implicit this parameter.boolean
hasReturn()
If the method returns a value eg is non-void.static boolean
isAssignable(TypeReference from, TypeReference to, IClassHierarchy cha)
Does "to x := from" hold?.protected boolean
isAssignable(SSAValue from, SSAValue to, IClassHierarchy cha)
Does "to x := from" hold?.static boolean
isSubclassOf(TypeReference sub, TypeReference superC, IClassHierarchy cha)
Is sub a subclass of superC (or the same).ParameterAccessor.Parameter
makeReturn(int ssa)
Create a "Parameter" containing the Return-Type w/o Type-checking.ParameterAccessor.Parameter
makeReturn(int ssa, TypeReference type, IClassHierarchy cha)
Create a "Parameter" containing the Return-Type with Type-checking.String
toString()
-
-
-
Constructor Detail
-
ParameterAccessor
public ParameterAccessor(MethodReference mRef, IClassHierarchy cha)
Reads the parameters of a MethodReference CAUTION:. Do _not_ use ParameterAceesor(IMethod.getReference()), but ParameterAceesor(IMehod)! Using this Constructor influences the SSA-Values returned later. The cha is needed to determine whether mRef is static. If this is already known one should prefer the faster#ParameterAccessor(ParameterAccessor, boolean)
.- Parameters:
mRef
- The method to read the parameters from.
-
ParameterAccessor
public ParameterAccessor(MethodReference mRef, boolean hasImplicitThis)
Reads the parameters of a MethodReference CAUTION:. Do _not_ use ParameterAceesor(IMethod.getReference()), but ParameterAceesor(IMehod)! This constructor is faster than {@link #ParameterAccessor(MethodReference, IClassHierarchy}.- Parameters:
mRef
- The method to read the parameters from.
-
ParameterAccessor
public ParameterAccessor(IMethod method)
Read the parameters from an IMethod. Using this Constructor influences the SSA-Values returned later.- Parameters:
method
- The method to read the parameters from.
-
-
Method Detail
-
getParameter
public ParameterAccessor.Parameter getParameter(int no)
Make an Parameter Object using a Descriptor-based numbering (starting with 1). Number 1 is the first parameter in the methods Selector. No matter if the function has an implicit this pointer. If the Function has an implicit this-pointer you can access it using getThis().- Parameters:
no
- the number in the Selector- Returns:
- new Parameter-Object for no
- Throws:
IllegalArgumentExceptions
- if the parameter is zeroArrayIndexOutOfBoundsException
- if no is not within bounds [1 to numberOfParameters]
-
getParameterNo
public int getParameterNo(int no)
Return the SSA-Value to access a parameter using a Descriptor-based numbering (starting with 1). Number 1 is the first parameter in the methods Selector. No matter if the function has an implicit this pointer. If the Function has an implicit this-pointer you can acess it using getThisNo().- Parameters:
no
- the number in the Selector- Returns:
- the offseted number for accessing the parameter
- Throws:
IllegalArgumentException
- if the parameter is zeroArrayIndexOutOfBoundsException
- if no is not within bounds [1 to numberOfParameters]
-
getParameterNo
public int getParameterNo(ParameterAccessor.Parameter param)
Same as Parameter.getNumber().- Returns:
- SSA-Value to access the parameters contents.
-
all
public List<ParameterAccessor.Parameter> all()
This list _excludes_ the implicit this-pointer (if any). If you want the implicit this-pointer use getThis().- Returns:
- All parameters appearing in the Selector.
-
getThis
public ParameterAccessor.Parameter getThis()
Return the implicit this-pointer (or throw). This obviously only works on non-static methods. You probably want to check if the method has such an implicit this using hasImplicitThis() as this method will throw if there is none. If you only want the number use the more lightweight getThisNo().- Returns:
- Object containing all Information on the parameter.
- Throws:
IllegalStateException
- if the function has no implicit this
-
getThisAs
public ParameterAccessor.Parameter getThisAs(TypeReference asType)
Return the implicit this-pointer as a supertype.- Parameters:
asType
- A type of a super-class of this
-
getThisNo
public int getThisNo()
Return the SSA-Value of the implicit this-pointer (or throw). This obviously only works on non-static methods. You probably want to check if the method has such an implicit this using hasImplicitThis() as this method will throw if there is none.- Returns:
- Number of the this.
- Throws:
IllegalStateException
- if the function has no implicit this.
-
hasImplicitThis
public boolean hasImplicitThis()
If the method has an implicit this parameter.
-
makeReturn
public ParameterAccessor.Parameter makeReturn(int ssa)
Create a "Parameter" containing the Return-Type w/o Type-checking. This should be of rather theoretical use.- Throws:
IllegalStateException
- if used on a void-Function
-
makeReturn
public ParameterAccessor.Parameter makeReturn(int ssa, TypeReference type, IClassHierarchy cha)
Create a "Parameter" containing the Return-Type with Type-checking.- Parameters:
ssa
- The value to returntype
- The type of ssacha
- The ClassHierarchy to use for the assignability test- Throws:
IllegalStateException
- if used on a void-Function
-
firstInSelector
public int firstInSelector()
The SSA-Value to acces the parameter appearing first in the Descriptor with.- Throws:
IllegalArgumentException
- if the method has no parameters in its Descriptor.
-
getParameterType
public TypeReference getParameterType(int no)
Prefer: getParameter(int no) or all(). Get the type of the parameter (not this) using a fixed numbering. Number 1 is the first parameter in the methods Selector. No matter if the function has an implicit this pointer. Use all() if you want to get all parameter-types.- Parameters:
no
- the number in the Selector- Returns:
- the type of the parameter
-
firstOf
public ParameterAccessor.Parameter firstOf(TypeName tName)
First parameter in the selector that matches _exactly_.- Returns:
- first parameter found or null if there is none
- Throws:
IllegalArgumentException
- if searching for void or null
-
firstOf
public ParameterAccessor.Parameter firstOf(TypeReference tRef)
First parameter in the selector that matches _exactly_.- Returns:
- first parameter found or null if there is none
- Throws:
IllegalArgumentException
- if searching for void or null
-
allExtend
public List<ParameterAccessor.Parameter> allExtend(TypeName tName, IClassHierarchy cha)
All parameters in the selector that are a subclass of tName (slow). TypeNames have to be looked up first, do prefer the variant with the TypeReference if one is available.- Throws:
IllegalArgumentException
- if searching for void or null
-
allExtend
public List<ParameterAccessor.Parameter> allExtend(TypeReference tRef, IClassHierarchy cha)
All parameters in the selector that are a subclass of tRef (slow).- Throws:
IllegalArgumentException
- if searching for void or null
-
firstExtends
public ParameterAccessor.Parameter firstExtends(TypeName tName, IClassHierarchy cha)
First parameter in the selector that is a subclass of tName (slow). TypeNames have to be lloked up first, do prefer the variant with the TypeReference if one is available.- Returns:
- first parameter found or null if there is none
- Throws:
IllegalArgumentException
- if searching for void or null
-
firstExtends
public ParameterAccessor.Parameter firstExtends(TypeReference tRef, IClassHierarchy cha)
First parameter in the selector that is a subclass of tRef (slow).- Returns:
- first parameter found or null if there is none
- Throws:
IllegalArgumentException
- if searching for void or null
-
getFirstAfter
public int getFirstAfter()
The first SSA-Number after the parameters. This is useful for making synthetic methods.
-
forInvokeStatic
public int[] forInvokeStatic(List<? extends SSAValue> args)
Generate the params-param for an InvokeIstruction w/o type checking.- Parameters:
args
- list to build the arguments from - without implicit this
-
forInvokeStatic
public int[] forInvokeStatic(List<? extends SSAValue> args, ParameterAccessor target, IClassHierarchy cha)
Generate the params-param for an InvokeIstruction with type checking.- Parameters:
args
- list to build the arguments from - without implicit thistarget
- the method to be called - for type checking onlycha
- if types don't match exactly needed for the assignability check (may be null if that check is not wanted)- Throws:
IllegalArgumentException
- if you call this method on a target that needs an implicit thisIllegalArgumentException
- if args length does not match the targets param-lengthIllegalArgumentException
- if a parameter is unassignable
-
forInvokeVirtual
public int[] forInvokeVirtual(int self, List<? extends SSAValue> args)
Generate the params-param for an InvokeIstruction w/o type checking.- Parameters:
self
- the this-pointer to useargs
- the rest of the arguments. Be shure it does not start with a this pointer. This is _not_ checked so you can use a this-pointer as an argument. However a warning is issued.- Throws:
IllegalArgumentException
- if the value of self is to small in the current method
-
forInvokeVirtual
public int[] forInvokeVirtual(int self, List<? extends SSAValue> args, ParameterAccessor target, IClassHierarchy cha)
Generate the params-param for an InvokeIstruction with type checking.- Parameters:
self
- the this-pointer to useargs
- list to build the arguments from - without implicit thistarget
- the method to be called - for type checking onlycha
- if types don't match exactly needed for the assignability check (may be null if that check is not wanted)- Throws:
IllegalArgumentException
- if you call this method on a target that needs an implicit thisIllegalArgumentException
- if args length does not match the targets param-lengthIllegalArgumentException
- if a parameter is unassignable
-
connectThrough
public List<SSAValue> connectThrough(ParameterAccessor callee, Set<? extends SSAValue> overrides, Set<? extends SSAValue> defaults, IClassHierarchy cha, IInstantiator instantiator, Object... instantiatorArgs)
Connects though parameters from the calling function (overridable) - CAUTION:. This functions makes is decisions based on Type-Referes only so if a TypeReference occurs multiple times in the caller or callee it may make surprising connections. The List of Parameters is generated based on the overrides, than parameters in 'this' are searched, finally we'll fall back to defaults. A "perfect match" is searched. If a parameter was not assigned yet these three sources are considdered again but cha.isAssignableFrom is used. If the parameter was still not found a value of 'null' is used. This funktion is useful when generating wrapper-functions.- Parameters:
callee
- The function to generate the parameter-list foroverrides
- If a parameter occurs here, it is preferred over the ones present in thisdefaults
- If a parameter is not present in this or the overrides, defaults are searched. If the parameter is not present there null is assigned.cha
- Optional class hierarchy for testing assignability- Returns:
- the parameter-list for the call of toMethod
-
isAssignable
public static boolean isAssignable(TypeReference from, TypeReference to, IClassHierarchy cha)
Does "to x := from" hold?.
-
isSubclassOf
public static boolean isSubclassOf(TypeReference sub, TypeReference superC, IClassHierarchy cha) throws ClassLookupException
Is sub a subclass of superC (or the same).- Throws:
ClassLookupException
-
forMethod
public MethodReference forMethod()
The method this accessor reads the parameters from.
-
isAssignable
protected boolean isAssignable(SSAValue from, SSAValue to, IClassHierarchy cha)
Does "to x := from" hold?.
-
forInvokeStatic
public int[] forInvokeStatic(List<? extends ParameterAccessor.Parameter> args, MethodReference target, IClassHierarchy cha)
Shorthand for forInvokeStatic(final List extends Parameter> args, final ParameterAccessor target, final IClassHierarchy cha). Generates a new ParameterAccessor for target and hands the call through.
-
forInvokeVirtual
public int[] forInvokeVirtual(int self, List<? extends ParameterAccessor.Parameter> args, MethodReference target, IClassHierarchy cha)
Shorthand for forInvokeVirtual(final int self, final List extends Parameter> args, final ParameterAccessor target, final IClassHierarchy cha). Generates a new ParameterAccessor for target and hands the call through.
-
hasReturn
public boolean hasReturn()
If the method returns a value eg is non-void.
-
connectThrough
public List<SSAValue> connectThrough(ParameterAccessor callee, Set<? extends SSAValue> overrides, Set<? extends SSAValue> defaults, IClassHierarchy cha)
Assign parameters to a call based on their type. this variant of connectThrough cannot create new instances if needed.- Parameters:
callee
- The function to generate the parameter-list foroverrides
- If a parameter occurs here, it is preferred over the ones present in thisdefaults
- If a parameter is not present in this or the overrides, defaults are searched. If the parameter is not present there null is assigned.cha
- Optional class hierarchy for testing assignability- Returns:
- the parameter-list for the call of toMethod
-
getReturnType
public TypeReference getReturnType()
Handed through to the IMethod / MethodReference
-
getNumberOfParameters
public int getNumberOfParameters()
Number of parameters _excluding_ implicit this
-
dump
public String dump()
Extensive output for debugging purposes.
-
-