Skip to content

Instantly share code, notes, and snippets.

@TIHan
Created January 25, 2024 19:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TIHan/2feee389c3c56ee255f779e5cc464251 to your computer and use it in GitHub Desktop.
Save TIHan/2feee389c3c56ee255f779e5cc464251 to your computer and use it in GitHub Desktop.
scoped closure?
using System.Runtime.CompilerServices;
namespace ConsoleApp2
{
internal unsafe class Program
{
class A
{
public int X = 123;
public object o = new object();
public A(int x)
{
X = x;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Consume(object o)
{
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Consume(int x)
{
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Consume(A o)
{
Consume(o.X);
Consume(o.o);
}
ref struct scopedClo0
{
public ref A o;
public scopedClo0(ref A o)
{
this.o = ref o;
}
public static void Invoke(ref scopedClo0 clo)
{
Consume(clo.o);
}
}
struct scopedFun
{
public IntPtr ptr;
public IntPtr fnptr;
[MethodImpl(MethodImplOptions.NoInlining)]
public scopedFun(IntPtr ptr, IntPtr fnptr)
{
this.ptr = ptr;
this.fnptr = fnptr;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Call(scopedFun sf)
{
var f = (delegate*<IntPtr, void>)sf.fnptr;
f(sf.ptr);
}
static void Create(int x)
{
var o = new A(x);
var clo = new scopedClo0(ref o);
delegate*<ref scopedClo0, void> fnptr = &scopedClo0.Invoke;
var sf = new scopedFun((nint)(&clo), (nint)fnptr);
Call(sf);
}
static void Main(string[] args)
{
for (int i = 0; i < 10000000; i++)
{
Create(i);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment