@@ -741,6 +741,7 @@ private static unsafe void BuildDeserializeMapBody(ILGenerator g, Type type, Lay
741741 g . MarkLabel ( labels [ ( uint ) JumpLabels . Map32 ] ) ;
742742 g . Emit ( OpCodes . Ldarg_0 ) ;
743743 g . EmitCall ( OpCodes . Call , GetResultMethod ( ReadUInt32 ) , null ) ;
744+ g . Emit ( OpCodes . Br , mapType ) ;
744745
745746 g . MarkLabel ( mapType ) ;
746747 g . Emit ( OpCodes . Stloc_0 ) ;
@@ -770,35 +771,69 @@ private static unsafe void BuildDeserializeMapBody(ILGenerator g, Type type, Lay
770771 // load string
771772 {
772773 var lblStringCases = new Label [ ] { g . DefineLabel ( ) , g . DefineLabel ( ) , g . DefineLabel ( ) } ;
774+ Label stringType = g . DefineLabel ( ) ;
775+
776+ var localCode = g . DeclareLocal ( typeof ( byte ) ) ;
773777
774778 g . Emit ( OpCodes . Ldarg_0 ) ;
775779 g . EmitCall ( OpCodes . Call , GetResultMethod ( ReadByte ) , null ) ;
776-
780+ g . Emit ( OpCodes . Stloc , localCode ) ;
781+
782+ Label lblIsFixStr = g . DefineLabel ( ) ;
783+ Label lblCheckStrSwitch = g . DefineLabel ( ) ;
784+ Label lblStringType = g . DefineLabel ( ) ;
785+
786+ g . Emit ( OpCodes . Ldloc , localCode ) ;
787+ g . Emit ( OpCodes . Ldc_I4 , 0xA0 ) ;
788+ g . Emit ( OpCodes . Blt , lblCheckStrSwitch ) ; // if < 0xA0 go to switch
789+
790+ g . Emit ( OpCodes . Ldloc , localCode ) ;
791+ g . Emit ( OpCodes . Ldc_I4 , 0xBF ) ;
792+ g . Emit ( OpCodes . Bgt , lblCheckStrSwitch ) ; // if > 0xBF go to switch
793+
794+ // if we are here.. it's a fixstr
795+ g . MarkLabel ( lblIsFixStr ) ;
796+ // length = code & 0x1F
797+ g . Emit ( OpCodes . Ldloc , localCode ) ;
798+ g . Emit ( OpCodes . Ldc_I4 , 0x1F ) ;
799+ g . Emit ( OpCodes . And ) ;
800+ g . Emit ( OpCodes . Conv_U4 ) ; // optional if localLength is uint
801+ g . Emit ( OpCodes . Stloc_S , ( byte ) 4 ) ; // save length in local 4
802+ g . Emit ( OpCodes . Br , lblStringType ) ;
803+
804+ // if it's not fixstr, let's switch for Str8/16/32
805+ g . MarkLabel ( lblCheckStrSwitch ) ;
806+
807+ g . Emit ( OpCodes . Ldloc , localCode ) ;
777808 g . Emit ( OpCodes . Ldc_I4 , ( uint ) MsgPackCode . Str8 ) ;
778809 g . Emit ( OpCodes . Sub ) ;
779810 g . Emit ( OpCodes . Switch , lblStringCases ) ;
780811 g . Emit ( OpCodes . Br , defaultLabel ) ;
781812
782- Label stringType = g . DefineLabel ( ) ;
783- // case 0xd9: string with 8 byte sized length
813+ // case 0xd9 (Str8) with 8 byte sized length
784814 g . MarkLabel ( lblStringCases [ 0 ] ) ;
785815 g . Emit ( OpCodes . Ldarg_0 ) ;
786816 g . EmitCall ( OpCodes . Call , GetResultMethod ( ReadByte ) , null ) ;
787- g . Emit ( OpCodes . Br , stringType ) ;
817+ g . Emit ( OpCodes . Conv_U4 ) ;
818+ g . Emit ( OpCodes . Stloc_S , ( byte ) 4 ) ;
819+ g . Emit ( OpCodes . Br , lblStringType ) ;
788820
789821 // case 0xda: string with 16 byte sized length
790822 g . MarkLabel ( lblStringCases [ 1 ] ) ;
791823 g . Emit ( OpCodes . Ldarg_0 ) ;
792824 g . EmitCall ( OpCodes . Call , GetResultMethod ( ReadUInt16 ) , null ) ;
793- g . Emit ( OpCodes . Br , stringType ) ;
825+ g . Emit ( OpCodes . Conv_U4 ) ;
826+ g . Emit ( OpCodes . Stloc_S , ( byte ) 4 ) ;
827+ g . Emit ( OpCodes . Br , lblStringType ) ;
794828
795829 // case 0xdb: string with 32 byte sized length
796830 g . MarkLabel ( lblStringCases [ 2 ] ) ;
797831 g . Emit ( OpCodes . Ldarg_0 ) ;
798832 g . EmitCall ( OpCodes . Call , GetResultMethod ( ReadUInt32 ) , null ) ;
799-
800- g . MarkLabel ( stringType ) ;
801833 g . Emit ( OpCodes . Stloc_S , ( byte ) 4 ) ;
834+ g . Emit ( OpCodes . Br , lblStringType ) ;
835+
836+ g . MarkLabel ( lblStringType ) ;
802837 }
803838
804839 if ( members . Count > 0 )
0 commit comments