I'm writing a code that marshal any structure to byte array. I have a method:
    public static byte[] Serialize(MyStruct value)
    {
        IntPtr p = new IntPtr(&value);
        byte[] result = new byte[12]; 
        Marshal.Copy(p, result, 0, result.Length);
        return result;
    }
Here is IL for this code:
.method public hidebysig static uint8[]  Serialize(valuetype Program/MyStruct 'value') cil managed
{
  // code size:       37 (0x25)
  .maxstack  4
  .locals init ([0] native int p,
           [1] uint8[] result,
           [2] uint8[] V_2)
  IL_0000:  nop
  IL_0001:  ldloca.s   p
  IL_0003:  ldarga.s   'value'
  IL_0005:  conv.u
  IL_0006:  call       instance void [mscorlib]System.IntPtr::.ctor(void*)
  IL_000b:  ldc.i4.s   12
  IL_000d:  newarr     [mscorlib]System.Byte
  IL_0012:  stloc.1
  IL_0013:  ldloc.0
  IL_0014:  ldloc.1
  IL_0015:  ldc.i4.0
  IL_0016:  ldloc.1
  IL_0017:  ldlen
  IL_0018:  conv.i4
  IL_0019:  call       void [mscorlib]System.Runtime.InteropServices.Marshal::Copy(native int,
                                                                                   uint8[],
                                                                                   int32,
                                                                                   int32)
  IL_001e:  nop
  IL_001f:  ldloc.1
  IL_0020:  stloc.2
  IL_0021:  br.s       IL_0023
  IL_0023:  ldloc.2
  IL_0024:  ret
} // end of method MyStruct::Serialize
now I'm trying to emit generic method:
private static class SerializationHolder<T> where T : struct
{
    public static readonly Func<T, byte[]> Value = CreateDelegate();
    private static Func<T, byte[]> CreateDelegate()
    {
        var dm = new DynamicMethod("Serialize" + typeof (T).Name,
            typeof (byte[]),
            new[] {typeof (T)},
            Assembly.GetExecutingAssembly().ManifestModule);
        const string parameterName = "value";
        dm.DefineParameter(1, ParameterAttributes.None, parameterName);
        var generator = dm.GetILGenerator();
        var p = generator.DeclareLocal(typeof (IntPtr));
        generator.DeclareLocal(typeof (byte));
        generator.DeclareLocal(typeof (byte));
        generator.Emit(OpCodes.Ldloca_S, p);
        generator.Emit(OpCodes.Ldarga_S, parameterName);
        generator.Emit(OpCodes.Conv_U);
        var intPtrCtor = typeof (IntPtr).GetConstructor(new[] {typeof(void*)});
        Debug.Assert(intPtrCtor != null);
        generator.Emit(OpCodes.Call, intPtrCtor);
        var sizeInBytes = Marshal.SizeOf(typeof (T));
        generator.Emit(OpCodes.Ldc_I4_S, sizeInBytes);
        generator.Emit(OpCodes.Newarr, typeof (byte));
        generator.Emit(OpCodes.Stloc_1);
        generator.Emit(OpCodes.Ldloc_0);
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Ldc_I4_0);
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Ldlen);
        generator.Emit(OpCodes.Conv_I4);
        var marshalCopy = typeof (Marshal).GetMethod("Copy", new[] {typeof (IntPtr), typeof (byte[]), typeof (int), typeof (int)});
        generator.EmitCall(OpCodes.Call, marshalCopy, null);
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Stloc_2);
        generator.Emit(OpCodes.Ldloc_2);
        generator.Emit(OpCodes.Ret);
        return (Func<T, byte[]>)dm.CreateDelegate(typeof(Func<T, byte[]>));
    }
}
but when I'm trying to call it it fails with CLR detected an invalid program. I think the problem is in this line:
        generator.Emit(OpCodes.Ldarga_S, parameterName);
but if I'm writing:
        generator.Emit(OpCodes.Ldarga_S, 0);
if fails with NullReferenceException
Now I have a code that do it with generic type T but it uses undocumented keywords
public static byte[] Serialize<T>(this T value) where T : struct
{
    TypedReference tr = __makeref(value);
    IntPtr p = *(IntPtr*)&tr;
    int sizeInBytes = Marshal.SizeOf(typeof(T));
    byte[] result = new byte[sizeInBytes];
    Marshal.Copy(p, result, 0, result.Length);
    return result;
}
It's unstable and can break down in new .Net releases so I want to replace it with Emit-based code