Skip to content

Commit d26d04e

Browse files
Merge pull request #3 from manups4e/master
fix(vendor/msgpack): fix TypeFormatter in non-indexed layout
2 parents 29dc2c1 + afa0392 commit d26d04e

File tree

1 file changed

+42
-7
lines changed

1 file changed

+42
-7
lines changed

MsgPack/Formatters/TypeFormatter.cs

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)