static System.IntPtr AddressOfRef <T>(ref T t) { unsafe { System.TypedReference reference = __makeref(t); System.TypedReference *pRef = &reference; return((System.IntPtr)pRef); //(&pRef) } }
static System.IntPtr AddressOfRef <T>(ref T t) //refember ReferenceTypes are references to the CLRHeader //where TOriginal : struct { System.TypedReference reference = __makeref(t); System.TypedReference *pRef = &reference; return((System.IntPtr)pRef); //(&pRef) }
static unsafe void InternalGetReference(void *arr, System.TypedReference *typedref, int ranks, int *rank_indices) { // idx = rightmost-index + 2nd-right * rightmost-size + 3rd-right * 2nd-right-size * right-size + ... // rank checking is done by System.Array members in coreclr int *lovals = *(int **)((byte *)arr + ArrayOperations.GetLoboundsOffset()); int *sizes = *(int **)((byte *)arr + ArrayOperations.GetSizesOffset()); // first get index of first rank if (rank_indices[0] > sizes[0]) { throw new IndexOutOfRangeException(); } int index = rank_indices[0] - lovals[0]; // now repeat mul rank size; add rank index; rank-1 times for (int rank = 1; rank < ranks; rank++) { if (rank_indices[rank] > sizes[rank]) { throw new IndexOutOfRangeException(); } index *= sizes[rank]; index += rank_indices[rank]; } // get pointer to actual data int et_size = *(int *)((byte *)arr + ArrayOperations.GetElemSizeOffset()); void *ptr = *(byte **)((byte *)arr + ArrayOperations.GetInnerArrayOffset()) + index * et_size; // store to the typed reference *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceValueOffset()) = ptr; *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceTypeOffset()) = *(void **)((byte *)arr + ArrayOperations.GetElemTypeOffset()); }