// map back "trace[start, start + to.size - 1]" through this transformation. // // tinfo is the parent // transformation info for the whole program -- it is used for recursively // calling the mapBack procedure on callee traces public ErrorTraceInstr mapBackTrace(List <ErrorTraceInstr> trace, int start, ModifyTrans tinfo) { Debug.Assert(start >= 0); Debug.Assert(start + to.Count - 1 < trace.Count); // Find the "info" for "from". It is obtained from the // corresponding instruction, if one is provided. Else // we search through "to" to find (any) valid info. InstrInfo info = null; if (correspondingInstr >= 0) { info = trace[start + correspondingInstr].info; } else { // Default info (invalid) info = new InstrInfo(); for (int i = start; i < start + to.Count; i++) { if (trace[i].info.isValid) { info = trace[i].info; break; } } } Debug.Assert(info != null); ErrorTraceInstr ret = null; if (from.type == InstrTypeEnum.CALL || from.type == InstrTypeEnum.ASYNC) { // check if the corresponding instruction is also a call if (correspondingInstr >= 0 && trace[start + correspondingInstr].isCall()) { var calleeTrace = (trace[start + correspondingInstr] as CallInstr).calleeTrace; if (calleeTrace != null) { // Recurse on the callee trace calleeTrace = tinfo.mapBackTrace(calleeTrace); } ret = new CallInstr(from.callee, calleeTrace, (from.type == InstrTypeEnum.ASYNC ? true : false), info); } else { // no corresponding callee trace ret = new CallInstr(from.callee, null, (from.type == InstrTypeEnum.ASYNC ? true : false), info); } } else { ret = new IntraInstr(info); } Debug.Assert(ret != null); return(ret); }
public ErrorTrace mapBackTrace(ErrorTrace trace) { Debug.Assert(ltinfo != null && gtinfo != null); if (!onlyLocals) { // First, globals trace = gtinfo.mapBackTrace(trace); } // Next, locals trace = ltinfo.mapBackTrace(trace); return(trace); }
public override ErrorTrace mapBackTrace(ErrorTrace trace) { return(tinfo.mapBackTrace(trace)); }