12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781 |
- 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 TestStructSizingExplicitStructWithSizeAndPack8()
- {
- return UnsafeUtility.SizeOf<StructExplicitWithSizeAndPack8>();
- }
-
- private struct StructExplicitWithSizeAndPack8Wrapper
- {
- public byte FieldA;
- public StructExplicitWithSizeAndPack8 FieldB;
-
- public StructExplicitWithSizeAndPack8Wrapper(byte a, StructExplicitWithSizeAndPack8 b)
- {
- FieldA = a;
- FieldB = b;
- }
- }
-
- [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.Sequential, Size = 12)]
- private struct StructSequentialWithSizeSmallerThanNatural
- {
- public double FieldA;
- public int FieldB;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_StructSizeNotSupported)]
- public static unsafe int TestStructSequentialWithSizeSmallerThanNatural()
- {
- return UnsafeUtility.SizeOf<StructSequentialWithSizeSmallerThanNatural>();
- }
-
- [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
-
- /* Unsafe.ByteOffset - Disabled in net core 7 due to :
-
- Framework Net 7
-
-
- IL_0000: ldarg.1 IL_0000: newobj System.Void System.PlatformNotSupportedException::.ctor()
- IL_0001: ldarg.0 IL_0005: throw args(IL_0000(newobj))
- IL_0002: sub args(IL_0000(ldarg.1), IL_0001(ldarg.0))
- IL_0003: ret args(IL_0002(sub))
- */
- [TestCompiler(typeof(StructWithNonBlittableTypes), ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_TypeNotBlittableForFunctionPointer,
- IgnoreOnNetCore = true)]
- 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;
- }
-
- #if NETFRAMEWORK
- // Note on Net7 the issue this is testing for is fixed.
-
- // 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]
- [RestrictPlatform(".NET falls back to auto-layout for this struct, but Mono doesn't", Platform.Windows)]
- 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);
- }
- #endif
-
- [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;
- }
- }
- }
|