static unsafe void *InternalToObject(void *typedref) { // get the type from the typed reference to see if we need to box the object // or simply return the address as a reference type void *et = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceTypeOffset()); void *src = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceValueOffset()); void *etextends = *(void **)((byte *)et + ClassOperations.GetVtblExtendsVtblPtrOffset()); if (etextends == OtherOperations.GetStaticObjectAddress("_Zu1L") || etextends == OtherOperations.GetStaticObjectAddress("_ZW6System4Enum")) { // this is a boxed value type. Get its size var vt_size = TysosType.GetValueTypeSize(et); // build a new boxed type var ret = MemoryOperations.GcMalloc(*(int *)((byte *)et + ClassOperations.GetVtblTypeSizeOffset())); // dst ptr var dst = (byte *)ret + ClassOperations.GetBoxedTypeDataOffset(); CopyMem(dst, (byte *)src, vt_size); return(ret); } else { // simply copy the reference return(*(void **)src); } }
static unsafe void InternalSetValue(void *typedref, void *objval) { // get the type from the typed reference to see if we need to unbox the object // or store as a reference type void *et = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceTypeOffset()); void *ptr = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceValueOffset()); void *etextends = *(void **)((byte *)et + ClassOperations.GetVtblExtendsVtblPtrOffset()); if (etextends == OtherOperations.GetStaticObjectAddress("_Zu1L") || etextends == OtherOperations.GetStaticObjectAddress("_ZW6System4Enum")) { // this is a boxed value type. Get its size var vt_size = TysosType.GetValueTypeSize(et); // src ptr void *src = *(void **)((byte *)objval + ClassOperations.GetBoxedTypeDataOffset()); CopyMem((byte *)ptr, (byte *)src, vt_size); } else { // simply copy the reference *(void **)ptr = objval; } }
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()); }