public Stm buildObject(TreeFactory tf, ObjectInfo info, boolean exported) { FieldMap cfm = ((TreeBuilder) runtime.getTreeBuilder()).cfm; assert !info.type().isArray(); assert !info.type().isPrimitive(); List<Stm> stmlist = new ArrayList<Stm>(); // header stmlist.add(makeHeader(tf, info, exported)); int startOffset = headerFinalOffset(info); // fields, in field order List<HField> l = cfm.fieldList(info.type()); int endOffset = (l.size() == 0) ? startOffset : cfm.fieldOffset(l.get(l.size() - 1)) + cfm.fieldSize(l.get(l.size() - 1)); Stm s = makeFields(tf, info, l, startOffset, endOffset); if (s != null) stmlist.add(s); // done -- ta da! return Stm.toStm(stmlist); }
public Stm buildArray(TreeFactory tf, ArrayInfo info, boolean exported) { FieldMap cfm = ((TreeBuilder) runtime.getTreeBuilder()).cfm; assert info.type().isArray(); HClass cType = info.type().getComponentType(); List<Stm> stmlist = new ArrayList<Stm>(info.length() + 2); // header stmlist.add(makeHeader(tf, info, exported)); int startOffset = headerFinalOffset(info); // fields of the object, including the length field. in order. List<HField> l = cfm.fieldList(info.type()); assert l.size() > 0; // always at least the length field! int endOffset = cfm.fieldOffset(l.get(l.size() - 1)) + cfm.fieldSize(l.get(l.size() - 1)); Stm s = makeFields(tf, info, l, startOffset, endOffset); assert s != null; // always the length! stmlist.add(s); // data for (int i = 0; i < info.length(); i++) stmlist.add(makeDatum(tf, info.get(i))); // done -- ta da! return Stm.toStm(stmlist); }
Stm makePadding(TreeFactory tf, int bytes) { List<Stm> stmlist = new ArrayList<Stm>(); while (bytes > 0) if (bytes >= 8) { stmlist.add(_DATUM(tf, new CONST(tf, null, (long) 0))); bytes -= 8; } else if (bytes >= 4) { stmlist.add(_DATUM(tf, new CONST(tf, null, (int) 0))); bytes -= 4; } else if (bytes >= 2) { stmlist.add(_DATUM(tf, new CONST(tf, null, 16, false, 0))); bytes -= 2; } else { stmlist.add(_DATUM(tf, new CONST(tf, null, 8, false, 0))); bytes -= 1; } // small-to-big Collections.reverse(stmlist); // done! return Stm.toStm(stmlist); }
protected Stm makeFields( TreeFactory tf, Info info, List<HField> fields, int startOffset, int endOffset) { assert endOffset >= startOffset; FieldMap cfm = ((TreeBuilder) runtime.getTreeBuilder()).cfm; List<Stm> stmlist = new ArrayList<Stm>(2 * fields.size()); int offset = startOffset; for (Iterator<HField> it = fields.iterator(); it.hasNext(); ) { HField hf = it.next(); int thisOffset = cfm.fieldOffset(hf); if (thisOffset < startOffset) continue; // ignore if (thisOffset > endOffset) break; // done. assert thisOffset >= offset : "fields in order"; if (thisOffset > offset) // handle padding stmlist.add(makePadding(tf, thisOffset - offset)); stmlist.add(makeDatum(tf, lookup(info, hf))); offset = thisOffset + cfm.fieldSize(hf); } // final padding, if needed. if (endOffset > offset) stmlist.add(makePadding(tf, endOffset - offset)); // done -- ta da! return Stm.toStm(stmlist); // MAY RETURN NULL. }
protected Stm makeHeader(TreeFactory tf, Info info, boolean exported) { List<Stm> stmlist = new ArrayList<Stm>(4); // align to word boundary. stmlist.add(new ALIGN(tf, null, 4)); // label: stmlist.add(new LABEL(tf, null, info.label(), exported)); // claz pointer stmlist.add(_DATUM(tf, runtime.getNameMap().label(info.type()))); // hash code. // this is of pointer size, and must have the low bit set. we *could* // emit a symbolic reference to info.label()+1 or some such, but // this would complicate the pattern-matching instruction selector. // so instead we'll just select a random number of the right length // and set the low bit. stmlist.add( makeDatum( tf, pointersAreLong ? (Number) new Long(1 | rnd.nextLong()) : (Number) new Integer(1 | rnd.nextInt()))); // okay, done with header. return Stm.toStm(stmlist); }