Git Product home page Git Product logo

cecil's People

Contributors

atykhyy avatar carlokok avatar cshung avatar dgrunwald avatar erozenfeld avatar gluck avatar ignas2 avatar jbevain avatar jeremymeng avatar joelmartinez avatar joj avatar joshpeterson avatar ltrzesniewski avatar marek-safar avatar mrvoorhe avatar radekdoulik avatar rolfbjarne avatar sbomer avatar scott-ferguson-unity avatar simoncropp avatar stephanedelcroix avatar stevegilham avatar tautvydaszilys avatar thaystg avatar therzok avatar tmat avatar vargaz avatar vitek-karas avatar xen2 avatar zastai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cecil's Issues

NullReferenceException when enum_type cannot be resolved

When an attribute uses an enum defined in other assembly and Cecil cannot resolve that assembly, the following exception occurs.
Cecil should not assume that referenced assemblies are always available and provide as much information as possible in such cases.

NullReferenceException
at Mono.Cecil.SignatureReader.ReadCustomAttributeEnum(TypeReference enum_type) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2838
at Mono.Cecil.SignatureReader.ReadCustomAttributeElementValue(TypeReference type) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2740
at Mono.Cecil.SignatureReader.ReadCustomAttributeElement(TypeReference type) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2726
at Mono.Cecil.SignatureReader.ReadCustomAttributeFixedArgument(TypeReference type) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2661
at Mono.Cecil.SignatureReader.ReadCustomAttributeConstructorArguments(CustomAttribute attribute, Collection1 parameters) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2652 at Mono.Cecil.MetadataReader.ReadCustomAttributeSignature(CustomAttribute attribute) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2194 at Mono.Cecil.CustomAttribute.<Resolve>b__2(CustomAttribute attribute, MetadataReader reader) in c:\work\cecil\Mono.Cecil\CustomAttribute.cs:line 194 at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func3 read) in c:\work\cecil\Mono.Cecil\ModuleDefinition.cs:line 553
at Mono.Cecil.CustomAttribute.Resolve() in c:\work\cecil\Mono.Cecil\CustomAttribute.cs:line 193
at Mono.Cecil.CustomAttribute.get_ConstructorArguments() in c:\work\cecil\Mono.Cecil\CustomAttribute.cs:line 102

Saved modules grow in size

I compile an assembly using Visual Studio 2010, C#.
Target Framework is version 4 Client Profile.
Output type is class library.
Platform target is Any CPU.
Optimize code is on.
Allow Unsafe code is off.
There are no managed resources and no native resources.
The assembly is signed (strong name).

The PE Header says:
Section Alignment = 8192
File Alignment = 512

.text section is 254 KB
.rsrc section is 1 KB
.reloc section is 512 bytes

CLR Header says
MetaData is 147,59 KB

Total file size is 256 KB.

I then open the module using

ModuleDefinition md = ModuleDefinition.ReadModule(modulepath);

and save it using

WriterParameters wp = new WriterParameters
{
    WriteSymbols = md.HasSymbols
};

md.Write(modulepath, wp);

The new file is now 258.5 KB.

The .text section has grown to 255.5 KB
A .sdata section has been added, 512 bytes

CLR Header says MetaData is now down to 147.5 KB.

The .text section should not grow.
A .sdata section should not be added.
The total file size should not increase (It would be ok if it went down without loosing information).

I have not tested this on other modules.

Bug in MethodDefinition properties for MethodImplAttributes

The getter methods are incorrectly using attributes whereas impl_attributes is expected.
For example:

        public bool IsIL {
            get { return attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL); }
            set { impl_attributes = impl_attributes.SetMaskedAttributes((ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.IL, value); }
        }

We sould have:

        public bool IsIL {
            get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL); }
            set { impl_attributes = impl_attributes.SetMaskedAttributes((ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.IL, value); }
        }

Fire an event when the resolver fails

A per (now old) discussion on IRC. Application, like Gendarme, would benefit knowing/solving resolver failures. E.g. asking the user to manually locate mscorlib.dll instead of failing for an unknown (or newer) framework.

Expose types' ElementType

ElementType should be cleaned up to be made public, and TypeReference.etype should be exposed.

Possible property name, by order of preference: MetadataType, SignatureType, CoreType, TypeCode.

Mono.Cecil.Rocks.MethodBodyRocks::ComputeOffsets should not be private

