Example #1
0
        public void NullFilterOnFilterHandlerShouldThrow()
        {
            var body = CreateDummyBody(true);

            var tryStart     = new CilInstructionLabel();
            var tryEnd       = new CilInstructionLabel();
            var handlerStart = new CilInstructionLabel();
            var handlerEnd   = new CilInstructionLabel();

            var handler = new CilExceptionHandler
            {
                TryStart     = tryStart,
                TryEnd       = tryEnd,
                HandlerStart = handlerStart,
                HandlerEnd   = handlerEnd,
                HandlerType  = CilExceptionHandlerType.Filter
            };

            body.Instructions.Add(CilOpCodes.Nop);
            tryStart.Instruction     = body.Instructions.Add(CilOpCodes.Leave, handlerEnd);
            tryEnd.Instruction       = body.Instructions.Add(CilOpCodes.Endfilter);
            handlerStart.Instruction = body.Instructions.Add(CilOpCodes.Leave, handlerEnd);
            handlerEnd.Instruction   = body.Instructions.Add(CilOpCodes.Ret);

            body.ExceptionHandlers.Add(handler);
            Assert.Throws <InvalidCilInstructionException>(() => body.VerifyLabels());
        }
Example #2
0
        public void FinallyHandlerExpectsNoValueOnStack()
        {
            var body = CreateDummyBody(true);

            var end = new CilInstructionLabel();

            var tryStart     = new CilInstructionLabel();
            var tryEnd       = new CilInstructionLabel();
            var handlerStart = new CilInstructionLabel();
            var handlerEnd   = new CilInstructionLabel();

            body.ExceptionHandlers.Add(new CilExceptionHandler
            {
                HandlerType   = CilExceptionHandlerType.Finally,
                ExceptionType = body.Owner.Module.CorLibTypeFactory.Object.ToTypeDefOrRef(),
                TryStart      = tryStart,
                TryEnd        = tryEnd,
                HandlerStart  = handlerStart,
                HandlerEnd    = handlerEnd,
            });

            tryStart.Instruction     = body.Instructions.Add(CilOpCodes.Nop);
            tryEnd.Instruction       = body.Instructions.Add(CilOpCodes.Leave, end);
            handlerStart.Instruction = body.Instructions.Add(CilOpCodes.Nop);
            handlerEnd.Instruction   = body.Instructions.Add(CilOpCodes.Leave, end);
            end.Instruction          = body.Instructions.Add(CilOpCodes.Ret);

            Assert.Equal(0, body.ComputeMaxStack());
        }
Example #3
0
        public void ValidHandlerShouldNotThrow()
        {
            var body = CreateDummyBody(true);

            var tryStart     = new CilInstructionLabel();
            var tryEnd       = new CilInstructionLabel();
            var handlerStart = new CilInstructionLabel();
            var handlerEnd   = new CilInstructionLabel();

            var handler = new CilExceptionHandler
            {
                TryStart     = tryStart,
                TryEnd       = tryEnd,
                HandlerStart = handlerStart,
                HandlerEnd   = handlerEnd,
                HandlerType  = CilExceptionHandlerType.Exception
            };

            body.Instructions.Add(CilOpCodes.Nop);
            tryStart.Instruction     = body.Instructions.Add(CilOpCodes.Leave, handlerEnd);
            handlerStart.Instruction = tryEnd.Instruction = body.Instructions.Add(CilOpCodes.Leave, handlerEnd);
            handlerEnd.Instruction   = body.Instructions.Add(CilOpCodes.Ret);

            body.ExceptionHandlers.Add(handler);
            body.VerifyLabels();
        }
