Comments
3 comments
-
Hi Sergey,
Thanks for the bug report. I have poped this in our bug tracking system (Ref RR-19) and we will take a look at it over the next month or so and see if we can get the code generation working more accurately in this case.
Regards,
James -
this bug is still there...
-
.method public hidebysig specialname newslot virtual final instance !T get_Item(int32 index) cil managed { .maxstack 8 L_0000: ldarg.1 L_0001: ldarg.0 L_0002: ldfld int32 System.Collections.Generic.List`1<!T>::_size L_0007: blt.un.s L_000e L_0009: call void System.ThrowHelper::ThrowArgumentOutOfRangeException() L_000e: ldarg.0 L_000f: ldfld !0[] System.Collections.Generic.List`1<!T>::_items L_0014: ldarg.1 L_0015: ldelem.any !T L_001a: ret }
It's not exactly 'type casting' that it doesn't support (there is casting in the C# code, and that's how you would represent this code, but there's no conv instruction), but rather the use of unsigned comparisons on what was a signed variable. It should probably be surrounded in unchecked() too [I'm guessing that the MS source code in question was compiled in uncheckd mode... though really reflector should detect when checked vs unchecked are used when it's significant]
For this code the trick is just that, a trick - neither value is expected to ever _actually_ be negative, it's just that the unsigned branch instruction is less expensive (by "one" apparently. one what, we may never know). But in the general case this would be a good thing to fix.
Add comment
Please sign in to leave a comment.
One small example is the List<T> class of .NET Framework.
Let's look at the original Microsoft code:
And please compare with Reflector result:
Reflector skips type casting at the line:
if ((uint) index >= (uint)_size) {
That makes disassembled code erratic.
If we look at IL code, all is correct:
Reflector doesn't translate blt.un.s instruction properly.