Skip to content

Instantly share code, notes, and snippets.

View GrabYourPitchforks's full-sized avatar
😵
On other projects, not checking GitHub notifications - ping via Teams if urgent.

Levi Broderick GrabYourPitchforks

😵
On other projects, not checking GitHub notifications - ping via Teams if urgent.
View GitHub Profile
@GrabYourPitchforks
GrabYourPitchforks / utf8_charcount.cs
Created June 25, 2024 20:38
UTF8 char count testing
using System;
using System.Buffers;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using System.Text;
using System.Text.Unicode;
using BenchmarkDotNet.Attributes;
@GrabYourPitchforks
GrabYourPitchforks / memory_guidelines.md
Last active May 29, 2024 11:04
Memory usage guidelines

Memory<T> usage guidelines

This document describes the relationship between Memory<T> and its related classes (MemoryPool<T>, IMemoryOwner<T>, etc.). It also describes best practices when accepting Memory<T> instances in public API surface. Following these guidelines will help developers write clear, bug-free code.

First, a tour of the basic exchange types

  • Span<T> is the basic exchange type that represents contiguous buffers. These buffers may be backed by managed memory (such as T[] or System.String). They may also be backed by unmanaged memory (such as via stackalloc or a raw void*). The Span<T> type is not heapable, meaning that it cannot appear as a field in classes, and it cannot be used across yield or await boundaries.

  • Memory is a wrapper around an object that can generate a Span. For instance, Memory instances can be backed by T[], System.String (readonly), and even SafeHandle instances. Memory cannot be backed by "transient" unmanaged me

Problem summary

While working on the System.Text.Encodings.Web refactoring I noticed that we have several duplicates of the System.Text.Rune type (or its backing logic) throughout our projects.

The official implementation exposed by System.Runtime:

A copy used by the Utf8String OOB:

@GrabYourPitchforks
GrabYourPitchforks / memory_docs_samples.md
Last active January 20, 2024 13:29
Memory<T> API documentation and samples

Memory<T> API documentation and samples

This document describes the APIs of Memory<T>, IMemoryOwner<T>, and MemoryManager<T> and their relationships to each other.

See also the Memory<T> usage guidelines document for background information.

First, a brief summary of the basic types

  • Memory<T> is the basic type that represents a contiguous buffer. This type is a struct, which means that developers cannot subclass it and override the implementation. The basic implementation of the type is aware of contigious memory buffers backed by T[] and System.String (in the case of ReadOnlyMemory<char>).
@GrabYourPitchforks
GrabYourPitchforks / memorymarshal_cast_utf8.cs
Last active December 10, 2022 15:14
MemoryMarshal.Cast challenge
using System;
using System.Runtime.InteropServices;
using System.Text;
class Program
{
static void Main(string[] args)
{
{
// the text below is meaningless
@GrabYourPitchforks
GrabYourPitchforks / ref-asm.cs
Last active May 27, 2022 22:58
Type name parsing
public sealed class PublicKeyToken : IEquatable<PublicKeyToken>
{
public PublicKeyToken(byte[] publicKeyTokenBytes);
public PublicKeyToken(ReadOnlySpan<byte> publicKeyTokenBytes);
public PublicKeyToken(string publicKeyTokenHexString);
public PublicKeyToken(ReadOnlySpan<char> publicKeyTokenHexString);
public ReadOnlySpan<byte> RawBytes { get; }
public string TokenString { get; }
public byte[] GetPublicKeyTokenBytes();
@GrabYourPitchforks
GrabYourPitchforks / csharp_singlecopy_struct.md
Last active March 31, 2021 17:46
C# single-copy struct proposal

Problem statement and core scenario

We want to introduce the idea of a value type where the underlying data is only ever "live" in at most one place. The canonical example is the internal ValueStringBuilder struct type, which performs internal ArrayPool management.

ValueStringBuilder builder = new ValueStringBuilder(); // VSB is a struct type
builder.Append("foo");
builder.Append(obj);
HelperMethod(ref builder); // builder passed by ref to helper methods
return builder.ToString(); // ToString releases underlying rented arrays back to pool
@GrabYourPitchforks
GrabYourPitchforks / fnptrs_reflection.md
Last active January 29, 2021 22:17
Draft function pointers in reflection spec

Draft function pointers in reflection spec

Passing function pointers as parameters to MethodInfo.Invoke

The reflection stack should treat function pointer arguments as standard pointer arguments for the purposes of method invocation. This means that boxed IntPtr arguments should be accepted as parameters to these methods in MethodInfo.Invoke scenarios. For methods which return function pointers, they should be returned as boxed IntPtrs.

The reflection stack, for convenience, should also consider allowing developers to pass System.Reflection.Pointer instances as input arguments to these methods.

Inspecting function pointer types

@GrabYourPitchforks
GrabYourPitchforks / fieldoffset.cs
Created November 28, 2020 23:22
FieldOffset as unsafe
using System;
using System.Runtime.InteropServices;
namespace FieldOffsetSample
{
class Program
{
static void Main(string[] args)
{
MyStruct myStruct = default;