Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vector2<T> #1

Open
wants to merge 11 commits into
base: generic-vector
Choose a base branch
from

Conversation

john-h-k
Copy link

Will add details in a sec when on phone

@HurricanKai HurricanKai mentioned this pull request Jun 12, 2020
Will add details in a sec when I am on my phone
@john-h-k
Copy link
Author

think i've fixed the commits now

@john-h-k john-h-k changed the title Add generic numeric Vector2<T> Jun 16, 2020
@@ -7,6 +7,118 @@

namespace System.Numerics
{
public readonly struct Vector2<T> : IEquatable<Vector2<T>>, IFormattable
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to need to be autogenerated via the ref assembly generator. Won't block on this though.

@@ -0,0 +1 @@
using Matrix3x2Double = System.Numerics.Matrix3x2<System.Double>;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to not use using like this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is it becomes much hard to generate tests without it, as you can't simply insert the type name into the test name because <> are not legal chars in method name ofc

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, so use two different replacements. One is the name with <> and one is the name without

{
public partial class Vector2Tests
{
[Fact] public void Vector2CopyToTest() { Vector2 v1 = new Vector2(2.0f, 3.0f); var a = new Single[3]; var b = new Single[2]; Assert.Throws<ArgumentOutOfRangeException>(() => v1.CopyTo(a, -1)); Assert.Throws<ArgumentOutOfRangeException>(() => v1.CopyTo(a, a.Length)); v1.CopyTo(a, 1); v1.CopyTo(b); Assert.Equal(0.0, a[0]); Assert.Equal(2.0, a[1]); Assert.Equal(3.0, a[2]); Assert.Equal(2.0, b[0]); Assert.Equal(3.0, b[1]); } [Fact] public void Vector2GetHashCodeTest() { Vector2 v1 = new Vector2(2.0f, 3.0f); Vector2 v2 = new Vector2(2.0f, 3.0f); Vector2 v3 = new Vector2(3.0f, 2.0f); Assert.Equal(v1.GetHashCode(), v1.GetHashCode()); Assert.Equal(v1.GetHashCode(), v2.GetHashCode()); Assert.NotEqual(v1.GetHashCode(), v3.GetHashCode()); Vector2 v4 = new Vector2(0.0f, 0.0f); Vector2 v6 = new Vector2(1.0f, 0.0f); Vector2 v7 = new Vector2(0.0f, 1.0f); Vector2 v8 = new Vector2(1.0f, 1.0f); Assert.NotEqual(v4.GetHashCode(), v6.GetHashCode()); Assert.NotEqual(v4.GetHashCode(), v7.GetHashCode()); Assert.NotEqual(v4.GetHashCode(), v8.GetHashCode()); Assert.NotEqual(v7.GetHashCode(), v6.GetHashCode()); Assert.NotEqual(v8.GetHashCode(), v6.GetHashCode()); Assert.NotEqual(v8.GetHashCode(), v7.GetHashCode()); } [Fact] public void Vector2ToStringTest() { string separator = CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; CultureInfo enUsCultureInfo = new CultureInfo("en-US"); Vector2 v1 = new Vector2(2.0f, 3.0f); string v1str = v1.ToString(); string expectedv1 = string.Format(CultureInfo.CurrentCulture , "<{1:G}{0} {2:G}>" , new object[] { separator, 2, 3 }); Assert.Equal(expectedv1, v1str); string v1strformatted = v1.ToString("c", CultureInfo.CurrentCulture); string expectedv1formatted = string.Format(CultureInfo.CurrentCulture , "<{1:c}{0} {2:c}>" , new object[] { separator, 2, 3 }); Assert.Equal(expectedv1formatted, v1strformatted); string v2strformatted = v1.ToString("c", enUsCultureInfo); string expectedv2formatted = string.Format(enUsCultureInfo , "<{1:c}{0} {2:c}>" , new object[] { enUsCultureInfo.NumberFormat.NumberGroupSeparator, 2, 3 }); Assert.Equal(expectedv2formatted, v2strformatted); string v3strformatted = v1.ToString("c"); string expectedv3formatted = string.Format(CultureInfo.CurrentCulture , "<{1:c}{0} {2:c}>" , new object[] { separator, 2, 3 }); Assert.Equal(expectedv3formatted, v3strformatted); } // A test for Distance (Vector2, Vector2) [Fact] public void Vector2DistanceTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(3.0f, 4.0f); Single expected = (Single)System.Math.Sqrt(8); Single actual; actual = Vector2.Distance(a, b); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Distance did not return the expected value."); } // A test for Distance (Vector2, Vector2) // Distance from the same point [Fact] public void Vector2DistanceTest2() { Vector2 a = new Vector2(1.051f, 2.05f); Vector2 b = new Vector2(1.051f, 2.05f); Single actual = Vector2.Distance(a, b); Assert.Equal(0.0f, actual); } // A test for DistanceSquared (Vector2, Vector2) [Fact] public void Vector2DistanceSquaredTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(3.0f, 4.0f); Single expected = 8.0f; Single actual; actual = Vector2.DistanceSquared(a, b); Assert.True(MathHelper.Equal(expected, actual), "Vector2.DistanceSquared did not return the expected value."); } // A test for Dot (Vector2, Vector2) [Fact] public void Vector2DotTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(3.0f, 4.0f); Single expected = 11.0f; Single actual; actual = Vector2.Dot(a, b); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Dot did not return the expected value."); } // A test for Dot (Vector2, Vector2) // Dot test for perpendicular vector [Fact] public void Vector2DotTest1() { Vector2 a = new Vector2(1.55f, 1.55f); Vector2 b = new Vector2(-1.55f, 1.55f); Single expected = 0.0f; Single actual = Vector2.Dot(a, b); Assert.Equal(expected, actual); } // A test for Dot (Vector2, Vector2) // Dot test with special Single values [Fact] public void Vector2DotTest2() { Vector2 a = new Vector2(Single.MinValue, Single.MinValue); Vector2 b = new Vector2(Single.MaxValue, Single.MaxValue); Single actual = Vector2.Dot(a, b); Assert.True(Single.IsNegativeInfinity(actual), "Vector2.Dot did not return the expected value."); } // A test for Length () [Fact] public void Vector2LengthTest() { Vector2 a = new Vector2(2.0f, 4.0f); Vector2 target = a; Single expected = (Single)System.Math.Sqrt(20); Single actual; actual = target.Length(); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Length did not return the expected value."); } // A test for Length () // Length test where length is zero [Fact] public void Vector2LengthTest1() { Vector2 target = Vector2.Zero; Single expected = 0.0f; Single actual; actual = target.Length(); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Length did not return the expected value."); } // A test for LengthSquared () [Fact] public void Vector2LengthSquaredTest() { Vector2 a = new Vector2(2.0f, 4.0f); Vector2 target = a; Single expected = 20.0f; Single actual; actual = target.LengthSquared(); Assert.True(MathHelper.Equal(expected, actual), "Vector2.LengthSquared did not return the expected value."); } // A test for LengthSquared () // LengthSquared test where the result is zero [Fact] public void Vector2LengthSquaredTest1() { Vector2 a = new Vector2(0.0f, 0.0f); Single expected = 0.0f; Single actual = a.LengthSquared(); Assert.Equal(expected, actual); } // A test for Min (Vector2, Vector2) [Fact] public void Vector2MinTest() { Vector2 a = new Vector2(-1.0f, 4.0f); Vector2 b = new Vector2(2.0f, 1.0f); Vector2 expected = new Vector2(-1.0f, 1.0f); Vector2 actual; actual = Vector2.Min(a, b); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Min did not return the expected value."); } [Fact] public void Vector2MinMaxCodeCoverageTest() { Vector2 min = new Vector2(0, 0); Vector2 max = new Vector2(1, 1); Vector2 actual; // Min. actual = Vector2.Min(min, max); Assert.Equal(actual, min); actual = Vector2.Min(max, min); Assert.Equal(actual, min); // Max. actual = Vector2.Max(min, max); Assert.Equal(actual, max); actual = Vector2.Max(max, min); Assert.Equal(actual, max); } // A test for Max (Vector2, Vector2) [Fact] public void Vector2MaxTest() { Vector2 a = new Vector2(-1.0f, 4.0f); Vector2 b = new Vector2(2.0f, 1.0f); Vector2 expected = new Vector2(2.0f, 4.0f); Vector2 actual; actual = Vector2.Max(a, b); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Max did not return the expected value."); } // A test for Clamp (Vector2, Vector2, Vector2) [Fact] public void Vector2ClampTest() { Vector2 a = new Vector2(0.5f, 0.3f); Vector2 min = new Vector2(0.0f, 0.1f); Vector2 max = new Vector2(1.0f, 1.1f); // Normal case. // Case N1: specified value is in the range. Vector2 expected = new Vector2(0.5f, 0.3f); Vector2 actual = Vector2.Clamp(a, min, max); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Clamp did not return the expected value."); // Normal case. // Case N2: specified value is bigger than max value. a = new Vector2(2.0f, 3.0f); expected = max; actual = Vector2.Clamp(a, min, max); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Clamp did not return the expected value."); // Case N3: specified value is smaller than max value. a = new Vector2(-1.0f, -2.0f); expected = min; actual = Vector2.Clamp(a, min, max); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Clamp did not return the expected value."); // Case N4: combination case. a = new Vector2(-2.0f, 4.0f); expected = new Vector2(min.X, max.Y); actual = Vector2.Clamp(a, min, max); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Clamp did not return the expected value."); // User specified min value is bigger than max value. max = new Vector2(0.0f, 0.1f); min = new Vector2(1.0f, 1.1f); // Case W1: specified value is in the range. a = new Vector2(0.5f, 0.3f); expected = max; actual = Vector2.Clamp(a, min, max); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Clamp did not return the expected value."); // Normal case. // Case W2: specified value is bigger than max and min value. a = new Vector2(2.0f, 3.0f); expected = max; actual = Vector2.Clamp(a, min, max); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Clamp did not return the expected value."); // Case W3: specified value is smaller than min and max value. a = new Vector2(-1.0f, -2.0f); expected = max; actual = Vector2.Clamp(a, min, max); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Clamp did not return the expected value."); } // A test for Lerp (Vector2, Vector2, Single) [Fact] public void Vector2LerpTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(3.0f, 4.0f); Single t = 0.5f; Vector2 expected = new Vector2(2.0f, 3.0f); Vector2 actual; actual = Vector2.Lerp(a, b, t); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Lerp did not return the expected value."); } // A test for Lerp (Vector2, Vector2, Single) // Lerp test with factor zero [Fact] public void Vector2LerpTest1() { Vector2 a = new Vector2(0.0f, 0.0f); Vector2 b = new Vector2(3.18f, 4.25f); Single t = 0.0f; Vector2 expected = Vector2.Zero; Vector2 actual = Vector2.Lerp(a, b, t); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Lerp did not return the expected value."); } // A test for Lerp (Vector2, Vector2, Single) // Lerp test with factor one [Fact] public void Vector2LerpTest2() { Vector2 a = new Vector2(0.0f, 0.0f); Vector2 b = new Vector2(3.18f, 4.25f); Single t = 1.0f; Vector2 expected = new Vector2(3.18f, 4.25f); Vector2 actual = Vector2.Lerp(a, b, t); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Lerp did not return the expected value."); } // A test for Lerp (Vector2, Vector2, Single) // Lerp test with factor > 1 [Fact] public void Vector2LerpTest3() { Vector2 a = new Vector2(0.0f, 0.0f); Vector2 b = new Vector2(3.18f, 4.25f); Single t = 2.0f; Vector2 expected = b * 2.0f; Vector2 actual = Vector2.Lerp(a, b, t); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Lerp did not return the expected value."); } // A test for Lerp (Vector2, Vector2, Single) // Lerp test with factor < 0 [Fact] public void Vector2LerpTest4() { Vector2 a = new Vector2(0.0f, 0.0f); Vector2 b = new Vector2(3.18f, 4.25f); Single t = -2.0f; Vector2 expected = -(b * 2.0f); Vector2 actual = Vector2.Lerp(a, b, t); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Lerp did not return the expected value."); } // A test for Lerp (Vector2, Vector2, Single) // Lerp test with special Single value [Fact] public void Vector2LerpTest5() { Vector2 a = new Vector2(45.67f, 90.0f); Vector2 b = new Vector2(Single.PositiveInfinity, Single.NegativeInfinity); Single t = 0.408f; Vector2 actual = Vector2.Lerp(a, b, t); Assert.True(Single.IsPositiveInfinity(actual.X), "Vector2.Lerp did not return the expected value."); Assert.True(Single.IsNegativeInfinity(actual.Y), "Vector2.Lerp did not return the expected value."); } // A test for Lerp (Vector2, Vector2, Single) // Lerp test from the same point [Fact] public void Vector2LerpTest6() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(1.0f, 2.0f); Single t = 0.5f; Vector2 expected = new Vector2(1.0f, 2.0f); Vector2 actual = Vector2.Lerp(a, b, t); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Lerp did not return the expected value."); } // A test for Lerp (Vector2, Vector2, Single) // Lerp test with values known to be innacurate with the old lerp impl [Fact] public void Vector2LerpTest7() { Vector2 a = new Vector2(0.44728136f); Vector2 b = new Vector2(0.46345946f); Single t = 0.26402435f; Vector2 expected = new Vector2(0.45155275f); Vector2 actual = Vector2.Lerp(a, b, t); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Lerp did not return the expected value."); } // A test for Lerp (Vector2, Vector2, Single) // Lerp test with values known to be innacurate with the old lerp impl // (Old code incorrectly gets 0.33333588) [Fact] public void Vector2LerpTest8() { Vector2 a = new Vector2(-100); Vector2 b = new Vector2(0.33333334f); Single t = 1f; Vector2 expected = new Vector2(0.33333334f); Vector2 actual = Vector2.Lerp(a, b, t); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Lerp did not return the expected value."); } // // A test for Transform(Vector2, Matrix4x4) // [Fact] // public void Vector2TransformTest() // { // Vector2 v = new Vector2(1.0f, 2.0f); // Matrix4x4 m = // Matrix4x4.CreateRotationX(MathHelper.ToRadians(30.0f)) * // Matrix4x4.CreateRotationY(MathHelper.ToRadians(30.0f)) * // Matrix4x4.CreateRotationZ(MathHelper.ToRadians(30.0f)); // m.M41 = 10.0f; // m.M42 = 20.0f; // m.M43 = 30.0f; // Vector2 expected = new Vector2(10.316987f, 22.183012f); // Vector2 actual; // actual = Vector2.Transform(v, m); // Assert.True(MathHelper.Equal(expected, actual), "Vector2.Transform did not return the expected value."); // } // // A test for Transform(Vector2, Matrix3x2) // [Fact] // public void Vector2Transform3x2Test() // { // Vector2 v = new Vector2(1.0f, 2.0f); // Matrix3x2 m = Matrix3x2.CreateRotation(MathHelper.ToRadians(30.0f)); // m.M31 = 10.0f; // m.M32 = 20.0f; // Vector2 expected = new Vector2(9.866025f, 22.23205f); // Vector2 actual; // actual = Vector2.Transform(v, m); // Assert.True(MathHelper.Equal(expected, actual), "Vector2.Transform did not return the expected value."); // } // // A test for TransformNormal (Vector2, Matrix4x4) // [Fact] // public void Vector2TransformNormalTest() // { // Vector2 v = new Vector2(1.0f, 2.0f); // Matrix4x4 m = // Matrix4x4.CreateRotationX(MathHelper.ToRadians(30.0f)) * // Matrix4x4.CreateRotationY(MathHelper.ToRadians(30.0f)) * // Matrix4x4.CreateRotationZ(MathHelper.ToRadians(30.0f)); // m.M41 = 10.0f; // m.M42 = 20.0f; // m.M43 = 30.0f; // Vector2 expected = new Vector2(0.3169873f, 2.18301272f); // Vector2 actual; // actual = Vector2.TransformNormal(v, m); // Assert.True(MathHelper.Equal(expected, actual), "Vector2.Tranform did not return the expected value."); // } // // A test for TransformNormal (Vector2, Matrix3x2) // [Fact] // public void Vector2TransformNormal3x2Test() // { // Vector2 v = new Vector2(1.0f, 2.0f); // Matrix3x2 m = Matrix3x2.CreateRotation(MathHelper.ToRadians(30.0f)); // m.M31 = 10.0f; // m.M32 = 20.0f; // Vector2 expected = new Vector2(-0.133974612f, 2.232051f); // Vector2 actual; // actual = Vector2.TransformNormal(v, m); // Assert.True(MathHelper.Equal(expected, actual), "Vector2.Transform did not return the expected value."); // } // // A test for Transform (Vector2, Quaternion) // [Fact] // public void Vector2TransformByQuaternionTest() // { // Vector2 v = new Vector2(1.0f, 2.0f); // Matrix4x4 m = // Matrix4x4.CreateRotationX(MathHelper.ToRadians(30.0f)) * // Matrix4x4.CreateRotationY(MathHelper.ToRadians(30.0f)) * // Matrix4x4.CreateRotationZ(MathHelper.ToRadians(30.0f)); // Quaternion q = Quaternion.CreateFromRotationMatrix(m); // Vector2 expected = Vector2.Transform(v, m); // Vector2 actual = Vector2.Transform(v, q); // Assert.True(MathHelper.Equal(expected, actual), "Vector2.Transform did not return the expected value."); // } // // A test for Transform (Vector2, Quaternion) // // Transform Vector2 with zero quaternion // [Fact] // public void Vector2TransformByQuaternionTest1() // { // Vector2 v = new Vector2(1.0f, 2.0f); // Quaternion q = new Quaternion(); // Vector2 expected = v; // Vector2 actual = Vector2.Transform(v, q); // Assert.True(MathHelper.Equal(expected, actual), "Vector2.Transform did not return the expected value."); // } // // A test for Transform (Vector2, Quaternion) // // Transform Vector2 with identity quaternion // [Fact] // public void Vector2TransformByQuaternionTest2() // { // Vector2 v = new Vector2(1.0f, 2.0f); // Quaternion q = Quaternion.Identity; // Vector2 expected = v; // Vector2 actual = Vector2.Transform(v, q); // Assert.True(MathHelper.Equal(expected, actual), "Vector2.Transform did not return the expected value."); // } // A test for Normalize (Vector2) [Fact] public void Vector2NormalizeTest() { Vector2 a = new Vector2(2.0f, 3.0f); Vector2 expected = new Vector2(0.554700196225229122018341733457f, 0.8320502943378436830275126001855f); Vector2 actual; actual = Vector2.Normalize(a); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Normalize did not return the expected value."); } // A test for Normalize (Vector2) // Normalize zero length vector [Fact] public void Vector2NormalizeTest1() { Vector2 a = new Vector2(); // no parameter, default to 0.0f Vector2 actual = Vector2.Normalize(a); Assert.True(Single.IsNaN(actual.X) && Single.IsNaN(actual.Y), "Vector2.Normalize did not return the expected value."); } // A test for Normalize (Vector2) // Normalize infinite length vector [Fact] public void Vector2NormalizeTest2() { Vector2 a = new Vector2(Single.MaxValue, Single.MaxValue); Vector2 actual = Vector2.Normalize(a); Vector2 expected = new Vector2(0, 0); Assert.Equal(expected, actual); } // A test for operator - (Vector2) [Fact] public void Vector2UnaryNegationTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 expected = new Vector2(-1.0f, -2.0f); Vector2 actual; actual = -a; Assert.True(MathHelper.Equal(expected, actual), "Vector2.operator - did not return the expected value."); } // A test for operator - (Vector2) // Negate test with special Single value [Fact] public void Vector2UnaryNegationTest1() { Vector2 a = new Vector2(Single.PositiveInfinity, Single.NegativeInfinity); Vector2 actual = -a; Assert.True(Single.IsNegativeInfinity(actual.X), "Vector2.operator - did not return the expected value."); Assert.True(Single.IsPositiveInfinity(actual.Y), "Vector2.operator - did not return the expected value."); } // A test for operator - (Vector2) // Negate test with special Single value [Fact] public void Vector2UnaryNegationTest2() { Vector2 a = new Vector2(Single.NaN, 0.0f); Vector2 actual = -a; Assert.True(Single.IsNaN(actual.X), "Vector2.operator - did not return the expected value."); Assert.True(Single.Equals(0.0f, actual.Y), "Vector2.operator - did not return the expected value."); } // A test for operator - (Vector2, Vector2) [Fact] public void Vector2SubtractionTest() { Vector2 a = new Vector2(1.0f, 3.0f); Vector2 b = new Vector2(2.0f, 1.5f); Vector2 expected = new Vector2(-1.0f, 1.5f); Vector2 actual; actual = a - b; Assert.True(MathHelper.Equal(expected, actual), "Vector2.operator - did not return the expected value."); } // A test for operator * (Vector2, Single) [Fact] public void Vector2MultiplyOperatorTest() { Vector2 a = new Vector2(2.0f, 3.0f); const Single factor = 2.0f; Vector2 expected = new Vector2(4.0f, 6.0f); Vector2 actual; actual = a * factor; Assert.True(MathHelper.Equal(expected, actual), "Vector2.operator * did not return the expected value."); } // A test for operator * (Single, Vector2) [Fact] public void Vector2MultiplyOperatorTest2() { Vector2 a = new Vector2(2.0f, 3.0f); const Single factor = 2.0f; Vector2 expected = new Vector2(4.0f, 6.0f); Vector2 actual; actual = factor * a; Assert.True(MathHelper.Equal(expected, actual), "Vector2.operator * did not return the expected value."); } // A test for operator * (Vector2, Vector2) [Fact] public void Vector2MultiplyOperatorTest3() { Vector2 a = new Vector2(2.0f, 3.0f); Vector2 b = new Vector2(4.0f, 5.0f); Vector2 expected = new Vector2(8.0f, 15.0f); Vector2 actual; actual = a * b; Assert.True(MathHelper.Equal(expected, actual), "Vector2.operator * did not return the expected value."); } // A test for operator / (Vector2, Single) [Fact] public void Vector2DivisionTest() { Vector2 a = new Vector2(2.0f, 3.0f); Single div = 2.0f; Vector2 expected = new Vector2(1.0f, 1.5f); Vector2 actual; actual = a / div; Assert.True(MathHelper.Equal(expected, actual), "Vector2.operator / did not return the expected value."); } // A test for operator / (Vector2, Vector2) [Fact] public void Vector2DivisionTest1() { Vector2 a = new Vector2(2.0f, 3.0f); Vector2 b = new Vector2(4.0f, 5.0f); Vector2 expected = new Vector2(2.0f / 4.0f, 3.0f / 5.0f); Vector2 actual; actual = a / b; Assert.True(MathHelper.Equal(expected, actual), "Vector2.operator / did not return the expected value."); } // A test for operator / (Vector2, Single) // Divide by zero [Fact] public void Vector2DivisionTest2() { Vector2 a = new Vector2(-2.0f, 3.0f); Single div = 0.0f; Vector2 actual = a / div; Assert.True(Single.IsNegativeInfinity(actual.X), "Vector2.operator / did not return the expected value."); Assert.True(Single.IsPositiveInfinity(actual.Y), "Vector2.operator / did not return the expected value."); } // A test for operator / (Vector2, Vector2) // Divide by zero [Fact] public void Vector2DivisionTest3() { Vector2 a = new Vector2(0.047f, -3.0f); Vector2 b = new Vector2(); Vector2 actual = a / b; Assert.True(Single.IsInfinity(actual.X), "Vector2.operator / did not return the expected value."); Assert.True(Single.IsInfinity(actual.Y), "Vector2.operator / did not return the expected value."); } // A test for operator + (Vector2, Vector2) [Fact] public void Vector2AdditionTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(3.0f, 4.0f); Vector2 expected = new Vector2(4.0f, 6.0f); Vector2 actual; actual = a + b; Assert.True(MathHelper.Equal(expected, actual), "Vector2.operator + did not return the expected value."); } // A test for Vector2 (Single, Single) [Fact] public void Vector2ConstructorTest() { Single x = 1.0f; Single y = 2.0f; Vector2 target = new Vector2(x, y); Assert.True(MathHelper.Equal(target.X, x) && MathHelper.Equal(target.Y, y), "Vector2(x,y) constructor did not return the expected value."); } // A test for Vector2 () // Constructor with no parameter [Fact] public void Vector2ConstructorTest2() { Vector2 target = new Vector2(); Assert.Equal(0.0f, target.X); Assert.Equal(0.0f, target.Y); } // A test for Vector2 (Single, Single) // Constructor with special Singleing values [Fact] public void Vector2ConstructorTest3() { Vector2 target = new Vector2(Single.NaN, Single.MaxValue); Assert.Equal(target.X, Single.NaN); Assert.Equal(target.Y, Single.MaxValue); } // A test for Vector2 (Single) [Fact] public void Vector2ConstructorTest4() { Single value = 1.0f; Vector2 target = new Vector2(value); Vector2 expected = new Vector2(value, value); Assert.Equal(expected, target); value = 2.0f; target = new Vector2(value); expected = new Vector2(value, value); Assert.Equal(expected, target); } // A test for Add (Vector2, Vector2) [Fact] public void Vector2AddTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(5.0f, 6.0f); Vector2 expected = new Vector2(6.0f, 8.0f); Vector2 actual; actual = Vector2.Add(a, b); Assert.Equal(expected, actual); } // A test for Divide (Vector2, Single) [Fact] public void Vector2DivideTest() { Vector2 a = new Vector2(1.0f, 2.0f); Single div = 2.0f; Vector2 expected = new Vector2(0.5f, 1.0f); Vector2 actual; actual = Vector2.Divide(a, div); Assert.Equal(expected, actual); } // A test for Divide (Vector2, Vector2) [Fact] public void Vector2DivideTest1() { Vector2 a = new Vector2(1.0f, 6.0f); Vector2 b = new Vector2(5.0f, 2.0f); Vector2 expected = new Vector2(1.0f / 5.0f, 6.0f / 2.0f); Vector2 actual; actual = Vector2.Divide(a, b); Assert.Equal(expected, actual); } // A test for Equals (object) [Fact] public void Vector2EqualsTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(1.0f, 2.0f); // case 1: compare between same values object obj = b; bool expected = true; bool actual = a.Equals(obj); Assert.Equal(expected, actual); // case 2: compare between different values b = new Vector2(b.X, 10); obj = b; expected = false; actual = a.Equals(obj); Assert.Equal(expected, actual); // case 3: compare between different types. obj = new Quaternion(); expected = false; actual = a.Equals(obj); Assert.Equal(expected, actual); // case 3: compare against null. obj = null; expected = false; actual = a.Equals(obj); Assert.Equal(expected, actual); } // A test for Multiply (Vector2, Single) [Fact] public void Vector2MultiplyTest() { Vector2 a = new Vector2(1.0f, 2.0f); const Single factor = 2.0f; Vector2 expected = new Vector2(2.0f, 4.0f); Vector2 actual = Vector2.Multiply(a, factor); Assert.Equal(expected, actual); } // A test for Multiply (Single, Vector2) [Fact] public void Vector2MultiplyTest2() { Vector2 a = new Vector2(1.0f, 2.0f); const Single factor = 2.0f; Vector2 expected = new Vector2(2.0f, 4.0f); Vector2 actual = Vector2.Multiply(factor, a); Assert.Equal(expected, actual); } // A test for Multiply (Vector2, Vector2) [Fact] public void Vector2MultiplyTest3() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(5.0f, 6.0f); Vector2 expected = new Vector2(5.0f, 12.0f); Vector2 actual; actual = Vector2.Multiply(a, b); Assert.Equal(expected, actual); } // A test for Negate (Vector2) [Fact] public void Vector2NegateTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 expected = new Vector2(-1.0f, -2.0f); Vector2 actual; actual = Vector2.Negate(a); Assert.Equal(expected, actual); } // A test for operator != (Vector2, Vector2) [Fact] public void Vector2InequalityTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(1.0f, 2.0f); // case 1: compare between same values bool expected = false; bool actual = a != b; Assert.Equal(expected, actual); // case 2: compare between different values b = new Vector2(b.X, 10); expected = true; actual = a != b; Assert.Equal(expected, actual); } // A test for operator == (Vector2, Vector2) [Fact] public void Vector2EqualityTest() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(1.0f, 2.0f); // case 1: compare between same values bool expected = true; bool actual = a == b; Assert.Equal(expected, actual); // case 2: compare between different values b = new Vector2(b.X, 10); expected = false; actual = a == b; Assert.Equal(expected, actual); } // A test for Subtract (Vector2, Vector2) [Fact] public void Vector2SubtractTest() { Vector2 a = new Vector2(1.0f, 6.0f); Vector2 b = new Vector2(5.0f, 2.0f); Vector2 expected = new Vector2(-4.0f, 4.0f); Vector2 actual; actual = Vector2.Subtract(a, b); Assert.Equal(expected, actual); } // A test for UnitX [Fact] public void Vector2UnitXTest() { Vector2 val = new Vector2(1.0f, 0.0f); Assert.Equal(val, Vector2.UnitX); } // A test for UnitY [Fact] public void Vector2UnitYTest() { Vector2 val = new Vector2(0.0f, 1.0f); Assert.Equal(val, Vector2.UnitY); } // A test for One [Fact] public void Vector2OneTest() { Vector2 val = new Vector2(1.0f, 1.0f); Assert.Equal(val, Vector2.One); } // A test for Zero [Fact] public void Vector2ZeroTest() { Vector2 val = new Vector2(0.0f, 0.0f); Assert.Equal(val, Vector2.Zero); } // A test for Equals (Vector2) [Fact] public void Vector2EqualsTest1() { Vector2 a = new Vector2(1.0f, 2.0f); Vector2 b = new Vector2(1.0f, 2.0f); // case 1: compare between same values bool expected = true; bool actual = a.Equals(b); Assert.Equal(expected, actual); // case 2: compare between different values b = new Vector2(b.X, 10); expected = false; actual = a.Equals(b); Assert.Equal(expected, actual); } // A test for Vector2 comparison involving NaN values [Fact] public void Vector2EqualsNanTest() { Vector2 a = new Vector2(Single.NaN, 0); Vector2 b = new Vector2(0, Single.NaN); Assert.False(a == Vector2.Zero); Assert.False(b == Vector2.Zero); Assert.True(a != Vector2.Zero); Assert.True(b != Vector2.Zero); Assert.False(a.Equals(Vector2.Zero)); Assert.False(b.Equals(Vector2.Zero)); // Counterintuitive result - IEEE rules for NaN comparison are weird! Assert.False(a.Equals(a)); Assert.False(b.Equals(b)); } // A test for Reflect (Vector2, Vector2) [Fact] public void Vector2ReflectTest() { Vector2 a = Vector2.Normalize(new Vector2(1.0f, 1.0f)); // Reflect on XZ plane. Vector2 n = new Vector2(0.0f, 1.0f); Vector2 expected = new Vector2(a.X, -a.Y); Vector2 actual = Vector2.Reflect(a, n); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Reflect did not return the expected value."); // Reflect on XY plane. n = new Vector2(0.0f, 0.0f); expected = new Vector2(a.X, a.Y); actual = Vector2.Reflect(a, n); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Reflect did not return the expected value."); // Reflect on YZ plane. n = new Vector2(1.0f, 0.0f); expected = new Vector2(-a.X, a.Y); actual = Vector2.Reflect(a, n); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Reflect did not return the expected value."); } // A test for Reflect (Vector2, Vector2) // Reflection when normal and source are the same [Fact] public void Vector2ReflectTest1() { Vector2 n = new Vector2(0.45f, 1.28f); n = Vector2.Normalize(n); Vector2 a = n; Vector2 expected = -n; Vector2 actual = Vector2.Reflect(a, n); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Reflect did not return the expected value."); } // A test for Reflect (Vector2, Vector2) // Reflection when normal and source are negation [Fact] public void Vector2ReflectTest2() { Vector2 n = new Vector2(0.45f, 1.28f); n = Vector2.Normalize(n); Vector2 a = -n; Vector2 expected = n; Vector2 actual = Vector2.Reflect(a, n); Assert.True(MathHelper.Equal(expected, actual), "Vector2.Reflect did not return the expected value."); } [Fact] public void Vector2AbsTest() { Vector2 v1 = new Vector2(-2.5f, 2.0f); Vector2 v3 = Vector2.Abs(new Vector2(0.0f, Single.NegativeInfinity)); Vector2 v = Vector2.Abs(v1); Assert.Equal(2.5f, v.X); Assert.Equal(2.0f, v.Y); Assert.Equal(0.0f, v3.X); Assert.Equal(Single.PositiveInfinity, v3.Y); } [Fact] public void Vector2SqrtTest() { Vector2 v1 = new Vector2(-2.5f, 2.0f); Vector2 v2 = new Vector2(5.5f, 4.5f); Assert.Equal(2, (int)Vector2.SquareRoot(v2).X); Assert.Equal(2, (int)Vector2.SquareRoot(v2).Y); Assert.Equal(Single.NaN, Vector2.SquareRoot(v1).X); } #pragma warning disable xUnit2000 // 'sizeof(constant) should be argument 'expected'' error // A test to make sure these types are blittable directly into GPU buffer memory layouts [Fact] public unsafe void Vector2SizeofTest() { Assert.Equal(sizeof(Single) * 2, sizeof(Vector2)); Assert.Equal(sizeof(Single) * 2 * 2, sizeof(Vector2_2x)); Assert.Equal(sizeof(Single) * 2 + sizeof(Single), sizeof(Vector2PlusSingle)); Assert.Equal((sizeof(Single) * 2 + sizeof(Single)) * 2, sizeof(Vector2PlusSingle_2x)); } #pragma warning restore xUnit2000 // 'sizeof(constant) should be argument 'expected'' error [StructLayout(LayoutKind.Sequential)] struct Vector2_2x { private Vector2 _a; private Vector2 _b; } [StructLayout(LayoutKind.Sequential)] struct Vector2PlusSingle { private Vector2 _v; private Single _f; } [StructLayout(LayoutKind.Sequential)] struct Vector2PlusSingle_2x { private Vector2PlusSingle _a; private Vector2PlusSingle _b; }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file is not right

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File is still not right, lots of ^M characters

X = value[0];
}

static Vector2()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no static constructors

@@ -0,0 +1,1169 @@
[Fact]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These files need a license header too, which might impact how the templates are structured slightly.

Comment on lines 621 to 622


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Comment on lines 13 to 14


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Comment on lines 619 to 620


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

}


[Fact]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation

@@ -0,0 +1,1178 @@
/*********************************************************************************
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

License header needs to be first, auto-generated comment likely needs to go away now

Comment on lines 19 to 20


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Comment on lines 13 to 14


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

}


[Fact]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation

@@ -0,0 +1,1221 @@
using Vector3Single = System.Numerics.Vector3<System.Single>;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file looks like it wasn't fixed

}


[Fact]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation

@@ -0,0 +1,1404 @@
/*********************************************************************************
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the next three files

return Equal(a.X, b.X) && Equal(a.Y, b.Y);
}

// public static bool Equal<T>(Vector3<T> a, Vector3<T> b) where T : struct
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be implementable now?

@@ -1,380 +1,2 @@
// Licensed to the .NET Foundation under one or more agreements.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and a couple other files look to have been deleted and not replaced

tannergooding pushed a commit that referenced this pull request May 19, 2021
…tnet#52769)

Transition to GC Unsafe mode on every MONO_RT_EXTERNAL_ONLY function in
reflection.c

In particular, fix mono_reflection_type_from_name which is used in
https://github.com/xamarin/xamarin-android/blob/681887ebdbd192ce7ce1cd02221d4939599ba762/src/monodroid/jni/embedded-assemblies.cc#L350

Fixes stack traces like

```
05-14 08:06:12.848 31274 31274 F DEBUG   :       #00 pc 00000b99  [vdso] (__kernel_vsyscall+9)
05-14 08:06:12.848 31274 31274 F DEBUG   :       #1 pc 0005ad68  /apex/com.android.runtime/lib/bionic/libc.so (syscall+40) (BuildId: 6e3a0180fa6637b68c0d181c343e6806)
05-14 08:06:12.848 31274 31274 F DEBUG   :       #2 pc 00076511  /apex/com.android.runtime/lib/bionic/libc.so (abort+209) (BuildId: 6e3a0180fa6637b68c0d181c343e6806)
05-14 08:06:12.848 31274 31274 F DEBUG   :       #3 pc 0002afcd  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::mono_log_handler(char const*, char const*, char const*, int, void*)+141) (BuildId: 9726f32ad5f8fa5e7c5762baf2f6e3294da41cc1)
05-14 08:06:12.848 31274 31274 F DEBUG   :       #4 pc 00112c5d  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (eglib_log_adapter+141) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #5 pc 00020fdf  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (monoeg_g_logv+175) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #6 pc 0002113a  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (monoeg_g_log+42) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #7 pc 00128892  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_threads_transition_do_blocking+258) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #8 pc 0012a406  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_threads_enter_gc_safe_region_unbalanced_with_info+134) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #9 pc 0012a27e  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_threads_enter_gc_safe_region_internal+46) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #10 pc 000799a7  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_loader_lock+71) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #11 pc 000447a1  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_class_create_from_typedef+129) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #12 pc 0003c073  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_class_get_checked+99) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #13 pc 0003cc0f  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_class_from_name_checked_aux+735) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #14 pc 00037989  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_class_from_name_checked+73) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #15 pc 000cc5f4  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_reflection_get_type_internal+132) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #16 pc 000c9bce  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_reflection_get_type_with_rootimage+126) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #17 pc 000ca204  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (_mono_reflection_get_type_from_info+292) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #18 pc 000ca06e  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_reflection_type_from_name_checked+334) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #19 pc 000c9f01  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonosgen-2.0.so (mono_reflection_type_from_name+49) (BuildId: b67e93dd750dafdd6f65f408b021b6a3a74868ac)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #20 pc 0001b40b  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonodroid.so (xamarin::android::internal::EmbeddedAssemblies::typemap_java_to_managed(char const*)+427) (BuildId: 9726f32ad5f8fa5e7c5762baf2f6e3294da41cc1)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #21 pc 0001b551  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonodroid.so (xamarin::android::internal::EmbeddedAssemblies::typemap_java_to_managed(_MonoString*)+113) (BuildId: 9726f32ad5f8fa5e7c5762baf2f6e3294da41cc1)
05-14 08:06:12.849 31274 31274 F DEBUG   :       #22 pc 000211a7  /data/app/~~rMrkpKmVPaBpM5jKb8fPAg==/com.microsoft.maui-JfRo8RWSDJaNtJuBa0y7_Q==/lib/x86/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::typemap_java_to_managed(_MonoString*)+39) (BuildId: 9726f32ad5f8fa5e7c5762baf2f6e3294da41cc1)
```
tannergooding pushed a commit that referenced this pull request May 19, 2021
…2915)

* [build] Define NO_UNALIGNED_ACCESS for 32-bit arm platforms

Possibly related to crashes on Android like this:

```
05-18 10:59:07.466 17076 17076 F libc    : Fatal signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 0xb9c95a41 in tid 17076 (simplehellomaui), pid 17076 (simplehellomaui)
05-18 10:59:07.501 17104 17104 I crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone
05-18 10:59:07.502   989   989 I tombstoned: received crash request for pid 17076
05-18 10:59:07.503 17104 17104 I crash_dump32: performing dump of process 17076 (target tid = 17076)
05-18 10:59:07.512 17104 17104 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
05-18 10:59:07.512 17104 17104 F DEBUG   : Build fingerprint: 'google/crosshatch/crosshatch:11/RQ2A.210405.005/7181113:user/release-keys'
05-18 10:59:07.512 17104 17104 F DEBUG   : Revision: 'MP1.0'
05-18 10:59:07.512 17104 17104 F DEBUG   : ABI: 'arm'
05-18 10:59:07.515 17104 17104 F DEBUG   : Timestamp: 2021-05-18 10:59:07+0200
05-18 10:59:07.515 17104 17104 F DEBUG   : pid: 17076, tid: 17076, name: simplehellomaui  >>> com.microsoft.simplehellomaui <<<
05-18 10:59:07.515 17104 17104 F DEBUG   : uid: 10364
05-18 10:59:07.515 17104 17104 F DEBUG   : signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 0xb9c95a41
05-18 10:59:07.515 17104 17104 F DEBUG   :     r0  bb4a5cd0  r1  b9c95a49  r2  00000000  r3  e94c7520
05-18 10:59:07.515 17104 17104 F DEBUG   :     r4  0000000c  r5  00000000  r6  ff843c50  r7  ff843e70
05-18 10:59:07.515 17104 17104 F DEBUG   :     r8  b69547f8  r9  e99eac50  r10 00000000  r11 00000021
05-18 10:59:07.515 17104 17104 F DEBUG   :     ip  e94c74f0  sp  ff843c48  lr  bb31e0dd  pc  bb3a4d24
05-18 10:59:07.531   709   709 E Layer   : [Surface(name=Task=1)/@0x52e6b1a - animation-leash#0] No local sync point found
05-18 10:59:07.532   709   709 E Layer   : [Surface(name=Task=1571)/@0x9c90165 - animation-leash#0] No local sync point found
05-18 10:59:07.706 17104 17104 F DEBUG   : backtrace:
05-18 10:59:07.707 17104 17104 F DEBUG   :       #00 pc 000ddd24  /data/app/~~J4DFQ3c1v2YGrEurX7TNjg==/com.microsoft.simplehellomaui-_jGGPiZpZ3yT-QCTNDcgvQ==/lib/arm/libmonosgen-2.0.so (mono_method_to_ir+9232) (BuildId: d0a4e41a500357a621884b64f6ca8533b62a664b)
05-18 10:59:07.707 17104 17104 F DEBUG   :       #1 pc 000d7777  /data/app/~~J4DFQ3c1v2YGrEurX7TNjg==/com.microsoft.simplehellomaui-_jGGPiZpZ3yT-QCTNDcgvQ==/lib/arm/libmonosgen-2.0.so (inline_method+622) (BuildId: d0a4e41a500357a621884b64f6ca8533b62a664b)
05-18 10:59:07.707 17104 17104 F DEBUG   :       #2 pc 000ec0a3  /data/app/~~J4DFQ3c1v2YGrEurX7TNjg==/com.microsoft.simplehellomaui-_jGGPiZpZ3yT-QCTNDcgvQ==/lib/arm/libmonosgen-2.0.so (mono_method_to_ir+67470) (BuildId: d0a4e41a500357a621884b64f6ca8533b62a664b)
05-18 10:59:07.707 17104 17104 F DEBUG   :       #3 pc 000cda6d  /data/app/~~J4DFQ3c1v2YGrEurX7TNjg==/com.microsoft.simplehellomaui-_jGGPiZpZ3yT-QCTNDcgvQ==/lib/arm/libmonosgen-2.0.so (mini_method_compile+2264) (BuildId: d0a4e41a500357a621884b64f6ca8533b62a664b)
05-18 10:59:07.707 17104 17104 F DEBUG   :       #4 pc 000cf413  /data/app/~~J4DFQ3c1v2YGrEurX7TNjg==/com.microsoft.simplehellomaui-_jGGPiZpZ3yT-QCTNDcgvQ==/lib/arm/libmonosgen-2.0.so (mono_jit_compile_method_inner+50) (BuildId: d0a4e41a500357a621884b64f6ca8533b62a664b)
05-18 10:59:07.707 17104 17104 F DEBUG   :       #5 pc 000d1d7f  /data/app/~~J4DFQ3c1v2YGrEurX7TNjg==/com.microsoft.simplehellomaui-_jGGPiZpZ3yT-QCTNDcgvQ==/lib/arm/libmonosgen-2.0.so (mono_jit_compile_method_with_opt+1766) (BuildId: d0a4e41a500357a621884b64f6ca8533b62a664b)
05-18 10:59:07.707 17104 17104 F DEBUG   :       #6 pc 0012d94d  /data/app/~~J4DFQ3c1v2YGrEurX7TNjg==/com.microsoft.simplehellomaui-_jGGPiZpZ3yT-QCTNDcgvQ==/lib/arm/libmonosgen-2.0.so (common_call_trampoline+832) (BuildId: d0a4e41a500357a621884b64f6ca8533b62a664b)
05-18 10:59:07.707 17104 17104 F DEBUG   :       #7 pc 0012d5cb  /data/app/~~J4DFQ3c1v2YGrEurX7TNjg==/com.microsoft.simplehellomaui-_jGGPiZpZ3yT-QCTNDcgvQ==/lib/arm/libmonosgen-2.0.so (mono_magic_trampoline+62) (BuildId: d0a4e41a500357a621884b64f6ca8533b62a664b)
05-18 10:59:07.707 17104 17104 F DEBUG   :       #8 pc 0000006a <anonymous:b7986000>
```

* move to host/target sections
tannergooding pushed a commit that referenced this pull request Jul 6, 2021
…et#53792)

I have expanded the PerfMap format produced by Crossgen2 and
R2RDump to produce metadata in form of pseudo-symbol records with
high addresses. In this version I have implemented four metadata
entries - output GUID, target OS, target architecture and perfmap
format version number.  I have verified for System.Private.CoreLib
and for the composite framework that Crossgen2 and R2RDump
produce identical metadata.

To facilitate a smooth transition to the new perfmap format, in
accordance with Juan's suggestion I have introduced a new command-line
option to explicitly specify the perfmap format revision. As of today,
0 corresponds to the legacy Crossgen1-style output where the
perfmap file name includes the {MVID} section, perfmap format #1
corresponds to current Crossgen2 with its new naming scheme.
As of today there are no differences in the file content.

Thanks

Tomas
tannergooding pushed a commit that referenced this pull request Jan 13, 2022
…otnet#63598)

* Fix native frame unwind in syscall on arm64 for VS4Mac crash report.

Add arm64 version of StepWithCompactNoEncoding for syscall leaf node wrappers that have compact encoding of 0.

Fix ReadCompactEncodingRegister so it actually decrements the addr.

Change StepWithCompactEncodingArm64 to match what MacOS libunwind does for framed and frameless stepping.

arm64 can have frames with the same SP (but different IPs). Increment SP for this condition so createdump's unwind
loop doesn't break out on the "SP not increasing" check and the frames are added to the thread frame list in the
correct order.

Add getting the unwind info for tail called functions like this:

__ZL14PROCEndProcessPvji:
   36630:       f6 57 bd a9     stp     x22, x21, [sp, #-48]!
   36634:       f4 4f 01 a9     stp     x20, x19, [sp, #16]
   36638:       fd 7b 02 a9     stp     x29, x30, [sp, dotnet#32]
   3663c:       fd 83 00 91     add     x29, sp, dotnet#32
...
   367ac:       e9 01 80 52     mov     w9, #15
   367b0:       7f 3e 02 71     cmp     w19, dotnet#143
   367b4:       20 01 88 1a     csel    w0, w9, w8, eq
   367b8:       2e 00 00 94     bl      _PROCAbort
_TerminateProcess:
-> 367bc:       22 00 80 52     mov     w2, #1
   367c0:       9c ff ff 17     b       __ZL14PROCEndProcessPvji

The IP (367bc) returns the (incorrect) frameless encoding with nothing on the stack (uses an incorrect LR to unwind). To fix this
get the unwind info for PC -1 which points to PROCEndProcess with the correct unwind info. This matches how lldb unwinds this frame.

Always address module segment to IP lookup list instead of checking the module regions.

Strip pointer authentication bits on PC/LR.
tannergooding pushed a commit that referenced this pull request May 24, 2022
This adds support for EnC on arm64. A couple of notes on the
implementation compared to x64:
- On x64 we get the fixed stack size from unwind info. However, for the
  frames we set up on arm64 for EnC it is not possible to extract the
  frame size from there because their prologs generally look like

  stp fp, lr, [sp,#-16]!
  mov fp, sp
  sub sp, sp, dotnet#144

  with unwind codes like the following:

  set_fp; mov fp, sp

  save_fplr_x #1 (0x01); tp fp, lr, [sp, #-16]!

  As can be seen, it is not possible to get the fixed stack size from
  unwind info in this case. Instead we pass it through the GC info that
  already has a section for EnC data.

- On arm64 the JIT is required to place the PSPSym at the same offset
  from caller-SP for both the main function and for funclets. Due to
  this we try to allocate the PSPSym as early as possible in the main
  function and we must take some care in funclets.  However, this
  conflicts with the EnC frame header that the JIT uses to place values
  that must be preserved on EnC transitions. This is currently
  callee-saved registers and the MonitorAcquired boolean.

  Before this change we were allocating PSPSym above (before) the
  monitor acquired boolean, but we now have to allocate MonitorAcquired
  first, particularly because the size of the preserved header cannot
  change on EnC transitions, while the PSPSym can disappear or appear.
  This changes frame allocation slightly for synchronized functions.
tannergooding pushed a commit that referenced this pull request Jun 2, 2022
These helpers are used to report names of things in warnings. The functional changes are:
* For method parameters, use the parameter name if available (and only if not fallback to the #1 notation)
* For property accessor methods, use the C# naming scheme, so for example Type.Property.get instead of Type.get_Property.

Both of these changes are in preparation to bring NativeAOT closer in behavior to ILLink and the trim analyzers.

For this I moved some of the helpers to the common shared code.

Some unrelated code cleanup as well.

Co-authored-by: Michal Strehovský <[email protected]>
tannergooding pushed a commit that referenced this pull request Jun 17, 2022
* Fix the MacOS remote unwinder for VS4Mac

The wrong module was being passed to the remote unwinder because the load bias for shared modules
was being calculated incorrectly.

Issue: dotnet#63309

* Fix native frame unwind in syscall on arm64 for VS4Mac crash report

From PR in main: dotnet#63598

Add arm64 version of StepWithCompactNoEncoding for syscall leaf node wrappers that have compact encoding of 0.

Fix ReadCompactEncodingRegister so it actually decrements the addr.

Change StepWithCompactEncodingArm64 to match what MacOS libunwind does for framed and frameless stepping.

arm64 can have frames with the same SP (but different IPs). Increment SP for this condition so createdump's unwind
loop doesn't break out on the "SP not increasing" check and the frames are added to the thread frame list in the
correct order.

Add getting the unwind info for tail called functions like this:

__ZL14PROCEndProcessPvji:
   36630:       f6 57 bd a9     stp     x22, x21, [sp, #-48]!
   36634:       f4 4f 01 a9     stp     x20, x19, [sp, #16]
   36638:       fd 7b 02 a9     stp     x29, x30, [sp, dotnet#32]
   3663c:       fd 83 00 91     add     x29, sp, dotnet#32
...
   367ac:       e9 01 80 52     mov     w9, #15
   367b0:       7f 3e 02 71     cmp     w19, dotnet#143
   367b4:       20 01 88 1a     csel    w0, w9, w8, eq
   367b8:       2e 00 00 94     bl      _PROCAbort
_TerminateProcess:
-> 367bc:       22 00 80 52     mov     w2, #1
   367c0:       9c ff ff 17     b       __ZL14PROCEndProcessPvji

The IP (367bc) returns the (incorrect) frameless encoding with nothing on the stack (uses an incorrect LR to unwind). To fix this
get the unwind info for PC -1 which points to PROCEndProcess with the correct unwind info. This matches how lldb unwinds this frame.

Always address module segment to IP lookup list instead of checking the module regions.

Strip pointer authentication bits on PC/LR.
tannergooding pushed a commit that referenced this pull request Jun 23, 2022
* Initial implementation for contract customization

fix build errors

Move converter rooting to DefaultJsonTypeInfoResolver so that it can be used standalone

Fix ConfigurationList.IsReadOnly

Minor refactorings (#1)

* Makes the following changes:

* Move singleton initialization for DefaultTypeInfoResolver behind a static property.
* Consolidate JsonSerializerContext & IJsonTypeInfoResolver values to a single field.
* Move reflection fallback logic away from JsonSerializerContext and into JsonSerializerOptions

* Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs

* remove testing of removed field

Simplify the JsonTypeInfo.CreateObject implemenetation (#2)

* Simplify the JsonTypeInfo.CreateObject implemenetation

* Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.cs

* Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.cs

Co-authored-by: Krzysztof Wicher <[email protected]>

Co-authored-by: Krzysztof Wicher <[email protected]>

Tests and fixes for JsonTypeInfoKind.None

TypeInfo type mismatch tests

Allow setting NumberHandling on JsonTypeInfoKind.None

test resolver returning wrong type of options

JsonTypeInfo/JsonPropertyInfo mutability tests

rename test file

Move default converter rooting responsibility behind DefaultJsonTypeInfoResolver (#3)

* Move default converter rooting responsibility behind DefaultJsonTypeInfoResolver

* address feedback

Add simple test for using JsonTypeInfo<T> with APIs directly taking it

fix and tests for untyped/typed CreateObject

uncomment test cases, remove todo

More tests and tiny fixes

Add a JsonTypeInfoResolver.Combine test for JsonSerializerContext (#4)

* Fix JsonTypeInfoResolver.Combine for JsonSerializerContext

* Break up failing test

Fix simple scenarios for combining contexts (#6)

* Fix simple scenarios for combining contexts

* feedback

JsonSerializerContext combine test with different camel casing

Remove unneeded virtual calls & branching when accessing Get & Set delegates (#7)

JsonPropertyInfo tests everything minus ShouldSerialize & NumberHandling

Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs

Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs

throw InvalidOperationException rather than ArgumentNullException for source gen when PropertyInfo.Name is assigned through JsonPropertyInfoValues

tests for duplicated property names and JsonPropertyInfo.NumberHandling

Add tests for NumberHandling and failing tests for ShouldSerialize

disable the failing test and add extra checks

disable remainder of the failing ShouldSerialize tests, fix working one

Fix ShouldSerialize and IgnoreCondition interop

Add failing tests for CreateObject + parametrized constructors

Fix CreateObject support for JsonConstructor types (#10)

* Fix CreateObject support for JsonConstructor types

* address feedback

Make contexts more combinator friendly (#9)

* Make contexts more combinator friendly

* remove converter cache

* redesign test to account for JsonConstructorAttribute

* Combine unit tests

* address feedback

* Add acceptance tests for DataContract attributes & Specified pattern (#11)

* Add private field serialization acceptance test (#13)

* tests, PR feedback (#14)

* PR feedback and extra tests

* Shorten class name, remove incorrect check (not true for polimorphic cases)

* Make parameter matching for custom properties map property Name with parameter (#16)

* Test static initialization with JsonTypeInfo (#17)

* Fix test failures and proper fix this time (#18)

* Fix test failures and proper fix this time

* reinstate ActiveIssueAttribute

* PR feedback and adjust couple of tests which don't set TypeInfoResolver

* fix IAsyncEnumerable tests

* Lock JsonSerializerOptions in JsonTypeInfo.EnsureConfigured()

Co-authored-by: Eirik Tsarpalis <[email protected]>

Co-authored-by: Eirik Tsarpalis <[email protected]>
tannergooding pushed a commit that referenced this pull request Jul 1, 2022
E.g.,

Update LSRA "Allocating Registers" table description.

Dump nodes added during resolution, e.g.:
```
   BB29 bottom (BB08->BB08): move V25 from STK to rdi (Critical)
N001 (  1,  1) [001174] ----------z                 t1174 =    LCL_VAR   int    V25 cse4          rdi REG rdi
```

Dump more data in the LSRA block sequence data:
```
-BB03( 16   )
-BB04(  4   )
+BB03 ( 16   ) critical-in critical-out
+BB04 (  4   ) critical-out
```

When dumping various flow bitvectors, annotate the bitvectors better:
```
-BB25 in gen out
-0000000000000000
-0000000000000003 CSE #1.c
-0000000000000003 CSE #1.c
+BB25
+ in: 0000000000000000
+gen: 0000000000000003 CSE #1.c
+out: 0000000000000003 CSE #1.c
```

Dump hoisting bitvectors using the sorting number:
```
-  USEDEF  (5)={V04 V00 V01 V02 V03}
+  USEDEF  (5)={V00 V01 V02 V03 V04}
```

Also, fix various typos and formatting.
tannergooding pushed a commit that referenced this pull request Sep 1, 2022
* WIP: add gRPC tests

* Fix AOT and trimming

* WIP

* Implement IncludeNetworkSecurityConfig

* Use IncludeNetworkSecurityConfig

* Fix gRPC test

* Avoid git checkout

* Remove unnecessary code

* WIP: start working on CI configuration

* Remove WinHttpHandler

* Fix problem with SSL

* Change server host

* Setup CI (#1)

* Get Docker container building & exported via test build

* Changes

* Add missing pfx certificate

* changes

* cleanup

Co-authored-by: Simon Rozsival <[email protected]>

* Use tls

* Update yml

* Revert changes to the mono Android sample app

* Bump android image version

* Bump image version

* Enable TLS

* Remove hardcoded package versions

* Update package versions

* Update package versions

* Rename pipeline

* Move interop tests website dependencies versions to Versions.props

* Add cred scan supression for the interop test server private key

* Fix licenses

* Remove dependencies

* Fix path to Versions.props

* Remove unnecessary dependency version

* Fix building docker image

* Change pfx password

Co-authored-by: Jo Shields <[email protected]>
tannergooding pushed a commit that referenced this pull request Dec 17, 2022
* switch to managed thread ID in Lock

* fattening the lock

* __declspec(selectany)

* few tweaks

* fairness

* more room for thread ids

* remove CurrentNativeThreadId

* couple fixes

* fix win-arm64 build

* win-arm64 build , another try

* Apply suggestions from code review

Co-authored-by: Jan Kotas <[email protected]>

* fix after renaming

* do not report successful spin if thread has waited

* keep extern and undo mangling of tls_CurrentThread in asm

* use SyncTable indexer in less perf-sensitive places.

* GetNewHashCode just delegate to shared random

* Apply suggestions from code review

Co-authored-by: Jan Kotas <[email protected]>

* unchecked const conversion

* some refactoring comments and typos

* min number of spins in the backoff

* moved CurrentManagedThreadIdUnchecked to ManagedThreadId

* Use `-1` to report success and allow using  element #1 in the SyncTable

* use threadstatic for managed thread ID

* check before calling RhGetProcessCpuCount

* use 0 as default thread ID

Co-authored-by: Jan Kotas <[email protected]>
tannergooding pushed a commit that referenced this pull request Jun 9, 2023
…tnet#87189)

This fixes a startup crash on Big Sur:

> error: * Assertion at /Users/runner/work/1/s/src/mono/mono/utils/mono-hwcap-arm64.c:35, condition `res == 0' not met

Because sysctl can't find some of these options:

    $ sysctl hw.optional.armv8_crc32
    hw.optional.armv8_crc32: 1
    $ sysctl hw.optional.arm.FEAT_RDM
    sysctl: unknown oid 'hw.optional.arm.FEAT_RDM'
    $ sysctl hw.optional.arm.FEAT_DotProd
    sysctl: unknown oid 'hw.optional.arm.FEAT_DotProd'
    $ sysctl hw.optional.arm.FEAT_SHA1
    sysctl: unknown oid 'hw.optional.arm.FEAT_SHA1'
    $ sysctl hw.optional.arm.FEAT_SHA256
    sysctl: unknown oid 'hw.optional.arm.FEAT_SHA256'
    $ sysctl hw.optional.arm.FEAT_AES
    sysctl: unknown oid 'hw.optional.arm.FEAT_AES'

Full stack trace:

* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
  * frame #0: 0x0000010ef37560 libmonosgen-2.0.dylib`monoeg_assertion_message
    frame #1: 0x0000010ef375cc libmonosgen-2.0.dylib`mono_assertion_message + 32
    frame #2: 0x0000010ef40d6c libmonosgen-2.0.dylib`mono_hwcap_arch_init + 544
    frame #3: 0x0000010ef54bd8 libmonosgen-2.0.dylib`mono_hwcap_init + 72
    frame #4: 0x0000010ee14dc0 libmonosgen-2.0.dylib`parse_optimizations + 52
    frame #5: 0x0000010edbed48 libmonosgen-2.0.dylib`mono_init
    frame #6: 0x0000010ee18968 libmonosgen-2.0.dylib`mono_jit_init_version
    frame #7: 0x0000010f48a300 libxamarin-dotnet-debug.dylib`xamarin_bridge_initialize + 216
    frame #8: 0x0000010f4900a4 libxamarin-dotnet-debug.dylib`xamarin_main + 376
tannergooding pushed a commit that referenced this pull request Jan 3, 2024
Fixes dotnet#95367.

Relevant part of the JitDump:

```
Using `if true` assertions from pred BB02
Assertions in: #1
fgMorphTree BB04, STMT00021 (before)
               [000070] DA---------                         *  STORE_LCL_VAR ubyte  V10 tmp9
               [000057] -----------                         \--*  CAST      int <- ubyte <- int
               [000006] -----------                            \--*  EQ        int
               [000004] -----------                               +--*  LCL_VAR   ref    V02 tmp1          (last use)
               [000055] H----------                               \--*  CNS_INT(h) ref     'Frozen EmptyPartition`1<Int32> object'

Assertion prop for index #1 in BB04:
               [000006] -----------                         *  EQ        int
GenTreeNode creates assertion:
               [000070] DA---+-----                         *  STORE_LCL_VAR ubyte  V10 tmp9
In BB04 New Local Constant Assertion: V10 == [0000000000000001], index = #2

fgMorphTree BB04, STMT00021 (after)
               [000070] DA---+-----                         *  STORE_LCL_VAR ubyte  V10 tmp9
               [000055] H----+-----                         \--*  CNS_INT(h) int
```

The JitDump is unfinished because the compiler crashes when trying to dump the last line. Clearly, the `CNS_INT` is no longer a handle at that point because we just bashed it to a constant 1.
tannergooding pushed a commit that referenced this pull request Mar 18, 2024
CodeQL flagged various places where we're dereferencing pointers that could be NULL, this PR systematically cleans some of them up via g_assert.
* g_assert result of g_build_path calls
* Allocation failure handling
* mono_class_inflate_generic_class_checked can return NULL
tannergooding pushed a commit that referenced this pull request May 15, 2024
…#102133)

This generalizes the indir reordering optimization (that currently only
triggers for loads) to kick in for GT_STOREIND nodes.

The main complication with doing this is the fact that the data node of
the second indirection needs its own reordering with the previous
indirection. The existing logic works by reordering all nodes between
the first and second indirection that are unrelated to the second
indirection's computation to happen after it. Once that is done we know
that there are no uses of the first indirection's result between it and
the second indirection, so after doing the necessary interference checks
we can safely move the previous indirection to happen after the data
node of the second indirection.

Example:
```csharp
class Body { public double x, y, z, vx, vy, vz, mass; }

static void Advance(double dt, Body[] bodies)
{
    foreach (Body b in bodies)
    {
        b.x += dt * b.vx;
        b.y += dt * b.vy;
        b.z += dt * b.vz;
    }
}
```

Diff:
```diff
@@ -1,18 +1,17 @@
-G_M55007_IG04:  ;; offset=0x001C
+G_M55007_IG04:  ;; offset=0x0020
             ldr     x3, [x0, w1, UXTW #3]
             ldp     d16, d17, [x3, #0x08]
             ldp     d18, d19, [x3, #0x20]
             fmul    d18, d0, d18
             fadd    d16, d16, d18
-            str     d16, [x3, #0x08]
-            fmul    d16, d0, d19
-            fadd    d16, d17, d16
-            str     d16, [x3, #0x10]
+            fmul    d18, d0, d19
+            fadd    d17, d17, d18
+            stp     d16, d17, [x3, #0x08]
             ldr     d16, [x3, #0x18]
             ldr     d17, [x3, #0x30]
             fmul    d17, d0, d17
             fadd    d16, d16, d17
             str     d16, [x3, #0x18]
             add     w1, w1, #1
             cmp     w2, w1
             bgt     G_M55007_IG04
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants