Exemplo n.º 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;
                }
            }
        }