protected override void WriteNotEmpty(WriterMethodBuilderContext context) { var il = context.Il; context.WriteTypeCode(GroBufTypeCode.DateTimeOffset); context.LoadObjByRef(); // stack: [obj] il.Ldfld(Type.GetPrivateInstanceField(PlatformHelpers.DateTimeOffsetDateTimeFieldNames)); // stack: [obj.m_dateTime] context.LoadWriteEmpty(); // stack: [obj.m_dateTime, writeEmpty] context.LoadResult(); // stack: [obj.m_dateTime, writeEmpty, result] context.LoadIndexByRef(); // stack: [obj.m_dateTime, writeEmpty, result, ref index] context.LoadContext(); // stack: [obj.m_dateTime, writeEmpty, result, ref index, context] context.CallWriter(typeof(DateTime)); // writer(obj.m_dateTime, writeEmpty, result, ref index, context) context.LoadObjByRef(); // stack: [obj] il.Ldfld(Type.GetPrivateInstanceField(PlatformHelpers.DateTimeOffsetOffsetMinutesFieldNames)); // stack: [obj.m_offsetMinutes] context.LoadWriteEmpty(); // stack: [obj.m_offsetMinutes, writeEmpty] context.LoadResult(); // stack: [obj.m_offsetMinutes, writeEmpty, result] context.LoadIndexByRef(); // stack: [obj.m_offsetMinutes, writeEmpty, result, ref index] context.LoadContext(); // stack: [obj.m_offsetMinutes, writeEmpty, result, ref index, context] context.CallWriter(typeof(short)); // writer(obj.m_offsetMinutes, writeEmpty, result, ref index, context) }
protected override void WriteNotEmpty(WriterMethodBuilderContext context) { var il = context.Il; context.LoadObjByRef(); // stack: [obj] il.Ldfld(Type.GetField("_ticks", BindingFlags.Instance | BindingFlags.NonPublic)); // stack: [obj._ticks] context.LoadWriteEmpty(); // stack: [obj._ticks, writeEmpty] context.LoadResult(); // stack: [obj._ticks, writeEmpty, result] context.LoadIndexByRef(); // stack: [obj._ticks, writeEmpty, result, ref index] context.LoadContext(); // stack: [obj._ticks, writeEmpty, result, ref index, context] context.CallWriter(typeof(long)); // writer(obj._ticks, writeEmpty, result, ref index, context) }
protected override void WriteNotEmpty(WriterMethodBuilderContext context) { var il = context.Il; context.LoadObjByRef(); // stack: [&obj] il.Call(Type.GetProperty("Value").GetGetMethod()); // stack: [obj.Value] context.LoadWriteEmpty(); // stack: [obj.Value, writeEmpty] context.LoadResult(); // stack: [obj.Value, writeEmpty, result] context.LoadIndexByRef(); // stack: [obj.Value, writeEmpty, result, ref index] context.LoadContext(); // stack: [obj.Value, writeEmpty, result, ref index, context] context.CallWriter(Type.GetGenericArguments()[0]); // writer(obj.Value, writeEmpty, result, ref index, context) }
protected override void WriteNotEmpty(WriterMethodBuilderContext context) { var il = context.Il; context.LoadObj(); // stack: [obj] il.Call(Type.GetMethod("GetAddressBytes", BindingFlags.Instance | BindingFlags.Public)); // stack: [obj.GetAddressBytes()] context.LoadWriteEmpty(); // stack: [obj.GetAddressBytes(), writeEmpty] context.LoadResult(); // stack: [obj.GetAddressBytes(), writeEmpty, result] context.LoadIndexByRef(); // stack: [obj.GetAddressBytes(), writeEmpty, result, ref index] context.LoadContext(); // stack: [obj.GetAddressBytes(), writeEmpty, result, ref index, context] context.CallWriter(typeof(byte[])); // writer(obj.GetAddressBytes(), writeEmpty, result, ref index, context) }
protected override void WriteNotEmpty(WriterMethodBuilderContext context) { var il = context.Il; context.WriteTypeCode(GroBufTypeCode.DateTimeOffset); context.LoadObjByRef(); // stack: [obj] il.Ldfld(Type.GetField("m_dateTime", BindingFlags.Instance | BindingFlags.NonPublic)); // stack: [obj.m_dateTime] context.LoadWriteEmpty(); // stack: [obj.m_dateTime, writeEmpty] context.LoadResult(); // stack: [obj.m_dateTime, writeEmpty, result] context.LoadIndexByRef(); // stack: [obj.m_dateTime, writeEmpty, result, ref index] context.LoadContext(); // stack: [obj.m_dateTime, writeEmpty, result, ref index, context] context.CallWriter(typeof(DateTime)); // writer(obj.m_dateTime, writeEmpty, result, ref index, context) context.LoadObjByRef(); // stack: [obj] il.Ldfld(Type.GetField("m_offsetMinutes", BindingFlags.Instance | BindingFlags.NonPublic)); // stack: [obj.m_offsetMinutes] context.LoadWriteEmpty(); // stack: [obj.m_offsetMinutes, writeEmpty] context.LoadResult(); // stack: [obj.m_offsetMinutes, writeEmpty, result] context.LoadIndexByRef(); // stack: [obj.m_offsetMinutes, writeEmpty, result, ref index] context.LoadContext(); // stack: [obj.m_offsetMinutes, writeEmpty, result, ref index, context] context.CallWriter(typeof(short)); // writer(obj.m_offsetMinutes, writeEmpty, result, ref index, context) }
protected override void WriteNotEmpty(WriterMethodBuilderContext context) { var customSerializerField = context.Context.InitConstField(Type, 0, customSerializer); var il = context.Il; var length = context.LocalInt; var start = il.DeclareLocal(typeof(int)); context.LoadIndexByRef(); // stack: [ref index] context.LoadIndex(); // stack: [ref index, index] il.Dup(); // stack: [ref index, index, index] il.Stloc(start); // start = index; stack: [ref index, index] il.Ldc_I4(5); // stack: [ref index, index, 5] il.Add(); // stack: [ref index, index + 5] il.Stind(typeof(int)); // index = index + 5; stack: [] context.LoadField(customSerializerField); // stack: [customSerializer] context.LoadObj(); // stack: [customSerializer, obj] if (Type.IsValueType) { il.Box(Type); // stack: [customSerializer, (object)obj] } context.LoadWriteEmpty(); // stack: [customSerializer, (object)obj, writeEmpty] context.LoadResult(); // stack: [customSerializer, (object)obj, writeEmpty, result] context.LoadIndexByRef(); // stack: [customSerializer, (object)obj, writeEmpty, result, ref index] context.LoadContext(); // stack: [customSerializer, (object)obj, writeEmpty, result, ref index, context] int dummy = 0; var writeMethod = HackHelpers.GetMethodDefinition <IGroBufCustomSerializer>(serializer => serializer.Write(null, false, IntPtr.Zero, ref dummy, null)); il.Call(writeMethod); // customSerializer.Write((object)obj, writeEmpty, result, ref index, context); stack: [] context.LoadIndex(); // stack: [index] il.Ldloc(start); // stack: [index, start] il.Sub(); // stack: [index - start] il.Ldc_I4(5); // stack: [index - start, 5] il.Sub(); // stack: [index - start - 5] var writeLengthLabel = il.DefineLabel("writeLength"); var doneLabel = il.DefineLabel("done"); il.Dup(); // stack: [index - start - 5, index - start - 5] il.Stloc(length); // length = index - start - 5; stack: [length] il.Brtrue(writeLengthLabel); // if(length != 0) goto writeLength; context.LoadIndexByRef(); // stack: [ref index] il.Ldloc(start); // stack: [ref index, start] il.Stind(typeof(int)); // index = start context.WriteNull(); il.MarkLabel(writeLengthLabel); context.LoadResult(); // stack: [result] il.Ldloc(start); // stack: [result, start] il.Add(); // stack: [result + start] il.Dup(); // stack: [result + start, result + start] il.Ldc_I4((int)GroBufTypeCode.CustomData); // stack: [result + start, result + start, TypeCode.Object] il.Stind(typeof(byte)); // *(result + start) = TypeCode.Object; stack: [result + start] il.Ldc_I4(1); // stack: [result + start, 1] il.Add(); // stack: [result + start + 1] il.Ldloc(length); // stack: [result + start + 1, length] il.Stind(typeof(int)); // *(int*)(result + start + 1) = length il.MarkLabel(doneLabel); }
protected override void WriteNotEmpty(WriterMethodBuilderContext context) { var il = context.Il; var argument = Type.GetGenericArguments()[0]; context.LoadObj(); // stack: [obj] var factoryField = Type.GetField("m_valueFactory", BindingFlags.Instance | BindingFlags.NonPublic); il.Ldfld(factoryField); // stack: [obj.m_valueFactory] var factory = il.DeclareLocal(typeof(Func <>).MakeGenericType(argument)); il.Dup(); il.Stloc(factory); // factory = obj.m_valueFactory; stack: [factory] var writeUsual = il.DefineLabel("writeUsual"); il.Brfalse(writeUsual); // if(factory == null) goto writeUsual; stack: [] il.Ldloc(factory); string targetFieldName = GroBufHelpers.IsMono ? "m_target" : "_target"; il.Ldfld(typeof(Delegate).GetField(targetFieldName, BindingFlags.Instance | BindingFlags.NonPublic)); // stack: [factory.target] var rawData = il.DeclareLocal(typeof(RawData <>).MakeGenericType(Type.GetGenericArguments())); il.Isinst(rawData.Type); // stack: [factory.target as RawData] il.Dup(); il.Stloc(rawData); // rawData = factory.target as RawData; stack: [rawData] il.Brfalse(writeUsual); // if(!(rawData is RawData)) goto writeUsual; stack: [] il.Ldloc(rawData); // stack: [rawData] il.Ldfld(rawData.Type.GetField("serializerId", BindingFlags.Instance | BindingFlags.NonPublic)); // stack: [rawData.serializerId] context.LoadSerializerId(); // stack: [rawData.serializerId, context.serializerId] il.Bne_Un(writeUsual); // if(rawData.serializerId != context.serializerId) goto writeUsual; stack: [] var data = il.DeclareLocal(typeof(byte).MakeByRefType(), true); var length = il.DeclareLocal(typeof(int)); il.Ldloc(rawData); // stack: [rawData] il.Ldfld(rawData.Type.GetField("data", BindingFlags.Instance | BindingFlags.NonPublic)); // stack: [rawData.data] il.Dup(); // stack: [rawData.data, rawData.data] il.Ldlen(); // stack: [rawData.data, rawData.data.Length] il.Stloc(length); // length = rawData.data.Length; stack: [rawData.data] il.Ldc_I4(0); // stack: [rawData.data, 0] il.Ldelema(typeof(byte)); // stack: [&rawData.data[0]] il.Stloc(data); // data = &rawData.data; stack: [] il.Ldloc(length); context.AssertLength(); context.GoToCurrentLocation(); // stack: [&result[index]] il.Ldloc(data); // stack: [&result[index], data] il.Ldloc(length); // stack: [&result[index], data, data.Length] il.Cpblk(); // result[index] = data; stack: [] context.LoadIndexByRef(); // stack: [ref index] context.LoadIndex(); // stack: [ref index, index] il.Ldloc(length); // stack: [ref index, index, data.Length] il.Add(); // stack: [ref index, index + data.Length] il.Stind(typeof(int)); // index = index + data.Length; stack: [] il.FreePinnedLocal(data); // data = null; stack: [] il.Ret(); il.MarkLabel(writeUsual); context.LoadObj(); // stack: [obj] il.Call(Type.GetProperty("Value", BindingFlags.Instance | BindingFlags.Public).GetGetMethod()); // stack: [obj.Value] context.LoadWriteEmpty(); // stack: [obj.Value, writeEmpty] context.LoadResult(); // stack: [obj.Value, writeEmpty, result] context.LoadIndexByRef(); // stack: [obj.Value, writeEmpty, result, ref index] context.LoadContext(); // stack: [obj.Value, writeEmpty, result, ref index, context] context.CallWriter(argument); // writer(obj.Value, writeEmpty, result, ref index, context) }
protected override void WriteNotEmpty(WriterMethodBuilderContext context) { var il = context.Il; var writers = GroBufHelpers.LeafTypes.Select(type1 => type1 == null ? new KeyValuePair <Delegate, IntPtr>(null, IntPtr.Zero) : GetWriter(context, type1)).ToArray(); var writersField = context.Context.InitConstField(Type, 0, writers.Select(pair => pair.Value).ToArray()); context.Context.InitConstField(Type, 1, writers.Select(pair => pair.Key).ToArray()); il.Ldfld(typeof(GroBufHelpers).GetField("LeafTypeHandles", BindingFlags.Public | BindingFlags.Static)); // stack: [LeafTypeHandles] context.LoadObj(); // stack: [LeafTypeHandles, obj] il.Call(getTypeMethod); // stack: [LeafTypeHandles, obj.GetType()] var type = il.DeclareLocal(typeof(Type)); il.Dup(); // stack: [LeafTypeHandles, obj.GetType(), obj.GetType()] il.Stloc(type); // type = obj.GetType(); stack: [LeafTypeHandles, obj.GetType()] il.Call(typeTypeHandleProperty.GetGetMethod()); // stack: [LeafTypeHandles, obj.GetType().TypeHandle] var typeHandle = il.DeclareLocal(typeof(RuntimeTypeHandle)); il.Stloc(typeHandle); // typeHandle = obj.GetType().TypeHandle; stack: [LeafTypeHandles] il.Ldloca(typeHandle); // stack: [LeafTypeHandles, ref typeHandle] il.Call(runtimeTypeHandleValueProperty.GetGetMethod(), typeof(RuntimeTypeHandle)); // stack: [LeafTypeHandles, obj.GetType().TypeHandle.Value] var handle = il.DeclareLocal(typeof(IntPtr)); il.Dup(); // stack: [LeafTypeHandles, obj.GetType().TypeHandle.Value, obj.GetType().TypeHandle.Value] il.Stloc(handle); // handle = obj.GetType().TypeHandle.Value; stack: [LeafTypeHandles, handle] il.Ldc_I4(writers.Length); // stack: [LeafTypeHandles, handle, LeafTypeHandles.Length] il.Rem(true); // stack: [LeafTypeHandles, handle % LeafTypeHandles.Length] var index = il.DeclareLocal(typeof(int)); il.Conv <int>(); // stack: [LeafTypeHandles, (int)(handle % LeafTypeHandles.Length)] il.Dup(); // stack: [LeafTypeHandles, (int)(handle % LeafTypeHandles.Length), (int)(handle % LeafTypeHandles.Length)] il.Stloc(index); // index = (int)(handle % LeafTypeHandles.Length); stack: [LeafTypeHandles, index] il.Ldelem(typeof(IntPtr)); // stack: [LeafTypeHandles[index]] il.Ldloc(handle); // stack: [LeafTypeHandles[index], handle] var tryAsArrayLabel = il.DefineLabel("tryAsArray"); il.Bne_Un(tryAsArrayLabel); // if(LeafTypeHandles[index] != handle) goto tryAsArray; stack: [] context.LoadObj(); // stack: [obj] context.LoadWriteEmpty(); // stack: [obj, writeEmpty] context.LoadResult(); // stack: [obj, writeEmpty, result] context.LoadIndexByRef(); // stack: [obj, writeEmpty, result, ref index] context.LoadContext(); // stack: [obj, writeEmpty, result, ref index, context] context.LoadField(writersField); // stack: [obj, writeEmpty, result, ref index, context, writers] il.Ldloc(index); // stack: [obj, writeEmpty, result, ref index, context, writers, index] il.Ldelem(typeof(IntPtr)); // stack: [obj, writeEmpty, result, ref index, context, writers[index]] var parameterTypes = new[] { typeof(object), typeof(bool), typeof(byte *), typeof(int).MakeByRefType(), typeof(WriterContext) }; il.Calli(CallingConventions.Standard, typeof(void), parameterTypes); // stack: [writers[index](obj, writeEmpty, result, ref index, context)] il.Ret(); il.MarkLabel(tryAsArrayLabel); il.Ldloc(type); // stack: [obj.GetType()] il.Call(typeIsArrayProperty.GetGetMethod()); // stack: [obj.GetType().IsArray] var writeNullLabel = il.DefineLabel("writeNull"); il.Brfalse(writeNullLabel); context.LoadObj(); // stack: [obj] context.LoadWriteEmpty(); // stack: [obj, writeEmpty] context.LoadResult(); // stack: [obj, writeEmpty, result] context.LoadIndexByRef(); // stack: [obj, writeEmpty, result, ref index] context.LoadContext(); // stack: [obj, writeEmpty, result, ref index, context] context.LoadField(writersField); // stack: [obj, writeEmpty, result, ref index, context, writers] il.Ldc_I4(Array.IndexOf(GroBufHelpers.LeafTypes, typeof(object[]))); // stack: [obj, writeEmpty, result, ref index, context, writers, index of typeof(object[])] il.Ldelem(typeof(IntPtr)); // stack: [obj, writeEmpty, result, ref index, context, writers[index of typeof(object[])]] parameterTypes = new[] { typeof(object), typeof(bool), typeof(byte *), typeof(int).MakeByRefType(), typeof(WriterContext) }; il.Calli(CallingConventions.Standard, typeof(void), parameterTypes); // stack: [writers[index of typeof(object[])](obj, writeEmpty, result, ref index, context)] il.Ret(); il.MarkLabel(writeNullLabel); context.WriteNull(); }