/** * Get the compatible map of the field range maps in struct types <code>structT1</code> and <code> * structT2</code> * * @param structT1 * @param structT2 * @return a fresh and compatible field range map */ private RangeMap<Long, ECR> getCompatibleMap(StructType structT1, StructType structT2) { RangeMap<Long, ECR> fieldMap1 = structT1.getFieldMap(); RangeMap<Long, ECR> fieldMap2 = structT2.getFieldMap(); RangeMap<Long, ECR> fieldMap = FieldRangeMap.create(); fieldMap.putAll(fieldMap1); for (Entry<Range<Long>, ECR> entry : fieldMap2.asMapOfRanges().entrySet()) { Range<Long> range = entry.getKey(); ECR ecr = entry.getValue(); RangeMap<Long, ECR> subMap = fieldMap.subRangeMap(range); Map<Range<Long>, ECR> subMapRanges = subMap.asMapOfRanges(); if (subMapRanges.isEmpty()) { fieldMap.put(range, ecr); continue; } Range<Long> span = subMap.span(); fieldMap.remove(span); Range<Long> newRange = range.span(span); ECR joinECR = ecr; for (ECR elemECR : subMapRanges.values()) { joinECR = join(joinECR, elemECR); } fieldMap.put(newRange, joinECR); } return fieldMap; }
void ccjoin(Size rangeSize, ECR e1, ECR e2) { ValueType type1 = getType(e1); if (type1.isBottom()) { addCCjoin(rangeSize, e1, e2); return; } Size size1 = type1.getSize(); if (!Size.isLessThan(rangeSize, size1)) { addCCjoin(rangeSize, e1, e2); expand(e1, rangeSize); // expand(e1) would call setType(e1, ...) and thus ccjoin(e1, e2) return; } if (e1.equals(e2)) return; switch (type1.getKind()) { case BLANK: { addCCjoin(rangeSize, e1, e2); ValueType type2 = getType(e2); switch (type2.getKind()) { case BOTTOM: setType(e2, ValueType.blank(rangeSize, Parent.getBottom())); return; default: Size size2 = type2.getSize(); if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize); return; } } case SIMPLE: { ValueType type2 = getType(e2); switch (type2.getKind()) { case BOTTOM: setType( e2, ValueType.simple( type1.asSimple().getLoc(), type1.asSimple().getFunc(), rangeSize, Parent.getBottom(), type2.hasOpTag())); return; case BLANK: { setType( e2, ValueType.simple( type1.asSimple().getLoc(), type1.asSimple().getFunc(), type2.getSize(), type2.getParent(), type2.hasOpTag())); Size size2 = type2.getSize(); if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize); return; } case SIMPLE: { cjoin(type1.asSimple().getLoc(), type2.asSimple().getLoc()); cjoin(type1.asSimple().getFunc(), type2.asSimple().getFunc()); Size size2 = type2.getSize(); if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize); return; } case STRUCT: { addCCjoin(rangeSize, e1, e2); collapseStruct(e2, type2.asStruct()); return; } default: // lambda return; } } case STRUCT: { ValueType type2 = getType(e2); switch (type2.getKind()) { case BOTTOM: { RangeMap<Long, ECR> fieldMapCopy = FieldRangeMap.create(); fieldMapCopy.putAll(type1.asStruct().getFieldMap()); setType( e2, ValueType.struct( fieldMapCopy, rangeSize, Parent.getBottom(), type2.hasOpTag())); return; } case BLANK: { RangeMap<Long, ECR> fieldMapCopy = FieldRangeMap.create(); fieldMapCopy.putAll(type1.asStruct().getFieldMap()); Size size2 = type2.getSize(); setType( e2, ValueType.struct(fieldMapCopy, size2, type2.getParent(), type2.hasOpTag())); if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize); return; } case SIMPLE: { addCCjoin(rangeSize, e1, e2); Size size2 = type2.getSize(); if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize); for (ECR elemECR : type1.asStruct().getFieldMap().asMapOfRanges().values()) { ValueType elemType = getType(elemECR); Size elemSize = elemType.getSize(); ccjoin(elemSize, elemECR, e2); } return; } case STRUCT: { throw new IllegalArgumentException(); // Size size2 = type2.getSize(); // if(!Size.isLessThan(rangeSize, size2)) { // addCCjoin(rangeSize, e1, e2); // expand(e2, rangeSize); return; // } // // ValueType unifyStructType = unify(type1, type2); // unify structure type // eagerly // setType(e1, unifyStructType); // setType(e2, unifyStructType); // return; } default: return; // lambda } } default: return; // lambda } }