123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746 |
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using Burst.Compiler.IL.Tests.Helpers;
- using NUnit.Framework;
- using Unity.Burst;
- using Unity.Collections.LowLevel.Unsafe;
- using Unity.Mathematics;
- using UnityBenchShared;
-
- namespace Burst.Compiler.IL.Tests
- {
- internal partial class TestStructs
- {
- [TestCompiler]
- public static float test_struct_func_call_by_value()
- {
- var localVar = new CustomStruct();
- localVar.firstfield = 94;
- localVar.value = 123;
- return byvalue_function_helper(localVar);
- }
-
- [TestCompiler]
- public static float test_struct_func_call_by_ref()
- {
- var localVar = new CustomStruct
- {
- firstfield = 94,
- value = 123
- };
- byref_function_helper(ref localVar);
- return localVar.value;
- }
-
- [TestCompiler]
- public static float test_struct_func_call_instance()
- {
- var localVar = new CustomStruct2 { value = 123 };
- return localVar.returnDoubleValue();
- }
-
- [TestCompiler]
- public static float test_struct_constructor_nondefault()
- {
- var localVar = new CustomStruct2(123.0f);
- return localVar.value;
- }
-
- [TestCompiler]
- public static float test_struct_constructor_default()
- {
- var localVar = new CustomStruct2();
- localVar.value = 1;
- return localVar.value;
- }
-
- [TestCompiler]
- public static float test_struct_copysemantic()
- {
- var a = new CustomStruct2 { value = 123.0f };
- var b = a;
- b.value = 345;
- return b.value;
- }
-
- [TestCompiler]
- public static float test_struct_nested()
- {
- var a = new TestNestedStruct { v1 = { x = 5 } };
- return a.v1.x;
- }
-
- [TestCompiler(1.0f)]
- public static float test_struct_multiple_fields(float x)
- {
- var v = new TestVector4
- {
- x = 1.0f,
- y = 2.0f,
- z = 3.0f,
- w = 4.0f
- };
- return x + v.x + v.y + v.z + v.w;
- }
-
- [TestCompiler]
- public static float test_struct_multi_assign()
- {
- var a = new MultiAssignStruct(2.0F);
- return a.x + a.y + a.z;
- }
-
- [TestCompiler]
- public static int test_custom_struct_return_simple()
- {
- var a = return_value_helper_simple(1, 2);
- return a.firstfield + a.value;
- }
-
- [TestCompiler]
- public static int test_custom_struct_return_constructor()
- {
- var a = return_value_helper_constructor(1, 2);
- return a.firstfield + a.value;
- }
-
- [TestCompiler]
- public static int test_struct_self_reference()
- {
- var a = new SelfReferenceStruct
- {
- Value = 1
- };
- return a.Value;
- }
-
- [TestCompiler]
- public static int test_struct_deep()
- {
- var deep = new DeepStruct2();
- deep.value.value.SetValue(10);
- return deep.value.value.GetValue() + deep.value.value.value;
- }
-
- [TestCompiler(2)]
- public static int test_struct_empty(int x)
- {
- var emptyStruct = new EmptyStruct();
- var result = emptyStruct.Increment(x);
- return result;
- }
-
- [TestCompiler]
- public static float test_struct_with_static_fields()
- {
- StructWithStaticVariables myStruct = new StructWithStaticVariables();
- myStruct.myFloat = 5;
- myStruct = copy_struct_with_static_by_value(myStruct);
- mutate_struct_with_static_by_ref_value(ref myStruct);
- return myStruct.myFloat;
- }
-
- [TestCompiler(true)]
- [TestCompiler(false)]
- public static bool TestStructWithBoolAsInt(bool value)
- {
- var structWithBoolAsInt = new StructWithBoolAsInt(value);
- return structWithBoolAsInt;
- }
-
- [TestCompiler]
- [Ignore("IL Instruction LEAVE not yet supported")]
- public static int TestStructDisposable()
- {
- using (var structDisposable = new StructDisposable())
- {
- return structDisposable.x + 1;
- }
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_InstructionStsfldNotSupported)]
- public static void TestStructWithStaticFieldWrite()
- {
- var test = new StructWithStaticField();
- test.CheckWrite();
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoadingFromNonReadonlyStaticFieldNotSupported)]
- public static void TestStructWithStaticFieldRead()
- {
- var test = new StructWithStaticField();
- test.CheckRead();
- }
-
- [TestCompiler]
- public static int TestExplicitLayoutSize()
- {
- return UnsafeUtility.SizeOf<Color>();
- }
-
- [TestCompiler]
- public static int TestExplicitLayoutStruct()
- {
- var color = new Color() { Value = 0xAABBCCDD };
- var a = color.Value + GetColorR(ref color) + GetColorG(color) + color.GetColorB() + color.A;
- var pair = new NumberPair()
- {
- SignedA = -13,
- UnsignedB = 37
- };
- var b = pair.SignedA - ((int)pair.UnsignedA) + pair.SignedB - ((int)pair.UnsignedB);
- return ((int)a) + b;
- }
-
- static uint GetColorR(ref Color color)
- {
- return color.R;
- }
-
- static uint GetColorG(Color color)
- {
- return color.G;
- }
-
- [TestCompiler]
- public static uint TestExplicitLayoutWrite()
- {
- var color = new Color() { Value = 0xAABBCCDD };
- color.G = 3;
- ColorWriteBByRef(ref color, 7);
- return color.Value;
- }
-
- static void ColorWriteBByRef(ref Color color, byte v)
- {
- color.B = v;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private unsafe struct ExplicitLayoutStructUnaligned
- {
- [FieldOffset(0)] public int a;
- [FieldOffset(4)] public sbyte b;
- [FieldOffset(5)] public int c;
- [FieldOffset(9)] public fixed int d[4];
- }
-
- [TestCompiler]
- public static unsafe int TestExplicitLayoutStructUnaligned()
- {
- var value = new ExplicitLayoutStructUnaligned
- {
- a = -2,
- b = -5,
- c = 9
- };
-
- value.d[0] = 1;
- value.d[1] = 2;
- value.d[2] = 3;
- value.d[3] = 4;
-
- return value.a + value.b + value.c + value.d[0] + value.d[1] + value.d[2] + value.d[3];
- }
-
- [StructLayout(LayoutKind.Explicit)]
- public unsafe struct ExplicitLayoutStructFixedBuffer
- {
- [FieldOffset(0)]
- public int First;
- [FieldOffset(4)]
- public fixed int Data[128];
-
- public struct Provider : IArgumentProvider
- {
- public object Value => new ExplicitLayoutStructFixedBuffer(3);
- }
-
- public ExplicitLayoutStructFixedBuffer(int x)
- {
- First = x;
- fixed (int* dataPtr = Data)
- {
- dataPtr[8] = x + 2;
- }
- }
- }
-
- #if UNITY_ANDROID || UNITY_IOS
- [Ignore("This test fails on mobile platforms")]
- #endif
- [TestCompiler(typeof(ExplicitLayoutStructFixedBuffer.Provider))]
- public static unsafe int TestExplicitLayoutStructFixedBuffer(ref ExplicitLayoutStructFixedBuffer x)
- {
- return x.First + x.Data[8];
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 9)]
- public struct ExplicitStructWithSize
- {
- [FieldOffset(0)] public int a;
- [FieldOffset(4)] public sbyte b;
- [FieldOffset(5)] public int c;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructSizingExplicitStructWithSize()
- {
- return UnsafeUtility.SizeOf<ExplicitStructWithSize>();
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 9)]
- public struct SequentialStructWithSize
- {
- public int a;
- public int b;
- public sbyte c;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructSizingSequentialStructWithSize()
- {
- return UnsafeUtility.SizeOf<SequentialStructWithSize>();
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 13)]
- public struct SequentialStructWithSize2
- {
- public int a;
- public int b;
- public sbyte c;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructSizingSequentialStructWithSize2()
- {
- return UnsafeUtility.SizeOf<SequentialStructWithSize2>();
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 12, Pack = 8)]
- private struct StructSequentialWithSizeAndPack8
- {
- public double FieldA;
- public int FieldB;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructSizingSequentialStructWithSizeAndPack8()
- {
- return UnsafeUtility.SizeOf<StructSequentialWithSizeAndPack8>();
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 12, Pack = 8)]
- private struct StructExplicitWithSizeAndPack8
- {
- [FieldOffset(0)]
- public double FieldA;
- [FieldOffset(8)]
- public int FieldB;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructSizingSequentialStructWithSizeAndPack()
- {
- return UnsafeUtility.SizeOf<StructExplicitWithSizeAndPack8>();
- }
-
- private struct StructExplicitWithSizeAndPack8Wrapper
- {
- public byte FieldA;
- public StructExplicitWithSizeAndPack8 FieldB;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructExplicitWithSizeAndPack8Wrapper()
- {
- return UnsafeUtility.SizeOf<StructExplicitWithSizeAndPack8Wrapper>();
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 10)]
- private struct StructSequentialWithSizeSmallerThanActual
- {
- public double FieldA;
- public int FieldB;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructSequentialWithSizeSmallerThanActual()
- {
- return UnsafeUtility.SizeOf<StructSequentialWithSizeSmallerThanActual>();
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 10)]
- private struct StructExplicitWithSizeSmallerThanActual
- {
- [FieldOffset(0)]
- public double FieldA;
- [FieldOffset(8)]
- public int FieldB;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructExplicitWithSizeSmallerThanActual()
- {
- return UnsafeUtility.SizeOf<StructExplicitWithSizeSmallerThanActual>();
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 12)]
- private struct StructExplicitWithSizeAndOverlappingFields
- {
- [FieldOffset(0)]
- public double FieldA;
- [FieldOffset(4)]
- public int FieldB;
- [FieldOffset(8)]
- public int FieldC;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructExplicitWithSizeAndOverlappingFields()
- {
- return UnsafeUtility.SizeOf<StructExplicitWithSizeAndOverlappingFields>();
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 12)]
- private struct StructExplicitWithSize
- {
- [FieldOffset(0)]
- public double FieldA;
- [FieldOffset(8)]
- public int FieldB;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructExplicitWithSize()
- {
- return UnsafeUtility.SizeOf<StructExplicitWithSize>();
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 17)]
- private struct StructExplicitWithSize17
- {
- [FieldOffset(0)]
- public double FieldA;
- [FieldOffset(8)]
- public int FieldB;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructExplicitWithSize17()
- {
- return UnsafeUtility.SizeOf<StructExplicitWithSize17>();
- }
-
- [StructLayout(LayoutKind.Explicit)]
- public struct ExplicitStructEmpty { }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructZeroSizeNotSupported)]
- public static unsafe int TestStructSizingExplicitStructEmpty()
- {
- return UnsafeUtility.SizeOf<ExplicitStructEmpty>();
- }
-
- public struct ExplicitStructEmptyContainer
- {
- public ExplicitStructEmpty A;
- public int B;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructZeroSizeNotSupported)]
- public static unsafe int TestEmptyStructEmbeddedInStruct()
- {
- return UnsafeUtility.SizeOf<ExplicitStructEmptyContainer>();
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 0)]
- public struct ExplicitStructEmptyWithSize { }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructZeroSizeNotSupported)]
- public static unsafe int TestStructSizingExplicitStructEmptyWithSize()
- {
- return UnsafeUtility.SizeOf<ExplicitStructEmptyWithSize>();
- }
-
- public struct SequentialStructEmptyNoAttributes { }
-
- [TestCompiler]
- public static unsafe int TestStructSizingSequentialStructEmptyNoAttributes()
- {
- return UnsafeUtility.SizeOf<SequentialStructEmptyNoAttributes>();
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct SequentialStructEmpty { }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructZeroSizeNotSupported)]
- public static unsafe int TestStructSizingSequentialStructEmpty()
- {
- return UnsafeUtility.SizeOf<SequentialStructEmpty>();
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 0)]
- public struct SequentialStructEmptyWithSize { }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructZeroSizeNotSupported)]
- public static unsafe int TestStructSizingSequentialStructEmptyWithSize()
- {
- return UnsafeUtility.SizeOf<SequentialStructEmptyWithSize>();
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 1)]
- public struct SequentialStructEmptyWithNonZeroSize { }
-
- [TestCompiler]
- public static unsafe int TestStructSizingSequentialStructEmptyWithNonZeroSize()
- {
- return UnsafeUtility.SizeOf<SequentialStructEmptyWithNonZeroSize>();
- }
-
- [StructLayout(LayoutKind.Auto)]
- public struct AutoStruct
- {
- public int a;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructWithAutoLayoutNotSupported)]
- public static unsafe int TestAutoStruct()
- {
- return UnsafeUtility.SizeOf<AutoStruct>();
- }
-
- [TestCompiler]
- public static int TestNestedExplicitLayouts()
- {
- var nested = new NestedExplicit0()
- {
- Next = new NestedExplicit1()
- {
- Next = new NestedExplicit2()
- {
- FValue = 13.37f
- }
- }
- };
- var a = nested.NextAsInt + nested.Next.NextAsInt + nested.Next.Next.IValue;
- nested.Next.Next.FValue = 0.0042f;
- var b = nested.NextAsInt + nested.Next.NextAsInt + nested.Next.Next.IValue;
- return a + b;
- }
-
- [TestCompiler]
- public static int TestNestedExplicitLayoutsSize()
- {
-
- return UnsafeUtility.SizeOf<NestedExplicit0>();
- }
-
- [TestCompiler]
- public static uint TestBitcast()
- {
- return new FloatRepr()
- {
- Value = 13.37f
- }.AsUint;
- }
-
- [TestCompiler]
- public static uint TestExplicitStructFromCall()
- {
- return ReturnStruct().Value + ReturnStruct().R;
- }
-
- static Color ReturnStruct()
- {
- return new Color()
- {
- R = 10,
- G = 20,
- B = 30,
- A = 255
- };
- }
-
- [TestCompiler]
- public static unsafe uint TestExplicitLayoutStructWithFixedArray()
- {
- var x = new FixedArrayExplitLayoutStruct()
- {
- UpperUInt = 0xAABBCCDD,
- LowerUInt = 0xEEFF3344
- };
-
- uint sum = 0;
- for (int i = 0; i < 8; i++)
- {
- sum += x.Bytes[i];
- if (i < 4) sum += x.Shorts[i];
- }
-
- return x.UpperUInt + x.LowerUInt + sum;
- }
-
- [TestCompiler]
- public static unsafe int TestExplicitLayoutStructWithFixedArraySize()
- {
- return UnsafeUtility.SizeOf<FixedArrayExplitLayoutStruct>();
- }
-
- public struct StructInvalid
- {
- public string WowThatStringIsNotSupported;
- }
-
- //private struct StructInvalidProvider : IArgumentProvider
- //{
- // public object[] Arguments => new object[] { new StructInvalid() };
- //}
-
- private static CustomStruct return_value_helper_simple(int a, int b)
- {
- CustomStruct val;
- val.firstfield = a;
- val.value = b;
- return val;
- }
-
- private static CustomStruct return_value_helper_constructor(int a, int b)
- {
- return new CustomStruct(a, b);
- }
-
- private static float byvalue_function_helper(CustomStruct customStruct)
- {
- return customStruct.value * 2;
- }
-
- private static void byref_function_helper(ref CustomStruct customStruct)
- {
- customStruct.value = customStruct.value * 2;
- }
-
- static StructWithStaticVariables copy_struct_with_static_by_value(StructWithStaticVariables byValue)
- {
- byValue.myFloat += 2;
- return byValue;
- }
-
- static void mutate_struct_with_static_by_ref_value(ref StructWithStaticVariables byValue)
- {
- byValue.myFloat += 2;
- }
-
-
- private struct EmptyStruct
- {
- public int Increment(int x)
- {
- return x + 1;
- }
- }
-
- private struct CustomStruct
- {
- public int firstfield;
- public int value;
-
- public CustomStruct(int a, int b)
- {
- firstfield = a;
- value = b;
- }
- }
-
- struct DeepStruct2
- {
- #pragma warning disable 0649
- public DeepStruct1 value;
- #pragma warning restore 0649
- }
-
- struct DeepStruct1
- {
- #pragma warning disable 0649
- public DeepStruct0 value;
- #pragma warning restore 0649
- }
-
- struct DeepStruct0
- {
- public int value;
-
- public void SetValue(int value)
- {
- this.value = value;
- }
-
- public int GetValue()
- {
- return value;
- }
- }
-
- private struct CustomStruct2
- {
- public float value;
-
- public float returnDoubleValue()
- {
- return value;
- }
-
- public CustomStruct2(float initialValue)
- {
- value = initialValue;
- }
- }
-
- private struct TestVector4
- {
- public float x;
- public float y;
- public float z;
- public float w;
- }
-
- private struct StructWithBoolAsInt
- {
- private int _value;
-
- public StructWithBoolAsInt(bool value)
- {
- _value = value ? 1 : 0;
- }
-
- public static implicit operator bool(StructWithBoolAsInt val)
- {
- return val._value != 0;
- }
- }
-
- private struct TestNestedStruct
- {
- public TestVector4 v1;
- }
-
- private struct MultiAssignStruct
- {
- public float x;
- public float y;
- public float z;
-
- public MultiAssignStruct(float val)
- {
- x = y = z = val;
- }
- }
-
- private struct SelfReferenceStruct
- {
- #pragma warning disable 0649
- public int Value;
- public unsafe SelfReferenceStruct* Left;
- public unsafe SelfReferenceStruct* Right;
- #pragma warning restore 0649
- }
-
- private struct StructForSizeOf
- {
- #pragma warning disable 0649
-
- public IntPtr Value1;
-
- public Float4 Vec1;
-
- public IntPtr Value2;
-
- public Float4 Vec2;
- #pragma warning disable 0649
- }
-
- private struct StructWithStaticField
- {
- public static int MyField;
-
- public void CheckWrite()
- {
- MyField = 0;
- }
-
- public int CheckRead()
- {
- return MyField;
- }
- }
-
- private struct Float4
- {
- #pragma warning disable 0649
- public float x;
- public float y;
- public float z;
- public float w;
- #pragma warning restore 0649
- }
-
- private struct StructWithStaticVariables
- {
- #pragma warning disable 0414
- #pragma warning disable 0649
- const float static_const_float = 9;
- static string static_string = "hello";
-
- public float myFloat;
- public Float4 myFloat4;
-
- static float static_float_2 = 5;
- #pragma warning restore 0649
- #pragma warning restore 0414
- }
-
- struct StructDisposable : IDisposable
- {
- public int x;
-
-
- public void Dispose()
- {
- x++;
- }
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private struct Color
- {
- [FieldOffset(0)] public uint Value;
- [FieldOffset(0)] public byte R;
- [FieldOffset(1)] public byte G;
- [FieldOffset(2)] public byte B;
- [FieldOffset(3)] public byte A;
-
- public byte GetColorB()
- {
- return B;
- }
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private struct NumberPair
- {
- [FieldOffset(0)] public uint UnsignedA;
- [FieldOffset(0)] public int SignedA;
- [FieldOffset(4)] public uint UnsignedB;
- [FieldOffset(4)] public int SignedB;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private struct NestedExplicit0
- {
- [FieldOffset(0)] public NestedExplicit1 Next;
- [FieldOffset(0)] public int NextAsInt;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private struct NestedExplicit1
- {
- [FieldOffset(0)] public NestedExplicit2 Next;
- [FieldOffset(0)] public int NextAsInt;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private struct NestedExplicit2
- {
- [FieldOffset(0)] public float FValue;
- [FieldOffset(0)] public int IValue;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private struct FloatRepr
- {
- [FieldOffset(0)] public float Value;
- [FieldOffset(0)] public uint AsUint;
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 24)]
- private struct PaddedStruct
- {
- [FieldOffset(8)] public int Value;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private unsafe struct FixedArrayExplitLayoutStruct
- {
- [FieldOffset(0)] public fixed byte Bytes[8];
- [FieldOffset(0)] public fixed ushort Shorts[4];
- [FieldOffset(0)] public uint UpperUInt;
- [FieldOffset(4)] public uint LowerUInt;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- public unsafe struct Chunk
- {
- [FieldOffset(0)] public Chunk* Archetype;
- [FieldOffset(8)] public Chunk* metaChunkEntity;
-
- [FieldOffset(16)] public int Count;
- }
-
- [TestCompiler]
- public static unsafe int TestRegressionInvalidGetElementPtrStructLayout()
- {
- Chunk* c = stackalloc Chunk[1];
- c[0].Archetype = null;
- c[0].metaChunkEntity = null;
- c[0].Count = 0;
-
- return TestRegressionInvalidGetElementPtrStructLayoutInternal(0, 1, &c);
- }
-
- public static unsafe int TestRegressionInvalidGetElementPtrStructLayoutInternal(int index, int limit, Chunk** currentChunk)
- {
- int rValue = 0;
- while (index >= limit + 1)
- {
- rValue += (*currentChunk)->Count;
- index += 1;
- }
-
- return rValue;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- public unsafe struct Packet
- {
- [FieldOffset(0)] public int data;
- [FieldOffset(0)] public fixed byte moreData[1500];
- }
-
- [TestCompiler]
- public static unsafe int TestExplicitSizeReporting()
- {
- return sizeof(Packet);
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private struct ExplicitStructPackedButWithHoles
- {
- [FieldOffset(0)]
- public byte A;
-
- [FieldOffset(1)]
- public long B;
-
- [FieldOffset(21)]
- public byte C;
- }
-
- [TestCompiler]
- public static int TestExplicitStructPackedButWithHolesSize()
- {
- return UnsafeUtility.SizeOf<ExplicitStructPackedButWithHoles>();
- }
-
- [TestCompiler]
- public static unsafe int TestExplicitStructPackedButWithHolesOffsetC()
- {
- var value = new ExplicitStructPackedButWithHoles();
- var addressStart = &value;
- var addressField = &value.C;
- return (int)((byte*)addressField - (byte*)addressStart);
- }
-
- private struct ExplicitStructPackedButWithHolesContainer
- {
- public ExplicitStructPackedButWithHoles A;
- public int B;
- public ExplicitStructPackedButWithHoles C;
- }
-
- [TestCompiler]
- public static int TestExplicitStructPackedButWithHolesContainerSize()
- {
- return UnsafeUtility.SizeOf<ExplicitStructPackedButWithHolesContainer>();
- }
-
- [TestCompiler]
- public static unsafe int TestExplicitStructPackedButWithHolesContainerOffsetC()
- {
- var value = new ExplicitStructPackedButWithHolesContainer();
- var addressStart = &value;
- var addressField = &value.C;
- return (int)((byte*)addressField - (byte*)addressStart);
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private struct ExplicitStructNotPackedWithHoles
- {
- [FieldOffset(4)]
- public int A;
-
- [FieldOffset(12)]
- public int B;
- }
-
- [TestCompiler]
- public static int TestExplicitStructNotPackedWithHolesSize()
- {
- return UnsafeUtility.SizeOf<ExplicitStructNotPackedWithHoles>();
- }
-
- [TestCompiler]
- public static float TestExplicitStructNested()
- {
- StructWithNestUnion b;
- b.Value.Min = 5.0f;
-
- return b.Value.Min;
- }
-
- [TestCompiler]
- public static float TestExplicitStructNestedAsArgument()
- {
- float Helper(StructWithNestUnion outer)
- {
- return outer.Value.Min;
- }
-
- return Helper(new StructWithNestUnion
- {
- Value = new UnionValue { Min = 5.0f }
- });
- }
-
- public struct StructWithNestUnion
- {
- public UnionValue Value;
- }
-
- [StructLayout(LayoutKind.Explicit)]
-
- public struct UnionValue
- {
- [FieldOffset(0)]
- public float Min;
- [FieldOffset(4)]
- public float Max;
-
- [FieldOffset(0)]
- public uint Property;
- }
-
- #if UNITY_ANDROID || UNITY_IOS
- [Ignore("This test fails on mobile platforms")]
- #endif
- [TestCompiler(typeof(NetworkEndPoint.Provider), typeof(NetworkEndPoint.Provider), ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructByValueNotSupported)]
- public static bool TestABITransformIntoExplicitLayoutTransform(NetworkEndPoint a, NetworkEndPoint b)
- {
- return a.Compare(b);
- }
-
- [StructLayout(LayoutKind.Explicit)]
- public unsafe struct NetworkEndPoint
- {
- internal const int ArrayLength = 2;
- [FieldOffset(0)]
- internal fixed byte data[ArrayLength];
- [FieldOffset(0)]
- internal ushort family;
- [FieldOffset(28)]
- internal int length;
-
- public bool Compare(NetworkEndPoint other)
- {
- if (length != other.length)
- return false;
-
- return true;
- }
- public class Provider : IArgumentProvider
- {
- public object Value => default(NetworkEndPoint);
-
- }
- }
-
- public struct SequentialStructWithPaddingAndVectorField
- {
- public byte a;
- public float2 b;
-
- public class Provider : IArgumentProvider
- {
- public object Value => new SequentialStructWithPaddingAndVectorField { a = 1, b = new float2(4, 5) };
- }
- }
-
- #if UNITY_ANDROID || UNITY_IOS
- [Ignore("This test fails on mobile platforms")]
- #endif
- [TestCompiler(typeof(SequentialStructWithPaddingAndVectorField.Provider))]
- public static int TestSequentialStructWithPaddingAndVectorField(ref SequentialStructWithPaddingAndVectorField value)
- {
- return (int)value.b.x;
- }
-
- private static void TestSequentialStructWithPaddingAndVectorFieldRefHelper(ref SequentialStructWithPaddingAndVectorField value)
- {
- value.b.yx = value.b;
- value.b = value.b.yx;
- }
-
- #if UNITY_ANDROID || UNITY_IOS
- [Ignore("This test fails on mobile platforms")]
- #endif
- [TestCompiler(typeof(SequentialStructWithPaddingAndVectorField.Provider))]
- public static int TestSequentialStructWithPaddingAndVectorFieldRef(ref SequentialStructWithPaddingAndVectorField value)
- {
- TestSequentialStructWithPaddingAndVectorFieldRefHelper(ref value);
- return (int)value.b.x;
- }
-
- [TestCompiler]
- public static unsafe int TestSequentialStructWithPaddingAndVectorFieldPtr()
- {
- var vec = new float2(1, 2);
- var vecPtr = &vec;
- var value = new SequentialStructWithPaddingAndVectorField();
- value.b = *vecPtr;
- return (int)value.b.x;
- }
-
- [TestCompiler]
- public static unsafe int TestCreatingVectorTypeFromNonVectorScalarType()
- {
- var x = (short)4;
- var value = new int4(x, x, x, x);
- return value.w;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- public struct ExplicitVectors
- {
- [FieldOffset(0)]
- public int A;
- [FieldOffset(4)]
- public int2 B; //NB: Any Vector type is sufficient
- }
-
- [TestCompiler]
- public static unsafe int TestVectorLoadFromExplicitStruct()
- {
- var header = new ExplicitVectors { };
-
- return header.B.x;
- }
-
- [TestCompiler(DataRange.Standard)]
- public static unsafe int TestVectorStoreToExplicitStruct(ref int2 a)
- {
- var header = new ExplicitVectors { B = a };
-
- return header.B.x;
- }
-
- [TestCompiler(typeof(StructWithNonBlittableTypes), ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_TypeNotBlittableForFunctionPointer)]
- public static unsafe int TestStructWithNonBlittableTypes(ref StructWithNonBlittableTypes a)
- {
- var checksum = 0;
- checksum = (checksum * 397) ^ a.a0;
- checksum = (checksum * 397) ^ a.b0;
- checksum = (checksum * 397) ^ a.b1;
- checksum = (checksum * 397) ^ (a.d0 ? 10 : 0);
- checksum = (checksum * 397) ^ a.a1;
- checksum = (checksum * 397) ^ a.b1;
- checksum = (checksum * 397) ^ a.c1;
- checksum = (checksum * 397) ^ (a.d1 ? 0 : 7);
- checksum = (checksum * 397) ^ a.Check;
- return checksum;
- }
-
- [TestCompiler(typeof(StructWithNonBlittableTypesWithMarshalAs))]
- public static unsafe int TestStructWithBlittableTypesWithMarshalAs(ref StructWithNonBlittableTypesWithMarshalAs a)
- {
- var checksum = 0;
- checksum = (checksum * 397) ^ a.a0;
- checksum = (checksum * 397) ^ a.b0;
- checksum = (checksum * 397) ^ a.b1;
- checksum = (checksum * 397) ^ (a.d0 ? 10 : 0);
- checksum = (checksum * 397) ^ a.a1;
- checksum = (checksum * 397) ^ a.b1;
- checksum = (checksum * 397) ^ a.c1;
- checksum = (checksum * 397) ^ (a.d1 ? 0 : 7);
- checksum = (checksum * 397) ^ a.Check;
- return checksum;
- }
-
- [TestCompiler]
- public static int TestSizeOfStructWithBlittableTypesWithMarshalAs()
- {
- return UnsafeUtility.SizeOf<StructWithNonBlittableTypesWithMarshalAs>();
- }
-
- #if BURST_TESTS_ONLY
- [TestCompiler(typeof(StructWithNonBlittableTypes), ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_TypeNotBlittableForFunctionPointer)]
- public static int TestStructWithNonBlittableTypesOffset(ref StructWithNonBlittableTypes a)
- {
- return Unsafe.ByteOffset(ref a.a0, ref a.a1).ToInt32();
- }
- #endif
-
- [TestCompiler(typeof(StructWithBlittableTypes))]
- public static unsafe int TestStructWithBlittableTypes(ref StructWithBlittableTypes a)
- {
- var checksum = 0;
- checksum = (checksum * 397) ^ a.a;
- checksum = (checksum * 397) ^ a.b;
- checksum = (checksum * 397) ^ a.c;
- checksum = (checksum * 397) ^ a.d.x;
- checksum = (checksum * 397) ^ a.d.y;
- return checksum;
- }
-
- [TestCompiler]
- public static int TestStructWithPointerDependency()
- {
- var test = new StructWithPointerDependency();
- return test.DirectNoDependency.Value;
- }
-
- [TestCompiler]
- public static uint TestExplicitStructNestedFieldAccess()
- {
- var buffer = new StructWithNestUnionContainer();
- return buffer.Something.Value.Property;
- }
-
- public struct StructWithNestUnionContainer
- {
- public StructWithNestUnion Something => new StructWithNestUnion { Value = new UnionValue { Property = 42 } };
- }
-
- public struct StructWithBlittableTypes : IArgumentProvider
- {
- public StructWithBlittableTypes(int a, int b, int c, int2 d)
- {
- this.a = a;
- this.b = b;
- this.c = c;
- this.d = d;
- }
-
- public int a;
- public int b;
- public int c;
- public int2 d;
-
- public object Value => new StructWithBlittableTypes(1, 2, 3, new int2(4, 5));
- }
-
- public struct StructWithNonBlittableTypes : IArgumentProvider
- {
- public StructWithNonBlittableTypes(byte a0, byte b0, byte c0, bool d0, byte a1, byte b1, byte c1, bool d1, int check)
- {
- this.a0 = a0;
- this.b0 = b0;
- this.c0 = c0;
- this.d0 = d0;
- this.a1 = a1;
- this.b1 = b1;
- this.c1 = c1;
- this.d1 = d1;
- this.Check = check;
- }
-
- public byte a0;
- public byte b0;
- public byte c0;
- public bool d0;
-
- public byte a1;
- public byte b1;
- public byte c1;
- public bool d1;
-
- public int Check;
-
-
- public object Value => new StructWithNonBlittableTypes(1, 2, 3, true, 5, 6, 7, false, 0x12345678);
- }
-
- public struct StructWithNonBlittableTypesWithMarshalAs : IArgumentProvider
- {
- public StructWithNonBlittableTypesWithMarshalAs(byte a0, byte b0, byte c0, bool d0, byte a1, byte b1, byte c1, bool d1, int check)
- {
- this.a0 = a0;
- this.b0 = b0;
- this.c0 = c0;
- this.d0 = d0;
- this.a1 = a1;
- this.b1 = b1;
- this.c1 = c1;
- this.d1 = d1;
- this.Check = check;
- }
-
- public byte a0;
- public byte b0;
- public byte c0;
- [MarshalAs(UnmanagedType.U1)]
- public bool d0;
-
- public byte a1;
- public byte b1;
- public byte c1;
- [MarshalAs(UnmanagedType.U1)]
- public bool d1;
-
- public int Check;
-
-
- public object Value => new StructWithNonBlittableTypesWithMarshalAs(1, 2, 3, true, 5, 6, 7, false, 0x12345678);
- }
-
- public unsafe struct StructWithPointerDependency
- {
- public StructWithNoDependency* PointerToNoDependency;
-
- public StructWithNoDependency DirectNoDependency;
- }
-
- public struct StructWithNoDependency
- {
- public int Value;
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 4096)]
- public unsafe struct Sized4096
- {
- public byte First;
-
- public struct Provider : IArgumentProvider
- {
- public object Value => new Sized4096();
- }
- }
-
- [TestCompiler(typeof(Sized4096.Provider), typeof(Sized4096.Provider))]
- public static unsafe void TestSized4096(ref Sized4096 a, ref Sized4096 b)
- {
- a = b;
- }
-
- [TestCompiler(typeof(Sized4096.Provider), typeof(Sized4096.Provider))]
- public static unsafe void TestSized4096ManualCopy(ref Sized4096 a, ref Sized4096 b)
- {
- for (int i = 0; i < UnsafeUtility.SizeOf<Sized4096>(); i++)
- {
- fixed (byte* aBytes = &a.First, bBytes = &b.First)
- {
- aBytes[i] = bBytes[i];
- }
- }
- }
-
- [TestCompiler(typeof(Sized4096.Provider), typeof(Sized4096.Provider))]
- public static unsafe void TestSized4096CopyToAlloca(ref Sized4096 a, ref Sized4096 b)
- {
- Sized4096 c = b;
- (&c.First)[4] = 42;
- a = c;
- }
-
- [TestCompiler(typeof(Sized4096.Provider), typeof(Sized4096.Provider))]
- public static unsafe void TestSized4096CopyToStackAlloc0(ref Sized4096 a, ref Sized4096 b)
- {
- Sized4096* c = stackalloc Sized4096[1];
- (&c->First)[4] = 42;
- a = *c;
- }
-
- [TestCompiler(typeof(Sized4096.Provider), typeof(Sized4096.Provider))]
- public static unsafe void TestSized4096CopyToStackAlloc1(ref Sized4096 a, ref Sized4096 b)
- {
- byte* bytes = stackalloc byte[4096];
- Sized4096* c = (Sized4096*)bytes;
- (&c->First)[4] = 42;
- a = *c;
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 4096)]
- public struct MultipleSized4096
- {
- public Sized4096 a;
- public Sized4096 b;
-
- public struct Provider : IArgumentProvider
- {
- public object Value => new MultipleSized4096 { a = new Sized4096(), b = new Sized4096() };
- }
- }
-
- [TestCompiler(typeof(MultipleSized4096.Provider), typeof(Sized4096.Provider))]
- public static void TestMultipleSized4096(ref MultipleSized4096 a, ref Sized4096 b)
- {
- a.a = b;
- a.a.First = 42;
- b = a.b;
- }
-
- [TestCompiler(typeof(MultipleSized4096.Provider), typeof(Sized4096.Provider), typeof(Sized4096.Provider))]
- public static void TestMultipleSized4096CopyToAlloca(ref MultipleSized4096 a, ref Sized4096 b, ref Sized4096 c)
- {
- MultipleSized4096 d = default;
- d.a = b;
- b = d.b;
- c = a.a;
- a = d;
- }
-
- public unsafe struct Fixed4096
- {
- public fixed byte First[4096];
-
- public struct Provider : IArgumentProvider
- {
- public object Value => new Fixed4096();
- }
- }
-
- [TestCompiler(typeof(Fixed4096.Provider), typeof(Fixed4096.Provider))]
- public static unsafe void TestFixed4096(ref Fixed4096 a, ref Fixed4096 b)
- {
- a = b;
- }
-
- [TestCompiler(typeof(Fixed4096.Provider), typeof(Fixed4096.Provider))]
- public static unsafe void TestFixed4096ManualCopy(ref Fixed4096 a, ref Fixed4096 b)
- {
- for (int i = 0; i < UnsafeUtility.SizeOf<Fixed4096>(); i++)
- {
- a.First[i] = b.First[i];
- }
- }
-
- [TestCompiler(typeof(Fixed4096.Provider), typeof(Fixed4096.Provider))]
- public static unsafe void TestFixed4096CopyToAlloca(ref Fixed4096 a, ref Fixed4096 b)
- {
- Fixed4096 c = b;
- c.First[4] = 42;
- a = c;
- }
-
- [TestCompiler(typeof(Fixed4096.Provider), typeof(Fixed4096.Provider))]
- public static unsafe void TestFixed4096CopyToStackAlloc0(ref Fixed4096 a, ref Fixed4096 b)
- {
- Fixed4096* c = stackalloc Fixed4096[1];
- c->First[4] = 42;
- a = *c;
- }
-
- [TestCompiler(typeof(Fixed4096.Provider), typeof(Fixed4096.Provider))]
- public static unsafe void TestFixed4096CopyToStackAlloc1(ref Fixed4096 a, ref Fixed4096 b)
- {
- byte* bytes = stackalloc byte[4096];
- Fixed4096* c = (Fixed4096*)bytes;
- c->First[4] = 42;
- a = *c;
- }
-
- public unsafe struct PointersInStruct
- {
- public byte* a;
- public byte* b;
-
- public struct Provider : IArgumentProvider
- {
- public object Value => new PointersInStruct { a = null, b = null };
- }
- }
-
- [TestCompiler(typeof(PointersInStruct.Provider), typeof(Fixed4096.Provider))]
- public static unsafe void TestPointersInStruct(ref PointersInStruct a, ref Fixed4096 b)
- {
- fixed (byte* ptr = b.First)
- {
- a.a = ptr;
- }
-
- a.b = a.a;
- }
-
- private static unsafe T GenericGetT<T>(T* t) where T : unmanaged
- {
- return *t;
- }
-
- [TestCompiler(typeof(Fixed4096.Provider), typeof(Fixed4096.Provider))]
- public static unsafe void TestGetStructThroughGeneric(ref Fixed4096 a, ref Fixed4096 b)
- {
- fixed (void* ptr = &a)
- {
- var elem = GenericGetT<Fixed4096>((Fixed4096*) ptr);
- b = elem;
- }
- }
-
- [TestCompiler(typeof(Fixed4096.Provider), typeof(Fixed4096.Provider))]
- public static unsafe void TestGetStructThroughReadArrayElement(ref Fixed4096 a, ref Fixed4096 b)
- {
- fixed (void* ptr = &a)
- {
- var elem = UnsafeUtility.ReadArrayElement<Fixed4096>(ptr, 0);
- b = elem;
- }
- }
-
- [TestCompiler(typeof(Fixed4096.Provider), typeof(Fixed4096.Provider))]
- public static unsafe void TestSetStructThroughWriteArrayElement(ref Fixed4096 a, ref Fixed4096 b)
- {
- fixed (void* ptr = &a)
- {
- var elem = a;
- UnsafeUtility.WriteArrayElement(ptr, 0, elem);
- }
- }
-
- private struct Fixed1021
- {
- public unsafe fixed byte Data[1021];
- }
-
- [TestCompiler(typeof(Fixed4096.Provider))]
- public static unsafe void TestGetSetStructThroughReadWriteArrayElement(ref Fixed4096 a)
- {
- fixed (void* ptr1 = &a)
- {
- var ptr2 = (byte*) ptr1 + 1;
- UnsafeUtility.WriteArrayElement(ptr1, 0, UnsafeUtility.ReadArrayElement<Fixed1021>(ptr2, 0));
- }
- }
-
- [TestCompiler(typeof(Fixed4096.Provider))]
- public static unsafe void TestGetSetStructThroughReadWriteArrayElementNoAlias(ref Fixed4096 a)
- {
- fixed (void* ptr1 = &a)
- {
- var ptr2 = (byte*) ptr1 + UnsafeUtility.SizeOf<Fixed1021>();
- UnsafeUtility.WriteArrayElement(ptr1, 0, UnsafeUtility.ReadArrayElement<Fixed1021>(ptr2, 0));
- }
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 2)]
- public struct WithPadding
- {
- public byte A;
-
- public struct Provider : IArgumentProvider
- {
- public object Value => new WithPadding { A = 42 };
- }
- }
-
- private static readonly WithPadding withPadding = new WithPadding { A = 42 };
-
- [TestCompiler(typeof(ReturnBox))]
- public static unsafe byte TestWithPadding(WithPadding* o)
- {
- *o = withPadding;
- return withPadding.A;
- }
-
- [CompilerGenerated]
- [StructLayout(LayoutKind.Sequential)]
- public unsafe struct MyCompilerGeneratedButNotReally
- {
- public fixed int A[1];
- }
-
- private static readonly MyCompilerGeneratedButNotReally myCompilerGeneratedButNotReally = new MyCompilerGeneratedButNotReally { };
-
- [TestCompiler(typeof(ReturnBox))]
- public static unsafe int TestMyCompilerGeneratedButNotReallyStruct(MyCompilerGeneratedButNotReally* o)
- {
- *o = myCompilerGeneratedButNotReally;
-
- fixed (int* a = myCompilerGeneratedButNotReally.A)
- {
- return *a;
- }
- }
-
- public unsafe struct UninitFieldsAreZero
- {
- public fixed ushort a[3];
- public fixed byte b[3];
-
- public UninitFieldsAreZero(ushort x, ushort y, ushort z)
- {
- a[0] = x;
- a[1] = y;
- a[2] = z;
- }
- }
-
- [TestCompiler(typeof(ReturnBox))]
- public static unsafe void TestUninitFieldsAreZero(UninitFieldsAreZero* o)
- {
- o->a[0] = 42;
- o->a[1] = 42;
- o->a[2] = 42;
- o->b[0] = 42;
- o->b[1] = 42;
- o->b[2] = 42;
-
- var n = new UninitFieldsAreZero(13, 53, 4);
-
- *o = n;
- }
-
- #pragma warning disable 0649
- private struct ExplicitSizesMatchB
- {
- public uint U;
- }
- private struct ExplicitSizesMatchC
- {
- public ulong L;
- public uint U;
- public ushort S;
- public byte B;
- }
- [StructLayout(LayoutKind.Explicit)]
- private struct ExplicitSizesMatch
- {
- [FieldOffset(0)] public int A;
- [FieldOffset(4)] public ExplicitSizesMatchB B;
- [FieldOffset(4)] public ExplicitSizesMatchC C;
- }
- #pragma warning restore 0649
- [TestCompiler]
- public static unsafe int TestExplicitSizesMatch()
- {
- return sizeof(ExplicitSizesMatch);
- }
-
- #if BURST_TESTS_ONLY
- private struct ExplicitLayoutAndBoolStruct
- {
- [StructLayout(LayoutKind.Explicit)]
- public struct ExplicitLayoutStruct
- {
- [FieldOffset(0)]
- public byte Byte;
- }
-
- // Having `bool` AND a field whose type is an explicit-layout struct
- // causes .NET to fallback to auto-layout for the containing struct.
- public bool Bool;
- public ExplicitLayoutStruct ExplicitLayout;
- public long Int64;
- }
-
- // This test just exists to verify that .NET does indeed do the fallback
- // to auto-layout that we expect it does, since this is the underlying
- // reason for us to prevent the combination of
- // "bool + explicit-layout struct".
- [Test]
- [WindowsOnly(".NET falls back to auto-layout for this struct, but Mono doesn't")]
- public static unsafe void TestExplicitLayoutAndBoolCausesDotNetToFallbackToAutoLayout()
- {
- var s = new ExplicitLayoutAndBoolStruct();
-
- var offsetStart = (IntPtr)(&s);
- var offsetField = (IntPtr)(&s.Int64);
-
- var offset = offsetField.ToInt64() - offsetStart.ToInt64();
-
- // We would expect the offset to the `Int64` field to be 8.
- // But because .NET falls back to auto-layout,
- // and places the `Int64` field first,
- // the offset is actually 0.
- Assert.AreEqual((long)0, offset);
- }
-
- [TestCompiler(EnableAutoLayoutFallbackCheck = true, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_NonBlittableAndNonManagedSequentialStructNotSupported)]
- public static long TestExplicitLayoutAndBoolIsNotSupported()
- {
- return new ExplicitLayoutAndBoolStruct { Int64 = 8 }.Int64;
- }
-
- private struct ExplicitLayoutNestedAndBoolStruct
- {
- public struct SequentialLayoutStruct
- {
- #pragma warning disable 0649
- public ExplicitLayoutStruct ExplicitLayout;
- #pragma warning restore 0649
- }
-
- [StructLayout(LayoutKind.Explicit)]
- public struct ExplicitLayoutStruct
- {
- [FieldOffset(0)]
- public byte Byte;
- }
-
- #pragma warning disable 0649
- public bool Bool;
- public SequentialLayoutStruct SequentialLayout;
- #pragma warning restore 0649
- public long Int64;
- }
-
- [TestCompiler(EnableAutoLayoutFallbackCheck = true, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_NonBlittableAndNonManagedSequentialStructNotSupported)]
- public static long TestExplicitLayoutNestedAndBoolIsNotSupported()
- {
- return new ExplicitLayoutNestedAndBoolStruct { Int64 = 8 }.Int64;
- }
-
- private struct ExplicitLayoutStructAndBoolWithMarshalAs
- {
- [StructLayout(LayoutKind.Explicit)]
- public struct ExplicitLayoutStruct
- {
- [FieldOffset(0)]
- public byte Byte;
- }
-
- #pragma warning disable 0649
- [MarshalAs(UnmanagedType.U1)]
- public bool Bool;
- public ExplicitLayoutStruct ExplicitLayout;
- #pragma warning restore 0649
- public long Int64;
- }
-
- [TestCompiler(EnableAutoLayoutFallbackCheck = true, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_NonBlittableAndNonManagedSequentialStructNotSupported)]
- public static unsafe long TestExplicitLayoutAndBoolWithMarshalAsIsNotSupported()
- {
- return new ExplicitLayoutStructAndBoolWithMarshalAs { Int64 = 8 }.Int64;
- }
- #endif
-
- private struct SequentialLayoutAndBoolStruct
- {
- public struct SequentialLayoutStruct
- {
- #pragma warning disable 0649
- public byte Byte;
- #pragma warning restore 0649
- }
-
- #pragma warning disable 0649
- public bool Bool;
- public SequentialLayoutStruct SequentialLayout;
- #pragma warning restore 0649
- public long Int64;
- }
-
- [TestCompiler]
- public static unsafe long TestSequentialLayoutAndBoolIsSupported()
- {
- return new SequentialLayoutAndBoolStruct { Int64 = 8 }.Int64;
- }
- }
- }
|