예제 #1
0
        protected override void WriteNotEmpty(WriterMethodBuilderContext context)
        {
            var il = context.Il;

            context.WriteTypeCode(GroBufTypeCode.Guid);
            il.Ldc_I4(16);
            context.AssertLength();
            context.GoToCurrentLocation(); // stack: [&result[index]]
            context.LoadObjByRef();        // stack: [&result[index], &obj]
            il.Ldind(typeof(long));        // stack: [&result[index], (int64)*obj]
            il.Stind(typeof(long));        // result[index] = (int64)*obj
            context.IncreaseIndexBy8();    // index = index + 8
            context.GoToCurrentLocation(); // stack: [&result[index]]
            context.LoadObjByRef();        // stack: [&result[index], &obj]
            il.Ldc_I4(8);                  // stack: [&result[index], &obj, 8]
            il.Add();                      // stack: [&result[index], &obj + 8]
            il.Ldind(typeof(long));        // stack: [&result[index], *(&obj+8)]
            il.Stind(typeof(long));        // result[index] = (int64)*(obj + 8)
            context.IncreaseIndexBy8();    // index = index + 8
        }
예제 #2
0
        protected override void WriteNotEmpty(WriterMethodBuilderContext context)
        {
            var il = context.Il;

            context.WriteTypeCode(GroBufTypeCode.DateTimeNew);
            il.Ldc_I4(8);
            context.AssertLength();
            context.GoToCurrentLocation();         // stack: [&result[index]]
            context.LoadObjByRef();                // stack: [&result[index], &obj]
            il.Call(dateTimeToBinaryMethod, Type); // stack: [&result[index], obj.ToBinary()]
            il.Stind(typeof(long));                // result[index] = obj.ToBinary()
            context.IncreaseIndexBy8();            // index = index + 8
        }
예제 #3
0
        protected override void WriteNotEmpty(WriterMethodBuilderContext context)
        {
            int[]   values;
            ulong[] hashCodes;
            EnumHelpers.BuildHashCodesTable(Type, out values, out hashCodes);
            var hashCodesField = context.Context.InitConstField(Type, 0, hashCodes);
            var valuesField    = context.Context.InitConstField(Type, 1, values);

            var il = context.Il;

            context.LoadField(valuesField); // stack: [values]
            context.LoadObj();              // stack: [values, obj]
            il.Ldc_I4(values.Length);       // stack: [values, obj, values.Length]
            il.Rem(true);                   // stack: [values, obj % values.Length]
            il.Ldelem(typeof(int));         // stack: [values[obj % values.Length]]
            context.LoadObj();              // stack: [values[obj % values.Length], obj]
            il.Ceq();                       // stack: [values[obj % values.Length] == obj]
            var writeIntLabel = il.DefineLabel("writeInt");

            il.Brfalse(writeIntLabel);         // if(values[obj % values.Length] != obj) goto writeInt

            context.LoadField(hashCodesField); // stack: [hashCodes]
            context.LoadObj();                 // stack: [hashCodes, obj]
            il.Ldc_I4(hashCodes.Length);       // stack: [hashCodes, obj, hashCodes.Length]
            il.Rem(true);                      // stack: [hashCodes, obj % hashCodes.Length]
            il.Ldelem(typeof(long));           // stack: [hashCodes[obj % hashCodes.Length] = hashCode]
            var hashCode = il.DeclareLocal(typeof(ulong));

            il.Dup();           // stack: [hashCode, hashCode]
            il.Stloc(hashCode); // hashCode = hashCodes[obj % hashCodes.Length]; stack: [hashCode]
            il.Brfalse(writeIntLabel);
            context.WriteTypeCode(GroBufTypeCode.Enum);
            il.Ldc_I4(8);
            context.AssertLength();
            context.GoToCurrentLocation(); // stack: [&result[index]]
            il.Ldloc(hashCode);            // stack: [&result[index], hashCode]
            il.Stind(typeof(long));        // *(int64*)&result[index] = hashCode
            context.IncreaseIndexBy8();    // index = index + 8;
            il.Ret();
            il.MarkLabel(writeIntLabel);
            context.WriteTypeCode(GroBufTypeCode.Int32);
            il.Ldc_I4(4);
            context.AssertLength();
            context.GoToCurrentLocation(); // stack: [&result[index]]
            context.LoadObj();             // stack: [&result[index], obj]
            il.Stind(typeof(int));         // result[index] = obj
            context.IncreaseIndexBy4();    // index = index + 4
        }
예제 #4
0
        protected override void WriteNotEmpty(WriterMethodBuilderContext context)
        {
            var typeCode = GroBufTypeCodeMap.GetTypeCode(Type);

            context.WriteTypeCode(typeCode);
            context.GoToCurrentLocation(); // stack: [&result[index]]
            var il = context.Il;

            switch (typeCode)
            {
            case GroBufTypeCode.Int8:
            case GroBufTypeCode.UInt8:
            case GroBufTypeCode.Boolean:
                il.Ldc_I4(1);
                context.AssertLength();
                context.LoadObj();          // stack: [&result[index], obj]
                il.Stind(typeof(byte));     // result[index] = obj
                context.IncreaseIndexBy1(); // index = index + 1
                break;

            case GroBufTypeCode.Int16:
            case GroBufTypeCode.UInt16:
                il.Ldc_I4(2);
                context.AssertLength();
                context.LoadObj();          // stack: [&result[index], obj]
                il.Stind(typeof(short));    // result[index] = obj
                context.IncreaseIndexBy2(); // index = index + 2
                break;

            case GroBufTypeCode.Int32:
            case GroBufTypeCode.UInt32:
                il.Ldc_I4(4);
                context.AssertLength();
                context.LoadObj();          // stack: [&result[index], obj]
                il.Stind(typeof(int));      // result[index] = obj
                context.IncreaseIndexBy4(); // index = index + 4
                break;

            case GroBufTypeCode.Int64:
            case GroBufTypeCode.UInt64:
                il.Ldc_I4(8);
                context.AssertLength();
                context.LoadObj();          // stack: [&result[index], obj]
                il.Stind(typeof(long));     // result[index] = obj
                context.IncreaseIndexBy8(); // index = index + 8
                break;

            case GroBufTypeCode.Single:
                il.Ldc_I4(4);
                context.AssertLength();
                context.LoadObj();          // stack: [&result[index], obj]
                il.Stind(typeof(float));    // result[index] = obj
                context.IncreaseIndexBy4(); // index = index + 4
                break;

            case GroBufTypeCode.Double:
                il.Ldc_I4(8);
                context.AssertLength();
                context.LoadObj();          // stack: [&result[index], obj]
                il.Stind(typeof(double));   // result[index] = obj
                context.IncreaseIndexBy8(); // index = index + 8
                break;

            case GroBufTypeCode.Decimal:
                il.Ldc_I4(16);
                context.AssertLength();
                context.LoadObjByRef();        // stack: [&result[index], &obj]
                il.Ldind(typeof(long));        // stack: [&result[index], (int64)*obj]
                il.Stind(typeof(long));        // result[index] = (int64)*obj
                context.IncreaseIndexBy8();    // index = index + 8
                context.GoToCurrentLocation(); // stack: [&result[index]]
                context.LoadObjByRef();        // stack: [&result[index], &obj]
                il.Ldc_I4(8);                  // stack: [&result[index], &obj, 8]
                il.Add();                      // stack: [&result[index], &obj + 8]
                il.Ldind(typeof(long));        // stack: [&result[index], *(&obj+8)]
                il.Stind(typeof(long));        // result[index] = (int64)*(obj + 8)
                context.IncreaseIndexBy8();    // index = index + 8
                break;

            default:
                throw new NotSupportedException();
            }
        }