Skip to content

Commit cb77973

Browse files
json: codec functions now use codecCache
structs are not the only type kind which is capable of cycles: of relevance to json, at least maps, slices, and array pointers can be as well. Thus we're restructuring the "seen" parameter concept from being struct-specific to more broadly expressed in terms of codecs.
1 parent 3cfbf23 commit cb77973

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

json/codec.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ func typeid(t reflect.Type) unsafe.Pointer {
114114
return (*iface)(unsafe.Pointer(&t)).ptr
115115
}
116116

117-
func constructCachedCodec(t reflect.Type, cache map[unsafe.Pointer]codec) codec {
118-
c := constructCodec(t, map[reflect.Type]*structType{}, t.Kind() == reflect.Ptr)
117+
func constructCachedCodec(t reflect.Type, cache codecCache) codec {
118+
seen := make(codecCache)
119+
c := constructCodec(t, seen, t.Kind() == reflect.Ptr)
119120

120121
if inlined(t) {
121122
c.encode = constructInlineValueEncodeFunc(c.encode)
@@ -125,7 +126,7 @@ func constructCachedCodec(t reflect.Type, cache map[unsafe.Pointer]codec) codec
125126
return c
126127
}
127128

128-
func constructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) (c codec) {
129+
func constructCodec(t reflect.Type, seen codecCache, canAddr bool) (c codec) {
129130
switch t {
130131
case nullType, nil:
131132
c = codec{encode: encoder.encodeNull, decode: decoder.decodeNull}
@@ -261,7 +262,7 @@ func constructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr b
261262
return
262263
}
263264

264-
func constructStringCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec {
265+
func constructStringCodec(t reflect.Type, seen codecCache, canAddr bool) codec {
265266
c := constructCodec(t, seen, canAddr)
266267
return codec{
267268
encode: constructStringEncodeFunc(c.encode),
@@ -287,7 +288,7 @@ func constructStringToIntDecodeFunc(t reflect.Type, decode decodeFunc) decodeFun
287288
}
288289
}
289290

290-
func constructArrayCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec {
291+
func constructArrayCodec(t reflect.Type, seen codecCache, canAddr bool) codec {
291292
e := t.Elem()
292293
c := constructCodec(e, seen, canAddr)
293294
s := alignedSize(e)
@@ -311,7 +312,7 @@ func constructArrayDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) d
311312
}
312313
}
313314

314-
func constructSliceCodec(t reflect.Type, seen map[reflect.Type]*structType) codec {
315+
func constructSliceCodec(t reflect.Type, seen codecCache) codec {
315316
e := t.Elem()
316317
s := alignedSize(e)
317318

@@ -378,7 +379,7 @@ func constructSliceDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) d
378379
}
379380
}
380381

381-
func constructMapCodec(t reflect.Type, seen map[reflect.Type]*structType) codec {
382+
func constructMapCodec(t reflect.Type, seen codecCache) codec {
382383
var sortKeys sortFunc
383384
k := t.Key()
384385
v := t.Elem()
@@ -496,15 +497,15 @@ func constructMapDecodeFunc(t reflect.Type, decodeKey, decodeValue decodeFunc) d
496497
}
497498
}
498499

499-
func constructStructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec {
500+
func constructStructCodec(t reflect.Type, seen codecCache, canAddr bool) codec {
500501
st := constructStructType(t, seen, canAddr)
501502
return codec{
502503
encode: constructStructEncodeFunc(st),
503504
decode: constructStructDecodeFunc(st),
504505
}
505506
}
506507

507-
func constructStructType(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) *structType {
508+
func constructStructType(t reflect.Type, seen codecCache, canAddr bool) *structType {
508509
// Used for preventing infinite recursion on types that have pointers to
509510
// themselves.
510511
st := seen[t]
@@ -577,7 +578,7 @@ func constructEmbeddedStructPointerDecodeFunc(t reflect.Type, unexported bool, o
577578
}
578579
}
579580

580-
func appendStructFields(fields []structField, t reflect.Type, offset uintptr, seen map[reflect.Type]*structType, canAddr bool) []structField {
581+
func appendStructFields(fields []structField, t reflect.Type, offset uintptr, seen codecCache, canAddr bool) []structField {
581582
type embeddedField struct {
582583
index int
583584
offset uintptr
@@ -778,7 +779,7 @@ func encodeKeyFragment(s string, flags AppendFlags) string {
778779
return *(*string)(unsafe.Pointer(&b))
779780
}
780781

781-
func constructPointerCodec(t reflect.Type, seen map[reflect.Type]*structType) codec {
782+
func constructPointerCodec(t reflect.Type, seen codecCache) codec {
782783
e := t.Elem()
783784
c := constructCodec(e, seen, true)
784785
return codec{

0 commit comments

Comments
 (0)