update go-structr to v0.9.0 with new Timeline{} cache type

This commit is contained in:
kim 2025-03-12 16:40:21 +00:00
commit dcad8e1b99
19 changed files with 1291 additions and 412 deletions

View file

@ -1,3 +1,5 @@
//go:build go1.19 || go1.20 || go1.21 || go1.22 || go1.23
package mangler
import (
@ -35,8 +37,17 @@ func append_uint64(b []byte, u uint64) []byte {
}
type typecontext struct {
ntype reflect.Type
rtype reflect.Type
isptr bool
direct bool
ntype reflect.Type
rtype reflect.Type
}
func (ctx *typecontext) set_nested(direct bool) {
ctx.direct = ctx.direct && direct && !ctx.isptr
ctx.ntype = ctx.rtype
ctx.rtype = nil
ctx.isptr = false
}
func deref_ptr_mangler(ctx typecontext, mangle Mangler, n uint) Mangler {
@ -44,16 +55,14 @@ func deref_ptr_mangler(ctx typecontext, mangle Mangler, n uint) Mangler {
panic("bad input")
}
// Non-nested value types,
// i.e. just direct ptrs to
// primitives require one
// less dereference to ptr.
if ctx.ntype == nil {
// If this is a direct value type, i.e. non-nested primitive,
// or part of a single-field struct / single element array
// then it can be treated as a direct ptr with 1 less deref.
if ctx.direct {
n--
}
return func(buf []byte, ptr unsafe.Pointer) []byte {
// Deref n number times.
for i := n; i > 0; i-- {
@ -117,6 +126,15 @@ func iter_array_mangler(ctx typecontext, mangle Mangler) Mangler {
// no. array elements.
n := ctx.ntype.Len()
// Optimize
// easy cases.
switch n {
case 0:
return empty_mangler
case 1:
return mangle
}
// memory size of elem.
esz := ctx.rtype.Size()
@ -139,19 +157,27 @@ func iter_array_mangler(ctx typecontext, mangle Mangler) Mangler {
}
func iter_struct_mangler(ctx typecontext, manglers []Mangler) Mangler {
if ctx.rtype == nil || len(manglers) != ctx.rtype.NumField() {
if ctx.rtype == nil || len(manglers) != ctx.ntype.NumField() {
panic("bad input")
}
// Optimized easy cases.
switch len(manglers) {
case 0:
return empty_mangler
case 1:
return manglers[0]
}
type field struct {
mangle Mangler
offset uintptr
}
// Bundle together the fields and manglers.
fields := make([]field, ctx.rtype.NumField())
fields := make([]field, ctx.ntype.NumField())
for i := range fields {
rfield := ctx.rtype.FieldByIndex([]int{i})
rfield := ctx.ntype.Field(i)
fields[i].offset = rfield.Offset
fields[i].mangle = manglers[i]
if fields[i].mangle == nil {
@ -178,6 +204,10 @@ func iter_struct_mangler(ctx typecontext, manglers []Mangler) Mangler {
}
}
func empty_mangler(buf []byte, _ unsafe.Pointer) []byte {
return buf
}
// array_at returns ptr to index in array at ptr, given element size.
func array_at(ptr unsafe.Pointer, esz uintptr, i int) unsafe.Pointer {
return unsafe.Pointer(uintptr(ptr) + esz*uintptr(i))

View file

@ -8,6 +8,7 @@ import (
// function will be returned for given value interface{} and reflected type. Else panics.
func loadMangler(t reflect.Type) Mangler {
ctx := typecontext{rtype: t}
ctx.direct = true
// Load mangler fn
mng := load(ctx)
@ -103,6 +104,9 @@ func loadReflectPtr(ctx typecontext) Mangler {
n++
}
// Set ptr type.
ctx.isptr = true
// Search for elemn type mangler.
if mng := load(ctx); mng != nil {
return deref_ptr_mangler(ctx, mng, n)
@ -157,11 +161,13 @@ func loadReflectKnownSlice(ctx typecontext) Mangler {
// loadReflectSlice ...
func loadReflectSlice(ctx typecontext) Mangler {
// Set nesting type.
ctx.ntype = ctx.rtype
// Get nested element type.
ctx.rtype = ctx.rtype.Elem()
elem := ctx.rtype.Elem()
// Set this as nested type.
ctx.set_nested(false)
ctx.rtype = elem
// Preferably look for known slice mangler func
if mng := loadReflectKnownSlice(ctx); mng != nil {
@ -178,11 +184,14 @@ func loadReflectSlice(ctx typecontext) Mangler {
// loadReflectArray ...
func loadReflectArray(ctx typecontext) Mangler {
// Set nesting type.
ctx.ntype = ctx.rtype
// Get nested element type.
ctx.rtype = ctx.rtype.Elem()
elem := ctx.rtype.Elem()
// Set this as a nested value type.
direct := ctx.rtype.Len() <= 1
ctx.set_nested(direct)
ctx.rtype = elem
// Use manglers for nested iteration.
if mng := load(ctx); mng != nil {
@ -196,17 +205,15 @@ func loadReflectArray(ctx typecontext) Mangler {
func loadReflectStruct(ctx typecontext) Mangler {
var mngs []Mangler
// Set nesting type.
ctx.ntype = ctx.rtype
// Set this as a nested value type.
direct := ctx.rtype.NumField() <= 1
ctx.set_nested(direct)
// Gather manglers for all fields.
for i := 0; i < ctx.ntype.NumField(); i++ {
// Field typectx.
ctx := typecontext{
ntype: ctx.ntype,
rtype: ctx.ntype.Field(i).Type,
}
// Update context with field at index.
ctx.rtype = ctx.ntype.Field(i).Type
// Load mangler.
mng := load(ctx)