public void SimpleTryBlockWithinOneMethodWithTwoCatchHandlers()
        {
            //Arrange
            ITest test = new CorrectOrderCheck();

            MethodDesc mainMethod = new MethodDesc("Main", 3)
                                    .EntryPoint()
                                    .AddInheritanceAttributeFlag(MethodInheritanceAttributes.Global)
                                    .AddInstructions(new ILInstruction[]
            {
                new ILInstruction(ByteCode.Nop, "1. Just before try start").Data(1),
                //----------try begin-------------
                new ILInstruction(ByteCode.Nop, "2. At the try first instruction start").AddLabel("TryBeg").Data(2),
                new ILInstruction(ByteCode.Nop, "3. Just before throw").Data(3),
                new ILInstruction(ByteCode.Newobj, TempTypeLocator.InvalidOperationExceptionDesc.Methods[0].Metadata /*ctor*/),
                new ILInstruction(ByteCode.Throw),
                new ILInstruction(ByteCode.Nop, "Just after throw"),
                new ILInstruction(ByteCode.Nop, "Just before try leave instruction"),
                new ILInstruction(ByteCode.Leave, new Label("TryLeaveDest")).AddLabel("TryEnd"),
                //----------try end-------------
                new ILInstruction(ByteCode.Nop, "Between try and catch"),
                //----------catch1 begin-------------
                new ILInstruction(ByteCode.Nop, "4. At the catch1 start").AddLabel("Catch1Beg").Data(4),
                new ILInstruction(ByteCode.Pop),
                new ILInstruction(ByteCode.Nop, "5. Just before catch1 leave instruction").Data(5),
                new ILInstruction(ByteCode.Leave, new Label("CatchLeaveDest")).AddLabel("Catch1End"),
                //----------catch1 end-------------

                //----------catch2 begin-------------
                new ILInstruction(ByteCode.Pop).AddLabel("Catch2Beg"),
                new ILInstruction(ByteCode.Nop, "At the catch2 start"),
                new ILInstruction(ByteCode.Nop, "Just before catch2 leave instruction"),
                new ILInstruction(ByteCode.Leave, new Label("CatchLeaveDest")).AddLabel("Catch2End"),
                //----------catch2 end-------------
                new ILInstruction(ByteCode.Nop, "Instruction where try leave points").AddLabel("TryLeaveDest"),
                new ILInstruction(ByteCode.Nop, "6(end). Instruction where catch leave points").AddLabel("CatchLeaveDest").Data(6),
                new ILInstruction(ByteCode.Ret)
            });

            mainMethod.EHTable.AddCatchHandler("TryBeg", "TryEnd", new ClassToken("System.InvalidOperationException", false), "Catch1Beg", "Catch1End");
            mainMethod.EHTable.AddCatchHandler("TryBeg", "TryEnd", new ClassToken("System.Exception", false), "Catch2Beg", "Catch2End");


            CompiledModel compiledModel = new CompiledModel()
                                          .AddMethod(mainMethod);

            DomainModel domainModel = new DomainModel(new GCHeap.Factory(), new TypesHeap.Factory());

            domainModel.LoadType(TempTypeLocator.ObjectDesc);
            domainModel.LoadType(TempTypeLocator.ExceptionDesc);
            domainModel.LoadType(TempTypeLocator.InvalidOperationExceptionDesc);

            var executor = domainModel.GetExecutor(compiledModel, new ILOperationSet());

            //Act
            executor.Start();

            //Assert
            Assert.IsTrue(test.Success());
        }
        public void ThreeMethodsWithExThrowingAndFinalliesAndCatches()
        {
            //Arrange
            ITest test = new CorrectOrderCheck();

            MethodDesc thirdMethod = new MethodDesc("ThirdMethod", 3)
                                     .AddCallback(test)
                                     .AddInheritanceAttributeFlag(MethodInheritanceAttributes.Global)
                                     .AddInstructions(new ILInstruction[]
            {
                new ILInstruction(ByteCode.Nop, "1. Just before outer tryfin try start").Data(5),
                //----------outer tryfin try begin-------------
                new ILInstruction(ByteCode.Nop, "2. Outer tryfin try first instruction").AddLabel("OuterTryBeg").Data(6),

                //----------mid try begin-------------
                new ILInstruction(ByteCode.Nop, "3. At the mid try-catch try first instruction").AddLabel("MidTryBeg").Data(7),

                //----------inner try begin-------------
                new ILInstruction(ByteCode.Nop, "4. At the inner try first instruction").AddLabel("InnerTryBeg").Data(8),
                new ILInstruction(ByteCode.Nop, "5. Just before throw").Data(9),
                new ILInstruction(ByteCode.Newobj, TempTypeLocator.ExceptionDesc.Methods[0].Metadata /*ctor*/),
                new ILInstruction(ByteCode.Throw),
                new ILInstruction(ByteCode.Nop, "Just after throw"),
                new ILInstruction(ByteCode.Leave, new Label("InnerLeaveTarget")).AddLabel("InnerTryEnd"),
                //----------inner try end-------------
                new ILInstruction(ByteCode.Nop, "Between inner try and inner finally"),
                //----------inner finally begin-------------
                new ILInstruction(ByteCode.Nop, "6. Inner finally start").AddLabel("InnerFinBeg").Data(10),
                new ILInstruction(ByteCode.Nop, "7. Just before inner Endfinally").Data(11),
                new ILInstruction(ByteCode.Endfinally).AddLabel("InnerFinEnd"),
                //----------inner finally end-------------

                new ILInstruction(ByteCode.Nop).AddLabel("InnerLeaveTarget"),
                new ILInstruction(ByteCode.Leave, new Label("AfterMidBlock")).AddLabel("MidTryEnd"),
                //----------mid try end-------------

                //----------mid catch begin-------------
                new ILInstruction(ByteCode.Nop, "At the mid catch start").AddLabel("MidCatchBeg"),
                new ILInstruction(ByteCode.Nop, "Just before mid catch leave instruction"),
                new ILInstruction(ByteCode.Leave, new Label("AfterMidBlock")).AddLabel("MidCatchEnd"),
                //----------mid catch end-------------

                new ILInstruction(ByteCode.Nop, "Just before outer try leave instruction").AddLabel("AfterMidBlock"),
                new ILInstruction(ByteCode.Leave, new Label("OuterTryLeaveDest")).AddLabel("OuterTryEnd"),
                //----------outer try end-------------

                //----------outer finally begin-------------
                new ILInstruction(ByteCode.Nop, "8. At the outer finally start").AddLabel("OuterFinBeg").Data(12),
                new ILInstruction(ByteCode.Nop, "9. Just before Endfinally").Data(13),
                new ILInstruction(ByteCode.Endfinally).AddLabel("OuterFinEnd"),
                //----------outer finally end-------------

                new ILInstruction(ByteCode.Ret).AddLabel("OuterTryLeaveDest")
            });

            thirdMethod.EHTable.AddFinallyHandler("InnerTryBeg", "InnerTryEnd", "InnerFinBeg", "InnerFinEnd");
            thirdMethod.EHTable.AddCatchHandler("MidTryBeg", "MidTryEnd", TempTypeLocator.InvalidOperationExceptionDesc.Metadata, "MidCatchBeg", "MidCatchEnd");
            thirdMethod.EHTable.AddFinallyHandler("OuterTryBeg", "OuterTryEnd", "OuterFinBeg", "OuterFinEnd");



            MethodDesc secondMethod = new MethodDesc("SecondMethod", 3)
                                      .AddCallback(test)
                                      .AddInheritanceAttributeFlag(MethodInheritanceAttributes.Global)
                                      .AddInstructions(new ILInstruction[]
            {
                //----------outer try begin-------------
                new ILInstruction(ByteCode.Nop, "Outer try first instruction").AddLabel("OuterTryBeg").Data(3),

                //----------inner try begin-------------
                new ILInstruction(ByteCode.Nop, "At the inner try first instruction").AddLabel("InnerTryBeg").Data(4),

                new ILInstruction(ByteCode.Call, thirdMethod.Metadata),

                new ILInstruction(ByteCode.Leave, new Label("AfterMidBlock")).AddLabel("InnerTryEnd"),
                //----------inner try end-------------

                //----------inner finally begin-------------
                new ILInstruction(ByteCode.Nop, "Inner finally start").AddLabel("InnerFinBeg").Data(14),
                new ILInstruction(ByteCode.Nop, "Just before inner Endfinally").Data(15),
                new ILInstruction(ByteCode.Endfinally).AddLabel("InnerFinEnd"),
                //----------inner finally end-------------

                new ILInstruction(ByteCode.Nop, "Just before outer try leave instruction").AddLabel("AfterMidBlock"),
                new ILInstruction(ByteCode.Leave, new Label("OuterTryLeaveDest")).AddLabel("OuterTryEnd"),
                //----------outer try end-------------

                //----------outer finally begin-------------
                new ILInstruction(ByteCode.Nop, "At the outer finally start").AddLabel("OuterFinBeg").Data(16),
                new ILInstruction(ByteCode.Nop, "Just before Endfinally").Data(17),
                new ILInstruction(ByteCode.Endfinally).AddLabel("OuterFinEnd"),
                //----------outer finally end-------------

                new ILInstruction(ByteCode.Ret).AddLabel("OuterTryLeaveDest")
            });

            secondMethod.EHTable.AddFinallyHandler("InnerTryBeg", "InnerTryEnd", "InnerFinBeg", "InnerFinEnd");
            secondMethod.EHTable.AddFinallyHandler("OuterTryBeg", "OuterTryEnd", "OuterFinBeg", "OuterFinEnd");


            MethodDesc firstMethod = new MethodDesc("FirstMethod", 3)
                                     .EntryPoint()
                                     .AddInheritanceAttributeFlag(MethodInheritanceAttributes.Global)
                                     .AddCallback(test)
                                     .AddLocals(new LocalVarDescription[] {
                new LocalVarDescription()
                {
                    SType     = ESSlotType.HORef,
                    TypeToken = TempTypeLocator.ExceptionDesc.Metadata
                }
            })
                                     .AddInstructions(new ILInstruction[]
            {
                //----------outer try begin-------------
                new ILInstruction(ByteCode.Nop, "Outer try first instruction").AddLabel("OuterTryBeg").Data(1),

                //----------inner try begin-------------
                new ILInstruction(ByteCode.Nop, "At the inner try first instruction").AddLabel("InnerTryBeg").Data(2),

                new ILInstruction(ByteCode.Call, secondMethod.Metadata),

                new ILInstruction(ByteCode.Leave, new Label("AfterMidBlock")).AddLabel("InnerTryEnd"),
                //----------inner try end---------------

                //----------inner finally begin-----------
                new ILInstruction(ByteCode.Nop, "Inner finally start").AddLabel("InnerFinBeg").Data(18),
                new ILInstruction(ByteCode.Nop, "Just before inner Endfinally").Data(19),
                new ILInstruction(ByteCode.Endfinally).AddLabel("InnerFinEnd"),
                //----------inner finally end-------------

                new ILInstruction(ByteCode.Nop, "Just before outer try leave instruction").AddLabel("AfterMidBlock"),
                new ILInstruction(ByteCode.Leave, new Label("OuterTryLeaveDest")).AddLabel("OuterTryEnd"),
                //----------outer try end-------------

                //----------outer catch begin-------------
                new ILInstruction(ByteCode.Nop, "At the outer catch start").AddLabel("OuterCatchBeg").Data(20),
                new ILInstruction(ByteCode.Stloc, 0),
                new ILInstruction(ByteCode.Nop, "Just before outer catch leave").Data(21),
                new ILInstruction(ByteCode.Leave, new Label("OuterTryLeaveDest")).AddLabel("OuterCatchEnd"),
                //----------outer catch end-------------

                new ILInstruction(ByteCode.Ret).AddLabel("OuterTryLeaveDest").Data(22)
            });

            firstMethod.EHTable.AddFinallyHandler("InnerTryBeg", "InnerTryEnd", "InnerFinBeg", "InnerFinEnd");
            firstMethod.EHTable.AddCatchHandler("OuterTryBeg", "OuterTryEnd", TempTypeLocator.ExceptionDesc.Metadata, "OuterCatchBeg", "OuterCatchEnd");



            CompiledModel compiledModel = new CompiledModel()
                                          .AddMethod(firstMethod)
                                          .AddMethod(secondMethod)
                                          .AddMethod(thirdMethod);


            DomainModel domainModel = new DomainModel(new GCHeap.Factory(), new TypesHeap.Factory());

            domainModel.LoadType(TempTypeLocator.ObjectDesc);
            domainModel.LoadType(TempTypeLocator.ExceptionDesc);
            domainModel.LoadType(TempTypeLocator.InvalidOperationExceptionDesc);

            var executor = domainModel.GetExecutor(compiledModel, new ILOperationSet());

            //Act
            executor.Start();

            //Assert
            Assert.IsTrue(test.Success());
        }
        public void SimpleTryCatchAndTryFinallyHandlersWithinOneMethod()
        {
            //Arrange
            ITest test = new CorrectOrderCheck();

            MethodDesc mainMethod = new MethodDesc("Main", 3)
                                    .EntryPoint()
                                    .AddInheritanceAttributeFlag(MethodInheritanceAttributes.Global)
                                    .AddInstructions(new ILInstruction[]
            {
                new ILInstruction(ByteCode.Nop, "1. Just before outer try start").Data(1),
                //----------outer try begin-------------
                new ILInstruction(ByteCode.Nop, "2. At the outer try first instruction").AddLabel("OuterTryBeg").Data(2),

                //----------inner try begin-------------
                new ILInstruction(ByteCode.Nop, "3. At the inner try first instruction").AddLabel("InnerTryBeg").Data(3),
                new ILInstruction(ByteCode.Nop, "4. Just before throw").Data(4),
                new ILInstruction(ByteCode.Newobj, TempTypeLocator.ExceptionDesc.Methods[0].Metadata /*ctor*/),
                new ILInstruction(ByteCode.Throw),
                new ILInstruction(ByteCode.Nop, "Just after throw"),
                new ILInstruction(ByteCode.Leave, new Label("AfterInnerBlock")).AddLabel("InnerTryEnd"),
                //----------inner try end-------------
                new ILInstruction(ByteCode.Nop, "Between inner try and inner finally"),
                //----------inner finally begin-------------
                new ILInstruction(ByteCode.Nop, "5. Inner finally start").AddLabel("FinBeg").Data(5),
                new ILInstruction(ByteCode.Nop, "6. Just before Endfinally").Data(6),
                new ILInstruction(ByteCode.Endfinally).AddLabel("FinEnd"),
                //----------inner finally end-------------

                new ILInstruction(ByteCode.Nop, "Just before outer try leave instruction").AddLabel("AfterInnerBlock"),
                new ILInstruction(ByteCode.Leave, new Label("TryLeaveDest")).AddLabel("OuterTryEnd"),
                //----------outer try end-------------
                new ILInstruction(ByteCode.Nop, "Between try and catch"),
                //----------outer catch begin-------------
                new ILInstruction(ByteCode.Nop, "7. At the catch start").AddLabel("CatchBeg").Data(7),
                new ILInstruction(ByteCode.Pop),
                new ILInstruction(ByteCode.Nop, "8. Just before catch leave instruction").Data(8),
                new ILInstruction(ByteCode.Leave, new Label("CatchLeaveDest")).AddLabel("CatchEnd"),
                //----------outer catch end-------------

                new ILInstruction(ByteCode.Nop, "Instruction where try leave points").AddLabel("TryLeaveDest"),
                new ILInstruction(ByteCode.Nop, "9(end). Instruction where catch leave points").AddLabel("CatchLeaveDest").Data(9),
                new ILInstruction(ByteCode.Ret)
            });

            mainMethod.EHTable.AddCatchHandler("OuterTryBeg", "OuterTryEnd", TempTypeLocator.ExceptionDesc.Metadata, "CatchBeg", "CatchEnd");
            mainMethod.EHTable.AddFinallyHandler("InnerTryBeg", "InnerTryEnd", "FinBeg", "FinEnd");

            CompiledModel compiledModel = new CompiledModel()
                                          .AddMethod(mainMethod);

            DomainModel domainModel = new DomainModel(new GCHeap.Factory(), new TypesHeap.Factory());

            domainModel.LoadType(TempTypeLocator.ObjectDesc);
            domainModel.LoadType(TempTypeLocator.ExceptionDesc);
            domainModel.LoadType(TempTypeLocator.InvalidOperationExceptionDesc);

            var executor = domainModel.GetExecutor(compiledModel, new ILOperationSet());

            //Act
            executor.Start();

            //Assert
            Assert.IsTrue(test.Success());
        }
