Methods Summary |
---|
public void | addCodeAttribute(com.sun.org.apache.bcel.internal.classfile.Attribute a)Add an attribute to the code. Currently, the JVM knows about the
LineNumberTable, LocalVariableTable and StackMap attributes,
where the former two will be generated automatically and the
latter is used for the MIDP only. Other attributes will be
ignored by the JVM but do no harm. code_attrs_vec.add(a);
|
public void | addException(java.lang.String class_name)Add an exception possibly thrown by this method.
throws_vec.add(class_name);
|
public com.sun.org.apache.bcel.internal.generic.CodeExceptionGen | addExceptionHandler(com.sun.org.apache.bcel.internal.generic.InstructionHandle start_pc, com.sun.org.apache.bcel.internal.generic.InstructionHandle end_pc, com.sun.org.apache.bcel.internal.generic.InstructionHandle handler_pc, com.sun.org.apache.bcel.internal.generic.ObjectType catch_type)Add an exception handler, i.e., specify region where a handler is active and an
instruction where the actual handling is done.
if((start_pc == null) || (end_pc == null) || (handler_pc == null))
throw new ClassGenException("Exception handler target is null instruction");
CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc,
handler_pc, catch_type);
exception_vec.add(c);
return c;
|
public com.sun.org.apache.bcel.internal.generic.LineNumberGen | addLineNumber(com.sun.org.apache.bcel.internal.generic.InstructionHandle ih, int src_line)Give an instruction a line number corresponding to the source code line.
LineNumberGen l = new LineNumberGen(ih, src_line);
line_number_vec.add(l);
return l;
|
public com.sun.org.apache.bcel.internal.generic.LocalVariableGen | addLocalVariable(java.lang.String name, com.sun.org.apache.bcel.internal.generic.Type type, int slot, com.sun.org.apache.bcel.internal.generic.InstructionHandle start, com.sun.org.apache.bcel.internal.generic.InstructionHandle end)Adds a local variable to this method.
byte t = type.getType();
if(t != Constants.T_ADDRESS) {
int add = type.getSize();
if(slot + add > max_locals)
max_locals = slot + add;
LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
int i;
if((i = variable_vec.indexOf(l)) >= 0) // Overwrite if necessary
variable_vec.set(i, l);
else
variable_vec.add(l);
return l;
} else {
throw new IllegalArgumentException("Can not use " + type +
" as type for local variable");
}
|
public com.sun.org.apache.bcel.internal.generic.LocalVariableGen | addLocalVariable(java.lang.String name, com.sun.org.apache.bcel.internal.generic.Type type, com.sun.org.apache.bcel.internal.generic.InstructionHandle start, com.sun.org.apache.bcel.internal.generic.InstructionHandle end)Adds a local variable to this method and assigns an index automatically.
return addLocalVariable(name, type, max_locals, start, end);
|
public void | addObserver(com.sun.org.apache.bcel.internal.generic.MethodObserver o)Add observer for this object.
if(observers == null)
observers = new ArrayList();
observers.add(o);
|
public com.sun.org.apache.bcel.internal.generic.MethodGen | copy(java.lang.String class_name, com.sun.org.apache.bcel.internal.generic.ConstantPoolGen cp)
Method m = ((MethodGen)clone()).getMethod();
MethodGen mg = new MethodGen(m, class_name, this.cp);
if(this.cp != cp) {
mg.setConstantPool(cp);
mg.getInstructionList().replaceConstantPool(this.cp, cp);
}
return mg;
|
public java.lang.String | getArgumentName(int i) return arg_names[i];
|
public java.lang.String[] | getArgumentNames() return (String[])arg_names.clone();
|
public com.sun.org.apache.bcel.internal.generic.Type | getArgumentType(int i) return arg_types[i];
|
public com.sun.org.apache.bcel.internal.generic.Type[] | getArgumentTypes() return (Type[])arg_types.clone();
|
public java.lang.String | getClassName() return class_name;
|
public com.sun.org.apache.bcel.internal.classfile.Attribute[] | getCodeAttributes()
Attribute[] attributes = new Attribute[code_attrs_vec.size()];
code_attrs_vec.toArray(attributes);
return attributes;
|
private com.sun.org.apache.bcel.internal.classfile.CodeException[] | getCodeExceptions()
int size = exception_vec.size();
CodeException[] c_exc = new CodeException[size];
try {
for(int i=0; i < size; i++) {
CodeExceptionGen c = (CodeExceptionGen)exception_vec.get(i);
c_exc[i] = c.getCodeException(cp);
}
} catch(ArrayIndexOutOfBoundsException e) {}
return c_exc;
|
public com.sun.org.apache.bcel.internal.generic.CodeExceptionGen[] | getExceptionHandlers()
CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()];
exception_vec.toArray(cg);
return cg;
|
private com.sun.org.apache.bcel.internal.classfile.ExceptionTable | getExceptionTable(com.sun.org.apache.bcel.internal.generic.ConstantPoolGen cp)
int size = throws_vec.size();
int[] ex = new int[size];
try {
for(int i=0; i < size; i++)
ex[i] = cp.addClass((String)throws_vec.get(i));
} catch(ArrayIndexOutOfBoundsException e) {}
return new ExceptionTable(cp.addUtf8("Exceptions"),
2 + 2 * size, ex, cp.getConstantPool());
|
public java.lang.String[] | getExceptions()
String[] e = new String[throws_vec.size()];
throws_vec.toArray(e);
return e;
|
public com.sun.org.apache.bcel.internal.generic.InstructionList | getInstructionList() return il;
|
public com.sun.org.apache.bcel.internal.classfile.LineNumberTable | getLineNumberTable(com.sun.org.apache.bcel.internal.generic.ConstantPoolGen cp)
int size = line_number_vec.size();
LineNumber[] ln = new LineNumber[size];
try {
for(int i=0; i < size; i++)
ln[i] = ((LineNumberGen)line_number_vec.get(i)).getLineNumber();
} catch(ArrayIndexOutOfBoundsException e) {} // Never occurs
return new LineNumberTable(cp.addUtf8("LineNumberTable"),
2 + ln.length * 4, ln, cp.getConstantPool());
|
public com.sun.org.apache.bcel.internal.generic.LineNumberGen[] | getLineNumbers()
LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()];
line_number_vec.toArray(lg);
return lg;
|
public com.sun.org.apache.bcel.internal.classfile.LocalVariableTable | getLocalVariableTable(com.sun.org.apache.bcel.internal.generic.ConstantPoolGen cp)
LocalVariableGen[] lg = getLocalVariables();
int size = lg.length;
LocalVariable[] lv = new LocalVariable[size];
for(int i=0; i < size; i++)
lv[i] = lg[i].getLocalVariable(cp);
return new LocalVariableTable(cp.addUtf8("LocalVariableTable"),
2 + lv.length * 10, lv, cp.getConstantPool());
|
public com.sun.org.apache.bcel.internal.generic.LocalVariableGen[] | getLocalVariables()
int size = variable_vec.size();
LocalVariableGen[] lg = new LocalVariableGen[size];
variable_vec.toArray(lg);
for(int i=0; i < size; i++) {
if(lg[i].getStart() == null)
lg[i].setStart(il.getStart());
if(lg[i].getEnd() == null)
lg[i].setEnd(il.getEnd());
}
if(size > 1)
sort(lg, 0, size - 1);
return lg;
|
public int | getMaxLocals() return max_locals;
|
public int | getMaxStack() return max_stack;
|
public static int | getMaxStack(com.sun.org.apache.bcel.internal.generic.ConstantPoolGen cp, com.sun.org.apache.bcel.internal.generic.InstructionList il, com.sun.org.apache.bcel.internal.generic.CodeExceptionGen[] et)Computes stack usage of an instruction list by performing control flow analysis.
BranchStack branchTargets = new BranchStack();
/* Initially, populate the branch stack with the exception
* handlers, because these aren't (necessarily) branched to
* explicitly. in each case, the stack will have depth 1,
* containing the exception object.
*/
for (int i = 0; i < et.length; i++) {
InstructionHandle handler_pc = et[i].getHandlerPC();
if (handler_pc != null)
branchTargets.push(handler_pc, 1);
}
int stackDepth = 0, maxStackDepth = 0;
InstructionHandle ih = il.getStart();
while(ih != null) {
Instruction instruction = ih.getInstruction();
short opcode = instruction.getOpcode();
int delta = instruction.produceStack(cp) - instruction.consumeStack(cp);
stackDepth += delta;
if(stackDepth > maxStackDepth)
maxStackDepth = stackDepth;
// choose the next instruction based on whether current is a branch.
if(instruction instanceof BranchInstruction) {
BranchInstruction branch = (BranchInstruction) instruction;
if(instruction instanceof Select) {
// explore all of the select's targets. the default target is handled below.
Select select = (Select) branch;
InstructionHandle[] targets = select.getTargets();
for (int i = 0; i < targets.length; i++)
branchTargets.push(targets[i], stackDepth);
// nothing to fall through to.
ih = null;
} else if(!(branch instanceof IfInstruction)) {
// if an instruction that comes back to following PC,
// push next instruction, with stack depth reduced by 1.
if(opcode == Constants.JSR || opcode == Constants.JSR_W)
branchTargets.push(ih.getNext(), stackDepth - 1);
ih = null;
}
// for all branches, the target of the branch is pushed on the branch stack.
// conditional branches have a fall through case, selects don't, and
// jsr/jsr_w return to the next instruction.
branchTargets.push(branch.getTarget(), stackDepth);
} else {
// check for instructions that terminate the method.
if(opcode == Constants.ATHROW || opcode == Constants.RET ||
(opcode >= Constants.IRETURN && opcode <= Constants.RETURN))
ih = null;
}
// normal case, go to the next instruction.
if(ih != null)
ih = ih.getNext();
// if we have no more instructions, see if there are any deferred branches to explore.
if(ih == null) {
BranchTarget bt = branchTargets.pop();
if (bt != null) {
ih = bt.target;
stackDepth = bt.stackDepth;
}
}
}
return maxStackDepth;
|
public com.sun.org.apache.bcel.internal.classfile.Method | getMethod()Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively,
before calling this method (the same applies for max locals).
String signature = getSignature();
int name_index = cp.addUtf8(name);
int signature_index = cp.addUtf8(signature);
/* Also updates positions of instructions, i.e., their indices
*/
byte[] byte_code = null;
if(il != null)
byte_code = il.getByteCode();
LineNumberTable lnt = null;
LocalVariableTable lvt = null;
/* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
*/
if((variable_vec.size() > 0) && !strip_attributes)
addCodeAttribute(lvt = getLocalVariableTable(cp));
if((line_number_vec.size() > 0) && !strip_attributes)
addCodeAttribute(lnt = getLineNumberTable(cp));
Attribute[] code_attrs = getCodeAttributes();
/* Each attribute causes 6 additional header bytes
*/
int attrs_len = 0;
for(int i=0; i < code_attrs.length; i++)
attrs_len += (code_attrs[i].getLength() + 6);
CodeException[] c_exc = getCodeExceptions();
int exc_len = c_exc.length * 8; // Every entry takes 8 bytes
Code code = null;
if((il != null) && !isAbstract()) {
// Remove any stale code attribute
Attribute[] attributes = getAttributes();
for(int i=0; i < attributes.length; i++) {
Attribute a = attributes[i];
if(a instanceof Code)
removeAttribute(a);
}
code = new Code(cp.addUtf8("Code"),
8 + byte_code.length + // prologue byte code
2 + exc_len + // exceptions
2 + attrs_len, // attributes
max_stack, max_locals,
byte_code, c_exc,
code_attrs,
cp.getConstantPool());
addAttribute(code);
}
ExceptionTable et = null;
if(throws_vec.size() > 0)
addAttribute(et = getExceptionTable(cp)); // Add `Exceptions' if there are "throws" clauses
Method m = new Method(access_flags, name_index, signature_index,
getAttributes(), cp.getConstantPool());
// Undo effects of adding attributes
if(lvt != null) removeCodeAttribute(lvt);
if(lnt != null) removeCodeAttribute(lnt);
if(code != null) removeAttribute(code);
if(et != null) removeAttribute(et);
return m;
|
public com.sun.org.apache.bcel.internal.generic.Type | getReturnType() return getType();
|
public java.lang.String | getSignature()
return Type.getMethodSignature(type, arg_types);
|
public void | removeCodeAttribute(com.sun.org.apache.bcel.internal.classfile.Attribute a)Remove a code attribute. code_attrs_vec.remove(a);
|
public void | removeCodeAttributes()Remove all code attributes.
code_attrs_vec.clear();
|
public void | removeException(java.lang.String c)Remove an exception.
throws_vec.remove(c);
|
public void | removeExceptionHandler(com.sun.org.apache.bcel.internal.generic.CodeExceptionGen c)Remove an exception handler.
exception_vec.remove(c);
|
public void | removeExceptionHandlers()Remove all line numbers.
exception_vec.clear();
|
public void | removeExceptions()Remove all exceptions.
throws_vec.clear();
|
public void | removeLineNumber(com.sun.org.apache.bcel.internal.generic.LineNumberGen l)Remove a line number.
line_number_vec.remove(l);
|
public void | removeLineNumbers()Remove all line numbers.
line_number_vec.clear();
|
public void | removeLocalVariable(com.sun.org.apache.bcel.internal.generic.LocalVariableGen l)Remove a local variable, its slot will not be reused, if you do not use addLocalVariable
with an explicit index argument.
variable_vec.remove(l);
|
public void | removeLocalVariables()Remove all local variables.
variable_vec.clear();
|
public void | removeNOPs()Remove all NOPs from the instruction list (if possible) and update every
object refering to them, i.e., branch instructions, local variables and
exception handlers.
if(il != null) {
InstructionHandle next;
/* Check branch instructions.
*/
for(InstructionHandle ih = il.getStart(); ih != null; ih = next) {
next = ih.next;
if((next != null) && (ih.getInstruction() instanceof NOP)) {
try {
il.delete(ih);
} catch(TargetLostException e) {
InstructionHandle[] targets = e.getTargets();
for(int i=0; i < targets.length; i++) {
InstructionTargeter[] targeters = targets[i].getTargeters();
for(int j=0; j < targeters.length; j++)
targeters[j].updateTarget(targets[i], next);
}
}
}
}
}
|
public void | removeObserver(com.sun.org.apache.bcel.internal.generic.MethodObserver o)Remove observer for this object.
if(observers != null)
observers.remove(o);
|
public void | setArgumentName(int i, java.lang.String name) arg_names[i] = name;
|
public void | setArgumentNames(java.lang.String[] arg_names) this.arg_names = arg_names;
|
public void | setArgumentType(int i, com.sun.org.apache.bcel.internal.generic.Type type) arg_types[i] = type;
|
public void | setArgumentTypes(com.sun.org.apache.bcel.internal.generic.Type[] arg_types) this.arg_types = arg_types;
|
public void | setClassName(java.lang.String class_name) this.class_name = class_name;
|
public void | setInstructionList(com.sun.org.apache.bcel.internal.generic.InstructionList il) this.il = il;
|
public void | setMaxLocals(int m)Set maximum number of local variables. max_locals = m;
|
public void | setMaxLocals()Compute maximum number of local variables.
if(il != null) {
int max = isStatic()? 0 : 1;
if(arg_types != null)
for(int i=0; i < arg_types.length; i++)
max += arg_types[i].getSize();
for(InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
Instruction ins = ih.getInstruction();
if((ins instanceof LocalVariableInstruction) ||
(ins instanceof RET) || (ins instanceof IINC))
{
int index = ((IndexedInstruction)ins).getIndex() +
((TypedInstruction)ins).getType(cp).getSize();
if(index > max)
max = index;
}
}
max_locals = max;
} else
max_locals = 0;
|
public void | setMaxStack(int m)Set maximum stack size for this method. max_stack = m;
|
public void | setMaxStack()Computes max. stack size by performing control flow analysis.
if(il != null)
max_stack = getMaxStack(cp, il, getExceptionHandlers());
else
max_stack = 0;
|
public void | setReturnType(com.sun.org.apache.bcel.internal.generic.Type return_type) setType(return_type);
|
private static final void | sort(com.sun.org.apache.bcel.internal.generic.LocalVariableGen[] vars, int l, int r)Sort local variables by index
int i = l, j = r;
int m = vars[(l + r) / 2].getIndex();
LocalVariableGen h;
do {
while(vars[i].getIndex() < m) i++;
while(m < vars[j].getIndex()) j--;
if(i <= j) {
h=vars[i]; vars[i]=vars[j]; vars[j]=h; // Swap elements
i++; j--;
}
} while(i <= j);
if(l < j) sort(vars, l, j);
if(i < r) sort(vars, i, r);
|
public void | stripAttributes(boolean flag)Do not/Do produce attributes code attributesLineNumberTable and
LocalVariableTable, like javac -O strip_attributes = flag;
|
public final java.lang.String | toString()Return string representation close to declaration format,
`public static void _main(String[]) throws IOException', e.g.
String access = Utility.accessToString(access_flags);
String signature = Type.getMethodSignature(type, arg_types);
signature = Utility.methodSignatureToString(signature, name, access,
true, getLocalVariableTable(cp));
StringBuffer buf = new StringBuffer(signature);
if(throws_vec.size() > 0) {
for(Iterator e = throws_vec.iterator(); e.hasNext(); )
buf.append("\n\t\tthrows " + e.next());
}
return buf.toString();
|
public void | update()Call notify() method on all observers. This method is not called
automatically whenever the state has changed, but has to be
called by the user after he has finished editing the object.
if(observers != null)
for(Iterator e = observers.iterator(); e.hasNext(); )
((MethodObserver)e.next()).notify(this);
|