assert aArrType.getDimensions() != bArrType.getDimensions(); boolean aBaseTypeIsPrimitive = (aArrType.getBasicType() instanceof BasicType); boolean bBaseTypeIsPrimitive = (bArrType.getBasicType() instanceof BasicType); if (aArrType.getDimensions() < bArrType.getDimensions()) { minDimensions = aArrType.getDimensions(); maxDimensions = bArrType.getDimensions(); } else { minDimensions = bArrType.getDimensions(); maxDimensions = aArrType.getDimensions(); return new ArrayType(Type.OBJECT, maxDimensions - minDimensions); return new ArrayType(Type.OBJECT, Math.min(aArrType.getDimensions(), bArrType.getDimensions()));
expectedType = ((ArrayType) expectedType).getElementType(); actualType = ((ArrayType) actualType).getElementType();
public static String asString(ArrayType atype) { Type obj = atype.getBasicType(); String result = GenericUtilities.getString(obj); return result + Util.repeat("[]", atype.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(); }
public static double isDeepSerializable(ReferenceType type) throws ClassNotFoundException { if (type instanceof ArrayType) { ArrayType a = (ArrayType) type; Type t = a.getBasicType(); if (t instanceof ReferenceType) { type = (ReferenceType) t; } else { return 1.0; } } double result = isDeepSerializable(type.getSignature()); if (type instanceof GenericObjectType && Subtypes2.isContainer(type)) { GenericObjectType gt = (GenericObjectType) type; List<? extends ReferenceType> parameters = gt.getParameters(); if (parameters != null) { for(ReferenceType t : parameters) { double r = isDeepSerializable(t); if (result > r) { result = r; } } } } return result; } public static ReferenceType getLeastSerializableTypeComponent(ReferenceType type)
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); }
/** * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY * instruction, e.g. to the ConstantPool. * * @param type type of array class * @return index of entry */ public int addArrayClass( final ArrayType type ) { return addClass_(type.getSignature()); }
@Override public void visitANEWARRAY(ANEWARRAY obj) { consumeStack(obj); Type elementType = obj.getType(getCPG()); pushValue(new ArrayType(elementType, 1)); // We now have an exact type for this value. setTopOfStackIsExact(); }
public static ReferenceType getLeastSerializableTypeComponent(ReferenceType type) throws ClassNotFoundException { if (type instanceof ArrayType) { ArrayType a = (ArrayType) type; Type t = a.getBasicType(); if (t instanceof ReferenceType) { type = (ReferenceType) t; } else { return type; } } ReferenceType result = type; double value = isDeepSerializable(type.getSignature()); if (type instanceof GenericObjectType && Subtypes2.isContainer(type)) { GenericObjectType gt = (GenericObjectType) type; List<? extends ReferenceType> parameters = gt.getParameters(); if (parameters != null) { for(ReferenceType t : parameters) { double r = isDeepSerializable(t); if (value > r) { value = r; result = getLeastSerializableTypeComponent(t); } } } } return result; }
ArrayType argArray = (ArrayType) actualType; if (parmArray.getDimensions() != argArray.getDimensions()) { return IncompatibleTypes.ARRAY_AND_NON_ARRAY; return compareTypes(parmArray.getBasicType(), argArray.getBasicType(), ignoreBaseType);
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); }
/** * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY * instruction, e.g. to the ConstantPool. * * @param type type of array class * @return index of entry */ public int addArrayClass(ArrayType type) { return addClass_(type.getSignature()); }
assert aArrType.getDimensions() == bArrType.getDimensions(); Type aBaseType = aArrType.getBasicType(); Type bBaseType = bArrType.getBasicType(); boolean aBaseIsObjectType = (aBaseType instanceof ObjectType); boolean bBaseIsObjectType = (bBaseType instanceof ObjectType); assert (aBaseType instanceof BasicType) || (bBaseType instanceof BasicType); if (aArrType.getDimensions() > 1) { return new ArrayType(Type.OBJECT, aArrType.getDimensions() - 1); } else { assert aArrType.getDimensions() == 1; return new ArrayType(firstCommonBaseType, aArrType.getDimensions());
return null; return new ArrayType(componentType, index);
private static boolean isObjectType(Type type) { return ((ArrayType) type).getBasicType() instanceof ObjectType; }
public static String asString(ArrayType atype) { Type obj = atype.getBasicType(); String result = GenericUtilities.getString(obj); return result + Util.repeat("[]", atype.getDimensions()); } }
@Override public void visitAALOAD(AALOAD obj) { // To determine the type pushed on the stack, // we look at the type of the array reference which was // popped off of the stack. TypeFrame frame = getFrame(); try { frame.popValue(); // index Type arrayType = frame.popValue(); // arrayref if (arrayType instanceof ArrayType) { ArrayType arr = (ArrayType) arrayType; pushValue(arr.getElementType()); } else { pushValue(TypeFrame.getBottomType()); } } catch (DataflowAnalysisException e) { throw new InvalidBytecodeException("Stack underflow: " + e.getMessage()); } }
/** 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."); } } }
if (typeAsArrayType.getDimensions() < possibleSupertypeAsArrayType.getDimensions()) { return false; Type possibleSupertypeBasicType = possibleSupertypeAsArrayType.getBasicType(); if (!(possibleSupertypeBasicType instanceof ObjectType)) { return false; Type typeBasicType = typeAsArrayType.getBasicType(); if (typeAsArrayType.getDimensions() > possibleSupertypeAsArrayType.getDimensions()) { return isSubtype( new ArrayType(typeBasicType, typeAsArrayType.getDimensions() - possibleSupertypeAsArrayType.getDimensions()), (ObjectType) possibleSupertypeBasicType);
/** * @return element type of array, i.e., for int[][][] the element type is int[][] */ public Type getElementType() { if (dimensions == 1) { return basic_type; } return new ArrayType(basic_type, dimensions - 1); }