Ejemplo n.º 1
0
 private IEnumerable <JSStatement> CreateJsFinallyBlock(FinallyBlock finallyBlock, int p)
 {
     yield return(new JSFinallyBlock
     {
         Statements = CreateJsBlock(finallyBlock, p).Build().ToList()
     });
 }
        /// <summary>
        /// Appends the script to represent this object to the StringBuilder.
        /// </summary>
        /// <param name="builder">The StringBuilder to which the Javascript is appended.</param>
        /// <param name="options">The options to use when appending JavaScript</param>
        /// <param name="allowReservedWords"></param>
        internal protected override void AppendScript(StringBuilder builder, ScriptOptions options, bool allowReservedWords)
        {
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }

            if (_tryBlock == null)
            {
                throw new InvalidOperationException();
            }

            builder.Append("try");
            _tryBlock.AppendScript(builder, options, allowReservedWords);

            if (CatchBlock != null)
            {
                if (CatchVariable == null)
                {
                    throw new InvalidOperationException();
                }

                builder.Append("catch(");
                CatchVariable.AppendScript(builder, options, allowReservedWords);
                builder.Append(")");
                CatchBlock.AppendScript(builder, options, allowReservedWords);
            }

            if (FinallyBlock != null)
            {
                builder.Append("finally");
                FinallyBlock.AppendScript(builder, options, allowReservedWords);
            }
        }
Ejemplo n.º 3
0
        public FinallyBlock Build()
        {
            var finallyBlock = new FinallyBlock(_block);

            finallyBlock.Body = new OrderedBlockBuilder(_reader, "finally", finallyBlock).Build();

            return(finallyBlock);
        }
Ejemplo n.º 4
0
        public override void Clone(JsNode node)
        {
            base.Clone(node);
            var node2 = (JsTryStatement)node;

            node2.TryBlock     = TryBlock.Clone();
            node2.CatchClause  = CatchClause.Clone();
            node2.FinallyBlock = FinallyBlock.Clone();
        }
Ejemplo n.º 5
0
        internal TryStmt ParseTryStmt()
        {
            Token t = RequireAndGet(TokenType.TRY);

            Require(TokenType.EOS);
            var s = ParseStatementBlock();

            var cb = new List <CatchBlock>();

            while (La() == TokenType.CATCH)
            {
                cb.Add(ParseCatchBlock());
            }

            FinallyBlock fb = null;

            if (La() == TokenType.FINALLY)
            {
                var ft = ConsumeAndGet();
                Require(TokenType.EOS);
                fb = new FinallyBlock(ft, ParseStatementBlock());
            }

            Require(TokenType.END);
            Expect(TokenType.TRY);
            Require(TokenType.EOS);

            return(new TryStmt(t, s, cb.ToArray(), fb));

            CatchBlock ParseCatchBlock()
            {
                Token ct = RequireAndGet(TokenType.CATCH);

                Expect(TokenType.TO);

                Token n = ParseVarIdName();

                TypeExpr type = null;

                if (Expect(TokenType.AS))
                {
                    Require(type = ParseType(), ErrorCode.Expected, "type");
                }

                Expr when = null;

                if (Expect(TokenType.WHEN))
                {
                    when = RequireExpression();
                }

                Expect(TokenType.EOS);
                var cs = ParseStatementBlock();

                return(new CatchBlock(ct, n, type, when, cs));
            }
        }
Ejemplo n.º 6
0
            protected internal override void VisitFinallyBlock(FinallyBlock node, object data)
            {
                StackTypes stack = data as StackTypes;

                if (stack.Count != 0)
                {
                    throw new VerifierException();
                }

                AddTask(node.Next, stack);
            }
Ejemplo n.º 7
0
        void beginNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!beginChanging)
            {
                using (FinallyBlock.Create(beginChanging = true, _ => beginChanging = false))
                {
                    this.BeginValue = sender == beginNumericUpDown ? (float)beginNumericUpDown.Value : beginTrackBar.Value / 100f;

                    if (BeginValueChanged != null)
                    {
                        BeginValueChanged(this, EventArgs.Empty);
                    }
                }
            }
        }
Ejemplo n.º 8
0
        void endNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!endChanging)
            {
                using (FinallyBlock.Create(endChanging = true, _ => endChanging = false))
                {
                    this.EndValue = sender == endNumericUpDown ? (float)endNumericUpDown.Value : endTrackBar.Value / 100f;

                    if (EndValueChanged != null)
                    {
                        EndValueChanged(this, EventArgs.Empty);
                    }
                }
            }
        }