Example #4
0
        public void ExistingInstructionBranchTargetShouldNotThrow()
        {
            var body  = CreateDummyBody(true);
            var label = new CilInstructionLabel();

            body.Instructions.Add(CilOpCodes.Br_S, label);
            label.Instruction = body.Instructions.Add(CilOpCodes.Ret);

            body.VerifyLabels();
        }
        public void BranchWithSmallNegativeDeltaShouldOptimizeToShortBranch()
        {
            var instructions = CreateDummyMethod(false, 0, 0);
            var target       = new CilInstructionLabel();

            target.Instruction = instructions.Add(CilOpCodes.Nop);
            instructions.Add(CilOpCodes.Nop);
            instructions.Add(CilOpCodes.Nop);
            instructions.Add(CilOpCodes.Br, target);

            instructions.OptimizeMacros();

            Assert.Equal(CilOpCodes.Br_S, instructions[3].OpCode);
        }
        public void BranchWithLargeNegativeDeltaShouldNotOptimize()
        {
            var instructions = CreateDummyMethod(false, 0, 0);
            var target       = new CilInstructionLabel();

            target.Instruction = instructions.Add(CilOpCodes.Nop);

            for (int i = 0; i < 255; i++)
            {
                instructions.Add(CilOpCodes.Nop);
            }

            instructions.Add(CilOpCodes.Br, target);

            instructions.OptimizeMacros();

            Assert.Equal(CilOpCodes.Br, instructions[^ 1].OpCode);
Example #7
0
        public void ExceptionHandlerWithHandlerEndOutsideOfMethod()
        {
            // https://github.com/Washi1337/Echo/issues/101

            // Set up test case.
            var module = new ModuleDefinition("Module");
            var method = new MethodDefinition("MyMethod", MethodAttributes.Static,
                                              MethodSignature.CreateStatic(module.CorLibTypeFactory.Void));
            var body         = method.CilMethodBody = new CilMethodBody(method);
            var instructions = body.Instructions;

            var start        = new CilInstructionLabel();
            var tryStart     = new CilInstructionLabel();
            var handlerStart = new CilInstructionLabel();

            start.Instruction    = instructions.Add(CilOpCodes.Nop);
            tryStart.Instruction = instructions.Add(CilOpCodes.Nop);
            instructions.Add(CilOpCodes.Leave_S, start);
            handlerStart.Instruction = instructions.Add(CilOpCodes.Pop);
            instructions.Add(CilOpCodes.Leave_S, start);

            body.ExceptionHandlers.Add(new CilExceptionHandler
            {
                ExceptionType = module.CorLibTypeFactory.Object.ToTypeDefOrRef(),
                TryStart      = tryStart,
                TryEnd        = handlerStart,
                HandlerStart  = handlerStart,
                HandlerEnd    = instructions.EndLabel // Use end label.
            });

            instructions.CalculateOffsets();

            // Construct CFG.
            var cfg = body.ConstructStaticFlowGraph();

            // Verify handler exists.
            Assert.NotNull(cfg);
            Assert.Equal(3, cfg.Nodes.Count);
            var region = Assert.Single(cfg.Regions);
            var eh     = Assert.IsAssignableFrom <ExceptionHandlerRegion <CilInstruction> >(region);

            Assert.Single(eh.Handlers);
        }
Example #8
0
        public void JoiningPathsWithSameStackSizeShouldSucceed()
        {
            var body         = CreateDummyBody(false);
            var instructions = body.Instructions;

            var branchTarget1 = new CilInstructionLabel();
            var branchTarget2 = new CilInstructionLabel();

            instructions.Add(CilOpCodes.Ldarg_0);
            instructions.Add(CilOpCodes.Brtrue, branchTarget1);

            instructions.Add(CilOpCodes.Ldc_I4_1);
            instructions.Add(CilOpCodes.Br, branchTarget2);

            branchTarget1.Instruction = instructions.Add(CilOpCodes.Ldc_I4_0);
            branchTarget2.Instruction = instructions.Add(CilOpCodes.Nop);

            instructions.Add(CilOpCodes.Ret);

            Assert.Equal(1, body.ComputeMaxStack());
        }
Example #9
0
        public void LeaveInstructionShouldClearStackAndNotFail()
        {
            var body = CreateDummyBody(true);

            var end = new CilInstructionLabel();

            var tryStart     = new CilInstructionLabel();
            var tryEnd       = new CilInstructionLabel();
            var handlerStart = new CilInstructionLabel();
            var handlerEnd   = new CilInstructionLabel();

            body.ExceptionHandlers.Add(new CilExceptionHandler
            {
                HandlerType   = CilExceptionHandlerType.Exception,
                ExceptionType = body.Owner.Module.CorLibTypeFactory.Object.ToTypeDefOrRef(),
                TryStart      = tryStart,
                TryEnd        = tryEnd,
                HandlerStart  = handlerStart,
                HandlerEnd    = handlerEnd,
            });

            tryStart.Instruction = body.Instructions.Add(CilOpCodes.Nop);
            tryEnd.Instruction   = body.Instructions.Add(CilOpCodes.Leave, end);

            handlerStart.Instruction = body.Instructions.Add(CilOpCodes.Nop);
            // Push junk values on the stack.
            body.Instructions.Add(CilOpCodes.Ldc_I4_0);
            body.Instructions.Add(CilOpCodes.Ldc_I4_1);
            body.Instructions.Add(CilOpCodes.Ldc_I4_2);
            // Leave should clear.
            handlerEnd.Instruction = body.Instructions.Add(CilOpCodes.Leave, end);

            end.Instruction = body.Instructions.Add(CilOpCodes.Ret);

            Assert.Equal(4, body.ComputeMaxStack());
        }
Example #10
0
        public void JoiningPathsWithDifferentStackSizesShouldFail()
        {
            var body         = CreateDummyBody(false);
            var instructions = body.Instructions;

            var branchTarget1 = new CilInstructionLabel();
            var branchTarget2 = new CilInstructionLabel();
            var end           = new CilInstructionLabel();

            instructions.Add(CilOpCodes.Ldarg_0);
            instructions.Add(CilOpCodes.Brtrue, branchTarget1);

            instructions.Add(CilOpCodes.Ldc_I4_1);
            instructions.Add(CilOpCodes.Ldc_I4_2);
            instructions.Add(CilOpCodes.Br, branchTarget2);

            branchTarget1.Instruction = instructions.Add(CilOpCodes.Ldc_I4_0);
            branchTarget2.Instruction = instructions.Add(CilOpCodes.Nop);
            end.Instruction           = instructions.Add(CilOpCodes.Ret);

            var exception = Assert.ThrowsAny <StackImbalanceException>(() => body.ComputeMaxStack());

            Assert.Equal(end.Offset, exception.Offset);
        }