void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethod asyncMethod) { if (asyncMethod.KickoffMethod == null) { Error("KickoffMethod is null"); return; } uint kickoffMethod = GetMethodToken(asyncMethod.KickoffMethod); writer3.DefineKickoffMethod(kickoffMethod); if (asyncMethod.CatchHandlerInstruction != null) { int catchHandlerILOffset = info.GetOffset(asyncMethod.CatchHandlerInstruction); writer3.DefineCatchHandlerILOffset((uint)catchHandlerILOffset); } var stepInfos = asyncMethod.StepInfos; var yieldOffsets = new uint[stepInfos.Count]; var breakpointOffset = new uint[stepInfos.Count]; var breakpointMethods = new uint[stepInfos.Count]; for (int i = 0; i < yieldOffsets.Length; i++) { var stepInfo = stepInfos[i]; if (stepInfo.YieldInstruction == null) { Error("YieldInstruction is null"); return; } if (stepInfo.BreakpointMethod == null) { Error("BreakpointInstruction is null"); return; } if (stepInfo.BreakpointInstruction == null) { Error("BreakpointInstruction is null"); return; } yieldOffsets[i] = (uint)info.GetOffset(stepInfo.YieldInstruction); breakpointOffset[i] = (uint)GetExternalInstructionOffset(ref info, stepInfo.BreakpointMethod, stepInfo.BreakpointInstruction); breakpointMethods[i] = GetMethodToken(stepInfo.BreakpointMethod); } writer3.DefineAsyncStepInfo(yieldOffsets, breakpointOffset, breakpointMethods); }
PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody body, ISymbolMethod2 symMethod) { var kickoffToken = new MDToken(symMethod.KickoffMethod); if (kickoffToken.Table != MD.Table.Method) { return(null); } var kickoffMethod = module.ResolveMethod(kickoffToken.Rid); var rawStepInfos = symMethod.GetAsyncStepInfos(); var asyncMethod = new PdbAsyncMethod(rawStepInfos.Length); asyncMethod.KickoffMethod = kickoffMethod; var catchHandlerILOffset = symMethod.CatchHandlerILOffset; if (catchHandlerILOffset != null) { asyncMethod.CatchHandlerInstruction = GetInstruction(body, catchHandlerILOffset.Value); Debug.Assert(asyncMethod.CatchHandlerInstruction != null); } foreach (var rawInfo in rawStepInfos) { var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); Debug.Assert(yieldInstruction != null); if (yieldInstruction == null) { continue; } MethodDef breakpointMethod; Instruction breakpointInstruction; if (method.MDToken.Raw == rawInfo.BreakpointMethod) { breakpointMethod = method; breakpointInstruction = GetInstruction(body, rawInfo.BreakpointOffset); } else { var breakpointMethodToken = new MDToken(rawInfo.BreakpointMethod); Debug.Assert(breakpointMethodToken.Table == MD.Table.Method); if (breakpointMethodToken.Table != MD.Table.Method) { continue; } breakpointMethod = module.ResolveMethod(breakpointMethodToken.Rid); Debug.Assert(breakpointMethod != null); if (breakpointMethod == null) { continue; } breakpointInstruction = GetInstruction(breakpointMethod.Body, rawInfo.BreakpointOffset); } Debug.Assert(breakpointInstruction != null); if (breakpointInstruction == null) { continue; } asyncMethod.StepInfos.Add(new PdbAsyncStepInfo(yieldInstruction, breakpointMethod, breakpointInstruction)); } return(asyncMethod); }