No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

031-Pointers.cs 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.InteropServices;
  5. using Unity.Burst;
  6. using Unity.Collections;
  7. using Unity.Collections.LowLevel.Unsafe;
  8. using Unity.Jobs;
  9. using Unity.Mathematics;
  10. using UnityBenchShared;
  11. namespace Burst.Compiler.IL.Tests
  12. {
  13. internal class Pointers
  14. {
  15. [TestCompiler(1)]
  16. [TestCompiler(4)]
  17. [TestCompiler(5)]
  18. public static int CheckAddressOf(int a)
  19. {
  20. var value = new MyIntValue(a);
  21. ref int intValue = ref value.GetValuePtr();
  22. return intValue * 10 + 1;
  23. }
  24. public struct MyIntValue
  25. {
  26. public MyIntValue(int value)
  27. {
  28. Value = value;
  29. }
  30. public int Value;
  31. public unsafe ref int GetValuePtr()
  32. {
  33. fixed (void* ptr = &this)
  34. {
  35. return ref *(int*) ptr;
  36. }
  37. }
  38. }
  39. [TestCompiler(0, MyCastEnum.Value2)]
  40. [TestCompiler(1, MyCastEnum.Value0)]
  41. [TestCompiler(2, MyCastEnum.Value3)]
  42. public static unsafe MyCastEnum PointerCastEnum(int value, MyCastEnum newValue)
  43. {
  44. var ptvalue = new IntPtr(&value);
  45. var pEnum = (MyCastEnum*) ptvalue;
  46. *pEnum = newValue;
  47. return *pEnum;
  48. }
  49. #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_0_OR_GREATER
  50. [TestCompiler(50, 50)]
  51. public static unsafe bool PointerIEquatable(IntPtr a, IntPtr b)
  52. {
  53. return a.Equals(b); // This
  54. }
  55. #endif
  56. [TestCompiler(0, 0)]
  57. [TestCompiler(0, 1)]
  58. [TestCompiler(1, 0)]
  59. public static unsafe bool PointerCompare(IntPtr a, IntPtr b)
  60. {
  61. return a == b;
  62. }
  63. [TestCompiler(0)]
  64. [TestCompiler(1)]
  65. [TestCompiler(2)]
  66. public static unsafe bool RawPointerCompare(IntPtr value)
  67. {
  68. return (void*)value == (void*)1;
  69. }
  70. [TestCompiler(0)]
  71. [TestCompiler(1)]
  72. [TestCompiler(42424242)]
  73. [TestCompiler(0xC0FFEE4DEADBEEF)]
  74. public static unsafe int PointerHash(IntPtr value)
  75. {
  76. return value.GetHashCode();
  77. }
  78. [TestCompiler(0)]
  79. [TestCompiler(1)]
  80. [TestCompiler(42424242)]
  81. public static unsafe IntPtr PointerToPointer(IntPtr value)
  82. {
  83. return new IntPtr(value.ToPointer());
  84. }
  85. [TestCompiler(0, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_CallingManagedMethodNotSupported)]
  86. public static unsafe int PointerToString(IntPtr value)
  87. {
  88. return value.ToString().Length;
  89. }
  90. [TestCompiler(1)]
  91. [TestCompiler(255)]
  92. [TestCompiler(12351235)]
  93. public static unsafe int PointerAdd(int a)
  94. {
  95. var pA = (byte*)&a;
  96. var pDest = pA + 3;
  97. *pDest = (byte)a;
  98. return a;
  99. }
  100. [TestCompiler(1)]
  101. [TestCompiler(255)]
  102. [TestCompiler(12351235)]
  103. public static unsafe int PointerSub(int a)
  104. {
  105. var pA = (byte*)&a;
  106. var pDest = pA + 3;
  107. *(pDest - 1) = (byte)a;
  108. return a;
  109. }
  110. [TestCompiler]
  111. public static unsafe int PointerPointerSub()
  112. {
  113. var value = new StructForPointerPointerSub();
  114. int* pa = &value.A;
  115. int* pb = &value.B;
  116. var auto = (pb - pa);
  117. return (int)auto;
  118. }
  119. [TestCompiler]
  120. public static unsafe int WhileWithPointer()
  121. {
  122. var check = new CheckPointers { X = 1, Y = 2, Z = 3, W = 4 };
  123. int* pstart = &check.X;
  124. int* pend = &check.W;
  125. int result = 0;
  126. while (pstart <= pend)
  127. {
  128. result += *pstart;
  129. pstart++;
  130. }
  131. return result;
  132. }
  133. struct StructForPointerPointerSub
  134. {
  135. public int A;
  136. public int B;
  137. }
  138. [TestCompiler(1)]
  139. [TestCompiler(255)]
  140. [TestCompiler(12351235)]
  141. public static IntPtr IntPtrConstructor(int a)
  142. {
  143. return new IntPtr(a);
  144. }
  145. [TestCompiler(1U)]
  146. [TestCompiler(255U)]
  147. [TestCompiler(12351235U)]
  148. public static UIntPtr UIntPtrConstructor(uint a)
  149. {
  150. return new UIntPtr(a);
  151. }
  152. [TestCompiler(1)]
  153. [TestCompiler(255)]
  154. [TestCompiler(12351235)]
  155. public static int IntPtrToInt32(int a)
  156. {
  157. return new IntPtr(a).ToInt32();
  158. }
  159. [TestCompiler(1)]
  160. [TestCompiler(255)]
  161. [TestCompiler(12351235)]
  162. public static long IntPtrToInt64(int a)
  163. {
  164. return new IntPtr(a).ToInt64();
  165. }
  166. [TestCompiler(OverrideOn32BitNative = 4)]
  167. public static int IntPtrSize()
  168. {
  169. return IntPtr.Size;
  170. }
  171. // asserted in IntPtrProcessor
  172. [TestCompiler(OverrideOn32BitNative = true)]
  173. public static bool IntPtrSizeCompared()
  174. {
  175. return IntPtr.Size == 4;
  176. }
  177. [TestCompiler]
  178. public static IntPtr IntPtrZero()
  179. {
  180. return IntPtr.Zero;
  181. }
  182. [TestCompiler(1)]
  183. [TestCompiler(5)]
  184. public static IntPtr IntPtrAdd(IntPtr a)
  185. {
  186. return IntPtr.Add(a, 1);
  187. }
  188. [TestCompiler(1)]
  189. [TestCompiler(5)]
  190. public static IntPtr IntPtrAdd2(IntPtr a)
  191. {
  192. return a + 1;
  193. }
  194. [TestCompiler(1)]
  195. [TestCompiler(5)]
  196. public static IntPtr IntPtrSub(IntPtr a)
  197. {
  198. return IntPtr.Subtract(a, 1);
  199. }
  200. [TestCompiler(1)]
  201. [TestCompiler(5)]
  202. public static IntPtr IntPtrSub2(IntPtr a)
  203. {
  204. return a - 1;
  205. }
  206. [TestCompiler]
  207. public static UIntPtr UIntPtrZero()
  208. {
  209. return UIntPtr.Zero;
  210. }
  211. [TestCompiler(1U)]
  212. [TestCompiler(5U)]
  213. public static UIntPtr UIntPtrAdd(UIntPtr a)
  214. {
  215. return UIntPtr.Add(a, 1);
  216. }
  217. [TestCompiler(1U)]
  218. [TestCompiler(5U)]
  219. public static UIntPtr UIntPtrSubstract(UIntPtr a)
  220. {
  221. return UIntPtr.Subtract(a, 1);
  222. }
  223. [TestCompiler(1)]
  224. public static unsafe int PointerAccess(int a)
  225. {
  226. var value = a;
  227. var pValue = &value;
  228. pValue[0] = a + 5;
  229. return value;
  230. }
  231. [TestCompiler(0)] // Keep it at 0 only!
  232. public static unsafe int PointerAccess2(int a)
  233. {
  234. int value = 15;
  235. var pValue = &value;
  236. pValue[a] = value + 5;
  237. return value;
  238. }
  239. [TestCompiler(0)] // Keep it at 0 only!
  240. public static unsafe float PointerAccess3(int a)
  241. {
  242. float value = 15.0f;
  243. var pValue = &value;
  244. pValue[a] = value + 5.0f;
  245. return value;
  246. }
  247. [TestCompiler(0)]
  248. public static unsafe int PointerCompareViaInt(int a)
  249. {
  250. int b;
  251. if (&a == &b)
  252. return 1;
  253. else
  254. return 0;
  255. }
  256. [TestCompiler(0)]
  257. public static unsafe int IntPtrCompare(int a)
  258. {
  259. int b;
  260. IntPtr aPtr = (IntPtr)(&a);
  261. IntPtr bPtr = (IntPtr)(&b);
  262. if (aPtr == bPtr)
  263. return 1;
  264. else
  265. return 0;
  266. }
  267. [TestCompiler(typeof(IntPtrZeroProvider), 1)]
  268. [TestCompiler(typeof(IntPtrOneProvider), 2)]
  269. public static unsafe int UnsafeCompare(int* a, int b)
  270. {
  271. if (a == null)
  272. {
  273. return 1 + b;
  274. }
  275. return 2 + b;
  276. }
  277. unsafe struct NativeQueueBlockHeader
  278. {
  279. #pragma warning disable 0649
  280. public byte* nextBlock;
  281. public int itemsInBlock;
  282. #pragma warning restore 0649
  283. }
  284. [TestCompiler]
  285. public static unsafe void PointerCastWithStruct()
  286. {
  287. byte* currentWriteBlock = null;
  288. if (currentWriteBlock != null && ((NativeQueueBlockHeader*) currentWriteBlock)->itemsInBlock == 100)
  289. {
  290. ((NativeQueueBlockHeader*) currentWriteBlock)->itemsInBlock = 5;
  291. }
  292. }
  293. private class IntPtrZeroProvider : IArgumentProvider
  294. {
  295. public object Value => IntPtr.Zero;
  296. }
  297. private class IntPtrOneProvider : IArgumentProvider
  298. {
  299. public object Value => new IntPtr(1);
  300. }
  301. [TestCompiler]
  302. public static unsafe int FixedField()
  303. {
  304. var fixedStruct = new MyStructWithFixed();
  305. fixedStruct.Values[0] = 1;
  306. fixedStruct.Values[1] = 2;
  307. fixedStruct.Values[2] = 3;
  308. fixedStruct.Values[9] = 9;
  309. int result = 0;
  310. for (int i = 0; i < 10; i++)
  311. {
  312. result += fixedStruct.Values[i];
  313. }
  314. return result;
  315. }
  316. [TestCompiler(typeof(MyStructWithFixedProvider), 1)]
  317. //[TestCompiler(typeof(MyStructWithFixedProvider), 2)]
  318. public static unsafe int FixedFieldViaPointer(ref MyStructWithFixed fixedStruct, int i)
  319. {
  320. fixed (MyStructWithFixed* check = &fixedStruct)
  321. {
  322. int* data = check->Values;
  323. return data[i];
  324. }
  325. }
  326. [TestCompiler(typeof(MyStructWithFixedProvider))]
  327. public static unsafe int FixedInt32AndRefInt32(ref MyStructWithFixed fixedStruct)
  328. {
  329. fixed (int* data = &fixedStruct.Value)
  330. {
  331. // We do a call to ProcessInt after with a ref int
  332. // to check that we don't collide with the PinnedType introduced by the previous
  333. // fixed statement
  334. ProcessInt(ref *data);
  335. }
  336. return fixedStruct.Value;
  337. }
  338. private static void ProcessInt(ref int value)
  339. {
  340. value += 5;
  341. }
  342. public unsafe struct ConditionalTestStruct
  343. {
  344. public void* a;
  345. public void* b;
  346. }
  347. public unsafe struct PointerConditional : IJob, IDisposable
  348. {
  349. public ConditionalTestStruct* t;
  350. public void Execute()
  351. {
  352. t->b = t->a != null ? t->a : null;
  353. }
  354. public struct Provider : IArgumentProvider
  355. {
  356. public object Value
  357. {
  358. get
  359. {
  360. var value = new PointerConditional();
  361. value.t = (ConditionalTestStruct*)UnsafeUtility.Malloc(UnsafeUtility.SizeOf<ConditionalTestStruct>(), 4, Allocator.Persistent);
  362. value.t->a = (void*)0x12345678;
  363. value.t->b = null;
  364. return value;
  365. }
  366. }
  367. }
  368. public void Dispose()
  369. {
  370. UnsafeUtility.Free(t, Allocator.Persistent);
  371. }
  372. }
  373. [TestCompiler(typeof(PointerConditional.Provider))]
  374. public static unsafe bool TestConditionalPointer([NoAlias] ref PointerConditional job)
  375. {
  376. job.Execute();
  377. return job.t->a == job.t->b;
  378. }
  379. #if BURST_TESTS_ONLY
  380. // Disabled on .Net 7 due to Unsafe.ByteOffset
  381. [TestCompiler(IgnoreOnNetCore = true)]
  382. public static int TestFieldOffset()
  383. {
  384. var t = default(StructWithFields);
  385. return (int)Unsafe.ByteOffset(ref Unsafe.As<int, bool>(ref t.a), ref t.d);
  386. }
  387. #endif
  388. public struct StructWithFields
  389. {
  390. public int a;
  391. public int b;
  392. public bool c;
  393. public bool d;
  394. public bool e;
  395. public bool f;
  396. }
  397. public unsafe struct MyStructWithFixed
  398. {
  399. public fixed int Values[10];
  400. public int Value;
  401. }
  402. private struct MyStructWithFixedProvider : IArgumentProvider
  403. {
  404. public unsafe object Value
  405. {
  406. get
  407. {
  408. var field = new MyStructWithFixed();
  409. for (int i = 0; i < 10; i++)
  410. {
  411. field.Values[i] = (i + 1) * 5;
  412. }
  413. field.Value = 1235;
  414. return field;
  415. }
  416. }
  417. }
  418. [TestCompiler(0)]
  419. public static unsafe void TestCellVisibleInternal(int length)
  420. {
  421. int3* cellVisibleRequest = (int3*)0;
  422. bool*cellVisibleResult = (bool*)0;
  423. int3* visibleCells = (int3*)0;
  424. IsCellVisibleInternal(cellVisibleRequest, cellVisibleResult, visibleCells, length, length);
  425. }
  426. static unsafe void IsCellVisibleInternal(int3* cellVisibleRequest, bool* cellVisibleResult, int3* visibleCells, int requestLength, int visibleCellsLength)
  427. {
  428. for (int r = 0; r < requestLength; r++)
  429. {
  430. cellVisibleResult[r] = false;
  431. for (int i = 0; i < visibleCellsLength; i++)
  432. {
  433. if (visibleCells[i].x == cellVisibleRequest[r].x && visibleCells[i].y == cellVisibleRequest[r].y && visibleCells[i].z == cellVisibleRequest[r].z)
  434. {
  435. cellVisibleResult[r] = true;
  436. break;
  437. }
  438. }
  439. }
  440. }
  441. public enum MyCastEnum
  442. {
  443. Value0 = 0,
  444. Value1 = 1,
  445. Value2 = 2,
  446. Value3 = 3,
  447. }
  448. public struct CheckPointers
  449. {
  450. public int X;
  451. public int Y;
  452. public int Z;
  453. public int W;
  454. }
  455. // From https://github.com/Unity-Technologies/ECSJobDemos/issues/244
  456. [TestCompiler]
  457. public static unsafe int InitialiseViaCastedPointer()
  458. {
  459. int value = 0;
  460. void* ptr = &value;
  461. byte* asBytePtr = (byte*)ptr;
  462. ((int*)asBytePtr)[0] = -1;
  463. return value;
  464. }
  465. [TestCompiler(1)]
  466. public static unsafe int PointerWriteArg(int a)
  467. {
  468. return (int)TestPointerAndGeneric<float>((int*) a);
  469. }
  470. private static unsafe int* TestPointerAndGeneric<T>(int* p) where T : struct
  471. {
  472. p = (int*)(IntPtr)26;
  473. return p;
  474. }
  475. [TestCompiler(ExpectedDiagnosticId = DiagnosticId.WRN_ExceptionThrownInNonSafetyCheckGuardedFunction)]
  476. public static void TestBlobAssetReferenceData()
  477. {
  478. var blob = new BlobAssetReferenceData(IntPtr.Zero);
  479. blob.Validate();
  480. }
  481. [StructLayout(LayoutKind.Explicit, Size = 16)]
  482. internal unsafe struct BlobAssetHeader
  483. {
  484. [FieldOffset(0)] public void* ValidationPtr;
  485. [FieldOffset(8)] public int Length;
  486. [FieldOffset(12)] public Allocator Allocator;
  487. }
  488. internal unsafe struct BlobAssetReferenceData
  489. {
  490. [NativeDisableUnsafePtrRestriction]
  491. public byte* _ptr;
  492. public BlobAssetReferenceData(IntPtr zero)
  493. {
  494. _ptr = (byte*)zero;
  495. }
  496. internal BlobAssetHeader* Header => ((BlobAssetHeader*)_ptr) - 1;
  497. public void Validate()
  498. {
  499. if (_ptr != null)
  500. if (Header->ValidationPtr != _ptr)
  501. throw new InvalidOperationException("The BlobAssetReference is not valid. Likely it has already been unloaded or released");
  502. }
  503. }
  504. internal unsafe struct StackAllocCheck
  505. {
  506. public int* ptr;
  507. [MethodImpl(MethodImplOptions.NoInlining)]
  508. public void AddToPtr(int* otherPtr)
  509. {
  510. *otherPtr = 42;
  511. *ptr += 1;
  512. *ptr += *otherPtr;
  513. }
  514. public class Provider : IArgumentProvider
  515. {
  516. public object Value => new StackAllocCheck();
  517. }
  518. }
  519. [TestCompiler(typeof(StackAllocCheck.Provider))]
  520. public static unsafe bool StackAllocAliasCheck([NoAlias] ref StackAllocCheck stackAllocCheck)
  521. {
  522. int* ptr = stackalloc int[1];
  523. *ptr = 13;
  524. stackAllocCheck.ptr = ptr;
  525. stackAllocCheck.AddToPtr(ptr);
  526. if (*ptr != 86)
  527. {
  528. return false;
  529. }
  530. *stackAllocCheck.ptr = -4;
  531. *ptr += 1;
  532. *ptr += *stackAllocCheck.ptr;
  533. if (*ptr != -6)
  534. {
  535. return false;
  536. }
  537. return true;
  538. }
  539. [TestCompiler(1)]
  540. public static unsafe int NativeIntAddCheck(int a)
  541. {
  542. return (int)(&a + 1) - (int)&a;
  543. }
  544. public unsafe struct PointerArithmetic : IJob, IDisposable
  545. {
  546. [NativeDisableUnsafePtrRestriction] public int** pointers;
  547. public void Execute()
  548. {
  549. pointers[10] = pointers[10] + +1;
  550. pointers[20] = pointers[20] - +1;
  551. pointers[30] = pointers[30] - -1;
  552. pointers[40] = pointers[40] + -1;
  553. }
  554. public struct Provider : IArgumentProvider
  555. {
  556. public object Value
  557. {
  558. get
  559. {
  560. var value = new PointerArithmetic();
  561. value.pointers = (int**)UnsafeUtility.Malloc(1000*sizeof(int*), 8, Allocator.Persistent);
  562. UnsafeUtility.MemClear(value.pointers, 1000 * sizeof(int*));
  563. return value;
  564. }
  565. }
  566. }
  567. public void Dispose()
  568. {
  569. UnsafeUtility.Free(pointers, Allocator.Persistent);
  570. }
  571. }
  572. // The arithmetic test has been split to make it easier to see the mismatched value (rather than true!=false)
  573. // According to : https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/unsafe-code#pointer-types
  574. // Conversion between pointers and integrals is "Implementation Defined".
  575. [TestCompiler(typeof(PointerArithmetic.Provider))]
  576. public static unsafe Int64 TestArithmeticPointerA(ref PointerArithmetic job)
  577. {
  578. job.Execute();
  579. if (sizeof(int*) == 4)
  580. return (Int64)(UInt32)(job.pointers[10]); // Workaround IL2CPP 32bit Bug : https://fogbugz.unity3d.com/f/cases/1254635/
  581. return (Int64)job.pointers[10];
  582. }
  583. [TestCompiler(typeof(PointerArithmetic.Provider))]
  584. public static unsafe Int64 TestArithmeticPointerB(ref PointerArithmetic job)
  585. {
  586. job.Execute();
  587. if (sizeof(int*) == 4)
  588. return (Int64)(UInt32)(job.pointers[20]); // Workaround IL2CPP 32bit Bug : https://fogbugz.unity3d.com/f/cases/1254635/
  589. return (Int64)job.pointers[20];
  590. }
  591. [TestCompiler(typeof(PointerArithmetic.Provider))]
  592. public static unsafe Int64 TestArithmeticPointerC(ref PointerArithmetic job)
  593. {
  594. job.Execute();
  595. if (sizeof(int*) == 4)
  596. return (Int64)(UInt32)(job.pointers[30]); // Workaround IL2CPP 32bit Bug : https://fogbugz.unity3d.com/f/cases/1254635/
  597. return (Int64)job.pointers[30];
  598. }
  599. [TestCompiler(typeof(PointerArithmetic.Provider))]
  600. public static unsafe Int64 TestArithmeticPointerD(ref PointerArithmetic job)
  601. {
  602. job.Execute();
  603. if (sizeof(int*) == 4)
  604. return (Int64)(UInt32)(job.pointers[40]); // Workaround IL2CPP 32bit Bug : https://fogbugz.unity3d.com/f/cases/1254635/
  605. return (Int64)job.pointers[40];
  606. }
  607. private struct TestData
  608. {
  609. public int3 Min;
  610. public int Size;
  611. }
  612. [TestCompiler]
  613. public static unsafe int TestPointerWithIn()
  614. {
  615. var foo = stackalloc TestData[1];
  616. *foo = new TestData { Min = new int3(0, 1, 2), Size = 3 };
  617. return SubFunctionWithInPointer(in foo);
  618. }
  619. private static unsafe int SubFunctionWithInPointer(in TestData* node)
  620. {
  621. int3 data = node->Min;
  622. return node->Size + data.x + data.y + data.z;
  623. }
  624. /* System.Buffer::Memmove - Disabled on .Net 7 due to :
  625. Framework
  626. IL_000e: conv.ovf.u8 args(IL_000d(ldarg.3))
  627. IL_000f: call System.Void System.Buffer::Memmove(System.Byte*,System.Byte*,System.UInt64) args(IL_000b(ldarg.1), IL_000c(ldarg.0), IL_000e(conv.ovf.u8))
  628. .Net 7 (note reference no pointer...)
  629. IL_000e: conv.ovf.u args(IL_000d(ldarg.3))
  630. IL_000f: call System.Void System.Buffer::Memmove(System.Byte&,System.Byte&,System.UIntPtr) args(IL_000b(ldarg.1), IL_000c(ldarg.0), IL_000e(conv.ovf.u))
  631. */
  632. [TestCompiler(IgnoreOnNetCore = true)]
  633. public static unsafe int TestSystemBufferMemoryCopy()
  634. {
  635. var a = stackalloc int[2];
  636. a[0] = 42;
  637. System.Buffer.MemoryCopy(a + 0, a + 1, UnsafeUtility.SizeOf<int>(), UnsafeUtility.SizeOf<int>());
  638. return a[1];
  639. }
  640. [TestCompiler(0ul, byte.MinValue)]
  641. [TestCompiler(0ul, byte.MaxValue)]
  642. public static unsafe IntPtr PointerMathAddPNTypesByte(UInt64 p,byte a)
  643. {
  644. var pointer = (byte*)p;
  645. return new IntPtr(pointer + a); // Pointer LHS
  646. }
  647. [TestCompiler(0ul, byte.MinValue)]
  648. [TestCompiler(0ul, byte.MaxValue)]
  649. public static unsafe IntPtr PointerMathAddNPTypesByte(UInt64 p,byte a)
  650. {
  651. var pointer = (byte*)p;
  652. return new IntPtr(a + pointer); // Pointer RHS
  653. }
  654. [TestCompiler(0ul, byte.MinValue)]
  655. [TestCompiler(0ul, byte.MaxValue)]
  656. public static unsafe IntPtr PointerMathSubPNTypesByte(UInt64 p,byte a)
  657. {
  658. var pointer = (byte*)p;
  659. return new IntPtr(pointer - a); // Pointer LHS (no RHS since not legal in C#)
  660. }
  661. [TestCompiler(0ul, sbyte.MinValue)]
  662. [TestCompiler(0ul, sbyte.MaxValue)]
  663. public static unsafe IntPtr PointerMathAddPNTypesSByte(UInt64 p,sbyte a)
  664. {
  665. var pointer = (sbyte*)p;
  666. return new IntPtr(pointer + a); // Pointer LHS
  667. }
  668. [TestCompiler(0ul, sbyte.MinValue)]
  669. [TestCompiler(0ul, sbyte.MaxValue)]
  670. public static unsafe IntPtr PointerMathAddNPTypesSByte(UInt64 p,sbyte a)
  671. {
  672. var pointer = (sbyte*)p;
  673. return new IntPtr(a + pointer); // Pointer RHS
  674. }
  675. [TestCompiler(0ul, sbyte.MinValue)]
  676. [TestCompiler(0ul, sbyte.MaxValue)]
  677. public static unsafe IntPtr PointerMathSubPNTypesSByte(UInt64 p,sbyte a)
  678. {
  679. var pointer = (sbyte*)p;
  680. return new IntPtr(pointer - a); // Pointer LHS (no RHS since not legal in C#)
  681. }
  682. [TestCompiler(0ul, short.MinValue)]
  683. [TestCompiler(0ul, short.MaxValue)]
  684. public static unsafe IntPtr PointerMathAddPNTypesShort(UInt64 p,short a)
  685. {
  686. var pointer = (short*)p;
  687. return new IntPtr(pointer + a); // Pointer LHS
  688. }
  689. [TestCompiler(0ul, short.MinValue)]
  690. [TestCompiler(0ul, short.MaxValue)]
  691. public static unsafe IntPtr PointerMathAddNPTypesShort(UInt64 p,short a)
  692. {
  693. var pointer = (short*)p;
  694. return new IntPtr(a + pointer); // Pointer RHS
  695. }
  696. [TestCompiler(0ul, short.MinValue)]
  697. [TestCompiler(0ul, short.MaxValue)]
  698. public static unsafe IntPtr PointerMathSubPNTypesShort(UInt64 p,short a)
  699. {
  700. var pointer = (short*)p;
  701. return new IntPtr(pointer - a); // Pointer LHS (no RHS since not legal in C#)
  702. }
  703. [TestCompiler(0ul, ushort.MinValue)]
  704. [TestCompiler(0ul, ushort.MaxValue)]
  705. public static unsafe IntPtr PointerMathAddPNTypesUShort(UInt64 p,ushort a)
  706. {
  707. var pointer = (ushort*)p;
  708. return new IntPtr(pointer + a); // Pointer LHS
  709. }
  710. [TestCompiler(0ul, ushort.MinValue)]
  711. [TestCompiler(0ul, ushort.MaxValue)]
  712. public static unsafe IntPtr PointerMathAddNPTypesUShort(UInt64 p,ushort a)
  713. {
  714. var pointer = (ushort*)p;
  715. return new IntPtr(a + pointer); // Pointer RHS
  716. }
  717. [TestCompiler(0ul, ushort.MinValue)]
  718. [TestCompiler(0ul, ushort.MaxValue)]
  719. public static unsafe IntPtr PointerMathSubPNTypesUShort(UInt64 p,ushort a)
  720. {
  721. var pointer = (ushort*)p;
  722. return new IntPtr(pointer - a); // Pointer LHS (no RHS since not legal in C#)
  723. }
  724. [TestCompiler(0ul, int.MinValue)]
  725. [TestCompiler(0ul, int.MaxValue)]
  726. public static unsafe IntPtr PointerMathAddPNTypesInt(UInt64 p,int a)
  727. {
  728. var pointer = (int*)p;
  729. return new IntPtr(pointer + a); // Pointer LHS
  730. }
  731. [TestCompiler(0ul, int.MinValue)]
  732. [TestCompiler(0ul, int.MaxValue)]
  733. public static unsafe IntPtr PointerMathAddNPTypesInt(UInt64 p,int a)
  734. {
  735. var pointer = (int*)p;
  736. return new IntPtr(a + pointer); // Pointer RHS
  737. }
  738. [TestCompiler(0ul, int.MinValue)]
  739. [TestCompiler(0ul, int.MaxValue)]
  740. public static unsafe IntPtr PointerMathSubPNTypesInt(UInt64 p,int a)
  741. {
  742. var pointer = (int*)p;
  743. return new IntPtr(pointer - a); // Pointer LHS (no RHS since not legal in C#)
  744. }
  745. [TestCompiler(0ul, uint.MinValue)]
  746. [TestCompiler(0ul, uint.MaxValue)]
  747. public static unsafe IntPtr PointerMathAddPNTypesUInt(UInt64 p,uint a)
  748. {
  749. var pointer = (uint*)p;
  750. return new IntPtr(pointer + a); // Pointer LHS
  751. }
  752. [TestCompiler(0ul, uint.MinValue)]
  753. [TestCompiler(0ul, uint.MaxValue)]
  754. public static unsafe IntPtr PointerMathAddNPTypesUInt(UInt64 p,uint a)
  755. {
  756. var pointer = (uint*)p;
  757. return new IntPtr(a + pointer); // Pointer RHS
  758. }
  759. [TestCompiler(0ul, uint.MinValue)]
  760. [TestCompiler(0ul, uint.MaxValue)]
  761. public static unsafe IntPtr PointerMathSubPNTypesUInt(UInt64 p,uint a)
  762. {
  763. var pointer = (uint*)p;
  764. return new IntPtr(pointer - a); // Pointer LHS (no RHS since not legal in C#)
  765. }
  766. [TestCompiler(0ul, long.MinValue)]
  767. [TestCompiler(0ul, long.MaxValue)]
  768. public static unsafe IntPtr PolongerMathAddPNTypesLong(UInt64 p,long a)
  769. {
  770. var polonger = (long*)p;
  771. return new IntPtr(polonger + a); // Polonger LHS
  772. }
  773. [TestCompiler(0ul, long.MinValue)]
  774. [TestCompiler(0ul, long.MaxValue)]
  775. public static unsafe IntPtr PolongerMathAddNPTypesLong(UInt64 p,long a)
  776. {
  777. var polonger = (long*)p;
  778. return new IntPtr(a + polonger); // Polonger RHS
  779. }
  780. [TestCompiler(0ul, long.MinValue)]
  781. [TestCompiler(0ul, long.MaxValue)]
  782. public static unsafe IntPtr PolongerMathSubPNTypesLong(UInt64 p,long a)
  783. {
  784. var polonger = (long*)p;
  785. return new IntPtr(polonger - a); // Polonger LHS (no RHS since not legal in C#)
  786. }
  787. [TestCompiler(0ul, ulong.MinValue)]
  788. [TestCompiler(0ul, ulong.MaxValue)]
  789. public static unsafe IntPtr PolongerMathAddPNTypesULong(UInt64 p,ulong a)
  790. {
  791. var polonger = (ulong*)p;
  792. return new IntPtr(polonger + a); // Polonger LHS
  793. }
  794. [TestCompiler(0ul, ulong.MinValue)]
  795. [TestCompiler(0ul, ulong.MaxValue)]
  796. public static unsafe IntPtr PolongerMathAddNPTypesULong(UInt64 p,ulong a)
  797. {
  798. var polonger = (ulong*)p;
  799. return new IntPtr(a + polonger); // Polonger RHS
  800. }
  801. [TestCompiler(0ul, ulong.MinValue)]
  802. [TestCompiler(0ul, ulong.MaxValue)]
  803. public static unsafe IntPtr PolongerMathSubPNTypesULong(UInt64 p,ulong a)
  804. {
  805. var polonger = (ulong*)p;
  806. return new IntPtr(polonger - a); // Polonger LHS (no RHS since not legal in C#)
  807. }
  808. }
  809. }