wliao008 / buffalo

an aspect oriented programming framework using mono cecil for the .NET platform
1 stars 0 forks source link

Generated msil resulted in System.OverflowException #15

Closed wliao008 closed 11 years ago

wliao008 commented 11 years ago

ICSharpCode.Decompiler.DecompilerException: Error decompiling System.Object BuffaloTest.AcceptOneAspect::Invoke(Buffalo.MethodArgs) ---> System.OverflowException: Arithmetic operation resulted in an overflow. at ICSharpCode.Decompiler.ILAst.ILAstBuilder.StackSlot.ModifyStack(StackSlot[] stack, Int32 popCount, Int32 pushCount, ByteCode pushDefinition) at ICSharpCode.Decompiler.ILAst.ILAstBuilder.StackAnalysis(MethodDefinition methodDef) at ICSharpCode.Decompiler.ILAst.ILAstBuilder.Build(MethodDefinition methodDef, Boolean optimize, DecompilerContext context) at ICSharpCode.Decompiler.Ast.AstMethodBodyBuilder.CreateMethodBody(IEnumerable1 parameters) at ICSharpCode.Decompiler.Ast.AstMethodBodyBuilder.CreateMethodBody(MethodDefinition methodDef, DecompilerContext context, IEnumerable1 parameters) --- End of inner exception stack trace --- at ICSharpCode.Decompiler.Ast.AstMethodBodyBuilder.CreateMethodBody(MethodDefinition methodDef, DecompilerContext context, IEnumerable`1 parameters) at ICSharpCode.Decompiler.Ast.AstBuilder.CreateMethod(MethodDefinition methodDef) at ICSharpCode.Decompiler.Ast.AstBuilder.AddMethod(MethodDefinition method) at ICSharpCode.ILSpy.CSharpLanguage.DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) at ICSharpCode.ILSpy.TextView.DecompilerTextView.DecompileNodes(DecompilationContext context, ITextOutput textOutput) at ICSharpCode.ILSpy.TextView.DecompilerTextView.<>cDisplayClass17.b16()

Example program

    class Program
    {
        static void Main(string[] args)
        {
            dummy d = new dummy();
            d.AcceptMany(1, 5, 9);

            Console.Read();
        }
    }

    public class dummy
    {
        [AcceptOneAspect]
        public void AcceptMany(params object[] args)
        {
            foreach (var arg in args)
            {
                Console.WriteLine(arg);
            }
        }
    }

    [AcceptOneAspect(AttributeExclude = true)]
    public class AcceptOneAspect : MethodAroundAspect
    {
        public override object Invoke(MethodArgs args)
        {
            args.Proceed();
            return null;
        }
    }

Resulting MSIL:

.method public hidebysig virtual 
    instance object Invoke (
        class [Buffalo]Buffalo.MethodArgs args
    ) cil managed 
{
    // Method begins at RVA 0x2198
    // Code size 58 (0x3a)
    .maxstack 3
    .locals init (
        [0] object,
        [1] object,
        [2] object[]
    )

    IL_0000: nop
    IL_0001: ldarg.1
    IL_0002: callvirt instance object [Buffalo]Buffalo.MethodArgs::get_Instance()
    IL_0007: stloc 1
    IL_000b: ldarg.1
    IL_000c: callvirt instance object[] [Buffalo]Buffalo.MethodArgs::get_ParameterArray()
    IL_0011: stloc 2
    IL_0015: ldloc 1
    IL_0019: unbox.any BuffaloTest.dummy
    IL_001e: ldloc 2
    IL_0022: ldc.i4 0
    IL_0027: ldelem.ref
    IL_0028: unbox.any object[]
    IL_002d: callvirt instance void BuffaloTest.dummy::AcceptMany(object[])
    IL_0032: pop
    IL_0033: pop
    IL_0034: ldnull
    IL_0035: stloc.0
    IL_0036: br.s IL_0038

    IL_0038: ldloc.0
    IL_0039: ret
} // end of method AcceptOneAspect::Invoke
wliao008 commented 11 years ago

I think this has to do with the ReturnType and the storing of the returned value.

wliao008 commented 11 years ago
IL_002d: callvirt instance void BuffaloTest.dummy::AcceptMany(object[])
IL_0032: pop
IL_0033: pop

This is definitely the trouble code, the method returns void but we're popping the stack, and twice too.