It is virtually impossible to modify a method body without invalidating instruction offsets. After updating instructions, offsets must be updated too or Mono.Cecil.Cil.CodeWriter::WriteMethodBody will write wrong offsets in branch instructions.

I believe that ComputeOffsets should be a public instance member on MethodBody (or on InstructionCollection as per my other suggestion). This should allow programs to call ComputeOffsets after applying modifications to the method body and before running further analysis logic.

I also feel the method should be renamed to UpdateOffsets.

I believe that Mono.Cecil.Cil.CodeWriter::WriteMethodBody should call ComputeOffsets before writing the method body. This ensures that wrong branch offsets are not written in case a program did not call UpdateOffsets/ComputeOffsets.
-- edit: Mono.Cecil.Cil.CodeWriter::WriteMethodBody does compute offsets.

Alternatively, the UpdateOffsets is private, but is called automatically after every update to MethodBody.Instructions. This would make the API significantly easier to use, at the expense of reduced performance.

MethodBody.Instructions not safe to modify

MethodBody.Instructions returns a Collection which can be modified. However, when inserting or removing items, invariants are not maintained.

The collection can also be modified through an ILProcessor, where the Append, InsertBefore, InsertAfter, and Remove methods maintain the Instruction.Next and Instruction.Previous properties (as do the Emit and Replace functions through them).

This is not good. I suggest that MethodBody.Instructions return an InstructionCollection, inheriting from Collection, that maintains the Instruction.Next and Instruction.Previous properties. This responsibility can than be removed from ILProcessor. More importantly, it then becomes safe to modify the MethodBody.Instructions collection directly.

Instruction.Operand contains invalid branch instruction.

Hi Evain,

I decompiled a switch statement that follows:
switch (arg)
{
case 0:
{
return 2;
}
case 1:
{
return 4;
}
default:
{
return 0;
}
}

The result IL contains :
{IL_0004: switch IL_0013,IL_0018}

Followed by :
{IL_0011: br.s IL_001d}
{IL_0013: nop}

Now, instruction.Operand contains nop which is valid but not expected as it should contain the value from IL_0011 which is the switch branch needed to create proper control flow graph.

In this case, is it possible to send the desired OpCode through instruction.Operand ? So that implementer does not have to do an extra simulation on top it.

Regards,
Mehfuz

Resolving AssemblyNameReference with null Version

If you attempt to resolve an AssemblyNameReference with a null Version field, a null reference exception is thrown. This only happens when the assembly does not appear within the specified search directories.

eg.
GlobalAssemblyResolver.Instance.Resolve(AssemblyNameReference.Parse("System.Core"));

The exception is thrown in BaseAssemblyResolver.IsZero(). Its worth noting that AssemblyNameReference.Parse() returns a reference with a null version field if no version is specified in the fullname parameter. Is this by design?

Provide TypeSystem property as public

It should be great to have access to the TypeSystem properties in order to use the basic types.
There is no way at the moment to use these basic types so that Cecil uses the ElementType value rather than creating a reference on mscorlib and a TypeReference, for System.Object, System.Void, etc...

Expose ElementType of a TypeReference and make ElementType public

So we can determine wether a TypeReference is a primitive type or not.
Or expose e property that says wether a TypeReference is a primitive type ?

Primitive types are :
Boolean
Int8
UInt8
Int16
UInt16
Int32
UInt32
Int64
UInt64
IntPtr
UIntPtr
Char
Float32:
Float64

ModuleDefination.Types should return TypeReference

For now, ModuleDefination.Types returns TypeDefination.
It works well for normal types but not for generic types.
The same base class for GenericInstanceType and TypeDefination is TypeReference.
So I think ModuleDefination.Types should return TypeReference.
(There are other issues about generic types in cecil. Maybe the better way to solve it is to make GenericInstanceType inherits from TypeDefination.....)

Resolve should check exported types

When resolving a TypeReference failed, Cecil should try to check the exported types and if there's a match, resolve from the scope of the exported type.

Cannot rename generic type references

It is no longer possible to rename a generic type reference, due to the following commit :

6cc2e55

In AssemblyReader.cs, GetMemberReference method, the added condition prevents renames to generic type references to be saved :

  if (!member.ContainsGenericParameter)
    metadata.AddMemberReference (member);

If I comment out that if, it fixes the problem, but I presume it might break what you were trying to fix with that change.

