You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/12/09 13:13:08 UTC

[02/20] ignite git commit: IGNITE-2026: .NET: Fixed stack overflow caused by incorrect unboxing of value types.

IGNITE-2026: .NET: Fixed stack overflow caused by incorrect unboxing of value types.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/efe632b1
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/efe632b1
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/efe632b1

Branch: refs/heads/ignite-1537
Commit: efe632b18e760f699bedee906050f66eabadb077
Parents: 8ca163b
Author: Pavel Tupitsyn <pt...@gridgain.com>
Authored: Tue Dec 8 15:59:23 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Dec 8 15:59:23 2015 +0300

----------------------------------------------------------------------
 .../Binary/BinarySelfTest.cs                    | 67 ++++++++++++++++++++
 .../Impl/Binary/BinaryReflectiveActions.cs      |  4 +-
 .../Impl/Common/DelegateConverter.cs            | 15 +++--
 3 files changed, 78 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/efe632b1/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
index 88328ec..9232665 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
@@ -1028,6 +1028,20 @@ namespace Apache.Ignite.Core.Tests.Binary
             CheckObject(marsh, new OuterObjectType(), new InnerObjectType());
         }
 
+        [Test]
+        public void TestStructsReflective()
+        {
+            var marsh = new Marshaller(new BinaryConfiguration
+            {
+                TypeConfigurations = new[] {new BinaryTypeConfiguration(typeof (ReflectiveStruct))}
+            });
+
+            var obj = new ReflectiveStruct(15, 28.8);
+            var res = marsh.Unmarshal<ReflectiveStruct>(marsh.Marshal(obj));
+
+            Assert.AreEqual(res, obj);
+        }
+
         /**
          * <summary>Test handles.</summary>
          */
@@ -2228,5 +2242,58 @@ namespace Apache.Ignite.Core.Tests.Binary
                 return Foo;
             }
         }
+
+        private struct ReflectiveStruct : IEquatable<ReflectiveStruct>
+        {
+            private readonly int _x;
+            private readonly double _y;
+
+            public ReflectiveStruct(int x, double y)
+            {
+                _x = x;
+                _y = y;
+            }
+
+            public int X
+            {
+                get { return _x; }
+            }
+
+            public double Y
+            {
+                get { return _y; }
+            }
+
+            public bool Equals(ReflectiveStruct other)
+            {
+                return _x == other._x && _y.Equals(other._y);
+            }
+
+            public override bool Equals(object obj)
+            {
+                if (ReferenceEquals(null, obj))
+                    return false;
+
+                return obj is ReflectiveStruct && Equals((ReflectiveStruct) obj);
+            }
+
+            public override int GetHashCode()
+            {
+                unchecked
+                {
+                    return (_x*397) ^ _y.GetHashCode();
+                }
+            }
+
+            public static bool operator ==(ReflectiveStruct left, ReflectiveStruct right)
+            {
+                return left.Equals(right);
+            }
+
+            public static bool operator !=(ReflectiveStruct left, ReflectiveStruct right)
+            {
+                return !left.Equals(right);
+            }
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/efe632b1/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs
index b229898..15509fc 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs
@@ -398,9 +398,7 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             // Assign field value
             var targetParam = Expression.Parameter(typeof(object));
-            var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType);
-            var assignExpr = Expression.Call(DelegateConverter.GetWriteFieldMethod(field), targetParamConverted, 
-                readExpr);
+            var assignExpr = Expression.Call(DelegateConverter.GetWriteFieldMethod(field), targetParam, readExpr);
 
             // Compile and return
             return Expression.Lambda<BinaryReflectiveReadAction>(assignExpr, targetParam, readerParam).Compile();

http://git-wip-us.apache.org/repos/asf/ignite/blob/efe632b1/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs
index d32d475..5d1a4e2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs
@@ -250,20 +250,25 @@ namespace Apache.Ignite.Core.Impl.Common
         {
             Debug.Assert(field != null);
 
-            var module = Assembly.GetExecutingAssembly().GetModules()[0];
+            var declaringType = field.DeclaringType;
 
-            var method = new DynamicMethod(string.Empty, null, new[] { field.DeclaringType, field.FieldType }, module,
-                true);
+            Debug.Assert(declaringType != null);  // static fields are not supported
 
-            var il = method.GetILGenerator();
+            var method = new DynamicMethod(string.Empty, null, new[] { typeof(object), field.FieldType }, 
+                declaringType, true);
 
+            var il = method.GetILGenerator();
+            
             il.Emit(OpCodes.Ldarg_0);
+
+            if (declaringType.IsValueType)
+                il.Emit(OpCodes.Unbox, declaringType);   // modify boxed copy
+
             il.Emit(OpCodes.Ldarg_1);
             il.Emit(OpCodes.Stfld, field);
             il.Emit(OpCodes.Ret);
 
             return method;
         }
-
     }
 }
\ No newline at end of file