private static Pointer <byte> AddressOfHeapInternal <T>(T value, OffsetOptions offset) { // It is already assumed value is a class type //var tr = __makeref(value); //var heapPtr = **(IntPtr**) (&tr); var heapPtr = AddressOf(ref value).ReadPointer(); // NOTE: // Strings have their data offset by Offsets.OffsetToStringData // Arrays have their data offset by IntPtr.Size * 2 bytes (may be different for 32 bit) switch (offset) { case OffsetOptions.STRING_DATA: { Conditions.Require(RuntimeInfo.IsString(value)); string s = value as string; return(heapPtr + Offsets.OffsetToStringData); } case OffsetOptions.ARRAY_DATA: { Conditions.Require(RuntimeInfo.IsArray(value)); return(heapPtr + Offsets.OffsetToArrayData); } case OffsetOptions.FIELDS: { // todo: if the type is an array, should this return ArrayData, ...and if it's a string, // ... should this return StringData? // Skip over the MethodTable* return(heapPtr + Offsets.OffsetToData); } case OffsetOptions.NONE: return(heapPtr); case OffsetOptions.HEADER: return(heapPtr - Offsets.OffsetToData); default: throw new ArgumentOutOfRangeException(nameof(offset), offset, null); } }