Example #1
0
  /**
   * This (recursive) utility method makes sure that no subroutine is calling a subroutine that uses
   * the same local variable for the RET as themselves (recursively). This includes that subroutines
   * may not call themselves recursively, even not through intermediate calls to other subroutines.
   *
   * @throws StructuralCodeConstraintException if the above constraint is not satisfied.
   */
  private void noRecursiveCalls(Subroutine sub, HashSet<Integer> set) {
    Subroutine[] subs = sub.subSubs();

    for (int i = 0; i < subs.length; i++) {
      int index = ((RET) (subs[i].getLeavingRET().getInstruction())).getIndex();

      if (!set.add(new Integer(index))) {
        // Don't use toString() here because of possibly infinite recursive subSubs() calls then.
        SubroutineImpl si = (SubroutineImpl) subs[i];
        throw new StructuralCodeConstraintException(
            "Subroutine with local variable '"
                + si.localVariable
                + "', JSRs '"
                + si.theJSRs
                + "', RET '"
                + si.theRET
                + "' is called by a subroutine which uses the same local variable index as itself; maybe even a recursive call? JustIce's clean definition of a subroutine forbids both.");
      }

      noRecursiveCalls(subs[i], set);

      set.remove(new Integer(index));
    }
  }