3434//
3535
3636#if MONO_FEATURE_SRE
37+ using System . Buffers . Binary ;
3738using System . Collections . Generic ;
3839using System . Diagnostics . CodeAnalysis ;
3940using System . Diagnostics . SymbolStore ;
@@ -218,7 +219,7 @@ public LabelData(int addr, int maxStack)
218219 private int num_fixups ;
219220 internal Module module ;
220221 private int cur_block ;
221- private Stack ? open_blocks ;
222+ private Int32Stack ? open_blocks ;
222223 private ITokenGenerator token_gen ;
223224
224225 private const int defaultFixupSize = 4 ;
@@ -235,6 +236,9 @@ internal ILGenerator(Module m, ITokenGenerator token_gen, int size)
235236 this . token_gen = token_gen ;
236237 }
237238
239+ [ MemberNotNullWhen ( true , nameof ( open_blocks ) ) ]
240+ private bool InExceptionBlock => open_blocks != null && open_blocks . Count > 0 ;
241+
238242 private void make_room ( int nbytes )
239243 {
240244 if ( code_len + nbytes < code . Length )
@@ -246,10 +250,8 @@ private void make_room(int nbytes)
246250
247251 private void emit_int ( int val )
248252 {
249- code [ code_len ++ ] = ( byte ) ( val & 0xFF ) ;
250- code [ code_len ++ ] = ( byte ) ( ( val >> 8 ) & 0xFF ) ;
251- code [ code_len ++ ] = ( byte ) ( ( val >> 16 ) & 0xFF ) ;
252- code [ code_len ++ ] = ( byte ) ( ( val >> 24 ) & 0xFF ) ;
253+ BinaryPrimitives . WriteInt32LittleEndian ( code . AsSpan ( code_len ) , val ) ;
254+ code_len += 4 ;
253255 }
254256
255257 /* change to pass by ref to avoid copy */
@@ -343,9 +345,7 @@ private void InternalEndClause()
343345
344346 public virtual void BeginCatchBlock ( Type exceptionType )
345347 {
346- open_blocks ??= new Stack ( defaultExceptionStackSize ) ;
347-
348- if ( open_blocks . Count <= 0 )
348+ if ( ! InExceptionBlock )
349349 throw new NotSupportedException ( "Not in an exception block" ) ;
350350 if ( exceptionType != null && exceptionType . IsUserType )
351351 throw new NotSupportedException ( "User defined subclasses of System.Type are not yet supported." ) ;
@@ -371,10 +371,7 @@ public virtual void BeginCatchBlock(Type exceptionType)
371371
372372 public virtual void BeginExceptFilterBlock ( )
373373 {
374- if ( open_blocks == null )
375- open_blocks = new Stack ( defaultExceptionStackSize ) ;
376-
377- if ( open_blocks . Count <= 0 )
374+ if ( ! InExceptionBlock )
378375 throw new NotSupportedException ( "Not in an exception block" ) ;
379376 InternalEndClause ( ) ;
380377
@@ -384,8 +381,7 @@ public virtual void BeginExceptFilterBlock()
384381 public virtual Label BeginExceptionBlock ( )
385382 {
386383 //System.Console.WriteLine ("Begin Block");
387- if ( open_blocks == null )
388- open_blocks = new Stack ( defaultExceptionStackSize ) ;
384+ Int32Stack open_blocks = this . open_blocks ??= new Int32Stack ( defaultExceptionStackSize ) ;
389385
390386 if ( ex_handlers != null )
391387 {
@@ -406,10 +402,7 @@ public virtual Label BeginExceptionBlock()
406402
407403 public virtual void BeginFaultBlock ( )
408404 {
409- if ( open_blocks == null )
410- open_blocks = new Stack ( defaultExceptionStackSize ) ;
411-
412- if ( open_blocks . Count <= 0 )
405+ if ( ! InExceptionBlock )
413406 throw new NotSupportedException ( "Not in an exception block" ) ;
414407
415408 if ( ex_handlers ! [ cur_block ] . LastClauseType ( ) == ILExceptionBlock . FILTER_START )
@@ -425,10 +418,7 @@ public virtual void BeginFaultBlock()
425418
426419 public virtual void BeginFinallyBlock ( )
427420 {
428- if ( open_blocks == null )
429- open_blocks = new Stack ( defaultExceptionStackSize ) ;
430-
431- if ( open_blocks . Count <= 0 )
421+ if ( ! InExceptionBlock )
432422 throw new NotSupportedException ( "Not in an exception block" ) ;
433423
434424 InternalEndClause ( ) ;
@@ -520,25 +510,10 @@ public virtual void Emit(OpCode opcode, ConstructorInfo con)
520510
521511 public virtual void Emit ( OpCode opcode , double arg )
522512 {
523- byte [ ] s = BitConverter . GetBytes ( arg ) ;
524513 make_room ( 10 ) ;
525514 ll_emit ( opcode ) ;
526- if ( BitConverter . IsLittleEndian )
527- {
528- Array . Copy ( s , 0 , code , code_len , 8 ) ;
529- code_len += 8 ;
530- }
531- else
532- {
533- code [ code_len ++ ] = s [ 7 ] ;
534- code [ code_len ++ ] = s [ 6 ] ;
535- code [ code_len ++ ] = s [ 5 ] ;
536- code [ code_len ++ ] = s [ 4 ] ;
537- code [ code_len ++ ] = s [ 3 ] ;
538- code [ code_len ++ ] = s [ 2 ] ;
539- code [ code_len ++ ] = s [ 1 ] ;
540- code [ code_len ++ ] = s [ 0 ] ;
541- }
515+ BinaryPrimitives . WriteDoubleLittleEndian ( code . AsSpan ( code_len ) , arg ) ;
516+ code_len += 8 ;
542517 }
543518
544519 public virtual void Emit ( OpCode opcode , FieldInfo field )
@@ -553,8 +528,8 @@ public virtual void Emit(OpCode opcode, short arg)
553528 {
554529 make_room ( 4 ) ;
555530 ll_emit ( opcode ) ;
556- code [ code_len ++ ] = ( byte ) ( arg & 0xFF ) ;
557- code [ code_len ++ ] = ( byte ) ( ( arg >> 8 ) & 0xFF ) ;
531+ BinaryPrimitives . WriteInt16LittleEndian ( code . AsSpan ( code_len ) , arg ) ;
532+ code_len += 2 ;
558533 }
559534
560535 public virtual void Emit ( OpCode opcode , int arg )
@@ -568,14 +543,8 @@ public virtual void Emit(OpCode opcode, long arg)
568543 {
569544 make_room ( 10 ) ;
570545 ll_emit ( opcode ) ;
571- code [ code_len ++ ] = ( byte ) ( arg & 0xFF ) ;
572- code [ code_len ++ ] = ( byte ) ( ( arg >> 8 ) & 0xFF ) ;
573- code [ code_len ++ ] = ( byte ) ( ( arg >> 16 ) & 0xFF ) ;
574- code [ code_len ++ ] = ( byte ) ( ( arg >> 24 ) & 0xFF ) ;
575- code [ code_len ++ ] = ( byte ) ( ( arg >> 32 ) & 0xFF ) ;
576- code [ code_len ++ ] = ( byte ) ( ( arg >> 40 ) & 0xFF ) ;
577- code [ code_len ++ ] = ( byte ) ( ( arg >> 48 ) & 0xFF ) ;
578- code [ code_len ++ ] = ( byte ) ( ( arg >> 56 ) & 0xFF ) ;
546+ BinaryPrimitives . WriteInt64LittleEndian ( code . AsSpan ( code_len ) , arg ) ;
547+ code_len += 8 ;
579548 }
580549
581550 public virtual void Emit ( OpCode opcode , Label label )
@@ -792,21 +761,10 @@ public virtual void Emit(OpCode opcode, SignatureHelper signature)
792761
793762 public virtual void Emit ( OpCode opcode , float arg )
794763 {
795- byte [ ] s = BitConverter . GetBytes ( arg ) ;
796764 make_room ( 6 ) ;
797765 ll_emit ( opcode ) ;
798- if ( BitConverter . IsLittleEndian )
799- {
800- Array . Copy ( s , 0 , code , code_len , 4 ) ;
801- code_len += 4 ;
802- }
803- else
804- {
805- code [ code_len ++ ] = s [ 3 ] ;
806- code [ code_len ++ ] = s [ 2 ] ;
807- code [ code_len ++ ] = s [ 1 ] ;
808- code [ code_len ++ ] = s [ 0 ] ;
809- }
766+ BinaryPrimitives . WriteSingleLittleEndian ( code . AsSpan ( code_len ) , arg ) ;
767+ code_len += 4 ;
810768 }
811769
812770 public virtual void Emit ( OpCode opcode , string str )
@@ -909,10 +867,7 @@ public virtual void EmitWriteLine(string value)
909867
910868 public virtual void EndExceptionBlock ( )
911869 {
912- if ( open_blocks == null )
913- open_blocks = new Stack ( defaultExceptionStackSize ) ;
914-
915- if ( open_blocks . Count <= 0 )
870+ if ( ! InExceptionBlock )
916871 throw new NotSupportedException ( "Not in an exception block" ) ;
917872
918873 if ( ex_handlers ! [ cur_block ] . LastClauseType ( ) == ILExceptionBlock . FILTER_START )
@@ -923,7 +878,7 @@ public virtual void EndExceptionBlock()
923878 ex_handlers [ cur_block ] . End ( code_len ) ;
924879 open_blocks . Pop ( ) ;
925880 if ( open_blocks . Count > 0 )
926- cur_block = ( int ) open_blocks . Peek ( ) ! ;
881+ cur_block = open_blocks . Peek ( ) ! ;
927882 }
928883
929884 public virtual void EndScope ( )
@@ -995,26 +950,15 @@ internal void SetCode(byte[]? code, int max_stack)
995950 internal unsafe void SetCode ( byte * code , int code_size , int max_stack )
996951 {
997952 // Make a copy to avoid possible security problems
998- this . code = new byte [ code_size ] ;
999- for ( int i = 0 ; i < code_size ; ++ i )
1000- this . code [ i ] = code [ i ] ;
953+ this . code = new ReadOnlySpan < byte > ( code , code_size ) . ToArray ( ) ;
1001954 this . code_len = code_size ;
1002955 this . max_stack = max_stack ;
1003956 this . cur_stack = 0 ;
1004957 }
1005958
1006- internal ITokenGenerator TokenGenerator
1007- {
1008- get
1009- {
1010- return token_gen ;
1011- }
1012- }
959+ internal ITokenGenerator TokenGenerator => token_gen ;
1013960
1014- public virtual int ILOffset
1015- {
1016- get { return code_len ; }
1017- }
961+ public virtual int ILOffset => code_len ;
1018962 }
1019963
1020964 internal struct SequencePoint
@@ -1026,70 +970,33 @@ internal struct SequencePoint
1026970 public int EndCol ;
1027971 }
1028972
1029- internal sealed class Stack
973+ internal sealed class Int32Stack : List < int >
1030974 {
1031- private object ? [ ] _array ;
1032- private int _size ;
1033- private int _version ;
1034-
1035- private const int _defaultCapacity = 10 ;
1036-
1037- public Stack ( )
975+ public Int32Stack ( int initialCapacity ) : base ( initialCapacity )
1038976 {
1039- _array = new object [ _defaultCapacity ] ;
1040- _size = 0 ;
1041- _version = 0 ;
1042977 }
1043978
1044- public Stack ( int initialCapacity )
979+ public int Peek ( )
1045980 {
1046- if ( initialCapacity < 0 )
1047- throw new ArgumentOutOfRangeException ( nameof ( initialCapacity ) , SR . ArgumentOutOfRange_NeedNonNegNum ) ;
1048-
1049- if ( initialCapacity < _defaultCapacity )
1050- initialCapacity = _defaultCapacity ;
1051- _array = new object [ initialCapacity ] ;
1052- _size = 0 ;
1053- _version = 0 ;
1054- }
1055-
1056- public int Count
1057- {
1058- get
1059- {
1060- return _size ;
1061- }
1062- }
1063-
1064- public object ? Peek ( )
1065- {
1066- if ( _size == 0 )
981+ if ( Count == 0 )
1067982 throw new InvalidOperationException ( ) ;
1068983
1069- return _array [ _size - 1 ] ;
984+ return this [ Count - 1 ] ;
1070985 }
1071986
1072- public object ? Pop ( )
987+ public int Pop ( )
1073988 {
1074- if ( _size == 0 )
989+ if ( Count == 0 )
1075990 throw new InvalidOperationException ( ) ;
1076991
1077- _version ++ ;
1078- object ? obj = _array [ -- _size ] ;
1079- _array [ _size ] = null ;
1080- return obj ;
992+ int value = this [ Count - 1 ] ;
993+ RemoveAt ( Count - 1 ) ;
994+ return value ;
1081995 }
1082996
1083- public void Push ( object obj )
997+ public void Push ( int value )
1084998 {
1085- if ( _size == _array . Length )
1086- {
1087- object [ ] newArray = new object [ 2 * _array . Length ] ;
1088- Array . Copy ( _array , 0 , newArray , 0 , _size ) ;
1089- _array = newArray ;
1090- }
1091- _array [ _size ++ ] = obj ;
1092- _version ++ ;
999+ Add ( value ) ;
10931000 }
10941001 }
10951002}
0 commit comments