예제 #1
0
        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);
        }
예제 #2
0
        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()))));
            }
        }
예제 #3
0
        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));
        }
예제 #4
0
 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));
     }
 }
예제 #5
0
            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;
            }
예제 #6
0
 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
         });
     }
 }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }