Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
61f6e6e
Rebase to make review readable again.
Nov 11, 2016
d015dcf
Remove the type casts from DangerousGetPinnedReference - store object…
Nov 11, 2016
7f58320
Removed stable version list.
Nov 11, 2016
372dd2a
DangerousCreate gets more Dangerous...
Nov 11, 2016
82ea8d5
Updated dependency versions *again*.
Nov 11, 2016
f25a42a
IsReferenceFree fast-paths for common primitives.
Nov 11, 2016
c47176c
Move exception throwing out of inline code.
Nov 11, 2016
9f9665d
Remove Windows-only restriction.
Nov 11, 2016
79c4f3f
Remove baseline version.
Nov 11, 2016
bde890e
Don't hardcode array header size.
Nov 11, 2016
1c400cf
Another dependency version change!
Nov 11, 2016
7817577
Version => 4.0.0.0
Nov 11, 2016
85fe48f
Use Unsafe.Add rather than SpanHeloer.Add in this[index]
Nov 11, 2016
b4c7015
ThrowHelper.Throw ==> throw ThrowHelper.Create
Nov 11, 2016
7ee7dcf
Revert the specific primitive type checks in IsReferenceFree().
Nov 11, 2016
1ac3979
Fix DangerousGetPinnableReference to be a method to match spec.
Nov 14, 2016
dce1728
PR feedback.
Nov 14, 2016
3155862
More concise operator==
Nov 14, 2016
3334c94
Follow Ben's suggested ThrowHelper pattern.
Nov 14, 2016
e4fa8ac
Update ThrowHelper comments based on Ben's feedback.
Nov 14, 2016
4cfbba9
Remove trailing whitespace.
Nov 14, 2016
bdbaf59
Dependency bump. Again...
Nov 14, 2016
2850306
Fix up some tests so the IL is Span-legal.
Nov 14, 2016
a65d0b4
Add a reference assembly and some of the plumbing...
Nov 14, 2016
da8894d
Add C#6.0 workaround.
Nov 15, 2016
d551c71
Dependency update again.
Nov 15, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion pkg/Microsoft.Private.PackageBaseline/packageIndex.json
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,13 @@
"4.0.3.0": "4.4.0"
}
},
"System.Memory": {
"StableVersions": [
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not sound right. There is no stable 4.0.0 version of this package... .

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was copied from S.R.C.Unsafe, but I'm fine with removing that...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, there is stable package for S.R.CS.Unsafe .... .

],
"AssemblyVersionInPackageVersion": {
"4.0.0.0": "4.4.0"
}
},
"System.Net.Http": {
"StableVersions": [
"4.0.0",
Expand Down Expand Up @@ -2753,4 +2760,4 @@
"System.Security.Cryptography.Native.Apple": "runtime.native.System.Security.Cryptography.Apple",
"System.Security.Cryptography.Native.OpenSsl": "runtime.native.System.Security.Cryptography.OpenSsl"
}
}
}
9 changes: 8 additions & 1 deletion pkg/descriptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,13 @@
"System.Linq.EnumerableQuery"
]
},
{
"Name": "System.Memory",
"Description": "Provides types for efficient low-allocation access to memory.",
"CommonTypes": [
"System.Span",
]
},
{
"Name": "System.Net.Http",
"Description": "Provides a programming interface for modern HTTP applications, including HTTP client components that allow applications to consume web services over HTTP and HTTP components that can be used by both clients and servers for parsing HTTP headers.",
Expand Down Expand Up @@ -1623,7 +1630,7 @@
"System.ServiceProcess.ServiceType"
]
},
{
{
"Name": "System.Text.Encoding",
"Description": "Provides base abstract encoding classes for converting blocks of characters to and from blocks of bytes.",
"CommonTypes": [
Expand Down
27 changes: 27 additions & 0 deletions src/System.Memory/System.Memory.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.25831.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Memory", "src\System.Memory.csproj", "{4BBC8F69-D03E-4432-AA8A-D458FA5B235A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Memory.Tests", "tests\System.Memory.Tests.csproj", "{15DC55FA-E644-4B87-A62A-DCF849031633}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4BBC8F69-D03E-4432-AA8A-D458FA5B235A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4BBC8F69-D03E-4432-AA8A-D458FA5B235A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4BBC8F69-D03E-4432-AA8A-D458FA5B235A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4BBC8F69-D03E-4432-AA8A-D458FA5B235A}.Release|Any CPU.Build.0 = Release|Any CPU
{15DC55FA-E644-4B87-A62A-DCF849031633}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{15DC55FA-E644-4B87-A62A-DCF849031633}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15DC55FA-E644-4B87-A62A-DCF849031633}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15DC55FA-E644-4B87-A62A-DCF849031633}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
9 changes: 9 additions & 0 deletions src/System.Memory/pkg/System.Memory.builds
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<ItemGroup>
<Project Include="System.Memory.pkgproj" Condition="'$(OS)'=='Windows_NT'" />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this conditioned to only Windows_NT? We should avoid these conditions.

</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
</Project>

10 changes: 10 additions & 0 deletions src/System.Memory/pkg/System.Memory.pkgproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<ItemGroup>
<ProjectReference Include="..\src\System.Memory.csproj">
<SupportedFramework>net45;netcore45;wp8;wpa81;netcoreapp1.0;$(AllXamarinFrameworks)</SupportedFramework>
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
8 changes: 8 additions & 0 deletions src/System.Memory/ref/System.Memory.builds
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<ItemGroup>
<Project Include="System.Memory.csproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
</Project>
35 changes: 35 additions & 0 deletions src/System.Memory/ref/System.Memory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma warning disable 0809 //warning CS0809: Obsolete member 'Span<T>.Equals(object)' overrides non-obsolete member 'object.Equals(object)'
namespace System
{
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct Span<T>
{
public static readonly System.Span<T> Empty;
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public Span(T[] array) { throw null;}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public Span(T[] array, int start) { throw null;}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public Span(T[] array, int start, int length) { throw null;}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public unsafe Span(void* pointer, int length) { throw null;}
public bool IsEmpty { get { throw null; } }
public T this[int index] { [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]get { throw null; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]set { throw null; }}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public ref T GetItem(int index) { throw null; }
public int Length { get { throw null; } }
public void CopyTo(System.Span<T> destination) { }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public static System.Span<T> DangerousCreate(object obj, ref T objectData, int length) { throw null; }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public ref T DangerousGetPinnableReference() { throw null; }
[System.ObsoleteAttribute("Equals() on Span will always throw an exception. Use == instead.")]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public override bool Equals(object obj) { throw null; }
[System.ObsoleteAttribute("GetHashCode() on Span will always throw an exception.")]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public override int GetHashCode() { throw null; }
public static bool operator ==(System.Span<T> left, System.Span<T> right) { throw null; }
public static implicit operator System.Span<T> (T[] array) { throw null; }
public static implicit operator System.Span<T> (System.ArraySegment<T> arraySegment) { throw null; }
public static bool operator !=(System.Span<T> left, System.Span<T> right) { throw null; }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public System.Span<T> Slice(int start) { throw null; }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public System.Span<T> Slice(int start, int length) { throw null; }
public T[] ToArray() { throw null; }
public bool TryCopyTo(System.Span<T> destination) { throw null; }
}
}

19 changes: 19 additions & 0 deletions src/System.Memory/ref/System.Memory.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputType>Library</OutputType>
<CLSCompliant>false</CLSCompliant>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this 4.0.0.0?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What else would it be?

<NuGetTargetMoniker>.NETStandard,Version=v1.0</NuGetTargetMoniker>
<ProjectGuid>{0EF9D369-7097-44F9-BEBA-C32AF5EB4756}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<Compile Include="System.Memory.cs" />
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
9 changes: 9 additions & 0 deletions src/System.Memory/ref/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"dependencies": {
"Microsoft.NETCore.Platforms": "1.0.1",
"System.Runtime": "4.1.0"
},
"frameworks": {
"netstandard1.0": {}
}
}
135 changes: 135 additions & 0 deletions src/System.Memory/src/Resources/Strings.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema

Version 2.0

The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.

Example:

... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>

There are any number of "resheader" rows that contain simple
name/value pairs.

Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.

The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:

Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.

mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ArrayTypeMustBeExactMatch" xml:space="preserve">
<value>The array type must be exactly {0}.</value>
</data>
<data name="CannotCallEqualsOnSpan" xml:space="preserve">
<value>Equals() on Span and ReadOnlySpan is not supported. Use operator== instead.</value>
</data>
<data name="CannotCallGetHashCodeOnSpan" xml:space="preserve">
<value>GetHashCode() on Span and ReadOnlySpan is not supported.</value>
</data>
<data name="Argument_InvalidTypeWithPointersNotSupported" xml:space="preserve">
<value>Cannot use type '{0}'. Only value types without pointers or references are supported.</value>
</data>
<data name="Argument_DestinationTooShort" xml:space="preserve">
<value>Destination is too short.</value>
</data>
</root>
9 changes: 9 additions & 0 deletions src/System.Memory/src/System.Memory.builds
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<ItemGroup>
<Project Include="System.Memory.csproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
</Project>

29 changes: 29 additions & 0 deletions src/System.Memory/src/System.Memory.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<ProjectGuid>{4BBC8F69-D03E-4432-AA8A-D458FA5B235A}</ProjectGuid>
<AssemblyName>System.Memory</AssemblyName>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CLSCompliant>false</CLSCompliant>
<NuGetTargetMoniker>.NETStandard,Version=v1.0</NuGetTargetMoniker>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add:

<DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile>

so that all of your good docs end up getting validated and generated into a docs file.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

<DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile>
<IsPartialFacadeAssembly>false</IsPartialFacadeAssembly>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'" />
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
<Compile Include="System\Pinnable.cs" />
<Compile Include="System\Span.cs" />
<Compile Include="System\SpanHelpers.cs" />
<Compile Include="System\ThrowHelper.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' == 'true'">
<TargetingPackReference Include="System.Private.CoreLib" />
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
18 changes: 18 additions & 0 deletions src/System.Memory/src/System/Pinnable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System.Runtime.InteropServices;

namespace System
{
//
// This class exists solely so that arbitrary objects can be Unsafe-casted to it to get a ref to the start of the user data.
//
[StructLayout(LayoutKind.Sequential)]
internal sealed class Pinnable<T>
{
public T Data;
}
}
Loading