HCIUnit get(HClass hc) {
      HCIUnit hciu;
      HClass superclass;
      HCIUnit superclassInfo;

      hciu = (HCIUnit) m_table.get(hc);
      if (hciu == null) {
        if (hc.isArray()) { // Treat arrays differently
          int dims = HClassUtil.dims(hc);
          HClass baseclass = HClassUtil.baseClass(hc);
          // hc is not primitive, so hc.getLinker() is safe.
          superclass =
              baseclass.isPrimitive()
                  ? hc.getLinker().forName("java.lang.Object")
                  : (baseclass.getDescriptor().equals("Ljava/lang/Object;")
                      ? (HClassUtil.arrayClass(hc.getLinker(), baseclass, dims - 1))
                      : HClassUtil.arrayClass(hc.getLinker(), baseclass.getSuperclass(), dims));
        } else {
          superclass = hc.getSuperclass();
        }
        if (superclass != null) {
          superclassInfo = get(superclass);
          hciu = new HCIUnit(hc, superclassInfo);
        } else {
          hciu = new HCIUnit(hc);
        }
        m_table.put(hc, hciu);
      }
      return hciu;
    }
Exemple #2
0
 /**
  * create a new objectref with default field values.
  *
  * @exception InterpretedThrowable if class initializer throws an exception.
  */
 ObjectRef(StaticState ss, HClass type) {
   super(ss, type);
   this.fields = null;
   this.closure = null;
   // Initialize our fields.
   for (HClass sc = type; sc != null; sc = sc.getSuperclass()) {
     HField[] fl = sc.getDeclaredFields();
     for (int i = 0; i < fl.length; i++) if (!fl[i].isStatic()) update(fl[i], defaultValue(fl[i]));
   }
   // yay, done.
 }
  private void extend(HClass hc) {
    HField[] hFields = hc.getDeclaredFields();
    for (int i = 0; i < hFields.length; i++) {
      if (hFields[i].isStatic())
        m_currentStaticFieldOffset = m_memberMap.map(hFields[i], m_currentStaticFieldOffset);
      else m_currentFieldOffset = m_memberMap.map(hFields[i], m_currentFieldOffset);
    }

    HMethod[] hMethods = hc.getDeclaredMethods();
    for (int i = 0; i < hMethods.length; i++) {
      m_currentMethodOffset = m_memberMap.map(hMethods[i], m_currentMethodOffset);
    }
  }
 /** Find fields which are *not* subclass-final. */
 private Set findBadFields(HCodeFactory hcf, ClassHierarchy ch) {
   Set badFields = new HashSet();
   // for each callable method...
   for (Iterator it = ch.callableMethods().iterator(); it.hasNext(); ) {
     HMethod hm = (HMethod) it.next();
     HCode hc = hcf.convert(hm);
     if (hc == null) continue; // xxx: native methods may write fields!
     // construct a must-param oracle for constructors.
     MustParamOracle mpo = isConstructor(hm) ? new MustParamOracle(hc) : null;
     // examine this method for writes
     HClass thisClass = hc.getMethod().getDeclaringClass();
     for (Iterator it2 = hc.getElementsI(); it2.hasNext(); ) {
       Quad q = (Quad) it2.next();
       if (q instanceof SET) {
         SET qq = (SET) q;
         // ignore writes of static fields.
         if (qq.isStatic()) continue;
         // if this is a constructor, than it may write only
         // to fields of 'this'
         if (isConstructor(hm)
             && mpo.isMustParam(qq.objectref())
             && mpo.whichMustParam(qq.objectref()) == 0) continue; // this is a permitted write.
         // writes by subclass methods to superclass fields are
         // okay. (but not writes by 'this' methods to 'this'
         // fields, unless the method is a constructor)
         if (qq.field().getDeclaringClass().isInstanceOf(thisClass)
             &&
             // XXX i think the presence of the 'isConstructor'
             // clause here is a bug. constructor writes
             // should be taken care of by clause above.
             (isConstructor(hm) || !thisClass.equals(qq.field().getDeclaringClass())))
           continue; // subclass writes are permitted.
         // non-permitted write!
         badFields.add(qq.field());
       }
     }
     // on to the next!
   }
   // done!  we have set of all bad (not subclass-final) fields.
   return Collections.unmodifiableSet(badFields);
 }
 static final Object defaultValue(HClass ty) {
   if (!ty.isPrimitive()) return null;
   if (ty == HClass.Boolean) return new Boolean(false);
   if (ty == HClass.Byte) return new Byte((byte) 0);
   if (ty == HClass.Char) return new Character((char) 0);
   if (ty == HClass.Double) return new Double(0);
   if (ty == HClass.Float) return new Float(0);
   if (ty == HClass.Int) return new Integer(0);
   if (ty == HClass.Long) return new Long(0);
   if (ty == HClass.Short) return new Short((short) 0);
   throw new Error("Ack!  What kinda default value is this?!");
 }
 // make a wrapped 'zero' value of the specified type.
 private Object makeZero(HClass hc) {
   if (!hc.isPrimitive()) return null;
   if (hc == HClass.Boolean
       || hc == HClass.Byte
       || hc == HClass.Short
       || hc == HClass.Char
       || hc == HClass.Int) return new Integer(0);
   if (hc == HClass.Long) return new Long(0);
   if (hc == HClass.Float) return new Float(0);
   if (hc == HClass.Double) return new Double(0);
   assert false : ("unknown type: " + hc);
   return null;
 }