Program: 133167
Project: 133167
Buggy source:
/** 
 * Internal helper to implement constructs that need to wait for a number of variables, and then run some code
 * @param procName
 * @param waitVars
 * @param usedVariables
 * @param keepOpenVars
 * @param priority 
 * @param recursive 
 * @param shareWork if true, work will be shared with other rule enginesat the cost of higher overhead
 */
private void startAsync(String procName,List<Var> waitVars,List<Var> usedVariables,List<Var> keepOpenVars,Arg priority,boolean recursive,TaskMode mode){
  assert(priority == null || priority.isImmediateInt());
  mode.checkSpawn(execContextStack.peek());
  ArrayList<Var> toPassIn=new ArrayList<Var>();
  HashSet<String> alreadyInSet=new HashSet<String>();
  for (  Var v : usedVariables) {
    toPassIn.add(v);
    alreadyInSet.add(v.name());
    if (v.type().equals(Types.V_BLOB)) {
      throw new STCRuntimeError("String_Node_Str");
    }
  }
  for (  Var v : keepOpenVars) {
    if (!alreadyInSet.contains(v.name())) {
      toPassIn.add(v);
    }
  }
  List<String> args=new ArrayList<String>();
  args.add(Turbine.LOCAL_STACK_NAME);
  for (  Var v : toPassIn) {
    args.add(prefixVar(v.name()));
  }
  Sequence constructProc=new Sequence();
  String uniqueName=uniqueTCLFunctionName(procName);
  Proc proc=new Proc(uniqueName,usedTclFunctionNames,args,constructProc);
  tree.add(proc);
  boolean useDeepWait=false;
  List<Expression> waitFor=new ArrayList<Expression>();
  for (  Var w : waitVars) {
    if (recursive) {
      Type baseType=w.type();
      if (Types.isArray(w.type())) {
        baseType=new ArrayInfo(w.type()).baseType;
        useDeepWait=true;
      }
      if (Types.isScalarFuture(baseType)) {
      }
 else {
        throw new STCRuntimeError("String_Node_Str" + "String_Node_Str" + w.type().typeName());
      }
    }
    Expression waitExpr=getTurbineWaitId(w);
    waitFor.add(waitExpr);
  }
  incrementAllRefs(usedVariables,keepOpenVars);
  setPriority(priority);
  TclList action=buildAction(uniqueName,toPassIn);
  boolean local=execContextStack.peek() == ExecContext.CONTROL;
  if (useDeepWait) {
    int depths[]=new int[waitVars.size()];
    boolean isFile[]=new boolean[waitVars.size()];
    for (int i=0; i < waitVars.size(); i++) {
      Type waitVarType=waitVars.get(i).type();
      Type baseType;
      if (Types.isArray(waitVarType)) {
        ArrayInfo ai=new ArrayInfo(waitVarType);
        depths[i]=ai.nesting;
        baseType=ai.baseType;
      }
 else {
        depths[i]=0;
        baseType=waitVarType;
      }
      isFile[i]=Types.isFile(baseType);
    }
    pointStack.peek().add(Turbine.deepRule(uniqueName,waitFor,depths,isFile,action,mode,local));
  }
 else {
    pointStack.peek().add(Turbine.rule(uniqueName,waitFor,action,mode,local));
  }
  clearPriority(priority);
  pointStack.push(constructProc);
  ExecContext newExecContext;
  if (mode == TaskMode.LEAF) {
    newExecContext=ExecContext.LEAF;
  }
 else   if (mode == TaskMode.CONTROL) {
    newExecContext=ExecContext.CONTROL;
  }
 else {
    newExecContext=execContextStack.peek();
  }
  execContextStack.push(newExecContext);
}

Fixed version (ground truth):
/** 
 * Internal helper to implement constructs that need to wait for a number of variables, and then run some code
 * @param procName
 * @param waitVars
 * @param usedVars
 * @param keepOpenVars
 * @param priority 
 * @param recursive 
 * @param shareWork if true, work will be shared with other rule enginesat the cost of higher overhead
 */
private void startAsync(String procName,List<Var> waitVars,List<Var> usedVars,List<Var> keepOpenVars,Arg priority,boolean recursive,TaskMode mode){
  assert(priority == null || priority.isImmediateInt());
  mode.checkSpawn(execContextStack.peek());
  List<Var> allUsedVars=asyncUsedVars(usedVars,waitVars);
  ArrayList<Var> toPassIn=new ArrayList<Var>();
  HashSet<String> alreadyInSet=new HashSet<String>();
  for (  Var v : allUsedVars) {
    toPassIn.add(v);
    alreadyInSet.add(v.name());
    if (v.type().equals(Types.V_BLOB)) {
      throw new STCRuntimeError("String_Node_Str");
    }
  }
  for (  Var v : keepOpenVars) {
    if (!alreadyInSet.contains(v.name())) {
      toPassIn.add(v);
    }
  }
  List<String> args=new ArrayList<String>();
  args.add(Turbine.LOCAL_STACK_NAME);
  for (  Var v : toPassIn) {
    args.add(prefixVar(v.name()));
  }
  Sequence constructProc=new Sequence();
  String uniqueName=uniqueTCLFunctionName(procName);
  Proc proc=new Proc(uniqueName,usedTclFunctionNames,args,constructProc);
  tree.add(proc);
  boolean useDeepWait=false;
  List<Expression> waitFor=new ArrayList<Expression>();
  for (  Var w : waitVars) {
    if (recursive) {
      Type baseType=w.type();
      if (Types.isArray(w.type())) {
        baseType=new ArrayInfo(w.type()).baseType;
        useDeepWait=true;
      }
      if (Types.isScalarFuture(baseType)) {
      }
 else {
        throw new STCRuntimeError("String_Node_Str" + "String_Node_Str" + w.type().typeName());
      }
    }
    Expression waitExpr=getTurbineWaitId(w);
    waitFor.add(waitExpr);
  }
  incrementAllRefs(allUsedVars,keepOpenVars);
  setPriority(priority);
  TclList action=buildAction(uniqueName,toPassIn);
  boolean local=execContextStack.peek() == ExecContext.CONTROL;
  if (useDeepWait) {
    int depths[]=new int[waitVars.size()];
    boolean isFile[]=new boolean[waitVars.size()];
    for (int i=0; i < waitVars.size(); i++) {
      Type waitVarType=waitVars.get(i).type();
      Type baseType;
      if (Types.isArray(waitVarType)) {
        ArrayInfo ai=new ArrayInfo(waitVarType);
        depths[i]=ai.nesting;
        baseType=ai.baseType;
      }
 else {
        depths[i]=0;
        baseType=waitVarType;
      }
      isFile[i]=Types.isFile(baseType);
    }
    pointStack.peek().add(Turbine.deepRule(uniqueName,waitFor,depths,isFile,action,mode,local));
  }
 else {
    pointStack.peek().add(Turbine.rule(uniqueName,waitFor,action,mode,local));
  }
  clearPriority(priority);
  pointStack.push(constructProc);
  ExecContext newExecContext;
  if (mode == TaskMode.LEAF) {
    newExecContext=ExecContext.LEAF;
  }
 else   if (mode == TaskMode.CONTROL) {
    newExecContext=ExecContext.CONTROL;
  }
 else {
    newExecContext=execContextStack.peek();
  }
  execContextStack.push(newExecContext);
}