Loops inside an if statement are not decompiled correctly

If a while or for loop is placed inside an if statement then the loop is incorrectly decompiled.
Decompiling the following C# code:
[MyFunction]
public void SimpleHello()
{
int x = DateTime.Now.Day;
if (x == 15)
{
for (int i = 0; i < 15; i++)
Console.WriteLine(i);
}
}

produces:

public void SimpleHello()
{
DateTime V_2 = DateTime.get_Now();
int V_0 = &V_2.get_Day();
if (V_0 == 15)
{
int V_1 = 0;
Console.WriteLine(V_1);
V_1++;
// two lines above should be inside a (for) loop below
// the decompilation works if there is not if statement around the loop
while (V_1 < 15)
{
}
}
}

Calling code:
Assembly ass = Assembly.GetExecutingAssembly();
AssemblyDefinition ad = AssemblyFactory.GetAssembly(ass.Location);
ModuleDefinitionCollection mdc = ad.Modules;
StringBuilder sb = new StringBuilder();
StringWriter streamWriter = new StringWriter(sb);
foreach (ModuleDefinition mod in mdc)
{
Console.WriteLine(mod.Name);
foreach (TypeDefinition type in mod.Types)
{
Console.WriteLine(type.FullName);
foreach (MethodDefinition md in type.Methods)
{
foreach (CustomAttribute ca in md.CustomAttributes)
{
if (ca.Constructor.DeclaringType.Name == "MyFunctionAttribute")
{
Console.WriteLine(md.Name);
ILanguage lan = Cecil.Decompiler.Languages.CSharp.GetLanguage(Cecil.Decompiler.Languages.CSharpVersion.V3);
ILanguageWriter lanWriter = lan.GetWriter(new PlainTextFormatter(streamWriter));
lanWriter.Write(md);

                            Console.WriteLine(sb.ToString());
                        }
                    }
                }
            }
        }

Conflict problem with ExtensionMethod

Environment :

  • VS 2008
  • .Net Framework 3.5 SP1

Step to reproduce :

  • Added Mono.Cecil (0.9.2) as reference in my project
  • Use it in the source code (Github project : ObfuscarStandardAttributeHelper)
  • Compile it, no errors occured
  • Quit Visual Studio
  • Do some work again
  • Try to compile, revert changes, try to compile again

What I Expected :

I expected the project to compile without any issues as it occured the first time.

What I got :

Compilation issues :

Warning :
The predefined type 'System.Runtime.CompilerServices.ExtensionAttribute' is defined in
multiple assemblies in the global alias; using definition from 'c:\xxx\Mono.Cecil.dll'

Error CS0656
Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor'

Workaround :

Each time, you work again to the project, unreference Mono.Cecil, and reference it again

Add nunit to git repository.

Add the required nunit binaries to the git repository and change project reference appropriately.

Cecil depends on NUnit for its unit tests. The current version of NUnit is 2.5.8 however using that results in compile error in Addin.cs using type TestCaseResult. The best I can tell is NUnit 2.4.7 provides the required TestCaseResult type.

If the binaries for NUnit that Cecil requires is included in the git repository then there would not be issues for new people cloning and building the repository.

Accept reader parameters during assembly resolving

For the use case of disassembling with symbol info while using an assembly resolver, a new overload to IAssemblyResolver.Resolve could be provided. The workaround is calling MethodDefinition.ReadSymbols().

Currently, in the BaseAssemblyResolver class (line 95), the reader parameters are hardcoded.

return ModuleDefinition.ReadModule (file, new ReaderParameters { AssemblyResolver = this}).Assembly;

Provide API to read and write raw method bodies

We need an API to parse and emit code without creating costly Instruction instances.

For the reading part, we would move the ILParse functionality from Cecil.Rocks to Cecil.
For the writing part, we would need a context to store the operands to be mapped to actual tokens.

Import of vararg method

It seems that the ImportMethod method of the class Import has a bug: if the method as variable arguments, it defines the CallingConvention with the "&" operator, rather than the "|", so the resulting method doesn't have the vararg flag:

 if (method.IsVarArg())
                reference.CallingConvention &= MethodCallingConvention.VarArg;

should be:

 if (method.IsVarArg())
                reference.CallingConvention |= MethodCallingConvention.VarArg;

Another bug : the Sentinel parameter is not created, because the type.IsTypeSpecification() returns false for this type !