Beispiel #4
0
        public void TryFinallyInsideAnotherTryFinallyBlock()
        {
            ITest test = new CorrectOrderCheck();
            //Arrange
            MethodDesc mainMethod = new MethodDesc("Main", 3)
                                    .EntryPoint()
                                    .AddInheritanceAttributeFlag(MethodInheritanceAttributes.Global)
                                    .AddCallback(test)
                                    .AddLocals(new LocalVarDescription[]
            {
                new LocalVarDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
                new LocalVarDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
            })
                                    .AddArguments(new MethodArgDescription[]
            {
                new MethodArgDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
                new MethodArgDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
            })
                                    .AddInstructions(new ILInstruction[]
            {
                new ILInstruction(ByteCode.Nop, "1. Outer try start").Data(1),                       //0
                new ILInstruction(ByteCode.Nop, "2. Outer try leave instruction").Data(2),
                new ILInstruction(ByteCode.Leave, 13),                                               //2

                //----------outer finally begin-------------
                new ILInstruction(ByteCode.Nop, "3. Outer finally start").Data(3),               //3

                new ILInstruction(ByteCode.Nop, "4. Inner try first instruction start").Data(4), //4
                new ILInstruction(ByteCode.Nop, "5. Just before inner try leave instruction").Data(5),
                new ILInstruction(ByteCode.Leave, 11),                                           //6

                new ILInstruction(ByteCode.Nop, "Between inner try and inner finally"),

                new ILInstruction(ByteCode.Nop, "6. At the inner finally start").Data(6),               //8
                new ILInstruction(ByteCode.Nop, "7. Just before inner endfinally instruction").Data(7),
                new ILInstruction(ByteCode.Endfinally),                                                 //10

                new ILInstruction(ByteCode.Nop, "8. Just before outer endfinally instruction").Data(8), //11
                new ILInstruction(ByteCode.Endfinally),                                                 //12
                //----------outer finally end-------------

                new ILInstruction(ByteCode.Nop, "9(end). instruction where outer try's leave points").Data(9),                                //13
                new ILInstruction(ByteCode.Ret)
            });

            mainMethod.EHTable.AddFinallyHandler(4, 6, 8, 10);
            mainMethod.EHTable.AddFinallyHandler(0, 2, 3, 12);

            CompiledModel compiledModel = new CompiledModel()
                                          .AddMethod(mainMethod);

            DomainModel      domainModel = new DomainModel(new GCHeap.Factory(), new TypesHeap.Factory());
            IExecutionEngine executor    = domainModel.GetExecutor(compiledModel, new ILOperationSet());

            //Act
            executor.Start();

            //Assert
            Assert.IsTrue(test.Success());
        }
