import net.sf.rej.java.instruction.Label;
import net.sf.rej.java.instruction.Parameters;
public class InstructionCopier {
public Instruction copyInstruction(Instruction inst, ConstantPool sourcePool, ConstantPool destinationPool) {
Instruction copy = InstructionSet.getInstance().getInstruction(inst.getOpcode());
Parameters params = inst.getParameters();
Parameters copyParams = new Parameters();
for(int i=0; i < params.getCount(); i++) {
copyParams.addParam(params.getType(i));
switch (params.getType(i)) {
case TYPE_ARRAYTYPE:
copyParams.addValue(params.getObject(i));
break;
case TYPE_LOCAL_VARIABLE:
case TYPE_LOCAL_VARIABLE_READONLY:
case TYPE_LOCAL_VARIABLE_WIDE:
// TODO: should be done differently?
copyParams.addValue(params.getObject(i));
break;
case TYPE_CONSTANT_WIDE:
case TYPE_CONSTANT_READONLY:
case TYPE_CONSTANT:
copyParams.addValue(params.getObject(i));
break;
case TYPE_CONSTANT_POOL_CLASS: {
ClassInfo ci = (ClassInfo) sourcePool.get(params.getInt(i));
int index = destinationPool.optionalAddClassRef(ci.getName());
copyParams.addValue(index);
break;
}
case TYPE_CONSTANT_POOL_CONSTANT: {
ConstantPoolInfo cpi = sourcePool.get(params.getInt(i));
switch (cpi.getType()) {
case ConstantPoolInfo.DOUBLE: {
DoubleInfo di = (DoubleInfo)cpi;
DoubleInfo diCopy = new DoubleInfo(di.getHighBytes(), di.getLowBytes(), destinationPool);
int index = destinationPool.optionalAdd(diCopy);
copyParams.addValue(index);
break;
}
case ConstantPoolInfo.FLOAT: {
FloatInfo fi = (FloatInfo)cpi;
FloatInfo fiCopy = new FloatInfo(fi.getBytes(), destinationPool);
int index = destinationPool.optionalAdd(fiCopy);
copyParams.addValue(index);
break;
}
case ConstantPoolInfo.INTEGER: {
IntegerInfo ii = (IntegerInfo)cpi;
IntegerInfo iiCopy = new IntegerInfo(ii.getIntValue(), destinationPool);
int index = destinationPool.optionalAdd(iiCopy);
copyParams.addValue(index);
break;
}
case ConstantPoolInfo.LONG: {
LongInfo li = (LongInfo)cpi;
LongInfo liCopy = new LongInfo(li.getLongValue(), destinationPool);
int index = destinationPool.optionalAdd(liCopy);
copyParams.addValue(index);
break;
}
case ConstantPoolInfo.STRING: {
StringInfo si = (StringInfo)cpi;
int index = destinationPool.optionalAddString(si.getString());
copyParams.addValue(index);
break;
}
}
break;
}
case TYPE_CONSTANT_POOL_FIELD_REF: {
RefInfo ri = (RefInfo) sourcePool.get(params.getInt(i));
int index = destinationPool.optionalAddFieldRef(ri.getClassName(), ri.getTargetName(), ri.getMethodType());
copyParams.addValue(index);
break;
}
case TYPE_CONSTANT_POOL_METHOD_REF: {
RefInfo ri = (RefInfo) sourcePool.get(params.getInt(i));
int index = destinationPool.optionalAddMethodRef(ri.getClassName(), ri.getTargetName(), ri.getMethodType());
copyParams.addValue(index);
break;
}
case TYPE_LABEL:
Label label = (Label) params.getObject(i);
copyParams.addValue(new Label(label.getPosition()));
break;
case TYPE_SWITCH:
// TODO: Switch
break;
}
}
copy.setParameters(copyParams);
return copy;
}