Beispiel #1
0
        private void LinearizePath(MethodDefData pMethodDefData, IRInstruction pStartInstruction, Stack <IRStackObject> pStack, Queue <Tuple <IRInstruction, Stack <IRStackObject> > > pBranches)
        {
            int           stackReturn        = pStack.Count;
            IRInstruction currentInstruction = pStartInstruction;

            MethodDefData.MethodDefBodyData.MethodDefBodyExceptionData exceptionData = null;
            while (currentInstruction != null)
            {
                if (currentInstruction.Linearized && pStack.Count == stackReturn)
                {
                    break;
                }

                if ((exceptionData = Array.Find(pMethodDefData.Body.Exceptions, e => e.Flags == 0 && e.HandlerOffset == currentInstruction.ILOffset)) != null)
                {
                    IRType        exceptionType = Assembly.AppDomain.PresolveType(Assembly.File.ExpandMetadataToken(exceptionData.ClassTokenOrFilterOffset));
                    IRStackObject exceptionObj  = new IRStackObject();
                    exceptionObj.Type             = exceptionType;
                    exceptionObj.LinearizedTarget = new IRLinearizedLocation(IRLinearizedLocationType.Local);
                    exceptionObj.LinearizedTarget.Local.LocalIndex = currentInstruction.AddLinearizedLocal(pStack, exceptionType);
                    pStack.Push(exceptionObj);
                }

                currentInstruction.Linearize(pStack);
                currentInstruction.Linearized = true;
                switch (currentInstruction.Opcode)
                {
                case IROpcode.Branch:
                {
                    IRBranchInstruction branchInstruction = (IRBranchInstruction)currentInstruction;
                    if (branchInstruction.BranchCondition == IRBranchCondition.Always)
                    {
                        currentInstruction = branchInstruction.TargetIRInstruction;
                    }
                    else
                    {
                        pBranches.Enqueue(new Tuple <IRInstruction, Stack <IRStackObject> >(branchInstruction.TargetIRInstruction, pStack.Duplicate()));
                        currentInstruction = Instructions[currentInstruction.IRIndex + 1];
                    }
                    break;
                }

                case IROpcode.Switch:
                {
                    IRSwitchInstruction switchInstruction = (IRSwitchInstruction)currentInstruction;
                    foreach (IRInstruction targetInstruction in switchInstruction.TargetIRInstructions)
                    {
                        pBranches.Enqueue(new Tuple <IRInstruction, Stack <IRStackObject> >(targetInstruction, pStack.Duplicate()));
                    }
                    currentInstruction = Instructions[currentInstruction.IRIndex + 1];
                    break;
                }

                case IROpcode.Leave:
                {
                    IRLeaveInstruction leaveInstruction = (IRLeaveInstruction)currentInstruction;
                    currentInstruction = leaveInstruction.TargetIRInstruction;
                    break;
                }

                case IROpcode.Jump:
                case IROpcode.Throw:
                case IROpcode.Return: currentInstruction = null; break;

                default: currentInstruction = currentInstruction.IRIndex >= Instructions.Count ? null : Instructions[currentInstruction.IRIndex + 1]; break;
                }
            }
        }
Beispiel #2
0
        private void LinearizePath(MethodDefData pMethodDefData, IRInstruction pStartInstruction, Stack<IRStackObject> pStack, Queue<Tuple<IRInstruction, Stack<IRStackObject>>> pBranches)
        {
            int stackReturn = pStack.Count;
            IRInstruction currentInstruction = pStartInstruction;
            MethodDefData.MethodDefBodyData.MethodDefBodyExceptionData exceptionData = null;
            while (currentInstruction != null)
            {
                if (currentInstruction.Linearized && pStack.Count == stackReturn) break;

                if ((exceptionData = Array.Find(pMethodDefData.Body.Exceptions, e => e.Flags == 0 && e.HandlerOffset == currentInstruction.ILOffset)) != null)
                {
                    IRType exceptionType = Assembly.AppDomain.PresolveType(Assembly.File.ExpandMetadataToken(exceptionData.ClassTokenOrFilterOffset));
                    IRStackObject exceptionObj = new IRStackObject();
                    exceptionObj.Type = exceptionType;
                    exceptionObj.LinearizedTarget = new IRLinearizedLocation(IRLinearizedLocationType.Local);
                    exceptionObj.LinearizedTarget.Local.LocalIndex = currentInstruction.AddLinearizedLocal(pStack, exceptionType);
                    pStack.Push(exceptionObj);
                }

                currentInstruction.Linearize(pStack);
                currentInstruction.Linearized = true;
                switch (currentInstruction.Opcode)
                {
                    case IROpcode.Branch:
                        {
                            IRBranchInstruction branchInstruction = (IRBranchInstruction)currentInstruction;
                            if (branchInstruction.BranchCondition == IRBranchCondition.Always) currentInstruction = branchInstruction.TargetIRInstruction;
                            else
                            {
                                pBranches.Enqueue(new Tuple<IRInstruction, Stack<IRStackObject>>(branchInstruction.TargetIRInstruction, pStack.Duplicate()));
                                currentInstruction = Instructions[currentInstruction.IRIndex + 1];
                            }
                            break;
                        }
                    case IROpcode.Switch:
                        {
                            IRSwitchInstruction switchInstruction = (IRSwitchInstruction)currentInstruction;
                            foreach (IRInstruction targetInstruction in switchInstruction.TargetIRInstructions)
                            {
                                pBranches.Enqueue(new Tuple<IRInstruction, Stack<IRStackObject>>(targetInstruction, pStack.Duplicate()));
                            }
                            currentInstruction = Instructions[currentInstruction.IRIndex + 1];
                            break;
                        }
                    case IROpcode.Leave:
                        {
                            IRLeaveInstruction leaveInstruction = (IRLeaveInstruction)currentInstruction;
                            currentInstruction = leaveInstruction.TargetIRInstruction;
                            break;
                        }
                    case IROpcode.Jump:
                    case IROpcode.Throw:
                    case IROpcode.Return: currentInstruction = null; break;
                    default: currentInstruction = currentInstruction.IRIndex >= Instructions.Count ? null : Instructions[currentInstruction.IRIndex + 1]; break;
                }
            }
        }