void ReportUnassignedILRanges(ILBlock method) { var unassigned = ILRange.Invert(method.GetSelfAndChildrenRecursive <ILExpression>().SelectMany(e => e.ILRanges), context.CurrentMethod.Body.CodeSize).ToList(); if (unassigned.Count > 0) { Debug.WriteLine(string.Format("Unassigned ILRanges for {0}.{1}: {2}", this.context.CurrentMethod.DeclaringType.Name, this.context.CurrentMethod.Name, string.Join(", ", unassigned.Select(r => r.ToString())))); } }
List <ILNode> ConvertToAst(List <ByteCode> body) { List <ILNode> ast = new List <ILNode>(); // Convert stack-based IL code to ILAst tree foreach (ByteCode byteCode in body) { ILRange ilRange = new ILRange() { From = byteCode.Offset, To = byteCode.EndOffset }; if (byteCode.StackBefore == null) { // Unreachable code continue; } ILExpression expr = new ILExpression(byteCode.Code, byteCode.Operand); expr.ILRanges.Add(ilRange); if (byteCode.Prefixes != null && byteCode.Prefixes.Length > 0) { ILExpressionPrefix[] prefixes = new ILExpressionPrefix[byteCode.Prefixes.Length]; for (int i = 0; i < prefixes.Length; i++) { prefixes[i] = new ILExpressionPrefix((ILCode)byteCode.Prefixes[i].OpCode.Code, byteCode.Prefixes[i].Operand); } expr.Prefixes = prefixes; } // Label for this instruction if (byteCode.Label != null) { ast.Add(byteCode.Label); } // Reference arguments using temporary variables int popCount = byteCode.PopCount ?? byteCode.StackBefore.Length; for (int i = byteCode.StackBefore.Length - popCount; i < byteCode.StackBefore.Length; i++) { StackSlot slot = byteCode.StackBefore[i]; expr.Arguments.Add(new ILExpression(ILCode.Ldloc, slot.LoadFrom)); } // Store the result to temporary variable(s) if needed if (byteCode.StoreTo == null || byteCode.StoreTo.Count == 0) { ast.Add(expr); } else if (byteCode.StoreTo.Count == 1) { ast.Add(new ILExpression(ILCode.Stloc, byteCode.StoreTo[0], expr)); } else { ILVariable tmpVar = new ILVariable() { Name = "expr_" + byteCode.Offset.ToString("X2"), IsGenerated = true }; ast.Add(new ILExpression(ILCode.Stloc, tmpVar, expr)); foreach (ILVariable storeTo in byteCode.StoreTo.AsEnumerable().Reverse()) { ast.Add(new ILExpression(ILCode.Stloc, storeTo, new ILExpression(ILCode.Ldloc, tmpVar))); } } } return(ast); }