Skip to content

Instantly share code, notes, and snippets.

@bojanrajkovic
Created June 5, 2018 16:56
Show Gist options
  • Save bojanrajkovic/aa447f5a46904c5b72b9d4c46c554ff6 to your computer and use it in GitHub Desktop.
Save bojanrajkovic/aa447f5a46904c5b72b9d4c46c554ff6 to your computer and use it in GitHub Desktop.
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace create_delegate_crash
{
delegate void Peek<in TRow, TValue>(TRow row, long position, ref TValue value);
class Foo {
public string Bar = string.Empty;
}
class Program
{
static Delegate GeneratePeek<TOwn, TRow, TValue>(FieldInfo fieldInfo, OpCode assignmentOpCode)
{
// REVIEW: It seems like we really should cache these, instead of generating them per cursor.
Type[] args = { typeof(TOwn), typeof(TRow), typeof(long), typeof(TValue).MakeByRefType() };
var mb = new DynamicMethod("Peek", null, args, typeof(TOwn), true);
var il = mb.GetILGenerator();
il.Emit(OpCodes.Ldarg_3); // push arg3
il.Emit(OpCodes.Ldarg_1); // push arg1
il.Emit(OpCodes.Ldfld, fieldInfo); // push [stack top].[fieldInfo]
// Stobj needs to coupled with a type.
if (assignmentOpCode == OpCodes.Stobj) // [stack top-1] = [stack top]
il.Emit(assignmentOpCode, fieldInfo.FieldType);
else
il.Emit(assignmentOpCode);
il.Emit(OpCodes.Ret); // ret
return mb.CreateDelegate(typeof(Peek<TRow, TValue>));
}
static void Main(string[] args)
{
var foo = new Foo();
var fieldInfo = foo.GetType().GetField("Bar");
var peek = GeneratePeek<string, int, Foo>(fieldInfo, OpCodes.Stobj);
Console.WriteLine(peek);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment