use of org.apache.bcel.generic.Type in project core by s4.
the class ClonerGenerator method generate.
public Class generate(Class clazz) {
String className = clazz.getName();
Random rand = new Random(System.currentTimeMillis());
String clonerClassname = "Cloner" + (Math.abs(rand.nextInt() % 3256));
ClassGen cg = new ClassGen(clonerClassname, "java.lang.Object", clonerClassname + ".java", Constants.ACC_PUBLIC | Constants.ACC_SUPER, new String[] { "io.s4.util.Cloner" });
ConstantPoolGen cp = cg.getConstantPool();
InstructionFactory instFactory = new InstructionFactory(cg, cp);
InstructionList il = new InstructionList();
// build constructor method for new class
MethodGen constructor = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {}, "<init>", clonerClassname, il, cp);
il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
il.append(instFactory.createInvoke("java.lang.Object", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
il.append(InstructionFactory.createReturn(Type.VOID));
constructor.setMaxStack();
constructor.setMaxLocals();
cg.addMethod(constructor.getMethod());
il.dispose();
// build clone method
il = new InstructionList();
MethodGen method = new MethodGen(Constants.ACC_PUBLIC, Type.OBJECT, new Type[] { Type.OBJECT }, new String[] { "arg0" }, "clone", clonerClassname, il, cp);
il.append(InstructionConstants.ACONST_NULL);
il.append(InstructionFactory.createStore(Type.OBJECT, 2));
il.append(InstructionFactory.createLoad(Type.OBJECT, 1));
il.append(new INSTANCEOF(cp.addClass(new ObjectType(className))));
BranchInstruction ifeq_6 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
il.append(ifeq_6);
il.append(InstructionFactory.createLoad(Type.OBJECT, 1));
il.append(instFactory.createCheckCast(new ObjectType(className)));
il.append(InstructionFactory.createStore(Type.OBJECT, 2));
InstructionHandle ih_14 = il.append(InstructionFactory.createLoad(Type.OBJECT, 2));
il.append(new INSTANCEOF(cp.addClass(new ObjectType("java.lang.Cloneable"))));
BranchInstruction ifne_18 = InstructionFactory.createBranchInstruction(Constants.IFNE, null);
il.append(ifne_18);
il.append(instFactory.createFieldAccess("java.lang.System", "out", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
il.append(new PUSH(cp, "Not cloneable!"));
il.append(instFactory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL));
il.append(InstructionConstants.ACONST_NULL);
il.append(InstructionFactory.createReturn(Type.OBJECT));
InstructionHandle ih_31 = il.append(InstructionFactory.createLoad(Type.OBJECT, 2));
il.append(instFactory.createInvoke(className, "clone", Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
il.append(InstructionFactory.createReturn(Type.OBJECT));
ifeq_6.setTarget(ih_14);
ifne_18.setTarget(ih_31);
method.setMaxStack();
method.setMaxLocals();
cg.addMethod(method.getMethod());
il.dispose();
JavaClass jc = cg.getJavaClass();
ClonerClassLoader cl = new ClonerClassLoader();
return cl.loadClassFromBytes(clonerClassname, jc.getBytes());
}
use of org.apache.bcel.generic.Type in project jop by jop-devel.
the class JopMethodInfo method setInfo.
/**
* Extract linking information for this method
* @param addr the bytecode start address
*/
public void setInfo(int addr) {
codeAddress = addr;
Method m = getMethod();
margs = 0;
Type[] at = m.getArgumentTypes();
for (int i = 0; i < at.length; ++i) {
margs += at[i].getSize();
}
// for now only handle inits
if (!m.isStatic()) {
margs++;
}
if (m.isAbstract()) {
mstack = mreallocals = len = exclen = 0;
exctab = null;
} else {
mstack = m.getCode().getMaxStack();
// the 'real' locals - means without arguments
mreallocals = m.getCode().getMaxLocals() - margs;
// System.err.println(" ++++++++++++ "+methodId+" --> mlocals
// ="+mlocals+" margs ="+margs);
len = (m.getCode().getCode().length + 3) / 4;
exctab = m.getCode().getExceptionTable();
exclen = exctab != null ? exctab.length : 0;
// TODO: couldn't len=JOP...MAX_SIZE/4 be ok?
if (len >= JOPizer.METHOD_MAX_SIZE / 4 || mreallocals > 31 || margs > 31) {
// we interprete clinit on JOP - no size restriction
if (!m.getName().equals("<clinit>")) {
System.err.println("len(max:" + (JOPizer.METHOD_MAX_SIZE / 4) + ")=" + len + "mreallocals(max:31)=" + mreallocals + " margs(max:31)=" + margs);
System.err.println("wrong size: " + getCli().clazz.getClassName() + "." + methodId);
throw new Error();
}
}
// System.out.println((mstack+m.getCode().getMaxLocals())+" "+
// m.getName()+" maxStack="+mstack+"
// locals="+m.getCode().getMaxLocals());
}
}
use of org.apache.bcel.generic.Type in project jop by jop-devel.
the class ReplaceNativeAndCPIdx method replace.
private Method replace(Method method) {
MethodGen mg = new MethodGen(method, clazz.getClassName(), cpoolgen);
InstructionList il = mg.getInstructionList();
InstructionFinder f = new InstructionFinder(il);
String methodId = method.getName() + method.getSignature();
OldMethodInfo mi = getCli().getMethodInfo(methodId);
// find invokes first and replace call to Native by
// JOP native instructions.
String invokeStr = "InvokeInstruction";
for (Iterator i = f.search(invokeStr); i.hasNext(); ) {
InstructionHandle[] match = (InstructionHandle[]) i.next();
InstructionHandle first = match[0];
InvokeInstruction ii = (InvokeInstruction) first.getInstruction();
if (ii.getClassName(cpoolgen).equals(JOPizer.nativeClass)) {
short opid = (short) JopInstr.getNative(ii.getMethodName(cpoolgen));
if (opid == -1) {
System.err.println(method.getName() + ": cannot locate " + ii.getMethodName(cpoolgen) + ". Replacing with NOP.");
first.setInstruction(new NOP());
} else {
first.setInstruction(new NativeInstruction(opid, (short) 1));
((JOPizer) ai).outTxt.println("\t" + first.getPosition());
// then we remove pc+2 and pc+1 from the MGCI info
if (JOPizer.dumpMgci) {
il.setPositions();
int pc = first.getPosition();
// important: take the high one first
GCRTMethodInfo.removePC(pc + 2, mi);
GCRTMethodInfo.removePC(pc + 1, mi);
}
}
}
if (ii instanceof INVOKESPECIAL) {
// not an initializer
if (!ii.getMethodName(cpoolgen).equals("<init>")) {
// check if this is a super invoke
// TODO this is just a hack, use InvokeSite.isInvokeSuper() when this is ported to the new framework!
boolean isSuper = false;
String declaredType = ii.getClassName(cpoolgen);
JopClassInfo cls = getCli();
OldClassInfo superClass = cls.superClass;
while (superClass != null) {
if (superClass.clazz.getClassName().equals(declaredType)) {
isSuper = true;
break;
}
if ("java.lang.Object".equals(superClass.clazz.getClassName())) {
break;
}
superClass = superClass.superClass;
}
if (isSuper) {
Integer idx = ii.getIndex();
int new_index = getCli().cpoolUsed.indexOf(idx) + 1;
first.setInstruction(new JOPSYS_INVOKESUPER((short) new_index));
// System.err.println("invokesuper "+ii.getClassName(cpoolgen)+"."+ii.getMethodName(cpoolgen));
}
}
}
}
if (JOPizer.CACHE_INVAL) {
f = new InstructionFinder(il);
// find volatile reads and insert cache invalidation bytecode
String fieldInstr = "GETFIELD|GETSTATIC|PUTFIELD|PUTSTATIC";
for (Iterator i = f.search(fieldInstr); i.hasNext(); ) {
InstructionHandle[] match = (InstructionHandle[]) i.next();
InstructionHandle ih = match[0];
FieldInstruction fi = (FieldInstruction) ih.getInstruction();
JavaClass jc = JOPizer.jz.cliMap.get(fi.getClassName(cpoolgen)).clazz;
Field field = null;
while (field == null) {
Field[] fields = jc.getFields();
for (int k = 0; k < fields.length; k++) {
if (fields[k].getName().equals(fi.getFieldName(cpoolgen))) {
field = fields[k];
break;
}
}
if (field == null) {
try {
jc = jc.getSuperClass();
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new Error();
}
}
}
if (field.isVolatile()) {
if (field.getType().getSize() < 2) {
if (fi instanceof GETFIELD || fi instanceof GETSTATIC) {
ih.setInstruction(new InvalidateInstruction());
ih = il.append(ih, fi);
}
} else {
// this only works because we do not throw a
// NullPointerException for monitorenter/-exit!
ih.setInstruction(new ACONST_NULL());
ih = il.append(ih, new MONITORENTER());
ih = il.append(ih, fi);
ih = il.append(ih, new ACONST_NULL());
ih = il.append(ih, new MONITOREXIT());
}
}
}
}
f = new InstructionFinder(il);
// find instructions that access the constant pool
// and replace the index by the new value from ClassInfo
String cpInstr = "CPInstruction";
for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
InstructionHandle[] match = (InstructionHandle[]) it.next();
InstructionHandle ih = match[0];
CPInstruction cpii = (CPInstruction) ih.getInstruction();
int index = cpii.getIndex();
// we have to grab the information before we change
// the CP index.
FieldInstruction fi = null;
Type ft = null;
if (cpii instanceof FieldInstruction) {
fi = (FieldInstruction) ih.getInstruction();
ft = fi.getFieldType(cpoolgen);
}
Integer idx = new Integer(index);
// pos is the new position in the reduced constant pool
// idx is the position in the 'original' unresolved cpool
int pos = getCli().cpoolUsed.indexOf(idx);
int new_index = pos + 1;
// and putfield and by address for getstatic and putstatic
if (cpii instanceof GETFIELD || cpii instanceof PUTFIELD || cpii instanceof GETSTATIC || cpii instanceof PUTSTATIC) {
// we use the offset instead of the CP index
new_index = getFieldOffset(cp, index);
} else {
if (pos == -1) {
System.out.println("Error: constant " + index + " " + cpoolgen.getConstant(index) + " not found");
System.out.println("new cpool: " + getCli().cpoolUsed);
System.out.println("original cpool: " + cpoolgen);
System.exit(-1);
}
}
// set new index, position starts at
// 1 as cp points to the length of the pool
cpii.setIndex(new_index);
if (cpii instanceof FieldInstruction) {
boolean isRef = ft instanceof ReferenceType;
boolean isLong = ft == BasicType.LONG || ft == BasicType.DOUBLE;
if (fi instanceof GETSTATIC) {
if (isRef) {
ih.setInstruction(new GETSTATIC_REF((short) new_index));
} else if (isLong) {
ih.setInstruction(new GETSTATIC_LONG((short) new_index));
}
} else if (fi instanceof PUTSTATIC) {
if (isRef) {
if (!com.jopdesign.build.JOPizer.USE_RTTM) {
ih.setInstruction(new PUTSTATIC_REF((short) new_index));
}
} else if (isLong) {
ih.setInstruction(new PUTSTATIC_LONG((short) new_index));
}
} else if (fi instanceof GETFIELD) {
if (isRef) {
ih.setInstruction(new GETFIELD_REF((short) new_index));
} else if (isLong) {
ih.setInstruction(new GETFIELD_LONG((short) new_index));
}
} else if (fi instanceof PUTFIELD) {
if (isRef) {
if (!com.jopdesign.build.JOPizer.USE_RTTM) {
ih.setInstruction(new PUTFIELD_REF((short) new_index));
}
} else if (isLong) {
ih.setInstruction(new PUTFIELD_LONG((short) new_index));
}
}
}
}
Method m = mg.getMethod();
il.dispose();
return m;
}
use of org.apache.bcel.generic.Type in project jop by jop-devel.
the class AppInfo method getFieldRef.
/**
* Get a reference to a field using the given memberID.
*
* @param classRef The class which contains the field.
* @param memberID The memberID of the field. Only memberName and memberDescriptor are used. The descriptor
* defines the type of the field, if the field is unknown.
* @return A field reference with or without FieldInfo or ClassInfo.
*/
public FieldRef getFieldRef(ClassRef classRef, MemberID memberID) {
ClassInfo cls = classRef.getClassInfo();
if (cls != null) {
// We do not check for inherited fields here, this is done in FieldRef
FieldInfo field = cls.getFieldInfo(memberID.getMemberName());
if (field != null) {
return field.getFieldRef();
}
}
Type type = null;
if (memberID.hasDescriptor()) {
type = memberID.getDescriptor().getType();
}
return new FieldRef(classRef, memberID.getMemberName(), type);
}
use of org.apache.bcel.generic.Type in project jop by jop-devel.
the class SymbolicPointsTo method initial.
public ContextMap<CallString, SymbolicAddressMap> initial(InstructionHandle stmt) {
ContextMap<CallString, SymbolicAddressMap> retval = new ContextMap<CallString, SymbolicAddressMap>(new Context(), new HashMap<CallString, SymbolicAddressMap>());
SymbolicAddressMap init = new SymbolicAddressMap(bsFactory);
// Add symbolic stack names
int stackPtr = 0;
if (!entryMethod.isStatic()) {
init.putStack(stackPtr++, bsFactory.singleton(SymbolicAddress.rootAddress("$this")));
}
String[] args = entryMethod.getArgumentNames();
for (int i = 0; i < args.length; i++) {
Type ty = entryMethod.getArgumentType(i);
if (ty instanceof ReferenceType) {
init.putStack(stackPtr, bsFactory.singleton(SymbolicAddress.rootAddress("$" + args[i])));
}
stackPtr += ty.getSize();
}
retval.put(initialCallString, init);
return retval;
}
Aggregations