Program: 132956
Project: 132956
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 passIn
 * @param keepOpenVars
 * @param priority 
 * @param recursive
 */
private void startAsync(String procName,List<Var> waitVars,List<Var> passIn,Arg priority,boolean recursive,TaskMode mode){
  assert(priority == null || priority.isImmediateInt());
  mode.checkSpawn(execContextStack.peek());
  for (  Var v : passIn) {
    if (v.type().equals(Types.V_BLOB)) {
      throw new STCRuntimeError("String_Node_Str");
    }
  }
  List<String> args=new ArrayList<String>();
  args.add(Turbine.LOCAL_STACK_NAME);
  for (  Var v : passIn) {
    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       if (Types.isRef(baseType)) {
      }
 else {
        throw new STCRuntimeError("String_Node_Str" + "String_Node_Str" + w.type().typeName());
      }
    }
    Expression waitExpr=getTurbineWaitId(w);
    waitFor.add(waitExpr);
  }
  Expression action=buildActionFromVars(uniqueName,passIn);
  Expression priorityExpr=TclUtil.argToExpr(priority,true);
  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().append(Turbine.deepRule(uniqueName,waitFor,depths,isFile,action,mode,priorityExpr,execContextStack.peek()));
  }
 else {
    pointStack.peek().append(Turbine.rule(uniqueName,waitFor,action,mode,Target.rankAny(),priorityExpr,execContextStack.peek()));
  }
  pointStack.push(constructProc);
  ExecContext newExecContext;
  if (mode == TaskMode.WORKER) {
    newExecContext=ExecContext.WORKER;
  }
 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 passIn
 * @param keepOpenVars
 * @param priority 
 * @param recursive
 */
private void startAsync(String procName,List<Var> waitVars,List<Var> passIn,Arg priority,boolean recursive,TaskMode mode){
  assert(priority == null || priority.isImmediateInt());
  mode.checkSpawn(execContextStack.peek());
  for (  Var v : passIn) {
    if (v.type().equals(Types.V_BLOB)) {
      throw new STCRuntimeError("String_Node_Str");
    }
  }
  List<String> args=new ArrayList<String>();
  args.add(Turbine.LOCAL_STACK_NAME);
  for (  Var v : passIn) {
    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       if (Types.isRef(baseType)) {
      }
 else {
        throw new STCRuntimeError("String_Node_Str" + "String_Node_Str" + w.type().typeName());
      }
    }
    Expression waitExpr=getTurbineWaitId(w);
    waitFor.add(waitExpr);
  }
  List<Expression> action=buildActionFromVars(uniqueName,passIn);
  Expression priorityExpr=TclUtil.argToExpr(priority,true);
  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().append(Turbine.deepRule(uniqueName,waitFor,depths,isFile,action,mode,priorityExpr,execContextStack.peek()));
  }
 else {
    pointStack.peek().append(Turbine.rule(uniqueName,waitFor,action,mode,Target.rankAny(),priorityExpr,execContextStack.peek()));
  }
  pointStack.push(constructProc);
  ExecContext newExecContext;
  if (mode == TaskMode.WORKER) {
    newExecContext=ExecContext.WORKER;
  }
 else   if (mode == TaskMode.CONTROL) {
    newExecContext=ExecContext.CONTROL;
  }
 else {
    newExecContext=execContextStack.peek();
  }
  execContextStack.push(newExecContext);
}