Example #1
0
        public void TestGenericNameFormatting()
        {
            MetadataType testClass  = _testModule.GetType("ILDisassembler", "TestGenericClass`1");
            EcmaMethod   testMethod = (EcmaMethod)testClass.GetMethod("TestMethod", null);
            EcmaMethodIL methodIL   = EcmaMethodIL.Create(testMethod);

            Dictionary <int, string> interestingLines = new Dictionary <int, string>
            {
                { 4, "IL_0003:  ldstr       \"Hello \\\"World\\\"!\\n\"" },
                { 9, "IL_000D:  call        instance void class ILDisassembler.TestGenericClass`1<!TClassParam>::VoidGenericMethod<string, valuetype ILDisassembler.TestStruct>(!!0, int32, native int, class ILDisassembler.TestClass&)" },
                { 14, "IL_0017:  initobj     !TClassParam" },
                { 16, "IL_001E:  call        !!0 class ILDisassembler.TestGenericClass`1<!TClassParam>::MethodParamGenericMethod<class ILDisassembler.TestClass>(class ILDisassembler.TestGenericClass`1<!!0>, class ILDisassembler.TestGenericClass`1/Nested<!0>, valuetype ILDisassembler.TestStruct*[], !0)" },
                { 24, "IL_0030:  call        !!0 class ILDisassembler.TestGenericClass`1<!TClassParam>::MethodParamGenericMethod<!0>(class ILDisassembler.TestGenericClass`1<!!0>, class ILDisassembler.TestGenericClass`1/Nested<!0>, valuetype ILDisassembler.TestStruct*[], !0)" },
                { 26, "IL_0036:  ldtoken     !TClassParam" },
                { 28, "IL_003C:  ldtoken     valuetype [CoreTestAssembly]System.Nullable`1<int32>" },
                { 31, "IL_0043:  ldc.r8      3.14" },
                { 32, "IL_004C:  ldc.r4      1.68" },
                { 34, "IL_0053:  call        instance valuetype ILDisassembler.TestStruct class ILDisassembler.TestGenericClass`1<!TClassParam>::NonGenericMethod(float64, float32, int16)" },
                { 37, "IL_005A:  ldflda      !0 class ILDisassembler.TestGenericClass`1<!TClassParam>::somefield" },
                { 41, "IL_0067:  stfld       class ILDisassembler.TestClass class ILDisassembler.TestGenericClass`1<!TClassParam>::otherfield" },
                { 44, "IL_006E:  stfld       class ILDisassembler.TestGenericClass`1<class ILDisassembler.TestGenericClass`1<class ILDisassembler.TestClass>> class ILDisassembler.TestGenericClass`1<!TClassParam>::genericfield" },
                { 47, "IL_0075:  stfld       !0[] class ILDisassembler.TestGenericClass`1<!TClassParam>::arrayfield" },
                { 48, "IL_007A:  call        void ILDisassembler.TestClass::NonGenericMethod()" },
                { 49, "IL_007F:  ldsflda     valuetype ILDisassembler.TestStruct ILDisassembler.TestClass::somefield" },
                { 50, "IL_0084:  initobj     ILDisassembler.TestStruct" }
            };

            ILDisassember disasm = new ILDisassember(methodIL);

            int numLines = 1;

            while (disasm.HasNextInstruction)
            {
                string line = disasm.GetNextInstruction();
                string expectedLine;
                if (interestingLines.TryGetValue(numLines, out expectedLine))
                {
                    Assert.Equal(expectedLine, line);
                }
                numLines++;
            }

            Assert.Equal(52, numLines);
        }
        private MethodDebugInformation GetDebugInformation(MethodIL methodIL)
        {
            MethodDesc owningMethod = methodIL.OwningMethod;
            var        disasm       = new ILDisassember(methodIL);
            var        fmt          = new ILDisassember.ILTypeNameFormatter(null);

            ArrayBuilder <ILSequencePoint> sequencePoints = new ArrayBuilder <ILSequencePoint>();

            _tw.Write(".method ");
            // TODO: accessibility, specialname, calling conventions etc.
            if (!owningMethod.Signature.IsStatic)
            {
                _tw.Write("instance ");
            }
            _tw.Write(fmt.FormatName(owningMethod.Signature.ReturnType));
            _tw.Write(" ");
            _tw.Write(owningMethod.Name);
            if (owningMethod.HasInstantiation)
            {
                _tw.Write("<");
                for (int i = 0; i < owningMethod.Instantiation.Length; i++)
                {
                    if (i != 0)
                    {
                        _tw.Write(", ");
                    }
                    _tw.Write(fmt.FormatName(owningMethod.Instantiation[i]));
                }
                _tw.Write(">");
            }
            _tw.Write("(");
            for (int i = 0; i < owningMethod.Signature.Length; i++)
            {
                if (i != 0)
                {
                    _tw.Write(", ");
                }
                _tw.Write(fmt.FormatName(owningMethod.Signature[i]));
            }
            _tw.WriteLine(") cil managed"); _currentLine++;

            _tw.WriteLine("{"); _currentLine++;

            _tw.Write("  // Code size: ");
            _tw.Write(disasm.CodeSize);
            _tw.WriteLine(); _currentLine++;
            _tw.Write("  .maxstack ");
            _tw.Write(methodIL.MaxStack);
            _tw.WriteLine(); _currentLine++;

            LocalVariableDefinition[] locals = methodIL.GetLocals();
            if (locals != null && locals.Length > 0)
            {
                _tw.Write("  .locals ");
                if (methodIL.IsInitLocals)
                {
                    _tw.Write("init ");
                }

                _tw.Write("(");

                for (int i = 0; i < locals.Length; i++)
                {
                    if (i != 0)
                    {
                        _tw.WriteLine(","); _currentLine++;
                        _tw.Write("      ");
                    }
                    _tw.Write(fmt.FormatName(locals[i].Type));
                    _tw.Write(" ");
                    if (locals[i].IsPinned)
                    {
                        _tw.Write("pinned ");
                    }
                    _tw.Write("V_");
                    _tw.Write(i);
                }
                _tw.WriteLine(")"); _currentLine++;
            }
            _tw.WriteLine(); _currentLine++;

            while (disasm.HasNextInstruction)
            {
                _currentLine++;

                int offset = disasm.Offset;
                _tw.WriteLine(disasm.GetNextInstruction());
                sequencePoints.Add(new ILSequencePoint(offset, _fileName, _currentLine));
            }

            _tw.WriteLine("}"); _currentLine++;
            _tw.WriteLine(); _currentLine++;

            return(new SyntheticMethodDebugInformation(sequencePoints.ToArray()));
        }