11// Licensed to the .NET Foundation under one or more agreements. 
22// The .NET Foundation licenses this file to you under the MIT license. 
33
4- using  System . Buffers . Binary ; 
54using  System . Reflection . Metadata ; 
65using  System . Reflection . Metadata . Ecma335 ; 
7- using  System . Runtime . CompilerServices ; 
86using  System . Runtime . InteropServices ; 
97
108namespace  System . Reflection . Emit 
@@ -17,6 +15,7 @@ internal sealed class ILGeneratorImpl : ILGenerator
1715        private  readonly  InstructionEncoder  _il ; 
1816        private  bool  _hasDynamicStackAllocation ; 
1917        private  int  _maxStackSize ; 
18+         private  int  _currentStack ; 
2019
2120        internal  ILGeneratorImpl ( MethodBuilder  methodBuilder ,  int  size ) 
2221        { 
@@ -42,40 +41,46 @@ internal ILGeneratorImpl(MethodBuilder methodBuilder, int size)
4241        public  override  LocalBuilder  DeclareLocal ( Type  localType ,  bool  pinned )  =>  throw  new  NotImplementedException ( ) ; 
4342        public  override  Label  DefineLabel ( )  =>  throw  new  NotImplementedException ( ) ; 
4443
45-         public  override  void  Emit ( OpCode  opcode ) 
44+         private  void  UpdateStackSize ( OpCode  opCode ) 
45+         { 
46+             _currentStack  +=  opCode . EvaluationStackDelta ; 
47+             _maxStackSize  =  Math . Max ( _maxStackSize ,  _currentStack ) ; 
48+         } 
49+ 
50+         public  void  EmitOpcode ( OpCode  opcode ) 
4651        { 
4752            if  ( opcode  ==  OpCodes . Localloc ) 
4853            { 
4954                _hasDynamicStackAllocation  =  true ; 
5055            } 
51-             _il . OpCode ( ( ILOpCode ) opcode . Value ) ; 
5256
53-             // TODO: for now only count the Opcodes emitted, in order to calculate it correctly we might need to make internal Opcode APIs public 
54-             // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs#L48 
55-             _maxStackSize ++ ; 
57+             _il . OpCode ( ( ILOpCode ) opcode . Value ) ; 
58+             UpdateStackSize ( opcode ) ; 
5659        } 
5760
61+         public  override  void  Emit ( OpCode  opcode )  =>  EmitOpcode ( opcode ) ; 
62+ 
5863        public  override  void  Emit ( OpCode  opcode ,  byte  arg ) 
5964        { 
60-             _il . OpCode ( ( ILOpCode ) opcode . Value ) ; 
65+             EmitOpcode ( opcode ) ; 
6166            _builder . WriteByte ( arg ) ; 
6267        } 
6368
6469        public  override  void  Emit ( OpCode  opcode ,  double  arg ) 
6570        { 
66-             _il . OpCode ( ( ILOpCode ) opcode . Value ) ; 
71+             EmitOpcode ( opcode ) ; 
6772            _builder . WriteDouble ( arg ) ; 
6873        } 
6974
7075        public  override  void  Emit ( OpCode  opcode ,  float  arg ) 
7176        { 
72-             _il . OpCode ( ( ILOpCode ) opcode . Value ) ; 
77+             EmitOpcode ( opcode ) ; 
7378            _builder . WriteSingle ( arg ) ; 
7479        } 
7580
7681        public  override  void  Emit ( OpCode  opcode ,  short  arg ) 
7782        { 
78-             _il . OpCode ( ( ILOpCode ) opcode . Value ) ; 
83+             EmitOpcode ( opcode ) ; 
7984            _builder . WriteInt16 ( arg ) ; 
8085        } 
8186
@@ -86,98 +91,91 @@ public override void Emit(OpCode opcode, int arg)
8691            { 
8792                if  ( arg  >=  - 1  &&  arg  <=  8 ) 
8893                { 
89-                     _il . OpCode ( arg  switch 
94+                     EmitOpcode ( arg  switch 
9095                    { 
91-                         - 1  =>  ILOpCode . Ldc_i4_m1 , 
92-                         0  =>  ILOpCode . Ldc_i4_0 , 
93-                         1  =>  ILOpCode . Ldc_i4_1 , 
94-                         2  =>  ILOpCode . Ldc_i4_2 , 
95-                         3  =>  ILOpCode . Ldc_i4_3 , 
96-                         4  =>  ILOpCode . Ldc_i4_4 , 
97-                         5  =>  ILOpCode . Ldc_i4_5 , 
98-                         6  =>  ILOpCode . Ldc_i4_6 , 
99-                         7  =>  ILOpCode . Ldc_i4_7 , 
100-                         _ =>  ILOpCode . Ldc_i4_8 , 
96+                         - 1  =>  OpCodes . Ldc_I4_M1 , 
97+                         0  =>  OpCodes . Ldc_I4_0 , 
98+                         1  =>  OpCodes . Ldc_I4_1 , 
99+                         2  =>  OpCodes . Ldc_I4_2 , 
100+                         3  =>  OpCodes . Ldc_I4_3 , 
101+                         4  =>  OpCodes . Ldc_I4_4 , 
102+                         5  =>  OpCodes . Ldc_I4_5 , 
103+                         6  =>  OpCodes . Ldc_I4_6 , 
104+                         7  =>  OpCodes . Ldc_I4_7 , 
105+                         _ =>  OpCodes . Ldc_I4_8 
101106                    } ) ; 
102107                    return ; 
103108                } 
104109
105110                if  ( arg  >=  - 128  &&  arg  <=  127 ) 
106111                { 
107-                     _il . OpCode ( ILOpCode . Ldc_i4_s ) ; 
108-                     _builder . WriteSByte ( ( sbyte ) arg )  ; 
112+                     Emit ( OpCodes . Ldc_I4_S ,  ( sbyte ) arg ) ; 
109113                    return ; 
110114                } 
111115            } 
112116            else  if  ( opcode . Equals ( OpCodes . Ldarg ) ) 
113117            { 
114118                if  ( ( uint ) arg  <=  3 ) 
115119                { 
116-                     _il . OpCode ( arg  switch 
120+                     EmitOpcode ( arg  switch 
117121                    { 
118-                         0  =>  ILOpCode . Ldarg_0 , 
119-                         1  =>  ILOpCode . Ldarg_1 , 
120-                         2  =>  ILOpCode . Ldarg_2 , 
121-                         _ =>  ILOpCode . Ldarg_3 , 
122+                         0  =>  OpCodes . Ldarg_0 , 
123+                         1  =>  OpCodes . Ldarg_1 , 
124+                         2  =>  OpCodes . Ldarg_2 , 
125+                         _ =>  OpCodes . Ldarg_3 , 
122126                    } ) ; 
123127                    return ; 
124128                } 
125129
126130                if  ( ( uint ) arg  <=  byte . MaxValue ) 
127131                { 
128-                     _il . OpCode ( ILOpCode . Ldarg_s ) ; 
129-                     _builder . WriteByte ( ( byte ) arg ) ; 
132+                     Emit ( OpCodes . Ldarg_S ,  ( byte ) arg ) ; 
130133                    return ; 
131134                } 
132135
133136                if  ( ( uint ) arg  <=  ushort . MaxValue )  // this will be true except on misuse of the opcode 
134137                { 
135-                     _il . OpCode ( ILOpCode . Ldarg ) ; 
136-                     _builder . WriteInt16 ( ( short ) arg ) ; 
138+                     Emit ( OpCodes . Ldarg ,  ( short ) arg ) ; 
137139                    return ; 
138140                } 
139141            } 
140142            else  if  ( opcode . Equals ( OpCodes . Ldarga ) ) 
141143            { 
142144                if  ( ( uint ) arg  <=  byte . MaxValue ) 
143145                { 
144-                     _il . OpCode ( ILOpCode . Ldarga_s ) ; 
145-                     _builder . WriteByte ( ( byte ) arg ) ; 
146+                     Emit ( OpCodes . Ldarga_S ,  ( byte ) arg ) ; 
146147                    return ; 
147148                } 
148149
149150                if  ( ( uint ) arg  <=  ushort . MaxValue )  // this will be true except on misuse of the opcode 
150151                { 
151-                     _il . OpCode ( ILOpCode . Ldarga ) ; 
152-                     _builder . WriteInt16 ( ( short ) arg ) ; 
152+                     Emit ( OpCodes . Ldarga ,  ( short ) arg ) ; 
153153                    return ; 
154154                } 
155155            } 
156156            else  if  ( opcode . Equals ( OpCodes . Starg ) ) 
157157            { 
158158                if  ( ( uint ) arg  <=  byte . MaxValue ) 
159159                { 
160-                     _il . OpCode ( ILOpCode . Starg_s ) ; 
161-                     _builder . WriteByte ( ( byte ) arg ) ; 
160+                     Emit ( OpCodes . Starg_S ,  ( byte ) arg ) ; 
162161                    return ; 
163162                } 
164163
165164                if  ( ( uint ) arg  <=  ushort . MaxValue )  // this will be true except on misuse of the opcode 
166165                { 
167-                     _il . OpCode ( ILOpCode . Starg ) ; 
168-                     _builder . WriteInt16 ( ( short ) arg ) ; 
166+                     Emit ( OpCodes . Starg ,  ( short ) arg ) ; 
169167                    return ; 
170168                } 
171169            } 
172170
173171            // For everything else, put the opcode followed by the arg onto the stream of instructions. 
174-             _il . OpCode ( ( ILOpCode ) opcode . Value ) ; 
172+             EmitOpcode ( opcode ) ; 
175173            _builder . WriteInt32 ( arg ) ; 
176174        } 
177175
178176        public  override  void  Emit ( OpCode  opcode ,  long  arg ) 
179177        { 
180-             _il . OpCode ( ( ILOpCode ) opcode . Value ) ; 
178+             EmitOpcode ( opcode ) ; 
181179            _il . CodeBuilder . WriteInt64 ( arg ) ; 
182180        } 
183181
@@ -187,7 +185,7 @@ public override void Emit(OpCode opcode, string str)
187185            // represented by str. 
188186            ModuleBuilder  modBuilder  =  ( ModuleBuilder ) _methodBuilder . Module ; 
189187            int  tempVal  =  modBuilder . GetStringMetadataToken ( str ) ; 
190-             _il . OpCode ( ( ILOpCode ) opcode . Value ) ; 
188+             EmitOpcode ( opcode ) ; 
191189            _il . Token ( tempVal ) ; 
192190        } 
193191
0 commit comments