Beispiel #5
0
        public void TwoNestedTryFinallyBlocksWithinOneMethod()
        {
            ITest test = new CorrectOrderCheck();
            //Arrange
            MethodDesc mainMethod = new MethodDesc("Main", 3)
                                    .EntryPoint()
                                    .AddInheritanceAttributeFlag(MethodInheritanceAttributes.Global)
                                    .AddCallback(test)
                                    .AddLocals(new LocalVarDescription[]
            {
                new LocalVarDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
                new LocalVarDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
            })
                                    .AddArguments(new MethodArgDescription[]
            {
                new MethodArgDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
                new MethodArgDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
            })
                                    .AddInstructions(new ILInstruction[]
            {
                new ILInstruction(ByteCode.Ldc_I4, 2),
                new ILInstruction(ByteCode.Stloc, 0),
                new ILInstruction(ByteCode.Ldc_I4, 4),
                new ILInstruction(ByteCode.Stloc, 1),
                new ILInstruction(ByteCode.Nop, "1. Just before outer try start").Data(1),
                //----------outer try begin-------------
                new ILInstruction(ByteCode.Nop, "2. At the outer try first instruction start").AddLabel("OuterTryBeg").Data(2),                            //5
                new ILInstruction(ByteCode.Ldc_I4, 5),
                new ILInstruction(ByteCode.Stloc, 0),
                //----------inner try begin-------------
                new ILInstruction(ByteCode.Nop, "3. At the inner try first instruction start").AddLabel("InnerTryBeg").Data(3),                                //8
                new ILInstruction(ByteCode.Ldc_I4, 5),
                new ILInstruction(ByteCode.Stloc, 0),
                new ILInstruction(ByteCode.Nop, "4. Just before inner leave instruction").Data(4),
                new ILInstruction(ByteCode.Leave, new Label("AfterInnerBlock")).AddLabel("InnerTryEnd"),                                        //12
                //----------inner try end-------------
                new ILInstruction(ByteCode.Nop, "Just after inner try leave instruction"),
                new ILInstruction(ByteCode.Nop, "7. Where inner try's leave points to").AddLabel("AfterInnerBlock").Data(7),                              //14
                new ILInstruction(ByteCode.Ldc_I4, 5),
                new ILInstruction(ByteCode.Stloc, 0),
                new ILInstruction(ByteCode.Nop, "8. Just before outer leave instruction").Data(8),
                new ILInstruction(ByteCode.Leave, new Label("AfterOuterBlock")).AddLabel("OuterTryEnd"),                                       //18
                //----------outer try end-------------
                new ILInstruction(ByteCode.Nop, "Between outer try and finally"),
                //----------outer finally begin-------------
                new ILInstruction(ByteCode.Nop, "9. At the outer finally start").AddLabel("OuterFinBeg").Data(9),                                    //20
                new ILInstruction(ByteCode.Ldloc, 1),
                new ILInstruction(ByteCode.Ldloc, 0),
                new ILInstruction(ByteCode.Mul),
                new ILInstruction(ByteCode.Pop),
                new ILInstruction(ByteCode.Nop, "10. Just before outer endfinally instruction").Data(10),
                new ILInstruction(ByteCode.Endfinally).AddLabel("OuterFinEnd"),                                                            //26
                //----------outer finally end-------------
                new ILInstruction(ByteCode.Nop, "Just after outer endfinally instruction"),
                new ILInstruction(ByteCode.Nop, "11(end). instruction where outer try's leave points").AddLabel("AfterOuterBlock").Data(11),                               //28
                new ILInstruction(ByteCode.Ret),

                //----------inner finally begin-------------
                new ILInstruction(ByteCode.Nop, "5. At the inner finally start").AddLabel("InnerFinBeg").Data(5),                                           //30
                new ILInstruction(ByteCode.Ldloc, 1),
                new ILInstruction(ByteCode.Ldloc, 0),
                new ILInstruction(ByteCode.Mul),
                new ILInstruction(ByteCode.Pop),
                new ILInstruction(ByteCode.Nop, "6. Just before inner endfinally instruction").Data(6),
                new ILInstruction(ByteCode.Endfinally).AddLabel("InnerFinEnd"),                                        //36
                //----------inner finally end-------------
            });

            mainMethod.EHTable.AddFinallyHandler("InnerTryBeg", "InnerTryEnd", "InnerFinBeg", "InnerFinEnd");
            mainMethod.EHTable.AddFinallyHandler("OuterTryBeg", "OuterTryEnd", "OuterFinBeg", "OuterFinEnd");

            CompiledModel compiledModel = new CompiledModel()
                                          .AddMethod(mainMethod);

            DomainModel domainModel = new DomainModel(new GCHeap.Factory(), new TypesHeap.Factory());

            domainModel.LoadType(TempTypeLocator.Int32Desc);
            IExecutionEngine executor = domainModel.GetExecutor(compiledModel, new ILOperationSet());

            //Act
            executor.Start();

            //Assert
            Assert.IsTrue(test.Success());
        }
