/** * Method getBCELType. * Maps the java datatype and the BCEL datatype * * @param clazz the class * @return Type the type */ protected Type getBCELType(Class clazz) { if (clazz.isPrimitive()) { return getBCELPrimitiveType(clazz.getName()); } else if (!clazz.isArray()) { return new ObjectType(clazz.getName()); } else { String className = clazz.getName(); int index = className.lastIndexOf('['); int arrayDepth = className.indexOf('[') - className.lastIndexOf('[') + 1; if (className.charAt(index + 1) == 'L') { return new ArrayType(new ObjectType(clazz.getComponentType().getName()), arrayDepth); } return new ArrayType(getBCELPrimitiveType(className.substring(arrayDepth)), arrayDepth); } }
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */ public void visitNEW(NEW o){ indexValid(o, o.getIndex()); Constant c = cpg.getConstant(o.getIndex()); if (! (c instanceof ConstantClass)){ constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'."); } else{ ConstantUtf8 cutf8 = (ConstantUtf8) (cpg.getConstant( ((ConstantClass) c).getNameIndex() )); Type t = Type.getType("L"+cutf8.getBytes()+";"); if (t instanceof ArrayType){ constraintViolated(o, "NEW must not be used to create an array."); } } }
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */ public void visitMULTIANEWARRAY(MULTIANEWARRAY o){ indexValid(o, o.getIndex()); Constant c = cpg.getConstant(o.getIndex()); if (! (c instanceof ConstantClass)){ constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'."); } int dimensions2create = o.getDimensions(); if (dimensions2create < 1){ constraintViolated(o, "Number of dimensions to create must be greater than zero."); } Type t = o.getType(cpg); if (t instanceof ArrayType){ int dimensions = ((ArrayType) t).getDimensions(); if (dimensions < dimensions2create){ constraintViolated(o, "Not allowed to create array with more dimensions ('+dimensions2create+') than the one referenced by the CONSTANT_Class '"+t+"'."); } } else{ constraintViolated(o, "Expecting a CONSTANT_Class referencing an array type. [Constraint not found in The Java Virtual Machine Specification, Second Edition, 4.8.1]"); } }
static String printType( String signature ) { Type type = Type.getType(signature); byte t = type.getType(); if (t <= Constants.T_VOID) { return "Type." + Constants.TYPE_NAMES[t].toUpperCase(Locale.ENGLISH); } else if (type.toString().equals("java.lang.String")) { return "Type.STRING"; } else if (type.toString().equals("java.lang.Object")) { return "Type.OBJECT"; } else if (type.toString().equals("java.lang.StringBuffer")) { return "Type.STRINGBUFFER"; } else if (type instanceof ArrayType) { ArrayType at = (ArrayType) type; return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions() + ")"; } else { return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")"; } }
public static String createClassSignature(Type type) { byte typeCode = type.getType(); switch (typeCode) { case Const.T_OBJECT: ObjectType obj = (ObjectType)type; return obj.getClassName(); case Const.T_ARRAY: ArrayType arr = (ArrayType)type; StringBuilder name = new StringBuilder(createClassSignature(arr.getBasicType())); for(int i = 0; i < arr.getDimensions(); i++) { name.append("[]"); } return name.toString(); default: return Const.getTypeName(typeCode); } }
static String printType(String signature) { Type type = Type.getType(signature); byte t = type.getType(); if (t <= Constants.T_VOID) { return "Type." + Constants.TYPE_NAMES[t].toUpperCase(); } else if (type.toString().equals("java.lang.String")) { return "Type.STRING"; } else if (type.toString().equals("java.lang.Object")) { return "Type.OBJECT"; } else if (type.toString().equals("java.lang.StringBuffer")) { return "Type.STRINGBUFFER"; } else if (type instanceof ArrayType) { ArrayType at = (ArrayType) type; return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions() + ")"; } else { return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")"; } }
public void generateReadCode(InstructionList il, InstructionFactory factory, ConstantPoolGen cp, String className) { if (pointer) { ((GenericRootClass) varClass).generateReadPointerCode(il, factory, cp); } else if (dim == 0) { varClass.generateReadCode(il, factory, cp); } else if (varCounter == null) { ((IntrinsicRootClass) varClass).generateReadArrayCode(il, factory, cp, 1, new int[]{index}); } else { BasicMember varMember = getMember(varCounter); if (varMember == null) throw new RuntimeException("Cannot find variable counter "+varCounter); Type varMemberType = varMember.getJavaType(); il.append(InstructionConstants.ALOAD_0); il.append(factory.createInvoke(className, nameMangler.mangleMember(varCounter), varMemberType, Type.NO_ARGS, INVOKESPECIAL)); if (varMemberType != Type.INT && varMemberType != Type.BYTE && varMemberType != Type.CHAR && varMemberType != Type.SHORT) il.append(factory.createCast(varMemberType, Type.INT)); BasicType type = (BasicType) varClass.getJavaType(); il.append(new NEWARRAY(type)); il.append(InstructionConstants.DUP_X1); Type[] arrayArgType = new Type[] { new ArrayType(type, 1) }; il.append(factory.createInvoke("org.dianahep.root4j.core.RootInput", "readFixedArray", Type.VOID, arrayArgType, INVOKEINTERFACE)); } if (varClass.getConvertMethod() != null) { il.append(factory.createInvoke("org.dianahep.root4j.interfaces." + varClass.getClassName(), varClass.getConvertMethod(), varClass.getJavaTypeForMethod(), Type.NO_ARGS, INVOKEINTERFACE)); } }
private static void generateMethods(RootClass k, ConstantPoolGen cp, InstructionList il, InstructionFactory factory, ClassGen cg, String className, String clonesClassName) { RootMember[] members = k.getMembers(); for (int i = 0; i < members.length; i++) { BasicMember member = (BasicMember) members[i]; Type type = member.getJavaType(); Type arrayType = new ArrayType(type, 1); MethodGen mg = new MethodGen(ACC_PUBLIC, type, null, null, nameMangler.mangleMember(member.getName()), className, il, cp); il.append(InstructionConstants.ALOAD_0); il.append(factory.createGetField(className, "clones", new ObjectType(clonesClassName))); il.append(InstructionConstants.ALOAD_0); il.append(factory.createGetField(className, "index", Type.INT)); il.append(factory.createInvoke(clonesClassName, nameMangler.mangleMember(member.getName()), type, new Type[] { Type.INT }, INVOKEVIRTUAL)); il.append(InstructionFactory.createReturn(type)); mg.setMaxStack(); mg.setMaxLocals(); cg.addMethod(mg.getMethod()); il.dispose(); } }
IntrinsicRootClass(String name, BasicType type, Class javaClass, String readMethod) { this.name = name; this.type = type; this.javaClass = javaClass; this.readMethod = readMethod; this.arrayArgType = new Type[] { new ArrayType(type, 1) }; }
private static String className(Type type) { if (type.getType() <= Constants.T_VOID) { return PRIMITIVE_NAME; } else if (type instanceof ArrayType) { return className(((ArrayType) type).getBasicType()); } else { return type.toString(); } }
/** * Get the TypeCategory that represents this Object * * @see GenericUtilities.TypeCategory */ public static final TypeCategory getTypeCategory(Type type) { if (type instanceof GenericObjectType) return ((GenericObjectType) type).getTypeCategory(); if (type instanceof ObjectType || type instanceof NullType) return TypeCategory.PLAIN_OBJECT_TYPE; if (type instanceof ArrayType) return TypeCategory.ARRAY_TYPE; throw new IllegalArgumentException("Not a reference type: " + type); }
/** * Get String representation of a Type including Generic information */ public static final String getString(Type type) { if (type instanceof GenericObjectType) return ((GenericObjectType) type).toString(true); else if (type instanceof ArrayType) return TypeCategory.asString((ArrayType) type); else return type.toString(); }
private ReferenceType computeFirstCommonSuperclassOfReferenceTypes(ReferenceType a, ReferenceType b) throws ClassNotFoundException { boolean aIsArrayType = (a instanceof ArrayType); boolean bIsArrayType = (b instanceof ArrayType); if (aIsArrayType && bIsArrayType) { // Merging array types - kind of a pain. ArrayType aArrType = (ArrayType) a; ArrayType bArrType = (ArrayType) b; if (aArrType.getDimensions() == bArrType.getDimensions()) { return computeFirstCommonSuperclassOfSameDimensionArrays(aArrType, bArrType); } else { return computeFirstCommonSuperclassOfDifferentDimensionArrays(aArrType, bArrType); } } if (aIsArrayType || bIsArrayType) { // One of a and b is an array type, but not both. // Common supertype is Object. return Type.OBJECT; } // Neither a nor b is an array type. // Find first common supertypes of ObjectTypes. return getFirstCommonSuperclass((ObjectType) a, (ObjectType) b); }
/** * Get first common supertype of arrays with the same number of dimensions. * * @param aArrType * an ArrayType * @param bArrType * another ArrayType with the same number of dimensions * @return first common supertype * @throws ClassNotFoundException */ private ReferenceType computeFirstCommonSuperclassOfSameDimensionArrays(ArrayType aArrType, ArrayType bArrType) throws ClassNotFoundException { assert aArrType.getDimensions() == bArrType.getDimensions(); Type aBaseType = aArrType.getBasicType(); Type bBaseType = bArrType.getBasicType(); boolean aBaseIsObjectType = (aBaseType instanceof ObjectType); boolean bBaseIsObjectType = (bBaseType instanceof ObjectType); if (!aBaseIsObjectType || !bBaseIsObjectType) { assert (aBaseType instanceof BasicType) || (bBaseType instanceof BasicType); if (aArrType.getDimensions() > 1) { // E.g.: first common supertype of int[][] and WHATEVER[][] is // Object[] return new ArrayType(Type.OBJECT, aArrType.getDimensions() - 1); } else { assert aArrType.getDimensions() == 1; // E.g.: first common supertype type of int[] and WHATEVER[] is // Object return Type.OBJECT; } } else { assert (aBaseType instanceof ObjectType); assert (bBaseType instanceof ObjectType); // Base types are both ObjectTypes, and number of dimensions is // same. // We just need to find the first common supertype of base types // and return a new ArrayType using that base type. ObjectType firstCommonBaseType = getFirstCommonSuperclass((ObjectType) aBaseType, (ObjectType) bBaseType); return new ArrayType(firstCommonBaseType, aArrType.getDimensions()); } }
/** * Get the first common superclass of arrays with different numbers of * dimensions. * * @param aArrType * an ArrayType * @param bArrType * another ArrayType * @return ReferenceType representing first common superclass */ private ReferenceType computeFirstCommonSuperclassOfDifferentDimensionArrays(ArrayType aArrType, ArrayType bArrType) { assert aArrType.getDimensions() != bArrType.getDimensions(); boolean aBaseTypeIsPrimitive = (aArrType.getBasicType() instanceof BasicType); boolean bBaseTypeIsPrimitive = (bArrType.getBasicType() instanceof BasicType); if (aBaseTypeIsPrimitive || bBaseTypeIsPrimitive) { int minDimensions, maxDimensions; if (aArrType.getDimensions() < bArrType.getDimensions()) { minDimensions = aArrType.getDimensions(); maxDimensions = bArrType.getDimensions(); } else { minDimensions = bArrType.getDimensions(); maxDimensions = aArrType.getDimensions(); } if (minDimensions == 1) { // One of the types was something like int[]. // The only possible common supertype is Object. return Type.OBJECT; } else { // Weird case: e.g., // - first common supertype of int[][] and char[][][] is // Object[] // because f.c.s. of int[] and char[][] is Object // - first common supertype of int[][][] and char[][][][][] is // Object[][] // because f.c.s. of int[] and char[][][] is Object return new ArrayType(Type.OBJECT, maxDimensions - minDimensions); } } else { // Both a and b have base types which are ObjectTypes. // Since the arrays have different numbers of dimensions, the // f.c.s. will have Object as its base type. // E.g., f.c.s. of Cat[] and Dog[][] is Object[] return new ArrayType(Type.OBJECT, Math.min(aArrType.getDimensions(), bArrType.getDimensions())); } }
@Override protected void setUp() throws Exception { super.setUp(); typeSerializable = ObjectTypeFactory.getInstance("java.io.Serializable"); typeClonable = ObjectTypeFactory.getInstance("java.lang.Cloneable"); typeObject = ObjectTypeFactory.getInstance("java.lang.Object"); typeInteger = ObjectTypeFactory.getInstance("java.lang.Integer"); typeString = ObjectTypeFactory.getInstance("java.lang.String"); typeComparable = ObjectTypeFactory.getInstance("java.lang.Comparable"); typeList = ObjectTypeFactory.getInstance("java.util.List"); typeCollection = ObjectTypeFactory.getInstance("java.util.Collection"); typeHashSet = ObjectTypeFactory.getInstance("java.util.HashSet"); typeArrayClonable = new ArrayType(typeClonable, 1); typeArrayComparable = new ArrayType(typeComparable, 1); typeArrayObject = new ArrayType(typeObject, 1); typeArrayInteger = new ArrayType(typeInteger, 1); typeArrayString = new ArrayType(typeString, 1); typeArrayArrayObject = new ArrayType(typeObject, 2); typeArrayArraySerializable = new ArrayType(typeSerializable, 2); typeArrayArrayString = new ArrayType(typeString, 2); typeArrayInt = new ArrayType(Type.INT, 1); typeArrayArrayInt = new ArrayType(Type.INT, 2); typeArrayArrayArrayInt = new ArrayType(Type.INT, 3); typeArrayChar = new ArrayType(Type.CHAR, 1); typeArrayArrayChar = new ArrayType(Type.CHAR, 2); typeArrayArrayArrayChar = new ArrayType(Type.CHAR, 3); typeDynamicString = new FindRefComparison.DynamicStringType(); typeStaticString = new FindRefComparison.StaticStringType(); typeParameterString = new FindRefComparison.ParameterStringType(); }
protected Type getTypeForClass(Class<?> orig) { if (orig.isPrimitive()) return getTypeForPrimitive(orig); int dims = 0; while (orig.isArray()) { dims++; orig = orig.getComponentType(); } if (dims > 0) return new ArrayType(getTypeForClass(orig), dims); return new ObjectType(orig.getName()); }
static byte[] bcelHelloWorld() { ClassGen cg = new ClassGen("HelloWorld", "java/lang/Object", "HelloWorld.java", Constants.ACC_PUBLIC, null); cg.addEmptyConstructor(Constants.ACC_PUBLIC); ConstantPoolGen cp = cg.getConstantPool(); org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList(); org.apache.bcel.generic.InstructionFactory factory = new org.apache.bcel.generic.InstructionFactory( cg); MethodGen mg = new MethodGen(Constants.ACC_STATIC | Constants.ACC_PUBLIC, org.apache.bcel.generic.Type.VOID, new org.apache.bcel.generic.Type[] { new ArrayType( org.apache.bcel.generic.Type.STRING, 1) }, null, "main", "HelloWorld", il, cp); il.append(factory.createGetStatic("java/lang/System", "out", printStreamT)); il.append(new PUSH(cp, "Hello world!")); il.append(factory .createInvoke( "java.io.PrintStream", "println", org.apache.bcel.generic.Type.VOID, new org.apache.bcel.generic.Type[] { org.apache.bcel.generic.Type.STRING }, Constants.INVOKESPECIAL)); mg.setMaxStack(); cg.addMethod(mg.getMethod()); return cg.getJavaClass().getBytes(); }
static byte[] aspectjBcelHelloWorld() { org.aspectj.apache.bcel.generic.ClassGen cg = new org.aspectj.apache.bcel.generic.ClassGen( "HelloWorld", "java/lang/Object", "HelloWorld.java", Constants.ACC_PUBLIC, null); cg.addEmptyConstructor(Constants.ACC_PUBLIC); org.aspectj.apache.bcel.generic.ConstantPoolGen cp = cg .getConstantPool(); org.aspectj.apache.bcel.generic.InstructionList il = new org.aspectj.apache.bcel.generic.InstructionList(); org.aspectj.apache.bcel.generic.InstructionFactory factory = new org.aspectj.apache.bcel.generic.InstructionFactory( cg); org.aspectj.apache.bcel.generic.MethodGen mg = new org.aspectj.apache.bcel.generic.MethodGen( Constants.ACC_STATIC | Constants.ACC_PUBLIC, org.aspectj.apache.bcel.generic.Type.VOID, new org.aspectj.apache.bcel.generic.Type[] { new org.aspectj.apache.bcel.generic.ArrayType( org.aspectj.apache.bcel.generic.Type.STRING, 1) }, null, "main", "HelloWorld", il, cp); il.append(factory.createGetStatic("java/lang/System", "out", printStreamAT)); il.append(new org.aspectj.apache.bcel.generic.PUSH(cp, "Hello world!")); il.append(factory .createInvoke( "java.io.PrintStream", "println", org.aspectj.apache.bcel.generic.Type.VOID, new org.aspectj.apache.bcel.generic.Type[] { org.aspectj.apache.bcel.generic.Type.STRING }, Constants.INVOKESPECIAL)); mg.setMaxStack(); cg.addMethod(mg.getMethod()); return cg.getJavaClass().getBytes(); }
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */ public void visitANEWARRAY(ANEWARRAY o){ indexValid(o, o.getIndex()); Constant c = cpg.getConstant(o.getIndex()); if (! (c instanceof ConstantClass)){ constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'."); } Type t = o.getType(cpg); if (t instanceof ArrayType){ int dimensions = ((ArrayType) t).getDimensions(); if (dimensions >= 255){ constraintViolated(o, "Not allowed to create an array with more than 255 dimensions."); } } }
public void visitAllocationInstruction( AllocationInstruction i ) { Type type; if (i instanceof CPInstruction) { type = ((CPInstruction) i).getType(_cp); } else { type = ((NEWARRAY) i).getType(); } short opcode = ((Instruction) i).getOpcode(); int dim = 1; switch (opcode) { case Constants.NEW: _out.println("il.append(_factory.createNew(\"" + ((ObjectType) type).getClassName() + "\"));"); break; case Constants.MULTIANEWARRAY: dim = ((MULTIANEWARRAY) i).getDimensions(); case Constants.ANEWARRAY: case Constants.NEWARRAY: if (type instanceof ArrayType) { type = ((ArrayType) type).getBasicType(); } _out.println("il.append(_factory.createNewArray(" + BCELifier.printType(type) + ", (short) " + dim + "));"); break; default: throw new RuntimeException("Oops: " + opcode); } }
static byte[] bcelHelloWorld() { ClassGen cg = new ClassGen("HelloWorld", "java/lang/Object", "HelloWorld.java", Constants.ACC_PUBLIC, null); cg.addEmptyConstructor(Constants.ACC_PUBLIC); ConstantPoolGen cp = cg.getConstantPool(); org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList(); org.apache.bcel.generic.InstructionFactory factory = new org.apache.bcel.generic.InstructionFactory(cg); MethodGen mg = new MethodGen(Constants.ACC_STATIC | Constants.ACC_PUBLIC, org.apache.bcel.generic.Type.VOID, new org.apache.bcel.generic.Type[] { new ArrayType(org.apache.bcel.generic.Type.STRING, 1) }, null, "main", "HelloWorld", il, cp); il.append(factory.createGetStatic("java/lang/System", "out", printStreamT)); il.append(new PUSH(cp, "Hello world!")); il.append(factory.createInvoke("java.io.PrintStream", "println", org.apache.bcel.generic.Type.VOID, new org.apache.bcel.generic.Type[] { org.apache.bcel.generic.Type.STRING }, Constants.INVOKESPECIAL)); mg.setMaxStack(); cg.addMethod(mg.getMethod()); return cg.getJavaClass().getBytes(); }
static byte[] aspectjBcelHelloWorld() { org.aspectj.apache.bcel.generic.ClassGen cg = new org.aspectj.apache.bcel.generic.ClassGen("HelloWorld", "java/lang/Object", "HelloWorld.java", Constants.ACC_PUBLIC, null); cg.addEmptyConstructor(Constants.ACC_PUBLIC); org.aspectj.apache.bcel.generic.ConstantPoolGen cp = cg.getConstantPool(); org.aspectj.apache.bcel.generic.InstructionList il = new org.aspectj.apache.bcel.generic.InstructionList(); org.aspectj.apache.bcel.generic.InstructionFactory factory = new org.aspectj.apache.bcel.generic.InstructionFactory(cg); org.aspectj.apache.bcel.generic.MethodGen mg = new org.aspectj.apache.bcel.generic.MethodGen(Constants.ACC_STATIC | Constants.ACC_PUBLIC, org.aspectj.apache.bcel.generic.Type.VOID, new org.aspectj.apache.bcel.generic.Type[] { new org.aspectj.apache.bcel.generic.ArrayType(org.aspectj.apache.bcel.generic.Type.STRING, 1) }, null, "main", "HelloWorld", il, cp); il.append(factory.createGetStatic("java/lang/System", "out", printStreamAT)); il.append(new org.aspectj.apache.bcel.generic.PUSH(cp, "Hello world!")); il.append(factory.createInvoke("java.io.PrintStream", "println", org.aspectj.apache.bcel.generic.Type.VOID, new org.aspectj.apache.bcel.generic.Type[] { org.aspectj.apache.bcel.generic.Type.STRING }, Constants.INVOKESPECIAL)); mg.setMaxStack(); cg.addMethod(mg.getMethod()); return cg.getJavaClass().getBytes(); }
private void generateMethods(RootClass k, ConstantPoolGen cp, InstructionList il, InstructionFactory factory, ClassGen cg, String className) { RootMember[] members = k.getMembers(); for (int i = 0; i < members.length; i++) { BasicMember member = (BasicMember) members[i]; TLeaf leaf = (TLeaf) lMap.get(member); if (leaf == null) continue; String leafClassName = leaf.getClass().getName(); Type type = member.getJavaType(); Type arrayType = new ArrayType(type, 1); MethodGen mg = new MethodGen(ACC_PUBLIC, type, new Type[] { Type.INT }, new String[] { "index" }, nameMangler.mangleMember(member.getName()), className, il, cp); il.append(InstructionConstants.ALOAD_0); il.append(factory.createGetField(className, member.getName(), arrayType)); il.append(InstructionFactory.DUP); BranchHandle bh = il.append(new IFNONNULL(null)); il.append(InstructionFactory.POP); il.append(factory.createGetStatic(className, member.getName() + "Leaf", new ObjectType(leafClassName))); il.append(InstructionConstants.ALOAD_0); il.append(factory.createGetField("org.dianahep.root4j.core.Clones2", "hollowIndex", Type.LONG)); // BasicRootClass varClass = (BasicRootClass) member.getType(); il.append(factory.createInvoke(leafClassName, "setPosition", new ObjectType("org.dianahep.root4j.core.RootInput"), new Type[] { Type.LONG }, INVOKEVIRTUAL)); il.append(InstructionConstants.ALOAD_0); il.append(factory.createGetField("org.dianahep.root4j.core.Clones2", "size", Type.INT)); il.append((Instruction) factory.createNewArray(type, (short) 1)); il.append(InstructionConstants.DUP_X1); il.append(factory.createInvoke("org.dianahep.root4j.core.RootInput", "readFixedArray", Type.VOID, new Type[] { arrayType }, INVOKEINTERFACE)); il.append(InstructionConstants.DUP); il.append(InstructionConstants.ALOAD_0); il.append(InstructionConstants.SWAP); il.append(factory.createPutField(className, member.getName(), arrayType)); bh.setTarget(il.append(InstructionConstants.ILOAD_1)); il.append(InstructionFactory.createArrayLoad(type)); il.append(InstructionFactory.createReturn(type)); mg.setMaxStack(); mg.setMaxLocals(); cg.addMethod(mg.getMethod()); il.dispose(); } }
private void generateStreamer(RootClass k, ConstantPoolGen cp, InstructionList il, InstructionFactory factory, String className) { if (k.getClassName().equals("TObject") && optimize) return; RootMember[] members = k.getMembers(); int multiplier = 1; for (int i = 0; i < members.length; i++) { BasicMember member = (BasicMember) members[i]; if (optimize && ((i + 1) < members.length) && (member.getArrayDim() == 0) && member.getJavaType().equals(((BasicMember) members[i + 1]).getJavaType())) { multiplier++; } else { Type type = member.getJavaType(); Type arrayType = new ArrayType(type, 1); il.append(InstructionConstants.ALOAD_0); il.append(InstructionConstants.ALOAD_1); il.append(InstructionConstants.ILOAD_2); //length if (multiplier > 1) { il.append(new PUSH(cp, multiplier)); il.append(InstructionConstants.IMUL); } String varCounter = member.getVarCounter(); if (varCounter == null) { for (int j = 0; j < member.getArrayDim(); j++) il.append(new PUSH(cp, member.getMaxIndex(j))); il.append((Instruction) factory.createNewArray(((BasicRootClass) member.getType()).getJavaType(), (short) (member.getArrayDim() + 1))); il.append(InstructionConstants.DUP_X1); if (member.getArrayDim() == 0) { if (type instanceof ObjectType) { il.append(new PUSH(cp,member.getType().getClassName())); il.append(factory.createInvoke("org.dianahep.root4j.core.IOUtils", "readFixedArray", Type.VOID, new Type[] { RootType.ROOTINPUT, new ArrayType(Type.OBJECT, 1), RootType.STRING }, INVOKESTATIC)); } else { il.append(factory.createInvoke("org.dianahep.root4j.core.RootInput", "readFixedArray", Type.VOID, new Type[] { arrayType }, INVOKEINTERFACE)); } } else { il.append(factory.createInvoke("org.dianahep.root4j.core.RootInput", "readMultiArray", Type.VOID, new Type[] { new ArrayType(Type.OBJECT, 1) }, INVOKEINTERFACE)); } } else { il.append((Instruction) factory.createNewArray(type, (short)1)); il.append(InstructionConstants.DUP_X1); il.append(InstructionConstants.ALOAD_0); il.append(factory.createFieldAccess(className, varCounter, RootType.INTARRAY, Constants.GETFIELD)); il.append(factory.createInvoke("org.dianahep.root4j.core.IOUtils", "readVariableMultiArray", Type.VOID, new Type[] { RootType.ROOTINPUT,arrayType,RootType.INTARRAY }, INVOKESTATIC)); } il.append(factory.createPutField(className, member.getName(), arrayType)); multiplier = 1; } } }
void generateMain(ClassGen clg, Method origMain) { InstructionList il = new InstructionList(); MethodGen new_main = new MethodGen(Constants.ACC_STATIC | Constants.ACC_PUBLIC, Type.VOID, new Type[] { new ArrayType( Type.STRING, 1) }, new String[] { "argv" }, "main", clg .getClassName(), il, clg.getConstantPool()); il.append(ins_f.createNew(cashmereType)); il.append(new DUP()); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "isMaster", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); BranchHandle ifcmp = il.append(new IFEQ(null)); InstructionHandle origMain_handle = il.append(new ALOAD(0)); InstructionHandle try_start = il.append(ins_f.createInvoke(clg .getClassName(), origMain.getName(), Type.VOID, new Type[] { new ArrayType(Type.STRING, 1) }, Constants.INVOKESTATIC)); BranchHandle try_end = il.append(new GOTO(null)); InstructionHandle e_handler = il.append(getCashmere(ins_f)); il.append(new SWAP()); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "exit", Type.VOID, new Type[] { new ObjectType("java.lang.Throwable")}, Constants.INVOKEVIRTUAL)); BranchHandle gto2 = il.append(new GOTO(null)); InstructionHandle ifeq_target = il.append(getCashmere(ins_f)); ifcmp.setTarget(ifeq_target); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "client", Type.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.append(getCashmere(ins_f)); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "isMaster", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.append(new IFNE(origMain_handle)); InstructionHandle gto_target = il.append(getCashmere(ins_f)); try_end.setTarget(gto_target); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "exit", Type.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); InstructionHandle gto2_target = il.append(new RETURN()); gto2.setTarget(gto2_target); new_main.addExceptionHandler(try_start, try_end, e_handler, new ObjectType("java.lang.Throwable")); new_main.setMaxStack(); new_main.setMaxLocals(); new_main.addLocalVariable("argv", new ArrayType(Type.STRING, 1), 0, origMain_handle, null); removeLocalTypeTables(new_main); Method main = new_main.getMethod(); gen_c.addMethod(main); }
/** * Returns a JNI-style representation of the given data type passed * as a Class object. * * @param type - a Class object that wraps a data type. * @return a string that represents a JNI-style data type. */ public static String getJNIType(Type type) { StringBuffer result = new StringBuffer(); String suffix = ""; if (type instanceof ArrayType) { suffix = "Array"; type = ((ArrayType) type).getElementType(); } if (type instanceof ObjectType) { String objectType = "jobject"; // The suffix length is 0 only if the given type is not an array. if (suffix.length() == 0) { if (type.equals(Type.STRING)) { objectType = "jstring"; } else if (type.equals(Type.THROWABLE)) { objectType = "jthrowable"; } else if (((ObjectType) type).getClassName() .equals("java.lang.Class")) { objectType = "jclass"; } } result.append(objectType); } else if (type == Type.INT) { result.append("jint"); } else if (type == Type.BYTE) { result.append("jbyte"); } else if (type == Type.LONG) { result.append("jlong"); } else if (type == Type.FLOAT) { result.append("jfloat"); } else if (type == Type.DOUBLE) { result.append("jdouble"); } else if (type == Type.SHORT) { result.append("jshort"); } else if (type == Type.CHAR) { result.append("jchar"); } else if (type == Type.BOOLEAN) { result.append("jboolean"); } else if (type == Type.VOID) { result.append("void"); } return result.append(suffix).toString(); }
private static Method instrument_reflection(InstructionFactory inf, MethodGen mgen, ConstantPoolGen cpgen) { Method ret = mgen.getMethod(); InstructionList ilist = mgen.getInstructionList(); if (ilist == null || ilist.size() == 0) return ret; InstructionHandle[] ihdls = ilist.getInstructionHandles(); for (InstructionHandle ihdl : ihdls) { Instruction instr = ihdl.getInstruction(); // go through all instructions and look for invokes if (instr instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction) instr; ReferenceType rtype = invoke.getReferenceType(cpgen); if (rtype instanceof ObjectType) { String cname = ((ObjectType) rtype).getClassName(); String mname = invoke.getName(cpgen); // we look for exact match if (cname.equals("java.lang.reflect.Method") && mname.equals("invoke")) { // Util.log(rtype.toString()); Type[] arg_types = { new ObjectType(java.lang.reflect.Method.class.getCanonicalName()), Type.OBJECT, new ArrayType(Type.OBJECT, 1) }; ihdl.setInstruction(inf.createInvoke(SIFAStub.class.getCanonicalName(), "invoke", Type.OBJECT, arg_types, Constants.INVOKESTATIC)); } } else { // reference type can be ArrayType or UninitializedObjectType } } } ilist.setPositions(); mgen.setInstructionList(ilist); mgen.removeLineNumbers(); mgen.setMaxStack(); mgen.setMaxLocals(); ret = mgen.getMethod(); return ret; }
private static int getPriorityForBeingMutable(Type type) { if (type instanceof ArrayType) { return HIGH_PRIORITY; } else if (type instanceof ObjectType) { UnreadFieldsData unreadFields = AnalysisContext.currentAnalysisContext().getUnreadFieldsData(); ClassDescriptor cd = DescriptorFactory.getClassDescriptor((ObjectType) type); @SlashedClassName String className = cd.getClassName(); if (immutableClassNames.contains(className)) return Priorities.LOW_PRIORITY; XClass xClass = AnalysisContext.currentXFactory().getXClass(cd); if (xClass == null) return Priorities.IGNORE_PRIORITY; ClassDescriptor superclassDescriptor = xClass.getSuperclassDescriptor(); if (superclassDescriptor != null) { @SlashedClassName String superClassName = superclassDescriptor.getClassName(); if (superClassName.equals("java/lang/Enum")) return Priorities.LOW_PRIORITY; } boolean hasMutableField = false; boolean hasUpdates = false; for (XField f : xClass.getXFields()) if (!f.isStatic()) { if (!f.isFinal() && !f.isSynthetic()) { hasMutableField = true; if (unreadFields.isWrittenOutsideOfInitialization(f)) hasUpdates = true; } String signature = f.getSignature(); if (signature.startsWith("Ljava/util/concurrent") || signature.startsWith("Ljava/lang/StringB") || signature.charAt(0) == '[' || signature.indexOf("Map") >= 0 || signature.indexOf("List") >= 0 || signature.indexOf("Set") >= 0) hasMutableField = hasUpdates = true; } if (!hasMutableField && !xClass.isInterface() && !xClass.isAbstract()) return Priorities.LOW_PRIORITY; if (hasUpdates || className.startsWith("java/util") || className.indexOf("Map") >= 0 || className.indexOf("List") >= 0) return Priorities.HIGH_PRIORITY; return Priorities.NORMAL_PRIORITY; } else return Priorities.IGNORE_PRIORITY; }
public static String asString(ArrayType atype) { Type obj = atype.getBasicType(); String result = GenericUtilities.getString(obj); return result + Util.repeat("[]", atype.getDimensions()); }
public void initEntryFact(TypeFrame result) { // Make the frame valid result.setValid(); int slot = 0; // Clear the stack slots in the frame result.clearStack(); // Add local for "this" pointer, if present if (!methodGen.isStatic()) result.setValue(slot++, ObjectTypeFactory.getInstance(methodGen.getClassName())); // [Added: Support for Generics] // Get a parser that reads the generic signature of the method and // can be used to get the correct GenericObjectType if an argument // has a class type Iterator<String> iter = GenericSignatureParser.getGenericSignatureIterator(method); // Add locals for parameters. // Note that long and double parameters need to be handled // specially because they occupy two locals. Type[] argumentTypes = methodGen.getArgumentTypes(); for (Type argType : argumentTypes) { // Add special "extra" type for long or double params. // These occupy the slot before the "plain" type. if (argType.getType() == Constants.T_LONG) { result.setValue(slot++, TypeFrame.getLongExtraType()); } else if (argType.getType() == Constants.T_DOUBLE) { result.setValue(slot++, TypeFrame.getDoubleExtraType()); } // [Added: Support for Generics] String s = (iter == null || !iter.hasNext()) ? null : iter.next(); if (s != null && (argType instanceof ObjectType || argType instanceof ArrayType) && !(argType instanceof ExceptionObjectType)) { // replace with a generic version of the type try { Type t = GenericUtilities.getType(s); if (t != null) argType = t; } catch (RuntimeException e) { } // degrade gracefully } // Add the plain parameter type. result.setValue(slot++, argType); } // Set remaining locals to BOTTOM; this will cause any // uses of them to be flagged while (slot < methodGen.getMaxLocals()) result.setValue(slot++, TypeFrame.getBottomType()); }
static public @Nonnull IncompatibleTypes getPriorityForAssumingCompatible(Type expectedType, Type actualType, boolean pointerEquality) { if (!(expectedType instanceof ReferenceType)) return SEEMS_OK; if (!(actualType instanceof ReferenceType)) return SEEMS_OK; if (expectedType instanceof BasicType ^ actualType instanceof BasicType) { return INCOMPATIBLE_CLASSES; } while (expectedType instanceof ArrayType && actualType instanceof ArrayType) { expectedType = ((ArrayType) expectedType).getElementType(); actualType = ((ArrayType) actualType).getElementType(); } if (expectedType instanceof BasicType ^ actualType instanceof BasicType) { return PRIMATIVE_ARRAY_AND_OTHER_ARRAY; } if (expectedType instanceof BasicType && actualType instanceof BasicType) { if (!expectedType.equals(actualType)) return INCOMPATIBLE_PRIMATIVE_ARRAYS; else return SEEMS_OK; } if (expectedType instanceof ArrayType) { return getPriorityForAssumingCompatibleWithArray(actualType); } if (actualType instanceof ArrayType) { return getPriorityForAssumingCompatibleWithArray(expectedType); } if (expectedType.equals(actualType)) return SEEMS_OK; // For now, ignore the case where either reference is not // of an object type. (It could be either an array or null.) if (!(expectedType instanceof ObjectType) || !(actualType instanceof ObjectType)) return SEEMS_OK; return getPriorityForAssumingCompatible((ObjectType) expectedType, (ObjectType) actualType, pointerEquality); }