protected void mergeHandler(
      Type type, T store, List<Pair<Type, String>> handlers, Map<String, T> stores) {
    for (Pair<Type, String> p : handlers) {
      Type handler = p.first();

      if (Type.isSubtype(handler, type)) {
        T nstore = propagate(handler, store);
        merge(p.second(), nstore, stores);
        return; // completely subsumed
      } else if (Type.isSubtype(type, handler)) {
        T nstore = propagate(handler, store);
        merge(p.second(), nstore, stores);
        // not completely subsumed
        type = Type.intersect(type, Type.Negation(handler));
      }
    }
  }
Beispiel #2
0
    private void determineTypesUpto(int end) {
      Type[] environment = environments[0];

      for (int i = position; i < end; ++i) {
        Code code = stmts.get(i).code;
        if (code instanceof Code.Label) {
          Code.Label label = (Code.Label) code;
          Type[] nEnv = cache.get(label.label);
          environment = join(environment, nEnv);
        } else if (code instanceof Code.AbstractAssignable) {
          Code.AbstractAssignable c = (Code.AbstractAssignable) code;
          environment = Arrays.copyOf(environment, environment.length);
          environment[c.target] = c.assignedType();
        } else if (code instanceof Code.Goto) {
          Code.Goto gto = (Code.Goto) code;
          cache.put(gto.target, environment);
          environment = null;
        } else if (code instanceof Code.If) {
          Code.If gto = (Code.If) code;
          cache.put(gto.target, environment);
        } else if (code instanceof Code.IfIs) {
          Code.IfIs gto = (Code.IfIs) code;
          Type[] trueEnv = Arrays.copyOf(environment, environment.length);
          trueEnv[gto.operand] = Type.intersect(trueEnv[gto.operand], gto.rightOperand);
          cache.put(gto.target, trueEnv);
          environment[gto.operand] =
              Type.intersect(trueEnv[gto.operand], Type.Negation(gto.rightOperand));
        } else if (code instanceof Code.Switch) {
          Code.Switch sw = (Code.Switch) code;
          for (Pair<Constant, String> c : sw.branches) {
            cache.put(c.second(), environment);
          }
          cache.put(sw.defaultTarget, environment);
        } else if (code instanceof Code.ForAll) {
          // FIXME: what this need to do is update the type for the
          // index variable, and then invalidate it afterwards.
          throw new RuntimeException("need to implement for-all loop!");
        } else if (code instanceof Code.Return || code instanceof Code.Throw) {
          environment = null;
        }

        environments[i] = environment;
      }
    }
Beispiel #3
0
 private static Type[] join(Type[] env1, Type[] env2) {
   if (env1 == null) {
     return env2;
   } else if (env2 == null) {
     return env1;
   }
   Type[] result = new Type[env1.length];
   for (int i = 0; i != env1.length; ++i) {
     Type t1 = env1[i];
     Type t2 = env2[i];
     if (t1 == null && t2 == null) {
       result[i] = null;
     } else if (t1 == null) {
       result[i] = t2;
     } else if (t2 == null) {
       result[i] = t1;
     } else {
       result[i] = Type.Union(t1, t2);
     }
   }
   return result;
 }