/// <summary> /// Looks at the enumerator's get_Current method and figures out which of the fields holds the current value. /// </summary> void AnalyzeCurrentProperty() { MethodDefinition getCurrentMethod = enumeratorType.Methods.FirstOrDefault( m => m.Name.StartsWith("System.Collections.Generic.IEnumerator", StringComparison.Ordinal) && m.Name.EndsWith(".get_Current", StringComparison.Ordinal)); ILBlock method = CreateILAst(getCurrentMethod); if (method.Body.Count == 1) { // release builds directly return the current field ILExpression retExpr; FieldReference field; ILExpression ldFromObj; if (method.Body[0].Match(ILCode.Ret, out retExpr) && retExpr.Match(ILCode.Ldfld, out field, out ldFromObj) && ldFromObj.MatchThis()) { currentField = GetFieldDefinition(field); } } else if (method.Body.Count == 2) { ILVariable v, v2; ILExpression stExpr; FieldReference field; ILExpression ldFromObj; ILExpression retExpr; if (method.Body[0].Match(ILCode.Stloc, out v, out stExpr) && stExpr.Match(ILCode.Ldfld, out field, out ldFromObj) && ldFromObj.MatchThis() && method.Body[1].Match(ILCode.Ret, out retExpr) && retExpr.Match(ILCode.Ldloc, out v2) && v == v2) { currentField = GetFieldDefinition(field); } } if (currentField == null) throw new YieldAnalysisFailedException(); }
public void AddFieldDefinition (FieldDefinition field) { Fields [field.token.RID - 1] = field; }
/// <summary> /// Looks at the enumerator's ctor and figures out which of the fields holds the state. /// </summary> void AnalyzeCtor() { ILBlock method = CreateILAst(enumeratorCtor); foreach (ILNode node in method.Body) { FieldReference field; ILExpression instExpr; ILExpression stExpr; ILVariable arg; if (node.Match(ILCode.Stfld, out field, out instExpr, out stExpr) && instExpr.MatchThis() && stExpr.Match(ILCode.Ldloc, out arg) && arg.IsParameter && arg.OriginalParameter.Index == 0) { stateField = GetFieldDefinition(field); } } if (stateField == null) throw new YieldAnalysisFailedException(); }