/** * Returns <code>true</code> iff the given field is 'subclass-final' and there is at least one * callable constructor where the field's content can be predicted. */ public boolean isGood(HField hf) { if (hf.isStatic()) return false; if (badFields.contains(hf)) return false; // get declared methods of class (should include all constructors) List l = Arrays.asList(hf.getDeclaringClass().getDeclaredMethods()); // for each callable constructor... for (Iterator it = l.iterator(); it.hasNext(); ) { HMethod hm = (HMethod) it.next(); if (!ch.callableMethods().contains(hm)) continue; if (!isConstructor(hm)) continue; // okay, hm is a callable constructor. Map map = classifyMethod(hm); if (!map.containsKey(hf) || ((Classification) map.get(hf)).isGood()) return true; // this is a good field. } return false; // nothing good about this. }
private Object lookup(Info info, HField hf) { Object o = ro.get(hf, info); if (o != ro.NOT_A_VALUE) return o; if (info instanceof ArrayInfo && hf.getName().equals("length")) // XXX should wrap more precisely based on hf.getType(). // (arrays may have small length fields in future) return new Integer(((ArrayInfo) info).length()); assert info instanceof ObjectInfo : "field of array not given a value: " + hf + " / " + info; return ((ObjectInfo) info).get(hf); }
/** * @return the offset of of <code>hf</code> from the initial field. For instance, if <code>hf * </code> is the 3rd field in its class, <code>getFieldOffset</code> returns 2. */ public int getFieldOffset(HField hf) { return m_hcim.get(hf.getDeclaringClass()).getOffset(hf); }
/** * Returns the constant value which field <code>hf</code> is set to whenever the given constructor * is executed. Requires that <code>isConstant(constructor,hf)</code> be <code>true</code>. */ public Object constantValue(HMethod constructor, HField hf) { assert isConstant(constructor, hf); Classification c = (Classification) classifyMethod(constructor).get(hf); return (c == null) ? makeZero(hf.getType()) : c.constant; }
/** utility function copied from Interpret/Quads/Ref.java */ static final Object defaultValue(HField f) { if (f.isConstant()) return f.getConstant(); return defaultValue(f.getType()); }