Methods Summary |
---|
public static void | computeStackTypes(java.lang.String stackSig, java.util.Stack stack)stackSig is a signature for a list of types on the JVM stack with the
last type in the signature intended to be on the top of JVM stack.
For each type in the signature, pushes an Integer objects identifying
the types on top of the input Stack object.
for (int idx = 0; idx < stackSig.length(); idx++) {
int tp = 0;
switch(stackSig.charAt(idx)) {
case 'B":
case 'C":
case 'Z":
case 'S":
case 'I":
tp = T_INT;
break;
case 'F":
tp = T_FLOAT;
break;
case 'J":
tp = T_LONG;
break;
case 'D":
tp = T_DOUBLE;
break;
case '?":
tp = T_UNKNOWN;
break;
case 'W":
tp = T_WORD;
break;
case 'X":
tp = T_TWOWORD;
break;
case 'A":
/* This isn't a real type, but any object refrence */
tp = TC_OBJECT;
break;
case '[":
tp = TC_OBJECT;
while (stackSig.charAt(idx) == '[" || stackSig.charAt(idx) == ']")
idx++;
if (stackSig.charAt(idx) != 'L")
break;
/* fall through */
case 'L":
tp = TC_OBJECT;
idx = stackSig.indexOf(';", idx);
break;
default:
throw new InsnError("bad signature char");//NOI18N
}
stack.push(new Integer(tp));
}
|
public static int | countFieldWords(java.lang.String sig)Return the number of words of a field based on its signature.
if (sig == null || sig.length() < 1)
throw new InsnError ("not a field signature");//NOI18N
switch (sig.charAt(0)) {
case 'J": /* long */
case 'D": /* double */
return 2;
case 'B": /* byte */
case 'C": /* char */
case 'S": /* short */
case 'I": /* int */
case 'F": /* float */
case 'Z": /* boolean */
case 'L": /* object */
case '[": /* array */
return 1;
default:
throw new InsnError("missing case");//NOI18N
}
|
public static int | countMethodArgWords(java.lang.String sig)Return the number of words of arguments to the method
based on the method signature
if (sig.charAt(0) != '(")
throw new InsnError ("not a method signature");//NOI18N
int count = 0;
for (int idx = 1; sig.charAt(idx) != ')"; idx++) {
switch (sig.charAt(idx)) {
case 'B": /* byte */
case 'C": /* char */
case 'S": /* short */
case 'I": /* int */
case 'F": /* float */
case 'Z": /* boolean */
count++;
break;
case 'J": /* long */
case 'D": /* double */
count += 2;
break;
case 'L":
count++;
idx = sig.indexOf(';", idx);
break;
case '[":
count++;
while (sig.charAt(idx) == '[" || sig.charAt(idx) == ']")
idx++;
if (sig.charAt(idx) == 'L")
idx = sig.indexOf(';", idx);
/* else, let idx++ at loop iteration skip primitive descriptor */
break;
default:
throw new InsnError("missing case");//NOI18N
}
}
return count;
|
public static int | countMethodReturnWords(java.lang.String sig)Return the number of words of return value for the method
based on the method signature
int idx = sig.lastIndexOf(')") + 1;
if (idx == 0)
throw new InsnError ("not a method signature");//NOI18N
switch (sig.charAt(idx)) {
case 'J": /* long */
case 'D": /* double */
return 2;
case 'B": /* byte */
case 'C": /* char */
case 'S": /* short */
case 'I": /* int */
case 'F": /* float */
case 'Z": /* boolean */
case 'L": /* object */
case '[": /* array */
return 1;
case 'V": /* void */
return 0;
default:
throw new InsnError("missing case");//NOI18N
}
|
public static java.lang.String | elementSig(int valueType)Return the element type descriptor char for the element type.
The element type must be one of the T_ or TC_OBJECT.
switch(valueType) {
case T_BYTE:
return "B";//NOI18N
case T_CHAR:
return "C";//NOI18N
case T_BOOLEAN:
return "Z";//NOI18N
case T_SHORT:
return "S";//NOI18N
case T_INT:
return "I";//NOI18N
case T_LONG:
return "J";//NOI18N
case T_FLOAT:
return "F";//NOI18N
case T_DOUBLE:
return "D";//NOI18N
case TC_OBJECT:
return "Ljava/lang/Object;";//NOI18N
default:
throw new InsnError("bad element type");//NOI18N
}
|
public static int | elementSize(int elementType)Return the number of stack words required for a value of the specified
type on the operand stack.
switch(elementType) {
case T_LONG:
case T_DOUBLE:
case T_TWOWORD:
return 2;
default:
return 1;
}
|
public static int | elementType(java.lang.String sig)Return the element type for the first char in the type descriptor string.
if (sig == null || sig.length() < 1)
throw new InsnError ("not a value signature");//NOI18N
switch(sig.charAt(0)) {
case 'B":
return T_BOOLEAN;
case 'C":
return T_CHAR;
case 'Z":
return T_BYTE;
case 'S":
return T_SHORT;
case 'I":
return T_INT;
case 'J":
return T_LONG;
case 'F":
return T_FLOAT;
case 'D":
return T_DOUBLE;
case '[":
return TC_OBJECT;
case 'L":
return TC_OBJECT;
default:
throw new InsnError("bad signature char");//NOI18N
}
|
public static java.lang.String | extractArgSig(java.lang.String methodSig)Return the stack descriptor for the arguments to a method
invocation (not including any "this" argument)
return methodSig.substring(1, methodSig.indexOf(')"));
|
public static java.lang.String | extractResultSig(java.lang.String methodSig)Return the stack descriptor for the result of a method
invocation. Void return values yield "V".
return methodSig.substring(methodSig.indexOf(')")+1);
|
public static java.lang.String | extractReversedArgSig(java.lang.String methodSig)Return the reversed stack descriptor for the arguments to a method
invocation (not including any "this" argument). The top of stack
element will be first.
StringBuffer buf = new StringBuffer();;
reverseArgSig(buf, methodSig, 1);
return buf.toString();
|
public static int | nextSigElement(java.lang.String stackSig, int idx)stackSig is a signature for the types on the stack with the last
type in the signature on the top of stack. idx is the index of
the start of a valid signature type element. Return the index of
the next element (which may be past the end of the string).
switch(stackSig.charAt(idx)) {
case 'B":
case 'C":
case 'Z":
case 'S":
case 'I":
case 'F":
case 'J":
case 'D":
break;
case '[":
while (stackSig.charAt(idx) == '[" || stackSig.charAt(idx) == ']")
idx++;
if (stackSig.charAt(idx) != 'L")
break;
/* fall through */
case 'L":
idx = stackSig.indexOf(';", idx);
break;
default:
throw new InsnError("bad signature char");//NOI18N
}
idx++;
return idx;
|
public static java.lang.String | remapTypes(java.lang.String sig, java.util.Map classTranslations)classTranslations contains a set of mappings of class names.
For any types within the input signature which appear as keys
in the translation table, change the signature to replace the
original type with the translation. Return a string containing
the original signature with any translations applied.
/* Defer allocation of the string buffer until it's needed */
StringBuffer buf = null;
for (int idx = 0; idx < sig.length(); idx++) {
char c;
switch(c = sig.charAt(idx)) {
case '[":
/* An array - skip through the [] pairs, copying to buf if not null */
while ((c = sig.charAt(idx)) == '[" || c == ']") {
idx++;
if (buf != null)
buf.append(c);
}
/* If the next char isnt 'L', the next char is a simple type and
will be handled by the default 1 char translation */
if (sig.charAt(idx) != 'L")
break;
/* fall through to type name translation */
case 'L":
/* This is a type name */
idx++;
int endIdx = sig.indexOf(';", idx);
String typeName = sig.substring(idx, endIdx);
String mapTo = (String) classTranslations.get(typeName);
if (mapTo != null) {
/* This type needs translation - allocate the string buffer
now if needed and copy in all up to this type name. */
if (buf == null) {
buf = new StringBuffer(sig.length() + 20);
buf.append(sig.substring(0,idx-1));
}
typeName = mapTo;
}
if (buf != null) {
buf.append('L");
buf.append(typeName);
}
idx = endIdx;
c = ';";
break;
}
if (buf != null)
buf.append(c);
}
return (buf == null) ? sig : (buf.toString());
|
private static void | reverseArgSig(java.lang.StringBuffer buf, java.lang.String methodSig, int idx)Given a StringBuffer, a method descriptor, and a index to the
start of an argument descriptor, append the arguments to the
string buffer in reverse order.
char c = methodSig.charAt(idx);
if (c == ')")
return;
int startIdx = idx;
switch(c) {
case 'B":
case 'C":
case 'S":
case 'I":
case 'F":
case 'J":
case 'D":
case 'Z":
idx = idx+1;
break;
case '[":
while (methodSig.charAt(idx) == '[" || methodSig.charAt(idx) == ']")
idx++;
if (methodSig.charAt(idx) != 'L") {
idx++;
break;
}
/* fall through */
case 'L":
idx = methodSig.indexOf(';", idx) + 1;
break;
default:
throw new InsnError("bad signature char");//NOI18N
}
reverseArgSig(buf, methodSig, idx);
while (startIdx < idx)
buf.append(methodSig.charAt(startIdx++));
|
public static java.lang.String | translateClass(java.lang.String cls, java.util.Map classTranslations)classTranslations contains a set of mappings of class names.
Translate the class name (which may be an array class) according
to the entries in the translation table.
Return either the original string if no translation applies or
else the translated string.
if (cls.charAt(0) == '[")
return remapTypes(cls, classTranslations);
else {
String mapTo = (String) classTranslations.get(cls);
if (mapTo != null)
return mapTo;
return cls;
}
|
public static java.lang.String | userFieldSig(java.lang.String vmSig)Translates a VM type field signature into a user-format signature.
Just a front for the two argument overload of this method.
return userFieldSig(vmSig, 0);
|
public static java.lang.String | userFieldSig(java.lang.String vmSig, int idx)Translates a VM type field signature into a user-format signature.
String sigElement = "";//NOI18N
int arrayDims = 0;
boolean moreSig = true;
while (moreSig) {
moreSig = false;
char c = vmSig.charAt(idx);
switch (c) {
case 'B":
sigElement = "byte";//NOI18N
break;
case 'C":
sigElement = "char";//NOI18N
break;
case 'Z":
sigElement = "boolean";//NOI18N
break;
case 'S":
sigElement = "short";//NOI18N
break;
case 'I":
sigElement = "int";//NOI18N
break;
case 'F":
sigElement = "float";//NOI18N
break;
case 'J":
sigElement = "long";//NOI18N
break;
case 'D":
sigElement = "double";//NOI18N
break;
case 'V":
/* void isn't really valid as a field signature but this method
might be useful in implementing method signature conversion and
void is a valid return type. */
sigElement = "void";//NOI18N
break;
case '[":
idx++;
arrayDims++;
moreSig = true;
break;
case 'L":
int nextIdx = vmSig.indexOf(';", idx);
sigElement = vmSig.substring(idx+1,nextIdx).replace('/",'.");
break;
default:
throw new InsnError("bad signature char");//NOI18N
}
}
/* If a non-array type, we already have the answer */
if (arrayDims == 0)
return sigElement;
/* array types need a little more work */
StringBuffer buf = new StringBuffer(sigElement.length() + 2 * arrayDims);
buf.append(sigElement);
while (arrayDims-- > 0)
buf.append("[]");//NOI18N
return buf.toString();
|
public static java.lang.String | userMethodArgs(java.lang.String methodSig)Produce a user consumable representation of a method argument list
from the method signature. The return value is ignored.
/* This better be a method signature */
if (methodSig.charAt(0) != '(")
throw new InsnError("Invalid method signature");//NOI18N
StringBuffer buf = new StringBuffer();
buf.append('(");
int idx = 1;
boolean firstArg = true;
while (methodSig.charAt(idx) != ')") {
if (firstArg)
firstArg = false;
else
buf.append(", ");//NOI18N
buf.append(userFieldSig(methodSig, idx));
idx = nextSigElement(methodSig, idx);
}
buf.append(')");
return buf.toString();
|