[Mono-bugs] [Bug 76741][Wis] Changed - No runtime support for
nullable types
bugzilla-daemon at bugzilla.ximian.com
bugzilla-daemon at bugzilla.ximian.com
Mon Nov 21 13:49:26 EST 2005
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by bmaurer at users.sf.net.
http://bugzilla.ximian.com/show_bug.cgi?id=76741
--- shadow/76741 2005-11-21 12:09:38.000000000 -0500
+++ shadow/76741.tmp.28049 2005-11-21 13:49:26.000000000 -0500
@@ -117,6 +117,121 @@
(both apply to references and since Nullable<T> is a struct and is
never boxed itself it seems there isn't much to do here).
As for unbox, add a different opcode, no need to clutter the existing one.
BTW, please post in bug reports about generics, the IL code produced
by the MS compiler for the specific issues, like in this case
box/unbox etc, since having the C# code is quite useless.
+
+------- Additional Comments From bmaurer at users.sf.net 2005-11-21 13:49 -------
+IL code:
+
+ static T Z <T> (object o) {
+ return (T) o;
+ }
+
+.method private hidebysig static !!T Z<T>(object o) cil managed
+{
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: unbox.any !!T
+ IL_0006: ret
+} // end of method X::Z
+
+ static int? Z (object o) {
+ return (int?) o;
+ }
+
+.method private hidebysig static valuetype
+[mscorlib]System.Nullable`1<int32>
+ Z(object o) cil managed
+{
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: unbox.any valuetype [mscorlib]System.Nullable`1<int32>
+ IL_0006: ret
+} // end of method X::Z
+
+
+This is interesting that msft chooses to use unbox.any. I think they
+are doing this as an optimization: unbox.any includes an ldobj. Even
+when I use DateTime -- a completely non-generic class. However, the
+same concepts seems to apply to unbox and unbox.any
+
+
+One interesting case which I found, that I think may be a bug in
+Microsoft's impl is:
+
+enum E {
+ A, B, C
+}
+
+class X {
+ static void Main ()
+ {
+ object o = 1;
+
+ System.Console.WriteLine ((int) o);
+ System.Console.WriteLine ((int?) o);
+ System.Console.WriteLine ((E) o);
+ System.Console.WriteLine ((E?) o);
+ }
+}
+
+On Microsoft's jit, this prints
+1
+1
+B
+<invalid cast exception>
+
+So, the unbox on E is different from the unbox on E?
+
+The IL code generated for this case is:
+
+.method private hidebysig static void Main() cil managed
+{
+ .entrypoint
+ // Code size 67 (0x43)
+ .maxstack 1
+ .locals init (object V_0)
+ IL_0000: ldc.i4.1
+ IL_0001: box [mscorlib]System.Int32
+ IL_0006: stloc.0
+ IL_0007: ldloc.0
+ IL_0008: unbox.any [mscorlib]System.Int32
+ IL_000d: call void [mscorlib]System.Console::WriteLine(int32)
+ IL_0012: ldloc.0
+ IL_0013: unbox.any valuetype [mscorlib]System.Nullable`1<int32>
+ IL_0018: box valuetype [mscorlib]System.Nullable`1<int32>
+ IL_001d: call void [mscorlib]System.Console::WriteLine(object)
+ IL_0022: ldloc.0
+ IL_0023: unbox.any E
+ IL_0028: box E
+ IL_002d: call void [mscorlib]System.Console::WriteLine(object)
+ IL_0032: ldloc.0
+ IL_0033: unbox.any valuetype [mscorlib]System.Nullable`1<valuetype E>
+ IL_0038: box valuetype [mscorlib]System.Nullable`1<valuetype E>
+ IL_003d: call void [mscorlib]System.Console::WriteLine(object)
+ IL_0042: ret
+} // end of method X::Main
+
+
+Zoltan: the box/unbox opcodes are actually branchless today
+
+Paolo: the idea for castclass/isinst is great. Am still a bit confused
+about how to implement the branches for box and unbox. For box, I need
+to transform box T? into:
+
+if t == null
+ ret = null
+else
+ ret = box (t.value)
+
+The box operation is too complex to emit in burg (because it involves
+an allocation. So, I'd have to emit multiple new opcodes. But this
+would involve adding branches inside basic blocks earlier than we've
+ever done before, which I guess might alter some optimizations. This
+is why I was thinking about taking advantage of the inliner: it would
+split basic blocks for us.
+
+I think unbox is a bit easier, because it can be done completely in burg.
More information about the mono-bugs
mailing list