Beispiel #6
0
        public void SimpleTryFinally()
        {
            ITest test = new CorrectOrderCheck();
            //Arrange
            MethodDesc mainMethod = new MethodDesc("Main", 3)
                                    .EntryPoint()
                                    .AddInheritanceAttributeFlag(MethodInheritanceAttributes.Global)
                                    .AddCallback(test)
                                    .AddLocals(new LocalVarDescription[]
            {
                new LocalVarDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
                new LocalVarDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
            })
                                    .AddArguments(new MethodArgDescription[]
            {
                new MethodArgDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
                new MethodArgDescription()
                {
                    TypeToken = TempTypeLocator.Int32Desc.Metadata
                },
            })
                                    .AddInstructions(new ILInstruction[]
            {
                new ILInstruction(ByteCode.Ldc_I4, 2),
                new ILInstruction(ByteCode.Stloc, 0),
                new ILInstruction(ByteCode.Ldc_I4, 4),
                new ILInstruction(ByteCode.Stloc, 1),
                new ILInstruction(ByteCode.Nop, "1. Just before try start").Data(1),
                //----------try begin-------------
                new ILInstruction(ByteCode.Nop, "2. At the try first instruction start").AddLabel("TryBeg").Data(2),                            //5
                new ILInstruction(ByteCode.Ldc_I4, 5),
                new ILInstruction(ByteCode.Stloc, 0),
                new ILInstruction(ByteCode.Nop, "3. Just before leave instruction").Data(3),
                new ILInstruction(ByteCode.Leave, new Label("AfterBlock")).AddLabel("TryEnd"),                               //9                              //9
                //----------try end-------------
                new ILInstruction(ByteCode.Nop, "Between try and finally"),
                //----------finally begin-------------
                new ILInstruction(ByteCode.Nop, "4. At the finally start").AddLabel("FinBeg").Data(4),                                           //11
                new ILInstruction(ByteCode.Ldloc, 1),
                new ILInstruction(ByteCode.Ldloc, 0),
                new ILInstruction(ByteCode.Mul),
                new ILInstruction(ByteCode.Pop),
                new ILInstruction(ByteCode.Nop, "5. Just before endfinally instruction").Data(5),
                new ILInstruction(ByteCode.Endfinally).AddLabel("FinEnd"),                                                            //17
                //----------finally end-------------
                new ILInstruction(ByteCode.Nop, "Just after endfinally instruction"),
                new ILInstruction(ByteCode.Nop, "6(end). instruction where leave points").AddLabel("AfterBlock").Data(6),                                   //19
                new ILInstruction(ByteCode.Ret)
            });

            mainMethod.EHTable.AddFinallyHandler("TryBeg", "TryEnd", "FinBeg", "FinEnd");


            CompiledModel compiledModel = new CompiledModel()
                                          .AddMethod(mainMethod);

            DomainModel domainModel = new DomainModel(new GCHeap.Factory(), new TypesHeap.Factory());

            domainModel.LoadType(TempTypeLocator.Int32Desc);
            IExecutionEngine executor = domainModel.GetExecutor(compiledModel, new ILOperationSet());

            //Act
            executor.Start();

            //Assert
            Assert.IsTrue(test.Success());
        }