protected override void ReadNotEmpty(ReaderMethodBuilderContext context) { var il = context.Il; var source = il.DeclareLocal(typeof(IntPtr)); context.GoToCurrentLocation(); // stack: [&data[index]] il.Stloc(source); // source = &data[index]; stack: [] context.IncreaseIndexBy1(); // skip type code context.SkipValue(); context.GoToCurrentLocation(); // stack: [&data[index]] il.Ldloc(source); // stack: [&data[index], source] il.Sub(); // stack: [&data[index] - source = data length] var length = il.DeclareLocal(typeof(int)); il.Stloc(length); // length = &data[index] - source; stack: [] var array = il.DeclareLocal(typeof(byte[])); il.Ldloc(length); // stack: [length] il.Newarr(typeof(byte)); // stack: [new byte[length]] il.Stloc(array); // array = new byte[length]; stack: [] var dest = il.DeclareLocal(typeof(byte).MakeByRefType(), true); il.Ldloc(array); // stack: [array] il.Ldc_I4(0); // stack: [array, 0] il.Ldelema(typeof(byte)); // stack: [&array[0]] il.Stloc(dest); // dest = &array[0]; stack: [] il.Ldloc(dest); // stack: [dest] il.Ldloc(source); // stack: [dest, source] il.Ldloc(length); // stack: [dest, source, length] il.Cpblk(); // dest = source; stack: [] il.FreePinnedLocal(dest); // dest = null; stack: [] var argumentType = Type.GetGenericArguments()[0]; context.LoadResultByRef(); // stack: [ref result] context.LoadSerializerId(); // stack: [ref result, serializerId] il.Ldloc(array); // stack: [ref result, serializerId, array] context.LoadReader(argumentType); // stack: [ref result, serializerId, array, reader<arg>] context.LoadSerializerId(); // stack: [ref result, serializerId, array, reader<arg>, serializerId] il.Newobj(readerInvoker.GetConstructor(new[] { typeof(IntPtr), typeof(long) })); // stack: [ref result, serializerId, array, new ReaderInvoker(reader<arg>, serializerId)] il.Ldftn(readerInvoker.GetMethod("Read", BindingFlags.Instance | BindingFlags.Public)); var readDataFuncType = typeof(Func <,>).MakeGenericType(typeof(byte[]), argumentType); il.Newobj(readDataFuncType.GetConstructor(new[] { typeof(object), typeof(IntPtr) })); // stack: [ref result, serializerId, array, new Func<byte[], arg>(..)] var rawDataType = typeof(RawData <>).MakeGenericType(argumentType); il.Newobj(rawDataType.GetConstructor(new[] { typeof(long), typeof(byte[]), readDataFuncType })); // stack: [ref result, new RawData(serializerId, array, func)] il.Ldftn(rawDataType.GetMethod("GetValue", BindingFlags.Instance | BindingFlags.Public)); // stack: [ref result, new RawData(..), RawData.GetValue] var factoryType = typeof(Func <>).MakeGenericType(argumentType); il.Newobj(factoryType.GetConstructor(new[] { typeof(object), typeof(IntPtr) })); // stack: [ref result, new Func<arg>(new RawData(), RawData.GetValue)] il.Newobj(Type.GetConstructor(new[] { factoryType })); // stack: [ref result, new Lazy<arg>(new Func<arg>(new RawData(), RawData.GetValue))] il.Stind(Type); // result = new Lazy<argument>(array, func); stack: [] }