VTable/Native export section support

.NET supports VTable entries and native (pe) exports that invoke static methods as if they were written in a non-managed language. Cecil doesn't expose this feature yet.

Sporadic incorrect offset adjustments when inserting code

Using the following code to inject string interning whenever a string is stored inside a field on a rather large assembly resulted in 4 functions being rendered useless by wrong branch destinations.

                            Instruction instruction = methodBody.Instructions[index];
                            ILProcessor ilProcessor = methodBody.GetILProcessor();
                            if (instruction.OpCode == OpCodes.Stfld)
                            {
                                FieldDefinition fieldDef = instruction.Operand as FieldDefinition;
                                if (fieldDef != null && fieldDef.FieldType.FullName == "System.String")
                                {
                                    if (instruction.Previous.OpCode != OpCodes.Ldstr && instruction.Previous.OpCode != OpCodes.Call && instruction.Previous.Operand != null && !instruction.Previous.Operand.Equals(methRef))
                                    {
                                        ilProcessor.InsertBefore(instruction,
                                                                 ilProcessor.Create(OpCodes.Dup));
                                        ilProcessor.InsertBefore(instruction,
                                                                 ilProcessor.Create(OpCodes.Ldnull));
                                        ilProcessor.InsertBefore(instruction,
                                                                 ilProcessor.Create(OpCodes.Beq, instruction));
                                        ilProcessor.InsertBefore(instruction,
                                                                 ilProcessor.Create(OpCodes.Call, methRef));
                                        index += 4;
                                        retVal = true;
                                    }
                                }
                            }

The branches in consideration are not part of the injected code and show up in PE Verifier as follows

[IL]: Error: jmp / exception into the middle of an instruction.
[IL]: Error: Branch into try block.
[IL]: Error: Branch out of the method.

Especially in the branch out of method, there might be an overflow hapenning as the Offsets are very large. I will try to provide more information as I see it, but cannot share the tested assemblies...

NullReferenceException when calling methodDefinition.Body

MethodDefinition.Body throws a NullReferenceException when called on a method of an interface generated for COM interop.
(_System.Void Microsoft.Office.Interop.Excel._Application::VtblGap1_15())

namespace ciproject4
{
  public class ComInterop
  {
    public static void main(String args)
    {
      var excel = new Microsoft.Office.Interop.Excel.Application();
      excel.Cells[1, 1].Value2 = "Ma feuille Excel";
    }
  }
}

4 interfaces are generated by the compiler for this program :

  • Microsoft.Office.Interop.Excel._Application
  • Microsoft.Office.Interop.Excel.Application
  • Microsoft.Office.Interop.Excel.AppEvents
  • Microsoft.Office.Interop.Excel.AppEvents_Event

_Application declaration looks like that :

[ComImport, TypeIdentifier, Guid("000208D5-0000-0000-C000-000000000046"), CompilerGenerated, DefaultMember("_Default")]
public interface _Application
{
  void _VtblGap1_15();
  Range Cells { [return: MarshalAs(UnmanagedType.Interface)] [DispId(238)] get; }
}

Stacktrace :

