infra
/
goutils
Archived
1
0
Fork 0
This repository has been archived on 2022-04-06. You can view files and clone it, but cannot push or open issues or pull requests.
goutils/runtime/reflect.go

44 lines
1.2 KiB
Go

package runtime
import (
"unsafe"
"reflect"
"fmt"
)
//go:linkname typesByString reflect.typesByString
//go:nosplit
func typesByString(s string) []unsafe.Pointer
/*
TypeByString tries to find a reflect.Type corresponding to the type specified by
s.
It calls the unexported `reflect.typesByString` to do so. It will fail if
the type can't be found or if more than one type with the given name exist.
This relies on the following assumptions:
* The signature of `reflect.typesByString` must not change
* The value returned by `reflect.TypeOf(0)` is a `*reflect.rtype`
* The `reflect.Value` struct contains a `ptr` field of type `unsafe.Pointer`
*/
func TypeByString(s string) (reflect.Type, error) {
types := typesByString(s)
if len(types) == 0 {
return nil, fmt.Errorf("Type '%s' not found", s)
}
if len(types) > 1 {
return nil, fmt.Errorf("Type '%s' is ambiguous", s)
}
t := types[0]
pRtypeType := reflect.ValueOf(reflect.TypeOf(0)).Type()
rtype := reflect.New(pRtypeType).Elem()
ptr := unsafe.Pointer(reflect.ValueOf(rtype).FieldByName("ptr").Pointer())
*(*unsafe.Pointer)(ptr) = t
typ := rtype.Interface().(reflect.Type)
return typ, nil
}