Exemplo n.º 1
0
        protected override void CountSizeNotEmpty(SizeCounterMethodBuilderContext 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 countAsIntLabel = il.DefineLabel("countAsInt");

            il.Brfalse(countAsIntLabel);       // if(values[obj % values.Length] != obj) goto countAsInt
            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]
            il.Brfalse(countAsIntLabel);       // if(hashCode == 0) goto countAsInt;
            il.Ldc_I4(9);                      // stack: [9]
            il.Ret();                          // return 9;
            il.MarkLabel(countAsIntLabel);
            il.Ldc_I4(5);                      // stack: [5]
        }
Exemplo n.º 2
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
        }