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)
        }
예제 #2
0
        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)
        }
예제 #3
0
        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)
        }
예제 #4
0
        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)
        }
예제 #5
0
        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)
        }
예제 #6
0
        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);
        }
예제 #7
0
        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)
        }
예제 #8
0
        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();
        }