On 12 Dec., 05:24, "[email protected]"
<[email protected]> wrote:
> I have found that Cecil often add a modop to
> method paramters when I save assemblies.
I believe I just found the cause of this bug.
In the CIL standard, a Param is an optional sequence of CustomMod
followed by either
BYREF Type
TYPEDBYREF
Type
However, SignatureReader.ReadParameter() will always read CustomMods
first (correct) but then re-read them for BYREF and Type. As I read
the standard this is wrong: neither should re-read the CustomMods. The
BYREF should not, because they have already been read and the parsed
BYREF-token uniquely defines that we're going the "byref" route. And
the Type should not, because it will read the Type-information from
the original curs-position, ie drop what has been looked ahead. It is
as if the code was written at a time where a Type could have aditional
CustomMods, but it doesn't.
The same issue exists in ReadRetType (which is exactly like a Param,
but will also accept VOID) and in a LocalVarSig.
The issue came up when a user of our newly released EQATEC Profiler v2
had problems with a couple of assemblies in a quite large app. These
added modopt's caused signatures to mismatch. After fixing both Param
and ReturnType as in the patch below, the Cecil'ified code finally
worked perfectly, so the patch has been tried out in real life.
cheers,
Richard
-------------
Index: Mono.Cecil.Signatures/SignatureReader.cs
===================================================================
--- Mono.Cecil.Signatures/SignatureReader.cs (revision 121671)
+++ Mono.Cecil.Signatures/SignatureReader.cs (working copy)
@@ -319,9 +319,6 @@
lv.Constraint |= Constraint.Pinned;
else if (current == (int) ElementType.ByRef) {
lv.ByRef = true;
-
- if (lv.CustomMods == null ||
lv.CustomMods.Length == 0)
- lv.CustomMods = ReadCustomMods
(data, start, out start);
} else {
lv.Type = ReadType (data, cursor, out
start);
break;
@@ -370,12 +367,10 @@
case ElementType.ByRef :
rt.TypedByRef = rt.Void = false;
rt.ByRef = true;
- rt.CustomMods =
CombineCustomMods(rt.CustomMods, ReadCustomMods
(data, start, out start));
rt.Type = ReadType (data, start, out start);
break;
default :
rt.TypedByRef = rt.Void = rt.ByRef = false;
- rt.CustomMods = CombineCustomMods
(rt.CustomMods, ReadCustomMods
(data, start, out start));
rt.Type = ReadType (data, curs, out start);
break;
}
@@ -440,21 +435,12 @@
case ElementType.ByRef :
p.TypedByRef = false;
p.ByRef = true;
-
- if (p.CustomMods == null || p.CustomMods.Length
== 0)
- p.CustomMods = ReadCustomMods (data,
start, out start);
-
p.Type = ReadType (data, start, out start);
break;
default :
p.TypedByRef = false;
p.ByRef = false;
-
start = curs;
-
- if (p.CustomMods == null || p.CustomMods.Length
== 0)
- p.CustomMods = ReadCustomMods (data,
start, out start);
-
p.Type = ReadType (data, start, out start);
break;
}
--~--~---------~--~----~------------~-------~--~----~
--
mono-cecil
-~----------~----~----~----~------~----~------~--~---