Add NO_DYNAMIC_CODEGEN condition. We will be based on (non-emit) reflection.
[mono.git] / mcs / class / referencesource / System.Runtime.Serialization / System / Runtime / Serialization / BitFlagsGenerator.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4
5 namespace System.Runtime.Serialization
6 {
7     using System;
8     using System.Reflection;
9     using System.Reflection.Emit;
10     using System.Security;
11
12 #if !NO_DYNAMIC_CODEGEN
13     [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview (Critical) - works on CodeGenerator objects, which require Critical access.")]
14     class BitFlagsGenerator
15     {
16         int bitCount;
17         CodeGenerator ilg;
18         LocalBuilder[] locals;
19
20         public BitFlagsGenerator(int bitCount, CodeGenerator ilg, string localName)
21         {
22             this.ilg = ilg;
23             this.bitCount = bitCount;
24             int localCount = (bitCount + 7) / 8;
25             locals = new LocalBuilder[localCount];
26             for (int i = 0; i < locals.Length; i++)
27             {
28                 locals[i] = ilg.DeclareLocal(typeof(byte), localName + i, (byte) 0);
29             }
30         }
31
32         public static bool IsBitSet(byte[] bytes, int bitIndex)
33         {
34             int byteIndex = GetByteIndex(bitIndex);
35             byte bitValue = GetBitValue(bitIndex);
36             return (bytes[byteIndex] & bitValue) == bitValue;
37         }
38
39         public static void SetBit(byte[] bytes, int bitIndex)
40         {
41             int byteIndex = GetByteIndex(bitIndex);
42             byte bitValue = GetBitValue(bitIndex);
43             bytes[byteIndex] |= bitValue;
44         }
45
46         public int GetBitCount()
47         {
48             return bitCount;
49         }
50
51         public LocalBuilder GetLocal(int i)
52         {
53             return locals[i];
54         }
55
56         public int GetLocalCount()
57         {
58             return locals.Length;
59         }
60
61         public void Load(int bitIndex)
62         {
63             LocalBuilder local = locals[GetByteIndex(bitIndex)];
64             byte bitValue = GetBitValue(bitIndex);
65             ilg.Load(local);
66             ilg.Load(bitValue);
67             ilg.And();
68             ilg.Load(bitValue);
69             ilg.Ceq();
70         }
71
72         public void LoadArray()
73         {
74             LocalBuilder localArray = ilg.DeclareLocal(Globals.TypeOfByteArray, "localArray");
75             ilg.NewArray(typeof(byte), locals.Length);
76             ilg.Store(localArray);
77             for (int i = 0; i < locals.Length; i++)
78             {
79                 ilg.StoreArrayElement(localArray, i, locals[i]);
80             }
81             ilg.Load(localArray);
82         }
83
84         public void Store(int bitIndex, bool value)
85         {
86             LocalBuilder local = locals[GetByteIndex(bitIndex)];
87             byte bitValue = GetBitValue(bitIndex);
88             if (value)
89             {
90                 ilg.Load(local);
91                 ilg.Load(bitValue);
92                 ilg.Or();
93                 ilg.Stloc(local);
94             }
95             else
96             {
97                 ilg.Load(local);
98                 ilg.Load(bitValue);
99                 ilg.Not();
100                 ilg.And();
101                 ilg.Stloc(local);
102             }
103         }
104
105         static byte GetBitValue(int bitIndex)
106         {
107             return (byte)(1 << (bitIndex & 7));
108         }
109
110         static int GetByteIndex(int bitIndex)
111         {
112             return bitIndex >> 3;
113         }
114
115     }
116 #endif
117 }
118