public static List <ILRange> OrderAndJoint(IEnumerable <ILRange> input) { if (input == null) { throw new ArgumentNullException("Input is null!"); } List <ILRange> ranges = input.Where(r => r != null).OrderBy(r => r.From).ToList(); for (int i = 0; i < ranges.Count - 1;) { ILRange curr = ranges[i]; ILRange next = ranges[i + 1]; // Merge consequtive ranges if they intersect if (curr.From <= next.From && next.From <= curr.To) { curr.To = Math.Max(curr.To, next.To); ranges.RemoveAt(i + 1); } else { i++; } } return(ranges); }
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())))); } }
public List <ILRange> GetSelfAndChildrenRecursiveILRanges_OrderAndJoin() { // The current callers save the list as an annotation so always create a new list here // instead of having them pass in a cached list. var list = new List <ILRange>(); AddSelfAndChildrenRecursiveILRanges(list); return(ILRange.OrderAndJoinList(list)); }
protected void UpdateMemberMapping(MemberMapping memberMapping, TextPosition startLoc, TextPosition endLoc, IEnumerable <ILRange> ranges) { if (memberMapping == null) { return; } foreach (var range in ILRange.OrderAndJoin(ranges)) { memberMapping.MemberCodeMappings.Add(new SourceCodeMapping(range, startLoc, endLoc, memberMapping)); } }
static void SetResult(ILExpression expr, ILExpression n) { // IL ranges from removed nodes are assigned to the new operator expression var removednodes = expr.GetSelfAndChildrenRecursive <ILExpression>().Except(n.GetSelfAndChildrenRecursive <ILExpression>()); n.ILRanges = ILRange.OrderAndJoint(n.ILRanges.Concat(removednodes.SelectMany(el => el.ILRanges))); // the new expression is wrapped in a container so that negations aren't pushed through lifted comparison operations expr.Code = ILCode.Wrap; expr.Arguments.Clear(); expr.Arguments.Add(n); expr.ILRanges.Clear(); expr.InferredType = n.InferredType; }
protected void UpdateMemberMapping(MemberMapping memberMapping, TextLocation startLoc, TextLocation endLoc, IEnumerable <ILRange> ranges) { if (memberMapping == null) { return; } foreach (var range in ILRange.OrderAndJoin(ranges)) { memberMapping.MemberCodeMappings.Add(new SourceCodeMapping { StartLocation = startLoc, EndLocation = endLoc, ILInstructionOffset = range, MemberMapping = memberMapping }); } }
public static List <ILRange> OrderAndJoint(IEnumerable <ILRange> input) { List <ILRange> ranges = input.OrderBy(r => r.From).ToList(); for (int i = 0; i < ranges.Count - 1;) { ILRange curr = ranges[i]; ILRange next = ranges[i + 1]; // Merge consequtive ranges if they intersect if (curr.From <= next.From && next.From <= curr.To) { curr.To = Math.Max(curr.To, next.To); ranges.RemoveAt(i + 1); } else { i++; } } return(ranges); }
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.Count; for (int i = byteCode.StackBefore.Count - popCount; i < byteCode.StackBefore.Count; 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); }