2005-03-07 Martin Baulig <martin@ximian.com>
authorMartin Baulig <martin@novell.com>
Mon, 7 Mar 2005 05:55:39 +0000 (05:55 -0000)
committerMartin Baulig <martin@novell.com>
Mon, 7 Mar 2005 05:55:39 +0000 (05:55 -0000)
* generic.cs (Nullable.Unwrap): Implement IMemoryLocation and make
it work if `expr' is not an IMemoryLocation.
(Nullable.Lifted): Implement IMemoryLocation.
(Nullable.LiftedConversion.ResolveUnderlying): Use the correct
target type.

svn path=/trunk/mcs/; revision=41500

mcs/gmcs/ChangeLog
mcs/gmcs/generic.cs

index 93cbc05ebbb9c5873a36fcecffead6160df54993..d132289c3ce585002b44c6ef64e6b2212ba80311 100644 (file)
@@ -1,3 +1,11 @@
+2005-03-07  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (Nullable.Unwrap): Implement IMemoryLocation and make
+       it work if `expr' is not an IMemoryLocation.
+       (Nullable.Lifted): Implement IMemoryLocation.
+       (Nullable.LiftedConversion.ResolveUnderlying): Use the correct
+       target type.
+
 2005-03-05  Martin Baulig  <martin@ximian.com>
 
        * generic.cs (Nullable.Unwrap, Wrap): New protected classes.
index d9e0ab8743f3a5c9e19c0a6a7ead56c93fe79c3e..03ec6b4be852bf108f2bf04075a87063b8621191 100644 (file)
@@ -2314,11 +2314,14 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected class Unwrap : Expression
+               protected class Unwrap : Expression, IMemoryLocation
                {
                        Expression expr;
                        NullableInfo info;
 
+                       LocalTemporary temp;
+                       bool has_temp;
+
                        public Unwrap (Expression expr, Location loc)
                        {
                                this.expr = expr;
@@ -2331,6 +2334,9 @@ namespace Mono.CSharp {
                                if (expr == null)
                                        return null;
 
+                               if (!(expr is IMemoryLocation))
+                                       temp = new LocalTemporary (ec, expr.Type);
+
                                info = new NullableInfo (expr.Type);
                                type = info.UnderlyingType;
                                eclass = expr.eclass;
@@ -2339,14 +2345,27 @@ namespace Mono.CSharp {
 
                        public override void Emit (EmitContext ec)
                        {
-                               ((IMemoryLocation) expr).AddressOf (ec, AddressOp.LoadStore);
+                               AddressOf (ec, AddressOp.LoadStore);
                                ec.ig.EmitCall (OpCodes.Call, info.Value, null);
                        }
 
-                       public void EmitCheck (EmitContext ec)
+                       public void EmitCheck (EmitContext ec, Label label)
                        {
-                               ((IMemoryLocation) expr).AddressOf (ec, AddressOp.LoadStore);
+                               AddressOf (ec, AddressOp.LoadStore);
                                ec.ig.EmitCall (OpCodes.Call, info.HasValue, null);
+                               ec.ig.Emit (OpCodes.Brfalse, label);
+                       }
+
+                       public void AddressOf (EmitContext ec, AddressOp mode)
+                       {
+                               if (temp != null) {
+                                       if (!has_temp) {
+                                               temp.Store (ec);
+                                               has_temp = true;
+                                       }
+                                       temp.AddressOf (ec, AddressOp.LoadStore);
+                               } else
+                                       ((IMemoryLocation) expr).AddressOf (ec, AddressOp.LoadStore);
                        }
                }
 
@@ -2418,7 +2437,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public abstract class Lifted : Expression
+               public abstract class Lifted : Expression, IMemoryLocation
                {
                        Expression expr, underlying, wrap, null_value;
                        Unwrap unwrap;
@@ -2464,8 +2483,7 @@ namespace Mono.CSharp {
                                Label is_null_label = ig.DefineLabel ();
                                Label end_label = ig.DefineLabel ();
 
-                               unwrap.EmitCheck (ec);
-                               ig.Emit (OpCodes.Brfalse, is_null_label);
+                               unwrap.EmitCheck (ec, is_null_label);
 
                                wrap.Emit (ec);
                                ig.Emit (OpCodes.Br, end_label);
@@ -2475,6 +2493,11 @@ namespace Mono.CSharp {
 
                                ig.MarkLabel (end_label);
                        }
+
+                       public void AddressOf (EmitContext ec, AddressOp mode)
+                       {
+                               unwrap.AddressOf (ec, mode);
+                       }
                }
 
                public class LiftedConversion : Lifted
@@ -2494,14 +2517,15 @@ namespace Mono.CSharp {
 
                        protected override Expression ResolveUnderlying (Expression unwrap, EmitContext ec)
                        {
+                               Type type = TypeManager.GetTypeArguments (TargetType) [0];
+
                                if (IsUser) {
-                                       return Convert.UserDefinedConversion (
-                                               ec, unwrap, TargetType, loc, IsExplicit);
+                                       return Convert.UserDefinedConversion (ec, unwrap, type, loc, IsExplicit);
                                } else {
                                        if (IsExplicit)
-                                               return Convert.ExplicitConversion (ec, unwrap, TargetType, loc);
+                                               return Convert.ExplicitConversion (ec, unwrap, type, loc);
                                        else
-                                               return Convert.ImplicitConversion (ec, unwrap, TargetType, loc);
+                                               return Convert.ImplicitConversion (ec, unwrap, type, loc);
                                }
                        }
                }
@@ -2602,15 +2626,11 @@ namespace Mono.CSharp {
                                Label is_null_label = ig.DefineLabel ();
                                Label end_label = ig.DefineLabel ();
 
-                               if (left_unwrap != null) {
-                                       left_unwrap.EmitCheck (ec);
-                                       ig.Emit (OpCodes.Brfalse, is_null_label);
-                               }
+                               if (left_unwrap != null)
+                                       left_unwrap.EmitCheck (ec, is_null_label);
 
-                               if (right_unwrap != null) {
-                                       right_unwrap.EmitCheck (ec);
-                                       ig.Emit (OpCodes.Brfalse, is_null_label);
-                               }
+                               if (right_unwrap != null)
+                                       right_unwrap.EmitCheck (ec, is_null_label);
 
                                underlying.Emit (ec);
                                ig.Emit (OpCodes.Br, end_label);