reflect: add support for linked lists

Linked lists are usually implemented as follows:

    type linkedList struct {
        next *linkedList
        data int // whatever
    }

This caused a stack overflow while writing out the reflect run-time type
information. This has now been fixed by splitting the allocation of a
named type number from setting the underlying type in the sidetable.
This commit is contained in:
Ayke van Laethem
2019-08-10 21:52:14 +02:00
committed by Ron Evans
parent 0818a125c0
commit ea8e4079bc
7 changed files with 128 additions and 84 deletions
+3 -3
View File
@@ -5,10 +5,10 @@ import (
)
// This stores a varint for each named type. Named types are identified by their
// name instead of by their type. The named types stored in this struct are the
// simpler non-basic types: pointer, struct, and channel.
// name instead of by their type. The named types stored in this struct are
// non-basic types: pointer, struct, and channel.
//go:extern reflect.namedNonBasicTypesSidetable
var namedNonBasicTypesSidetable byte
var namedNonBasicTypesSidetable uintptr
//go:extern reflect.structTypesSidetable
var structTypesSidetable byte
+1 -1
View File
@@ -163,7 +163,7 @@ func (t Type) stripPrefix() Type {
if (t>>4)%2 != 0 {
// This is a named type. The data is stored in a sidetable.
namedTypeNum := t >> 5
n, _ := readVarint(unsafe.Pointer(uintptr(unsafe.Pointer(&namedNonBasicTypesSidetable)) + uintptr(namedTypeNum)))
n := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&namedNonBasicTypesSidetable)) + uintptr(namedTypeNum)*unsafe.Sizeof(uintptr(0))))
return Type(n)
}
// Not a named type, so the value is stored directly in the type code.