package org.ibex.classgen.opt; import java.io.*; import java.util.*; import org.ibex.classgen.*; import java.io.*; import java.util.*; import java.util.zip.*; public class Arena implements CGConst { public static interface Gladiator { } Context cx = new Context(); public static final int initialSize = 1000; // Initializers ////////////////////////////////////////////////////////////////////////////// public static Type.Class System_class = Type.Class.instance("java.lang.System"); public static Type.Class.Method System_arraycopy = System_class.method("arraycopy","(Ljava/lang/Object;ILjava/lang/Object;II)V"); public static Type.Class Gladiator_class = Type.Class.instance("org.ibex.classgen.opt.Arena$Gladiator"); boolean implementsGladiator(Type t) { return t instanceof Type.Class && implementsGladiator((Type.Class)t);} boolean implementsGladiator(Type.Class c) { return c.extendsOrImplements(Gladiator_class, cx); } String getArenaName(Type.Class c) { return c.getName().substring(0, c.getName().lastIndexOf('$')); } String getGladiatorName(Type.Class c) { return c.getName().substring(c.getName().lastIndexOf('$')+1); } Type.Class getArenaForGladiator(Type.Class c) { return Type.Class.instance(getArenaName(c)); } Type getSliceElementType(Type t) { return implementsGladiator(t) ? Type.INT : t; } Type.Class.Field getSliceForField(Type.Class.Field f) { Type.Class c = f.getDeclaringClass(); return getArenaForGladiator(c).field(getGladiatorName(c)+"$$"+f.getName(), getSliceElementType(f.getType()).makeArray()); } // Operations performed on the Gladiator class ////////////////////////////////////////////////////////////////////////// public Type.Class.Method.Body getSoleConstructor(Type.Class c) { Type.Class.Method.Body ret = null; Type.Class.Method.Body[] bodies = c.getBody(cx).methods(); for(int i=0; i")) mincBody.getUnits().remove(u); } } } if (m.isStatic()) continue; String name = c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "$$" + m.getName(); Type[] list = new Type[m.getNumArgs() + 1]; for(int i=0; i " + verdict); if (verdict) processGladiatorClass(cf.getType()); Type.Class.Field.Body[] fields = cf.fields(); for(int i=0; i") && implementsGladiator(mr.getDeclaringClass())) { name = "$init"; //li.remove(0); //pl.remove(0); } pl.add(IntType.v()); //li.add(iie.getBase()); Type.Class sc = mr.getDeclaringClass(); name = sc.getShortName().substring(sc.getShortName().lastIndexOf('$')+1) + "$$" + name; mr = Scene.v().makeMethodRef(getArenaForGladiator(sc), name, pl, implementsGladiator(mr.returnType()) ? IntType.v() : mr.returnType(), false); ie = Jimple.v().newVirtualInvokeExpr(body.getThisLocal(), mr, li); vb.setValue(v = ie); } else if (!(v instanceof StaticInvokeExpr)) { List l0 = mr.parameterTypes(); List l2 = new LinkedList(); for(Iterator it2 = l0.iterator(); it2.hasNext();) { Type t = (Type)it2.next(); l2.add(implementsGladiator(t) ? IntType.v() : t); } mr = Scene.v().makeMethodRef(mr.getDeclaringClass(), mr.name(), l2, implementsGladiator(mr.returnType()) ? IntType.v() : mr.returnType(), mr.isStatic()); ie.setMethodRef(mr); vb.setValue(v = ie); } for(int i=0; i", typelist); Local loc = viaLocal(Jimple.v().newNewExpr(Type.Ref.v(intClass)), body, s); List list = new LinkedList(); list.add(val); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(loc, intMethod.makeRef(), list)), s); b.setValue(loc); } if (val != null && val.getType() instanceof NullType && mr.parameterType(i) instanceof IntType) { b.setValue(IntConstant.v(-1)); } } } else if (v instanceof CastExpr) { CastExpr ce = (CastExpr)v; if (implementsGladiator(ce.getCastType())) { Type.Class arena = getArenaForGladiator(((Type.Ref)ce.getCastType()).Type.Class.instance()); Type.Class ic = Scene.v().Type.Class.instance("java.lang.Integer"); ce.setCastType(ic.getType()); Local l1 = Jimple.v().newLocal("tmpRef" + (tfr++), ic.getType()); body.getLocals().add(l1); Local l2 = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v()); body.getLocals().add(l2); Stmt s2 = Jimple.v().newAssignStmt(l1, Jimple.v().newCastExpr(ce.getOp(), ic.getType())); body.getUnits().insertBefore(s2, s); Stmt isNull = Jimple.v().newAssignStmt(l2, IntConstant.v(-1)); body.getUnits().insertAfter(isNull, s2); Stmt ifStmt = Jimple.v().newIfStmt(Jimple.v().newEqExpr(l1, NullConstant.v()), s); body.getUnits().insertAfter(ifStmt, isNull); Type.Class.MethodRef mr = Scene.v().makeMethodRef(ic, "intValue", new LinkedList(), IntType.v(), false); Stmt isNotNull = Jimple.v().newAssignStmt(l2, Jimple.v().newVirtualInvokeExpr(l1, mr, new LinkedList())); body.getUnits().insertAfter(isNotNull, ifStmt); vb.setValue(l2); qq = 0; // ??? break; } } else if (v instanceof FieldRef) { FieldRef ifr = (FieldRef)v; Type.Class.Field fr = ifr.getFieldRef(); Type t = fr.type(); if (implementsGladiator(fr.getDeclaringClass()) && fr.name().equals("this$0")) { vb.setValue(body.getThisLocal()); } else if (implementsGladiator(fr.getDeclaringClass())) { Type.Class arena = getArenaForGladiator(fr.getDeclaringClass()); if (fr.isStatic()) { vb.setValue(newIFR(body, getSliceForField(fr))); } else { InstanceFieldRef sfr = newIFR(body, getSliceForField(fr)); vb.setValue(Jimple.v().newArrayRef(viaLocal(sfr, body, s), ((InstanceFieldRef)ifr).getBase())); } } if ((t instanceof Type.Ref) && implementsGladiator(((Type.Ref)t).Type.Class.instance())) { Type.Class tc = ((Type.Ref)t).Type.Class.instance(); Type.Class arena = getArenaForGladiator(tc); ifr.setFieldRef(Scene.v().makeFieldRef(arena, fr.name(), IntType.v(), fr.isStatic())); } else if (t instanceof Type.Array) { Type.Array at = (Type.Array)t; Type et = at.getElementType(); if (et instanceof Type.Ref && implementsGladiator(((Type.Ref)et).Type.Class.instance())) ifr.setFieldRef(Scene.v().makeFieldRef(fr.getDeclaringClass(), fr.name(), IntType.v().makeType.Array(), fr.isStatic())); } } } } } return body; } */ public static void main(String[] s) throws Exception { new Arena().process(s); } public void process(String[] s) throws Exception { File outf = new File(s[0] + "-"); File inf = new File(s[0]); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outf)); ZipInputStream zis = new ZipInputStream(new FileInputStream(inf)); for(;;) { ZipEntry ze = zis.getNextEntry(); if (ze==null) break; String name = ze.getName(); if (!name.endsWith(".class")) { out.putNextEntry(ze); byte b[] = new byte[1024]; for(;;) { int numread = zis.read(b, 0, b.length); if (numread==-1) break; out.write(b, 0, numread); } continue; } System.out.println("updating " + name.substring(0, name.length()-6).replace('$','.').replace('/','.')); ClassFile cf = new ClassFile(new DataInputStream(zis)); cx.add(cf); } for(Iterator it = cx.enumerateClassFiles().iterator(); it.hasNext();) { ClassFile cf = (ClassFile)it.next(); System.out.println("processing " + cf.getType()); processClassFile(cf); } for(Iterator it = cx.enumerateClassFiles().iterator(); it.hasNext();) { ClassFile cf = (ClassFile)it.next(); System.out.println("dumping " + cf.getType()); out.putNextEntry(new ZipEntry(cf.getType().getName().replace('.', '/') + ".class")); cf.dump(out); } out.close(); outf.renameTo(inf); } }