at Mono.Cecil.Cil.CodeReader.IsInSection(Int32 rva) in Mono.Cecil.Cil\CodeReader.cs:line 88
at Mono.Cecil.Cil.CodeReader.MoveTo(Int32 rva) in Mono.Cecil.Cil\CodeReader.cs:line 78
at Mono.Cecil.Cil.CodeReader.ReadMethodBody() in Mono.Cecil.Cil\CodeReader.cs:line 93
at Mono.Cecil.Cil.CodeReader.ReadMethodBody(MethodDefinition method) in Mono.Cecil.Cil\CodeReader.cs:line 71
at Mono.Cecil.MetadataReader.ReadMethodBody(MethodDefinition method) in Mono.Cecil\AssemblyReader.cs:line 1830
at Mono.Cecil.MethodDefinition.<get_Body>b__2(MethodDefinition method, MetadataReader reader) in Mono.Cecil\MethodDefinition.cs:line 152
at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func`3 read) in Mono.Cecil\ModuleDefinition.cs:line 704
at Mono.Cecil.MethodDefinition.get_Body() in Mono.Cecil\MethodDefinition.cs:line 152

Cecil don't save correctly jump target

In some cases Cecil don't modify target address of an jump corretly.
So if we have following IL code before modifing file with Cecil we have:
br.s L_008a
After addings to instructions (ldstr & call) some instructions behind this IL the target adress is changed to:
br.s L_ffffff94
Of course this adress is not anymore valid.

To reproduce:

  • Download this: http://www.mediafire.com/?979incjigsc8i6e
  • Open solution and run it in debug mode (in debug folder it should appear a Test.exe)
  • Compare APMVisualisation.exe with Test.exe with SystemReflector

You can also see the error, if you start APMVisualisation.exe -> Load Log -> test.apm -> scroll up and down. And after this do the same with Test.exe (Test.exe is crashing)

System.NotSupportedException, Version not supported: 2.0

Sometimes when I'm calling Resolve on a TypeReference, I get the following exception:

System.NotSupportedException was unhandled
  Message="Version not supported: 2.0"
  Source="Mono.Cecil"
  StackTrace:
       vid Mono.Cecil.BaseAssemblyResolver.GetCorlib(AssemblyNameReference reference)
       vid Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name)
       vid Mono.Cecil.DefaultAssemblyResolver.Resolve(AssemblyNameReference name)
       vid Mono.Cecil.MetadataResolver.Resolve(IAssemblyResolver resolver, TypeReference type)
       vid Mono.Cecil.ModuleDefinition.Resolve(TypeReference type)
       vid Mono.Cecil.TypeReference.Resolve()

It seems that the TypeReference is referencing mscorlib 2.0 instead of mscorlib 2.0.0.0.

Bug in Mono.Cecil.Cil.VariableDefinitionCollection

When calling RemoveAt on Mono.Cecil.Cil.VariableDefinitionCollection, which is inherited from Collection, the variable indices are wrong.

The reason is that Collection::RemoveAt calls Collection::OnRemove before actually removing the item.
As a result, VariableDefinitionCollection::OnRemove calls ComputeIndexes() before the item is actually removed.
As a result, the call to VariableDefinitionCollection::ComputeIndexes() has no effect.

Import type only when writing PE file

It would be great to have Cecil import types only when the assembly is saved, as does Cci Metadata from Microsoft .

It would be easy to determine whether a TypeDefinition must be imported, from its Module property, and then from its Assembly property: if it's not the current Assembly, then the type must be a TypeReference, and the AssemblyReferences must be filled.

How long would it take to modify Cecil to work this way ?
Would there be some performance penalty?

Error in maxstack computation

The maxstack computed for these generated instructions is 1, whereas it must be 5, so the code does not execute. Can you see why ?

.method public static bool TestFilter(bool) cil managed
{
    .maxstack 1
    .locals init (
        [0] bool flag)
    L_0000: newobj instance void [mscorlib]System.Exception::.ctor()
    L_0005: throw 
    L_0006: leave L_001b
    L_000b: pop 
    L_000c: ldarg.0 
    L_000d: endfilter 
    L_000f: ldc.i4.1 
    L_0010: stloc.0 
    L_0011: leave L_001d
    L_0016: leave L_001b
    L_001b: ldc.i4.0 
    L_001c: stloc.0 
    L_001d: ldloc.0 
    L_001e: ret 
    .try L_0000 to L_000b filter L_000b handler L_000f to L_001b
}

Don't know how to create an instruction using a field from an "outer" generic instance type

First assembly :
Test.dll defines a generic type

public class G< T >
{
    public static T F;
}

Second assembly :

I want to define a ldsfld instruction - in a static Main method of a Test class - that uses the F field, but I don't know what context to pass to the ModuleDefinition.Import method in order to import the FieldDefinition :

  • if I pass the current MethodDefinition, that Import fails because the field type is a generic parameter that is not defined in the declaring Test class,
  • if I pass the the G<> TypeDefinition, it fails because the class doesn't belongs to the ModuleDefinition that contains the Test class...

In fact, I have the same importation errors when the G<> class is defined in the same ModuleDefinition, for exactly the same reasons.

Thanks a lot for your help.

Cecil's ExtensionAttribute breaks Code Contracts

This is an obscure one, and there are some workarounds, so it's not exactly a high priority, but:

  1. Compile Cecil against .NET 2.0 (or anything before, it appears, .NET 4.0.) The build process will pack in an implementation of System.Runtime.CompilerServices.ExtensionAttribute.
  2. Download Code Contracts Premium Edition from DevLabs (http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx#5), and start a new project under Visual Studio 2010 Premium-or-above.
  3. Add a reference to your copy of Cecil, and make sure that ExtensionAttribute gets pulled in (define at least one extension method.)

At this point, csc should start complaining about multiple implementations of ExtensionAttribute in the global namespace, as a warning. This is annoying but harmless, until you:

  1. Enable static contract checking in the project properties (Code Contracts -> Perform Static Contract Checking.)

at which point it breaks your build.

Workarounds:

  1. Assign Cecil's reference to a non-global alias, and put an "extern alias [alias]; using [alias]::Mono.Cecil;" at the top of your files. This breaks IntelliSense for Cecil and causes VS to display a bunch of build errors after you've modified your code, until you do a full build.
  2. Recompile Cecil against .NET 4.0 so that the ExtensionAttribute implementation is no longer included.

Please provide public static API to create Instruction instances

It should be possible to write the following method:

    public static void StartWithNop(Mono.Collections.Generic.Collection<Instruction> instructions)
    {
        Instruction nop = // maybe Instruction.Create(OpCodes.Nop, null);
        instructions.Insert(0, nop);
    }

Currently, the only way to create an instruction is via Create methods on ILProcessor. Obviously, this requires creating an instance of ILProcessor and passing it around. As this instance is not actually used by the Create methods, it seems rather pointless to create it and pass it around. Put differently: the Create methods can and should be static, in which case they belong on the Instruction class.

In the example above, the method currently needs and additional parameter, either an ILProcessor or a MethodBody.
In the case of passing an ILProcessor, there's no way that the method can check that the instructions parameter corresponds to the instructions collection hidden inside the ILProcessor (and hidden it is).
In the case of passing the MethodBody, the instructions collection does not need to be passed separately, but an ILProcessor must be created to be able to create an instruction.

Furthermore, creating instructions is the only thing that an ILProcessor is required for. Every other operation offered by ILProcessor is easy to do directly on an instructions collection.

I therefor propose the following:

  • static Create methods are added to the Instruction class
  • Create methods on ILProcessor delegate to Create methods on instruction class
  • Create methods on ILProcessor are marked obsolete

EmbeddedResource and streams

If I create a EmbeddedResource providing a Stream object, the method GetResourceData() doesn't exploit the stream field and fails.

I suggest the following:

public byte [] GetResourceData ()
{
    if (data != null)
        return data;

        // new code starts here
        if (stream != null)
                return ReadFully(stream);
        // new code ends here 

       if (offset.HasValue)
        return reader.GetManagedResourceStream (offset.Value).ToArray ();

    throw new InvalidOperationException ();
}

Here is an implementation of ReadFully (cf http://www.yoda.arachsys.com/csharp/readbinary.html) :

        /// 
        /// Reads data from a stream until the end is reached. The
        /// data is returned as a byte array. An IOException is
        /// thrown if any of the underlying IO calls fail.
        /// 
        /// The stream to read data from
        public static byte[] ReadFully(Stream stream)
        {
            byte[] buffer = new byte[32768];
            using (MemoryStream ms = new MemoryStream())
            {
                while (true)
                {
                    int read = stream.Read(buffer, 0, buffer.Length);
                    if (read <= 0)
                        return ms.ToArray();
                    ms.Write(buffer, 0, read);
                }
            }
        }

Can't rename a generic MethodReference

When renaming a MethodReference from another assembly, the change is not taken into account for methods with generic parameters.

For example, if a get a MethodReference from a call like module.GetMemberReferences.GetMemberReferences().OfType()

  • if the method is not generic and its name is changed, calls to GetMemberReferences give the method with the updated name
  • if the method has generic parameters, calls to GetMemberReferences give the old metadata. Of course, the name is lost when saving the assembly.

The behavior comes from AssemblyReader.GetMemberReference that doesn't cache generic methods.
It seems easy to fix but I don't know the side effects.

pdb round trip loses iterator information

When round tripping a pdb with Mono.Cecil and Mono.Cecil.Pdb, we're losing some custom data about iterators. VS is then unable to debug properly iterator variables.

It looks fixable.

With the CCI code, a PdbFunction has a iteratorClass field, mapping a method to its iterator class. Then the MoveNext method has an iteratorScopes field, which is a collection of scopes.

To encode that back in the PdbWriter, we have to use SetSymAttribute in between OpenMethod and CloseMethod. The PeWriter file of the CCI has the information.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.