@@ -113,7 +113,8 @@ func typeid(t reflect.Type) unsafe.Pointer {
113113}
114114
115115func constructCachedCodec (t reflect.Type , cache map [unsafe.Pointer ]codec ) codec {
116- c := constructCodec (t , map [reflect.Type ]* structType {}, t .Kind () == reflect .Ptr )
116+ seen := make (seenMap )
117+ c := constructCodec (t , seen , t .Kind () == reflect .Ptr )
117118
118119 if inlined (t ) {
119120 c .encode = constructInlineValueEncodeFunc (c .encode )
@@ -123,7 +124,14 @@ func constructCachedCodec(t reflect.Type, cache map[unsafe.Pointer]codec) codec
123124 return c
124125}
125126
126- func constructCodec (t reflect.Type , seen map [reflect.Type ]* structType , canAddr bool ) (c codec ) {
127+ type seenType struct {
128+ * codec
129+ * structType
130+ }
131+
132+ type seenMap map [reflect.Type ]seenType
133+
134+ func constructCodec (t reflect.Type , seen seenMap , canAddr bool ) (c codec ) {
127135 switch t {
128136 case nullType , nil :
129137 c = codec {encode : encoder .encodeNull , decode : decoder .decodeNull }
@@ -247,7 +255,7 @@ func constructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr b
247255 return
248256}
249257
250- func constructStringCodec (t reflect.Type , seen map [reflect. Type ] * structType , canAddr bool ) codec {
258+ func constructStringCodec (t reflect.Type , seen seenMap , canAddr bool ) codec {
251259 c := constructCodec (t , seen , canAddr )
252260 return codec {
253261 encode : constructStringEncodeFunc (c .encode ),
@@ -273,7 +281,7 @@ func constructStringToIntDecodeFunc(t reflect.Type, decode decodeFunc) decodeFun
273281 }
274282}
275283
276- func constructArrayCodec (t reflect.Type , seen map [reflect. Type ] * structType , canAddr bool ) codec {
284+ func constructArrayCodec (t reflect.Type , seen seenMap , canAddr bool ) codec {
277285 e := t .Elem ()
278286 c := constructCodec (e , seen , canAddr )
279287 s := alignedSize (e )
@@ -297,7 +305,7 @@ func constructArrayDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) d
297305 }
298306}
299307
300- func constructSliceCodec (t reflect.Type , seen map [reflect. Type ] * structType ) codec {
308+ func constructSliceCodec (t reflect.Type , seen seenMap ) codec {
301309 e := t .Elem ()
302310 s := alignedSize (e )
303311
@@ -364,7 +372,7 @@ func constructSliceDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) d
364372 }
365373}
366374
367- func constructMapCodec (t reflect.Type , seen map [reflect. Type ] * structType ) codec {
375+ func constructMapCodec (t reflect.Type , seen seenMap ) codec {
368376 var sortKeys sortFunc
369377 k := t .Key ()
370378 v := t .Elem ()
@@ -482,18 +490,19 @@ func constructMapDecodeFunc(t reflect.Type, decodeKey, decodeValue decodeFunc) d
482490 }
483491}
484492
485- func constructStructCodec (t reflect.Type , seen map [reflect. Type ] * structType , canAddr bool ) codec {
493+ func constructStructCodec (t reflect.Type , seen seenMap , canAddr bool ) codec {
486494 st := constructStructType (t , seen , canAddr )
487495 return codec {
488496 encode : constructStructEncodeFunc (st ),
489497 decode : constructStructDecodeFunc (st ),
490498 }
491499}
492500
493- func constructStructType (t reflect.Type , seen map [reflect. Type ] * structType , canAddr bool ) * structType {
501+ func constructStructType (t reflect.Type , seen seenMap , canAddr bool ) * structType {
494502 // Used for preventing infinite recursion on types that have pointers to
495503 // themselves.
496- st := seen [t ]
504+ seenInfo := seen [t ]
505+ st := seen [t ].structType
497506
498507 if st == nil {
499508 st = & structType {
@@ -503,7 +512,9 @@ func constructStructType(t reflect.Type, seen map[reflect.Type]*structType, canA
503512 typ : t ,
504513 }
505514
506- seen [t ] = st
515+ seenInfo .structType = st
516+ seen [t ] = seenInfo
517+
507518 st .fields = appendStructFields (st .fields , t , 0 , seen , canAddr )
508519
509520 for i := range st .fields {
@@ -563,7 +574,7 @@ func constructEmbeddedStructPointerDecodeFunc(t reflect.Type, unexported bool, o
563574 }
564575}
565576
566- func appendStructFields (fields []structField , t reflect.Type , offset uintptr , seen map [reflect. Type ] * structType , canAddr bool ) []structField {
577+ func appendStructFields (fields []structField , t reflect.Type , offset uintptr , seen seenMap , canAddr bool ) []structField {
567578 type embeddedField struct {
568579 index int
569580 offset uintptr
@@ -764,7 +775,7 @@ func encodeKeyFragment(s string, flags AppendFlags) string {
764775 return * (* string )(unsafe .Pointer (& b ))
765776}
766777
767- func constructPointerCodec (t reflect.Type , seen map [reflect. Type ] * structType ) codec {
778+ func constructPointerCodec (t reflect.Type , seen seenMap ) codec {
768779 e := t .Elem ()
769780 c := constructCodec (e , seen , true )
770781 return codec {
0 commit comments