예제 #1
0
  /**
   * Set type <code>e</code> as <code>type</code>
   *
   * @param e
   * @param type
   */
  void setType(ECR e, ValueType type) {
    ECR root = findRoot(e);
    root.setType(type);

    Collection<Pair<Size, ECR>> ccjoins = ImmutableList.copyOf(root.getCCjoins());
    root.clearCCjoins(ccjoins);
    for (Pair<Size, ECR> cjoinPair : ccjoins) ccjoin(cjoinPair.fst(), root, cjoinPair.snd());

    Collection<ECR> cjoins = ImmutableList.copyOf(root.getCjoins());
    root.clearCjoins(cjoins);
    for (ECR joinECR : cjoins) cjoin(root, joinECR);
  }
예제 #2
0
  /**
   * Collapse <code>structECR</code> by merge it with all its element ECRs, and set its type as the
   * cell type (simple type might with top size)
   *
   * @param structECR
   * @param structT
   * @param ECRCache avoid structure cycle
   * @return
   */
  private ValueType collapseStruct(ECR structECR, StructType structT, Collection<ECR> ECRCache) {
    // Ensure collapsed type to be simple
    ValueType unionType = null;

    // join components
    Collection<ECR> elems = structT.getFieldMap().asMapOfRanges().values();
    Collection<ECR> cjoins = Sets.newHashSet();
    Collection<Pair<Size, ECR>> ccjoins = Sets.newHashSet();

    for (ECR elem : elems) {
      ECR elemLoc = getLoc(elem);
      ValueType elemLocType = getType(elemLoc);
      Parent parent = elemLocType.getParent().removeECR(structECR);
      elemLocType.setParent(parent);

      if (!ECRCache.add(elemLoc)) continue; // ECRCache has elemLoc

      cjoins.addAll(getCjoins(elemLoc));
      elemLoc.clearCCjoins(ccjoins);
      ccjoins.addAll(getCCjoins(elemLoc));
      elemLoc.clearCCjoins(ccjoins);

      if (elemLocType.isStruct()) {
        elemLocType = collapseStruct(elemLoc, elemLocType.asStruct(), ECRCache);
      }

      union(structECR, elemLoc);
      unionType = unionType == null ? elemLocType : unify(unionType, elemLocType);
    }
    unionType = unionType == null ? ValueType.bottom() : unionType;

    setType(structECR, unionType);
    ECR root = findRoot(structECR);

    for (Pair<Size, ECR> cjoinPair : ccjoins) ccjoin(cjoinPair.fst(), root, cjoinPair.snd());

    for (ECR joinECR : cjoins) cjoin(root, joinECR);

    return unionType;
  }
예제 #3
0
  ECR join(ECR e1, ECR e2) {
    if (e1.equals(e2)) return e1;

    checkStructCollapse(e1, e2);

    ValueType t1 = getType(e1);
    ValueType t2 = getType(e2);

    Collection<Pair<Size, ECR>> ccjoins1 = ImmutableList.copyOf(getCCjoins(e1));
    Collection<Pair<Size, ECR>> ccjoins2 = ImmutableList.copyOf(getCCjoins(e2));

    Collection<ECR> cjoins1 = ImmutableList.copyOf(getCjoins(e1));
    Collection<ECR> cjoins2 = ImmutableList.copyOf(getCjoins(e2));

    ECR root = union(e1, e2);

    switch (t1.getKind()) {
      case BOTTOM:
        {
          switch (t2.getKind()) {
            case BOTTOM:
              {
                Collection<ECR> cjoins = Sets.newHashSet();
                cjoins.addAll(cjoins1);
                cjoins.addAll(cjoins2);
                root.addCjoins(cjoins);

                Collection<Pair<Size, ECR>> ccjoins = Sets.newHashSet();
                ccjoins.addAll(ccjoins1);
                ccjoins.addAll(ccjoins2);
                root.addCCjoins(ccjoins);

                break;
              }
            default:
              {
                root.setType(t2);

                root.clearCCjoins(ccjoins1);
                for (Pair<Size, ECR> pair : ccjoins1) ccjoin(pair.fst(), root, pair.snd());

                root.clearCjoins(cjoins1);
                for (ECR cjoin : cjoins1) cjoin(root, cjoin);

                break;
              }
          }
          break;
        }
      default:
        {
          switch (t2.getKind()) {
            case BOTTOM:
              {
                root.setType(t1);

                root.clearCCjoins(ccjoins2);
                for (Pair<Size, ECR> pair : ccjoins2) ccjoin(pair.fst(), root, pair.snd());

                root.clearCjoins(cjoins2);
                for (ECR cjoin : cjoins2) cjoin(root, cjoin);

                break;
              }
            default:
              {
                root.setType(t1);
                ValueType unionType = unify(t1, t2);

                ValueType freshType = getType(root);
                if (!freshType.equals(t1)) {
                  unionType = resolveType(root, unionType, freshType);
                }

                root.setType(unionType);

                root.clearCCjoins(ccjoins1);
                root.clearCCjoins(ccjoins2);

                for (Pair<Size, ECR> pair : ccjoins1) ccjoin(pair.fst(), root, pair.snd());
                for (Pair<Size, ECR> pair : ccjoins2) ccjoin(pair.fst(), root, pair.snd());
                break;
              }
          }
          break;
        }
    }

    return root;
  }