Ejemplo n.º 9
0
        public IDisposable SusupendNotification(bool notifyReset, bool checkRealChanges)
        {
            var cache = checkRealChanges ? this.ToArray() : null;

            return(FinallyBlock.Create(this.NotifyChanges = false, _ =>
            {
                this.NotifyChanges = true;

                if (notifyReset && (!checkRealChanges || !this.SequenceEqual(cache)))
                {
                    dispatcher.Invoke((Action <NotifyCollectionChangedEventArgs>)OnCollectionChanged,
                                      new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                }
            }));
        }
Ejemplo n.º 10
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public override void AcceptVisitor(StatementVisitor visitor)
        {
            visitor.VisitTryStatement(this);

            TryBlock.AcceptVisitor(visitor);

            foreach (var catchBlock in CatchBlocks)
            {
                catchBlock.AcceptVisitor(visitor);
            }

            if (FinallyBlock != null)
            {
                FinallyBlock.AcceptVisitor(visitor);
            }
        }
Ejemplo n.º 11
0
        void UpdateUIValues()
        {
            if (activePanel.Enabled = this.Caption != null)
            {
                beginLabel.Text = this.Caption.StartFrame.ToString("0.00");
                endLabel.Text   = (this.Caption.StartFrame + this.Caption.DurationFrame).ToString("0.00");
                timelineControl.CurrentAmount = (float)((this.CurrentFrame - this.Caption.StartFrame) / this.Caption.DurationFrame);
            }

            if (updates != null)
            {
                updates();
            }

            updates = null;

            if (this.AnimationData != null)
            {
                timelineControl.Amounts = this.AnimationData.X.Frames.Select(_ => _.FrameAmount).ToArray();
            }
            else
            {
                timelineControl.Amounts = null;
            }

            timelineControl.TryUpdate();

            if (parametersPanel.Enabled = this.Caption != null && this.AnimationData != null && this.IsAnimationEnabled)
            {
                if (!changing)
                {
                    using (FinallyBlock.Create(changing = true, _ => changing = false))
                    {
                        GetValueSet(xEntry, this.AnimationData.X);
                        GetValueSet(yEntry, this.AnimationData.Y);
                        GetValueSet(alphaEntry, this.AnimationData.Alpha);
                        GetValueSet(rotationEntry, this.AnimationData.Rotation);
                        GetValueSet(fontSizeEntry, this.AnimationData.FontSize);
                        GetValueSet(lineSpacingEntry, this.AnimationData.LineSpacing);
                        GetValueSet(letterSpacingEntry, this.AnimationData.LetterSpacing);
                        GetValueSet(shadowDistanceEntry, this.AnimationData.ShadowDistance);
                    }
                }
            }
        }
Ejemplo n.º 12
0
 public void SetNewValues()
 {
     if (!changing)
     {
         using (FinallyBlock.Create(changing = true, _ => changing = false))
             if (this.Caption != null && this.AnimationData != null)
             {
                 SetValueSet(xEntry, this.AnimationData.X);
                 SetValueSet(yEntry, this.AnimationData.Y);
                 SetValueSet(alphaEntry, this.AnimationData.Alpha);
                 SetValueSet(rotationEntry, this.AnimationData.Rotation);
                 SetValueSet(fontSizeEntry, this.AnimationData.FontSize);
                 SetValueSet(lineSpacingEntry, this.AnimationData.LineSpacing);
                 SetValueSet(letterSpacingEntry, this.AnimationData.LetterSpacing);
                 SetValueSet(shadowDistanceEntry, this.AnimationData.ShadowDistance);
             }
     }
 }
Ejemplo n.º 13
0
 protected override void VisitFinallyBlock(FinallyBlock node, object data)
 {
     throw new NodeNotSupportedException(node);
 }
Ejemplo n.º 14
0
 protected internal virtual void VisitFinallyBlock(FinallyBlock node, object data)
 {
     throw new NodeNotSupportedException(node);
 }
Ejemplo n.º 15
0
 protected static IDisposable AcquireUpgradableReaderLock(ReaderWriterLockSlim self)
 {
     return(FinallyBlock.Create(() => self.EnterUpgradeableReadLock(), () => self.ExitUpgradeableReadLock()));
 }
Ejemplo n.º 16
0
        public static MethodBodyBlock Convert(MethodEx method)
        {
            if (!method.IsVerified)
            {
                throw new ConvertionException();
            }
            MethodInfoExtention _method_  = new MethodInfoExtention(method.Method);
            MethodBodyBlock     mainBlock = new MethodBodyBlock(_method_.GetReturnType().type);

            mainBlock.Options["StackTypes"] = new StackTypes();
            Block currentBlock = mainBlock;

            Node[] heads = new Node[method.Count];
            Node[] tails = new Node[method.Count];
            Node   head = null;
            Node   tail = null;
            Node   firstBlock = null;
            Node   lastBlock = null;
            int    iNum, iNumNext;

            Variable[]    locals        = new Variable[method.Locals.Count];
            Variable[]    args          = new Variable[_method_.ArgCount];
            VariablesList methodVarList = mainBlock.Variables;

            for (int i = 0; i < args.Length; i++)
            {
                args[i]      = methodVarList.CreateVar(_method_.GetArgType(i).type, VariableKind.Parameter);
                args[i].Name = "Arg" + i;
//				methodVarList.Add(args[i]);
            }
            for (int i = 0; i < locals.Length; i++)
            {
                locals[i]      = methodVarList.CreateVar(method.Locals[i], VariableKind.Local);
                locals[i].Name = "Loc" + i;
//				methodVarList.Add(locals[i]);
            }

            BlockType nextBlockType;
            int       nextBlockStart = -1;
            int       nextBlockEnd   = 1 << 30;
            int       nextBlockIndex;
            Type      nextCatchBlockType;
            Hashtable tryBlocks    = new Hashtable();
            Hashtable filterBlocks = new Hashtable();
            Stack     blockEnds    = new Stack();

            blockEnds.Push(method.Count);
            FindNextBlockStart(method.EHClauses, out nextBlockType, ref nextBlockStart, ref nextBlockEnd, out nextCatchBlockType, out nextBlockIndex);

            //Nodes and blocks creation, blocks linkage
            for (iNum = 0; iNum < method.Count; iNum++)
            {
                while (iNum == (int)blockEnds.Peek())
                {
                    currentBlock = currentBlock.Parent;
                    blockEnds.Pop();
                }

                firstBlock = null;
                lastBlock  = null;
                Node thisBlock = null;
                while (iNum == nextBlockStart)
                {
                    Block currentBlockOld = currentBlock;

                    switch (nextBlockType)
                    {
                    case BlockType.Try:
                        currentBlock = new ProtectedBlock();
                        break;

                    case BlockType.Catch:
                        currentBlock = new CatchBlock(nextCatchBlockType);
                        break;

                    case BlockType.Finally:
                        currentBlock = new FinallyBlock(false);
                        break;

                    case BlockType.Filter:
                        currentBlock = new FilterBlock();
                        break;

                    case BlockType.FilteredCatch:
                        currentBlock = new UserFilteredBlock();
                        break;
                    }

                    currentBlock.setParent(currentBlockOld);

                    blockEnds.Push(nextBlockEnd);
                    if (thisBlock == null)
                    {
                        thisBlock = firstBlock = currentBlock;
                    }
                    else
                    {
                        thisBlock.Next = currentBlock;
                        thisBlock      = currentBlock;
                    }
                    switch (nextBlockType)
                    {
                    case BlockType.Try:
                        tryBlocks.Add(new Segment(nextBlockStart, nextBlockEnd), thisBlock);
                        break;

                    case BlockType.Filter:
                        filterBlocks.Add(new Segment(nextBlockStart, nextBlockEnd), thisBlock);
                        break;

                    case BlockType.Finally:
                    case BlockType.Catch:
                    {
                        Segment        tryBlockKey = FindProtectedBlock(method.EHClauses, nextBlockIndex);
                        ProtectedBlock tryBlock    = tryBlocks[tryBlockKey] as ProtectedBlock;
                        tryBlock.AddHandler(thisBlock as EHBlock);
                    }       break;

                    case BlockType.FilteredCatch:
                    {
                        Segment        tryBlockKey = FindProtectedBlock(method.EHClauses, nextBlockIndex);
                        ProtectedBlock tryBlock    = tryBlocks[tryBlockKey] as ProtectedBlock;
                        tryBlock.AddHandler(thisBlock as EHBlock);

                        Segment     filterKey   = FindFilterBlock(method.EHClauses, nextBlockIndex);
                        FilterBlock filterBlock = filterBlocks[filterKey] as FilterBlock;
                        (thisBlock as UserFilteredBlock).Filter = filterBlock;
                    }       break;
                    }
                    FindNextBlockStart(method.EHClauses, out nextBlockType, ref nextBlockStart, ref nextBlockEnd, out nextCatchBlockType, out nextBlockIndex);
                }
                lastBlock = thisBlock;

                Instruction i = method[iNum];
                switch (i.Code)
                {
                case InstructionCode.NEG:
                case InstructionCode.NOT:
                {
                    head = tail = new UnaryOp(UnaryOpFromCode(i.Code));
                    /*!*/ head.setParent(currentBlock);
                } break;

                case InstructionCode.ADD:
                case InstructionCode.AND:
                case InstructionCode.CEQ:
                case InstructionCode.CGT:
                case InstructionCode.CLT:
                case InstructionCode.DIV:
                case InstructionCode.MUL:
                case InstructionCode.OR:
                case InstructionCode.REM:
                case InstructionCode.SHL:
                case InstructionCode.SHR:
                case InstructionCode.SUB:
                case InstructionCode.XOR:
                {
                    head = tail = new BinaryOp(BinaryOpFromCode(i.Code), i.OverflowFlag, i.UnsignedFlag);
                    /*!*/ head.setParent(currentBlock);
                } break;

                case InstructionCode.LDC:
                    head = tail = new LoadConst(i.Param);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDARG:
                    head = tail = new LoadVar(args[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDLOC:
                    head = tail = new LoadVar(locals[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDARGA:
                    head = tail = new LoadVarAddr(args[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDLOCA:
                    head = tail = new LoadVarAddr(locals[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDIND:
                    head = tail = new LoadIndirect(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDFLD:
                {
                    FieldInfo field = i.Param as FieldInfo;
                    if (field.IsStatic)
                    {
                        head = new RemoveStackTop();
                        /*!*/ head.setParent(currentBlock);
                        //remove the object instance when accessing the static field with LDFLD
                        tail = new LoadField(field);
                        /*!*/ tail.setParent(currentBlock);
                        head.Next = tail;
                    }
                    else
                    {
                        head = tail = new LoadField(field);
                        /*!*/ head.setParent(currentBlock);
                    }
                }       break;

                case InstructionCode.LDFLDA:
                {
                    FieldInfo field = i.Param as FieldInfo;
                    if (field.IsStatic)
                    {
                        head = new RemoveStackTop();
                        /*!*/ head.setParent(currentBlock);
                        tail = new LoadFieldAddr(field);
                        /*!*/ tail.setParent(currentBlock);
                        head.Next = tail;
                    }
                    else
                    {
                        head = tail = new LoadFieldAddr(field);
                        /*!*/ head.setParent(currentBlock);
                    }
                }       break;

                case InstructionCode.LDSFLD:
                    head = tail = new LoadField(i.Param as FieldInfo);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDSFLDA:
                    head = tail = new LoadFieldAddr(i.Param as FieldInfo);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDELEM:
                    head = tail = new LoadElement(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDELEMA:
                    head = tail = new LoadElementAddr(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDOBJ:
                    head = tail = new LoadIndirect(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.SIZEOF:
                    head = tail = new LoadSizeOfValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDLEN:
                    head = tail = new LoadLength();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDTOKEN:
                    if (i.Param is Type)
                    {
                        head = tail = new LoadConst((i.Param as Type).TypeHandle);
                    }
                    else if (i.Param is MethodBase)
                    {
                        head = tail = new LoadConst((i.Param as MethodBase).MethodHandle);
                    }
                    else if (i.Param is FieldInfo)
                    {
                        head = tail = new LoadConst((i.Param as FieldInfo).FieldHandle);
                    }
                    else
                    {
                        throw new ConvertionException();
                    }
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDNULL:
                    head = tail = new LoadConst(null);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDSTR:
                    head = tail = new LoadConst(i.Param);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STARG:
                    head = tail = new StoreVar(args[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STLOC:
                    head = tail = new StoreVar(locals[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STIND:
                    head = tail = new StoreIndirect(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STFLD:
                {
                    FieldInfo field = i.Param as FieldInfo;
                    if (field.IsStatic)
                    {
                        head = new StoreField(field);
                        /*!*/ head.setParent(currentBlock);
                        tail = new RemoveStackTop();
                        /*!*/ tail.setParent(currentBlock);
                        head.Next = tail;
                    }
                    else
                    {
                        head = tail = new StoreField(i.Param as FieldInfo);
                        /*!*/ head.setParent(currentBlock);
                    }
                }       break;

                case InstructionCode.STSFLD:
                    head = tail = new StoreField(i.Param as FieldInfo);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STELEM:
                    head = tail = new StoreElement(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STOBJ:
                    head = tail = new StoreIndirect(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CPOBJ:
                    head = new LoadIndirect(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    tail = new StoreIndirect(i.Param as Type);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.DUP:
                    head = tail = new DuplicateStackTop();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CALL:
                    head = tail = new CallMethod(i.Param as MethodBase, false, i.HasTail);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CALLVIRT:
                    MethodInfo callee = i.Param as MethodInfo;
                    head = tail = new CallMethod(callee, callee.IsVirtual, i.HasTail);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.NEWOBJ:
                { ConstructorInfo ctor = i.Param as ConstructorInfo;
                  if (Verifier.IsDelegate(ctor.DeclaringType))
                  {
                      if (Verifier.IsInstanceDispatch(method, iNum))
                      {
                          heads[iNum - 1] = tails[iNum - 1] = null;
                          head            = tail = new CreateDelegate(ctor, method[iNum - 1].Param as MethodInfo, false);
                      }
                      else if (Verifier.IsVirtualDispatch(method, iNum))
                      {
                          heads[iNum - 2] = tails[iNum - 2] = null;
                          heads[iNum - 1] = tails[iNum - 1] = null;
                          head            = tail = new CreateDelegate(ctor, method[iNum - 1].Param as MethodInfo, true);
                      }
                  }
                  else
                  {
                      head = tail = new NewObject(ctor);
                  }
                  /*!*/ head.setParent(currentBlock); }       break;

                case InstructionCode.NEWARR:
                    head = tail = new NewArray(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.INITOBJ:
                    head = tail = new InitValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.ISINST:
                    head = tail = new CastClass(i.Param as Type, false);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CASTCLASS:
                    head = tail = new CastClass(i.Param as Type, true);
                    /*!*/ head.setParent(currentBlock);
                    break;


                case InstructionCode.BOX:
                    head = tail = new BoxValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.UNBOX:
                    head = tail = new UnboxValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CONV:
                    head = tail = new ConvertValue(i.TypeBySuffixOrParam(), i.OverflowFlag, i.UnsignedFlag);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.POP:
                    head = tail = new RemoveStackTop();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.BEQ:
                    head = new BinaryOp(BinaryOp.ArithOp.CEQ, false, false);
                    /*!*/ head.setParent(currentBlock);
                    tail = new Branch();
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BNE:
                    head = new BinaryOp(BinaryOp.ArithOp.CEQ, false, false);
                    /*!*/ head.setParent(currentBlock);
                    tail = new Branch();
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BGE:
                    if (TypeFixer.IsFloatOrCompatible(i.Stack.Top()))
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CLT, false, !i.UnsignedFlag);
                    }
                    else
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CLT, false, i.UnsignedFlag);
                    }
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BGT:
                    head = new BinaryOp(BinaryOp.ArithOp.CGT, false, i.UnsignedFlag);
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BLE:
                    if (TypeFixer.IsFloatOrCompatible(i.Stack.Top()))
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CGT, false, !i.UnsignedFlag);
                    }
                    else
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CGT, false, i.UnsignedFlag);
                    }
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BLT:
                    head = new BinaryOp(BinaryOp.ArithOp.CLT, false, i.UnsignedFlag);
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BRTRUE:
                    head = tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.BRFALSE:
                    head = tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.SWITCH:
                    head = tail = new Switch((i.Param as int[]).Length);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.BR:
                case InstructionCode.NOP:
                case InstructionCode.BREAK:
                case InstructionCode.LDFTN:                             // Expecting further delegate construction...
                case InstructionCode.LDVIRTFTN:                         //
                    head = tail = new DummyNode();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.THROW:
                    head = tail = new ThrowException();
                    /*!*/ head.setParent(currentBlock);
                    break;


                case InstructionCode.RET:
                case InstructionCode.ENDFINALLY:
                case InstructionCode.ENDFILTER:
                case InstructionCode.LEAVE:
                    head = tail = new Leave();
                    /*!*/ head.setParent(currentBlock);
                    break;

                default:
                    throw new ConvertionException();
                }
                if (head != null)
                {
                    head.Options["StackTypes"] = i.Stack.Clone() as StackTypes;
                }
                if (head != tail)                //=>   head :: BinaryOp, tail :: Branch
                //||   head :: LoadIndirect, tail :: StoreIndirect
                {
                    if (head is BinaryOp && tail is Branch)
                    {
                        StackTypes stack = i.Stack.Clone() as StackTypes;
                        stack.Pop();
                        stack.Pop();
                        stack.Push(typeof(int));
                        tail.Options["StackTypes"] = stack;
                    }
                    else if (head is LoadIndirect && tail is StoreIndirect)
                    {
                        StackTypes stack = i.Stack.Clone() as StackTypes;
                        TypeEx     type  = stack.Pop();                    //type == S&
                        stack.Push(type.type.GetElementType());
                        tail.Options["StackTypes"] = stack;
                    }
                }
                if (firstBlock != null)
                {
                    lastBlock.Next = head;
                    for (Node n = firstBlock; n != head; n = n.Next)
                    {
                        n.Options["StackTypes"] = i.Stack.Clone() as StackTypes;
                    }
                    head = firstBlock;
                    if (tail == null)
                    {
                        tail = lastBlock;                         //This may occure what the NOP instruction starts some block
                    }
                }
                heads[iNum] = head;
                tails[iNum] = tail;
            }            //for
            mainBlock.Next = heads[0];
            //Control flow linkage
            for (iNum = 0; iNum < method.Count; iNum++)
            {
                if (heads[iNum] == null)
                {
                    throw new ConvertionException();                     //impossible :)
                }
                Instruction i = method[iNum];

                switch (i.Code)
                {
                case InstructionCode.BR:
                case InstructionCode.LEAVE:
                    tails[iNum].Next = heads[(int)i.Param];
                    break;

                case InstructionCode.RET:
                case InstructionCode.ENDFINALLY:
                case InstructionCode.ENDFILTER:
                case InstructionCode.THROW:
                case InstructionCode.RETHROW:
                    break;

                case InstructionCode.BRFALSE:                     //false
                case InstructionCode.BGE:                         //false
                case InstructionCode.BLE:                         //false
                case InstructionCode.BNE:                         //false
                    tails[iNum].Next            = heads[(int)i.Param];
                    (tails[iNum] as Branch).Alt = heads[iNum + 1];
                    break;

                case InstructionCode.BRTRUE:                      //true
                case InstructionCode.BEQ:                         //true
                case InstructionCode.BGT:                         //true
                case InstructionCode.BLT:                         //true
                    tails[iNum].Next            = heads[iNum + 1];
                    (tails[iNum] as Branch).Alt = heads[(int)i.Param];
                    break;

                case InstructionCode.SWITCH:
                    tails[iNum].Next = heads[iNum + 1];
                    Switch node = tails[iNum] as Switch;
                    int[]  alt  = i.Param as int[];
                    for (int j = 0; j < node.Count; j++)
                    {
                        node[j] = heads[alt[j]];
                    }
                    break;

                default:
                    tails[iNum].Next = heads[iNum + 1];
                    break;
                }
            }

            //Removing DummyNodes
            for (iNum = 0; iNum < method.Count; iNum++)
            {
                if (heads[iNum] is DummyNode)
                {
                    Node   dummy = heads[iNum];
                    Node[] prev  = new Node[dummy.PrevArray.Count];
                    for (int j = 0; j < prev.Length; j++)
                    {
                        prev[j] = dummy.PrevArray[j];
                    }
                    for (int j = 0; j < prev.Length; j++)
                    {
                        prev[j].NextArray[prev[j].NextArray.IndexOf(dummy)] = dummy.Next;
                    }
                    dummy.RemoveFromGraph();
                }
            }


            return(mainBlock);
        }
Ejemplo n.º 17
0
 protected override void VisitFinallyBlock(FinallyBlock node, object data)
 {
     result = false;
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Begins a finally block on the given exception block.
 ///
 /// Only one finally block can be defined per exception block, and the block cannot appear within a catch block.
 ///
 /// The given exception block must still be open.
 /// </summary>
 public Emit BeginFinallyBlock(ExceptionBlock forTry, out FinallyBlock forFinally)
 {
     InnerEmit.BeginFinallyBlock(forTry, out forFinally);
     return(this);
 }
Ejemplo n.º 19
0
        /// <summary cref="M:Sigil.Emit.NonGeneric.Emit`1.BeginFinallyBlock(Sigil.ExceptionBlock)" />
        public EmitShorthand BeginFinallyBlock(ExceptionBlock forTry, out FinallyBlock forFinally)
        {
            forFinally = BeginFinallyBlock(forTry);

            return(this);
        }
Ejemplo n.º 20
0
 /// <summary cref="M:Sigil.Emit.NonGeneric.Emit`1.EndFinallyBlock(Sigil.FinallyBlock)" />
 public EmitShorthand EndFinallyBlock(FinallyBlock forFinally)
 {
     InnerEmit.EndFinallyBlock(forFinally);
     return(this);
 }
Ejemplo n.º 21
0
        public override string ToCode(ToCodeFormat format)
        {
            StringBuilder sb = new StringBuilder();

            // passing a "T" format means nested try's don't actually nest -- they
            // just add the catch clauses to the end
            if (format != ToCodeFormat.NestedTry)
            {
                sb.Append("try");
                if (TryBlock == null)
                {
                    // empty body
                    sb.Append("{}");
                }
                else
                {
                    sb.Append(TryBlock.ToCode(ToCodeFormat.NestedTry));
                }
            }
            else
            {
                sb.Append(TryBlock.ToCode(ToCodeFormat.NestedTry));
            }

            // handle the catch clause (if any)
            // catch should always have braces around it
            string catchString = (
                CatchBlock == null
                ? string.Empty
                : CatchBlock.Count == 0
                    ? "{}"
                    : CatchBlock.ToCode(ToCodeFormat.AlwaysBraces)
                );

            if (catchString.Length > 0)
            {
                Parser.Settings.NewLine(sb);
                sb.Append("catch(");
                if (m_catchVariable != null)
                {
                    sb.Append(m_catchVariable.ToString());
                }
                else if (m_catchVarName != null)
                {
                    sb.Append(m_catchVarName);
                }
                sb.Append(')');
                sb.Append(catchString);
            }

            // handle the finally, if any
            // finally should always have braces around it
            string finallyString = (
                FinallyBlock == null
              ? string.Empty
              : FinallyBlock.ToCode(ToCodeFormat.AlwaysBraces)
                );

            if (finallyString.Length > 0)
            {
                Parser.Settings.NewLine(sb);
                sb.Append("finally");
                sb.Append(finallyString);
            }
            return(sb.ToString());
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Process an unplugged method.
        /// </summary>
        /// <param name="aMethod">The method to process.</param>
        /// <param name="staticConstructorDependencyRoot">Null if method scanning is not a static constructor. Otherwise, the root node that represents the static constructor being scanned.</param>
        /// <returns>A new ILChunk with ILOpInfos and common attribites loaded. Null if any errors occur.</returns>
        /// <exception cref="System.Exception">
        /// Thrown when an unrecognised operand type is read. Can occur if MSBuild has been 
        /// updated/extended from when the kernel compiler was last updated.
        /// </exception>
        public ILChunk ProcessUnpluggedMethod(MethodBase aMethod, StaticConstructorDependency staticConstructorDependencyRoot = null)
        {
            ILChunk result = new ILChunk()
            {
                Plugged = false,
                Method = aMethod
            };

            //Pre-process common method attributes so we get information such as
            //whether to apply GC or not etc.
            ProcessCommonMethodAttributes(aMethod, result);

            //Get the method body which can then be used to get locals info and
            //IL bytes that are the IL code.
            MethodBody theMethodBody = aMethod.GetMethodBody();

            //Method body for something like [DelegateType].Invoke()
            //  is null
            if (theMethodBody == null)
            {
                //Just return empty method
                return result;
            }

            //For each local variable in this method
            foreach (LocalVariableInfo aLocal in theMethodBody.LocalVariables)
            {
                //Add it to our list of locals with some common information pre-worked out
                LocalVariable localItem = new LocalVariable()
                {
                    sizeOnStackInBytes = Utils.GetNumBytesForType(aLocal.LocalType),
                    isFloat = Utils.IsFloat(aLocal.LocalType),
                    TheType = aLocal.LocalType,
                    isGCManaged = Utils.IsGCManaged(aLocal.LocalType)
                };
                result.LocalVariables.Add(localItem);
            }


            //Used later to store location and length of the cleanup try-finally block
            int CleanUpBlock_TryOffset = 0;
            int CleanUpBlock_TryLength = 0;
            int CleanUpBlock_FinallyOffset = 0;
            int CleanUpBlock_FinallyLength = 0;
            //The "cleanup" block is the finally handler created by the IL reader that
            //calls GC.DecrementRefCount of locals and arguments as-required so that 
            //memory managed by the GC through objects gets freed correctly.
            //The try-section of the cleanup block surrounds all of the main code of the method
            //excluding the final "ret" instruction. In this way, even if an exception occurs, 
            //locals and args still get "cleaned up".
            
            //The IL bytes are the IL code.
            byte[] ILBytes = theMethodBody.GetILAsByteArray();
            //Note: IL offsets are usually calculated as the number of bytes offset from the
            //      start of the method.
            //Note: IL line numbers are IL offsets.

            //The current position in the IL bytes. 
            //This will change throughout the loop below so it always points past
            //all the bytes processed so far.
            int ILBytesPos = 0;
            //The previous position in the IL bytes.
            //This will only change in the loop below after a new IL op is created. In this way,
            //it actually points to the IL bytes position just before the new op is created.
            //That is to say, it points to the IL bytes pos of the start of the new op.
            int PrevILBytesPos = 0;

            //The previous IL op info that was created.
            //This is the latest one that was created as opposed the the one before that.
            //I.e. this is the last ILOpInfo added to the final list of IL op infos.
            ILOpInfo prevInfo = null;

            //Loop through all the IL bytes for this method...
            while (ILBytesPos < ILBytes.Length)
            {
                //The current System.Reflection.Emit.OpCode being processed
                OpCode currOpCode;
                //The unique number that identifies the op code. 
                //This number is also deliberately equivalent to Kernel.Compiler.ILOps.IlOp.OpCodes!
                ushort currOpCodeID = 0;
                //MSIL is saved such that OpIds that only require 1 byte, only use 1 byte!
                //ILBytes encoded as big-endian(?) so high bytes of the op code value (ID) come first
                //So if high byte is set to 0xFE then we need to load the next byte as low byte
                if (ILBytes[ILBytesPos] == 0xFE)
                {
                    currOpCodeID = (ushort)(0xFE00 + (short)ILBytes[ILBytesPos + 1]);
                    ILBytesPos += 2;
                }
                else
                {
                    currOpCodeID = (ushort)ILBytes[ILBytesPos];
                    ILBytesPos++;
                }
                //Load the op code from our pre-constructed list of all op codes
                currOpCode = AllOpCodes[currOpCodeID];

                int operandSize = 0;
                //Operand type tells us the operand size
                //We must:
                // a) Skip over the operand bytes so that we read the next IL op correctly
                // b) Store the operand bytes in the ILOpInfo for later use
                switch(currOpCode.OperandType)
                {
                    case OperandType.InlineBrTarget:
                        operandSize = 4;
                        break;
                    case OperandType.InlineField:
                        operandSize = 4;
                        break;
                    case OperandType.InlineI:
                        operandSize = 4;
                        break;
                    case OperandType.InlineI8:
                        operandSize = 8;
                        break;
                    case OperandType.InlineMethod:
                        operandSize = 4;
                        break;
                    case OperandType.InlineNone:
                        //No operands = no op size
                        break;
                    case OperandType.InlineR:
                        operandSize = 8;
                        break;
                    case OperandType.InlineSig:
                        operandSize = 4;
                        break;
                    case OperandType.InlineString:
                        operandSize = 4;
                        break;
                    case OperandType.InlineSwitch:
                        {
                            int count = Utils.ReadInt32(ILBytes, ILBytesPos);
                            ILBytesPos += 4;
                            operandSize = count * 4;
                        }
                        break;
                    case OperandType.InlineTok:
                        operandSize = 4;
                        break;
                    case OperandType.InlineType:
                        operandSize = 4;
                        break;
                    case OperandType.InlineVar:
                        operandSize = 2;
                        break;
                    case OperandType.ShortInlineBrTarget:
                        operandSize = 1;
                        break;
                    case OperandType.ShortInlineI:
                        operandSize = 1;
                        break;
                    case OperandType.ShortInlineR:
                        operandSize = 4;
                        break;
                    case OperandType.ShortInlineVar:
                        operandSize = 1;
                        break;
                    default:
                        throw new Exception("Unrecognised operand type!");
                }
                
                //Update the previous op with next position now that we
                //  know what that is...
                if (prevInfo != null)
                {
                    prevInfo.NextPosition = PrevILBytesPos;
                }

                //The IL reader pre-loads any methods that should be called by, for example, a call op
                //This was added so that the MethodToCall could be set by the IL reader to inject call ops
                //    - It was going to be a lot harder to try and get the "metadata token bytes" for the 
                //      method to call than to simply "pre-load" the method to call.
                MethodBase methodToCall = null;
                //Value bytes generally contain a constant value to be loaded or the bytes of a metadata token.
                //Metadata tokens can be used to retrieve information such as string literals or method infos
                //from the calling assembly.
                byte[] valueBytes = new byte[operandSize];
                //Don't bother copying 0 bytes...
                if (operandSize > 0)
                {
                    //Copy the bytes...
                    Array.Copy(ILBytes, ILBytesPos, valueBytes, 0, operandSize);

                    //If the op is one where the valueBytes are a metadata token pointing to a method:
                    if ((ILOps.ILOp.OpCodes)currOpCode.Value == ILOps.ILOp.OpCodes.Call ||
                        (ILOps.ILOp.OpCodes)currOpCode.Value == ILOps.ILOp.OpCodes.Calli ||
                        (ILOps.ILOp.OpCodes)currOpCode.Value == ILOps.ILOp.OpCodes.Callvirt ||
                        (ILOps.ILOp.OpCodes)currOpCode.Value == ILOps.ILOp.OpCodes.Ldftn ||
                        (ILOps.ILOp.OpCodes)currOpCode.Value == ILOps.ILOp.OpCodes.Newobj)
                    {
                        //Pre-load the method for reasons described above. 

                        //The metadata token that identifies the method to call in the DLL
                        //It is used to retrieve more information about the method from the DLL
                        int MethodMetadataToken = Utils.ReadInt32(valueBytes, 0);
                        //The method to call retrieved using the metasdata token
                        methodToCall = aMethod.Module.ResolveMethod(MethodMetadataToken);
                    }
                }

                //If the op being processed is a Return op and this method has GC applied:
                if ((ILOps.ILOp.OpCodes)currOpCode.Value == ILOps.ILOp.OpCodes.Ret &&
                    result.ApplyGC)
                {       
                    //We must insert the cleanup block code.

                    //Insert try-finally block around the entire method but just before Ret
                    //The finally block can then do clean-up of local variables and args
                    //1. Insert IL ops for doing locals / args cleanup
                    //2. Add the try/finally block (or just finally block if try block already exists)

                    //We must also consider the fact that just before a "ret" op, the return value is loaded.
                    //Since this cleanup block will wrap that load op, we must add code to store the return value 
                    //at the end of the try block and then re-load the return value after the finally block (but
                    //before the ret op.)

                    //Get a list of all the params to the current method
                    List<Type> allParams = result.Method.GetParameters()
                        .Select(x => x.ParameterType)
                        .ToList();
                    //If it isn't a static method:
                    if (!result.Method.IsStatic)
                    {
                        //The first param is the current instance reference.
                        allParams.Insert(0, result.Method.DeclaringType);
                    }
                    //Only insert the cleanup block if there are some params or locals to clean up.
                    //This is the first of two checks of this condition.
                    if (result.LocalVariables.Count > 0 ||
                        allParams.Count > 0)
                    {
                        //As per above we need to check for return value
                        LocalVariable returnValVariable = null;
                        //Return type of constructor is void, so only check proper methods
                        if(result.Method is MethodInfo)
                        {
                            Type returnType = ((MethodInfo)result.Method).ReturnType;
                            //Void return type = no return value
                            if(returnType != typeof(void))
                            {
                                //Add a new local variable for storing the return value
                                returnValVariable = new LocalVariable()
                                {
                                    isFloat = Utils.IsFloat(returnType),
                                    sizeOnStackInBytes = Utils.GetNumBytesForType(returnType),
                                    TheType = returnType,
                                    isGCManaged = Utils.IsGCManaged(returnType)
                                };
                                result.LocalVariables.Add(returnValVariable);
                                //This will become the penultimate IL op of the try-block
                                //It will immediately follow the op just before ret which 
                                //  will have loaded the return value or, at the very least,
                                //  the top-most item on the stack is the return value
                                //This op stores that return value in our new local variable
                                //  for reload after the finally block has completed.
                                result.ILOpInfos.Add(prevInfo = new ILOpInfo()
                                {
                                    opCode = OpCodes.Stloc,
                                    Position = PrevILBytesPos++,
                                    NextPosition = PrevILBytesPos,
                                    ValueBytes = BitConverter.GetBytes(result.LocalVariables.IndexOf(returnValVariable))
                                });
                            }
                        }
                        //This becomes the last op of the try-block (and is required to be
                        //  the last op of a try block)
                        result.ILOpInfos.Add(prevInfo = new ILOpInfo()
                        {
                            opCode = OpCodes.Leave_S,
                            Position = PrevILBytesPos++,
                            NextPosition = PrevILBytesPos,
                            ValueBytes = new byte[4]
                        });

                        //Try block length is now the length in IL bytes from start
                        //  (i.e. offset) to start of the current IL op. See above for
                        //  why we use PrevIlBytesPos.
                        CleanUpBlock_TryLength = PrevILBytesPos - CleanUpBlock_TryOffset;
                        //Finally offset is offset to first op of finally block i.e. 
                        //  current IL op position.
                        CleanUpBlock_FinallyOffset = PrevILBytesPos;
                        //Finally length is currently 0 - gets increased later.
                        CleanUpBlock_FinallyLength = 0;

                        //Add cleanup code for each local
                        for (int i = 0; i < result.LocalVariables.Count; i++)
                        {
                            //Clean-up local variables
                            //If the local variable is GC handled:
                            //1. Load the the local
                            //2. Call GC Dec Ref count

                            LocalVariable aVar = result.LocalVariables[i];
                            //Only add cleanup code if the local is actually GC managed.
                            if (Utils.IsGCManaged(aVar.TheType))
                            {
                                if (prevInfo != null)
                                {
                                    prevInfo.NextPosition = PrevILBytesPos;
                                }
                                //Load the local
                                result.ILOpInfos.Add(prevInfo = new ILOpInfo()
                                {
                                    opCode = OpCodes.Ldloc,
                                    Position = PrevILBytesPos++,
                                    NextPosition = -1,
                                    ValueBytes = BitConverter.GetBytes(i)
                                });
                                prevInfo.NextPosition = PrevILBytesPos;
                                //Decrement the ref count of the local
                                result.ILOpInfos.Add(prevInfo = new ILOpInfo()
                                {
                                    opCode = OpCodes.Call,
                                    Position = PrevILBytesPos++,
                                    NextPosition = -1,
                                    SetToGCDecRefCountMethod = true
                                });

                                CleanUpBlock_FinallyLength += 2;
                            }
                        }
                        //Add cleanup code for each arg
                        //Dec ref count of all args passed to the method 
                        for (int i = 0; i < allParams.Count; i++)
                        {
                            Type aVarType = allParams[i];
                            //Only add cleanup code if the arg is actually GC managed.
                            if (Utils.IsGCManaged(aVarType))
                            {
                                if (prevInfo != null)
                                {
                                    prevInfo.NextPosition = PrevILBytesPos;
                                }
                                result.ILOpInfos.Add(prevInfo = new ILOpInfo()
                                {
                                    opCode = OpCodes.Ldarg,
                                    Position = PrevILBytesPos++,
                                    NextPosition = -1,
                                    ValueBytes = BitConverter.GetBytes(i)
                                });
                                prevInfo.NextPosition = PrevILBytesPos;
                                result.ILOpInfos.Add(prevInfo = new ILOpInfo()
                                {
                                    opCode = OpCodes.Call,
                                    Position = PrevILBytesPos++,
                                    NextPosition = -1,
                                    SetToGCDecRefCountMethod = true
                                });

                                CleanUpBlock_FinallyLength += 2;
                            }
                        }

                        //Locals and args not necessarily of GC managed type
                        //  so we could potentially have cleaned up nothing
                        //This is the second of the two checks to make sure we 
                        //  only add cleanup code if there is something to cleanup
                        if (CleanUpBlock_FinallyLength > 0)
                        {
                            //If there is cleanup code, add the end of the finally block and
                            // reload the return value if necessary.

                            prevInfo.NextPosition = PrevILBytesPos;
                            result.ILOpInfos.Add(prevInfo = new ILOpInfo()
                            {
                                opCode = OpCodes.Endfinally,
                                Position = PrevILBytesPos++,
                                NextPosition = -1
                            });
                            CleanUpBlock_FinallyLength += 1;

                            if (returnValVariable != null)
                            {
                                result.ILOpInfos.Add(prevInfo = new ILOpInfo()
                                {
                                    opCode = OpCodes.Ldloc,
                                    Position = PrevILBytesPos++,
                                    NextPosition = PrevILBytesPos,
                                    ValueBytes = BitConverter.GetBytes(result.LocalVariables.IndexOf(returnValVariable))
                                });
                            }
                        }
                        else
                        {
                            //If there was nothing to cleanup, we need to remove 
                            //  the ops and locals etc. that got added earlier.
                            result.ILOpInfos.RemoveAt(result.ILOpInfos.Count - 1);
                            PrevILBytesPos--;

                            if(returnValVariable != null)
                            {
                                result.LocalVariables.Remove(returnValVariable);
                                result.ILOpInfos.RemoveAt(result.ILOpInfos.Count - 1);
                                PrevILBytesPos--;
                            }
                        }
                    }
                }

                if (staticConstructorDependencyRoot != null)
                {
                    //Create our static constructor dependency tree
                    
                    //Each of these ops could try to access a static method or field
                    switch((ILOps.ILOp.OpCodes)currOpCode.Value)
                    {
                        case ILOps.ILOp.OpCodes.Call:
                            //Check if the method to call is static and not a constructor itself
                            //If so, we must add the declaring type's static constructors to the tree
                            {
                                int metadataToken = Utils.ReadInt32(valueBytes, 0);
                                MethodBase methodBaseInf = aMethod.Module.ResolveMethod(metadataToken);
                                if(!(methodBaseInf.IsConstructor || methodBaseInf is ConstructorInfo))
                                {
                                    MethodInfo methodInf = (MethodInfo)methodBaseInf;
                                    ConstructorInfo[] staticConstructors = methodInf.DeclaringType.GetConstructors(BindingFlags.Static | BindingFlags.Public)
                                                               .Concat(methodInf.DeclaringType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic))
                                                               .ToArray();
                                    if (staticConstructors.Length > 0)
                                    {
                                        ConstructorInfo TheConstructor = staticConstructors[0];
                                        if (staticConstructorDependencyRoot[TheConstructor] == null)
                                        {
                                            staticConstructorDependencyRoot.Children.Add(new StaticConstructorDependency()
                                            {
                                                TheConstructor = TheConstructor
                                            });
                                        }
                                    }
                                }
                            }
                            break;
                        case ILOps.ILOp.OpCodes.Ldsfld:
                        case ILOps.ILOp.OpCodes.Ldsflda:
                        case ILOps.ILOp.OpCodes.Stsfld:
                            {
                                int metadataToken = Utils.ReadInt32(valueBytes, 0);
                                FieldInfo fieldInf = aMethod.Module.ResolveField(metadataToken);
                                ConstructorInfo[] staticConstructors = fieldInf.DeclaringType.GetConstructors(BindingFlags.Static | BindingFlags.Public)
                                                               .Concat(fieldInf.DeclaringType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic))
                                                               .ToArray();
                                if(staticConstructors.Length > 0)
                                {
                                    ConstructorInfo TheConstructor = staticConstructors[0];
                                    if (staticConstructorDependencyRoot[TheConstructor] == null)
                                    {
                                        staticConstructorDependencyRoot.Children.Add(new StaticConstructorDependency()
                                        {
                                            TheConstructor = TheConstructor
                                        });
                                    }
                                }
                            }
                            break;
                    }
                }

                //Add the IL op
                result.ILOpInfos.Add(prevInfo = new ILOpInfo()
                {
                    opCode = currOpCode,
                    Position = PrevILBytesPos,
                    // Next position set to -1 indicates no next op
                    NextPosition = -1,
                    ValueBytes = valueBytes,
                    MethodToCall = methodToCall
                });

                ILBytesPos += operandSize;
                PrevILBytesPos = ILBytesPos;
            }
            prevInfo.NextPosition = PrevILBytesPos;
            
            //Add the exception handlers (excluding Cleanup try-finally block - see below)
            foreach (ExceptionHandlingClause aClause in theMethodBody.ExceptionHandlingClauses)
            {
                ExceptionHandledBlock exBlock = result.GetExactExceptionHandledBlock(aClause.TryOffset);
                if (exBlock == null)
                {
                    exBlock = new ExceptionHandledBlock();
                    exBlock.Offset = aClause.TryOffset;
                    exBlock.Length = aClause.TryLength;
                    result.ExceptionHandledBlocks.Add(exBlock);
                }

                switch (aClause.Flags)
                {
                    case ExceptionHandlingClauseOptions.Fault:
                    case ExceptionHandlingClauseOptions.Clause:
                        {
                            CatchBlock catchBlock = new CatchBlock()
                            {
                                Offset = aClause.HandlerOffset,
                                Length = aClause.HandlerLength,
                                //Though not used, we may as well set it anyway
                                FilterType = aClause.CatchType
                            };
                            exBlock.CatchBlocks.Add(catchBlock);
                        }
                        break;
                    case ExceptionHandlingClauseOptions.Finally:
                        {
                            FinallyBlock finallyBlock = new FinallyBlock()
                            {
                                Offset = aClause.HandlerOffset,
                                Length = aClause.HandlerLength
                            };
                            exBlock.FinallyBlocks.Add(finallyBlock);
                        }
                        break;
                    default:
                        OutputError(new NotSupportedException("Exception handling clause not supported! Type: " + aClause.Flags.ToString()));
                        break;
                }
            }

            //Add the cleanup try-finally block
            //Only add the block if try-section has non-zero length and
            //  if the finally block has more than just the endfinally op
            if (CleanUpBlock_TryLength != 0 &&
                CleanUpBlock_FinallyLength > 1)
            {
                ExceptionHandledBlock cleanUpTryBlock = new ExceptionHandledBlock()
                {
                    Offset = CleanUpBlock_TryOffset,
                    Length = CleanUpBlock_TryLength
                };
                FinallyBlock cleanupFinallyBlock = new FinallyBlock()
                {
                    Offset = CleanUpBlock_FinallyOffset,
                    Length = CleanUpBlock_FinallyLength,
                };
                cleanUpTryBlock.FinallyBlocks.Add(cleanupFinallyBlock);
                result.ExceptionHandledBlocks.Add(cleanUpTryBlock);
            }
                            
            return result;
        }