From 4f6d598ea88f6afe47ceb9611d5e854c522e55b2 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 28 Mar 2021 22:31:27 +0200 Subject: [PATCH] reflect: implement Sizeof and Alignof for func values This is a small change that appears to be necessary for encoding/json support. It's simple enough to implement. --- compiler/sizes.go | 3 +++ src/reflect/type.go | 14 ++++++++++---- testdata/reflect.go | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/compiler/sizes.go b/compiler/sizes.go index 091c6a99..b46d3436 100644 --- a/compiler/sizes.go +++ b/compiler/sizes.go @@ -150,6 +150,9 @@ func (s *stdSizes) Sizeof(T types.Type) int64 { return s.PtrSize * 2 case *types.Pointer: return s.PtrSize + case *types.Signature: + // Func values in TinyGo are two words in size. + return s.PtrSize * 2 default: panic("unknown type: " + t.String()) } diff --git a/src/reflect/type.go b/src/reflect/type.go index ad067069..67396c77 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -533,13 +533,16 @@ func (t rawType) Size() uintptr { case Complex128: return 16 case String: - return unsafe.Sizeof(StringHeader{}) + return unsafe.Sizeof("") case UnsafePointer, Chan, Map, Ptr: return unsafe.Sizeof(uintptr(0)) case Slice: - return unsafe.Sizeof(SliceHeader{}) + return unsafe.Sizeof([]int{}) case Interface: return unsafe.Sizeof(interface{}(nil)) + case Func: + var f func() + return unsafe.Sizeof(f) case Array: return t.elem().Size() * uintptr(t.Len()) case Struct: @@ -579,13 +582,16 @@ func (t rawType) Align() int { case Complex128: return int(unsafe.Alignof(complex128(0))) case String: - return int(unsafe.Alignof(StringHeader{})) + return int(unsafe.Alignof("")) case UnsafePointer, Chan, Map, Ptr: return int(unsafe.Alignof(uintptr(0))) case Slice: - return int(unsafe.Alignof(SliceHeader{})) + return int(unsafe.Alignof([]int(nil))) case Interface: return int(unsafe.Alignof(interface{}(nil))) + case Func: + var f func() + return int(unsafe.Alignof(f)) case Struct: numField := t.NumField() alignment := 1 diff --git a/testdata/reflect.go b/testdata/reflect.go index 2ddbe8dd..b02dd6c8 100644 --- a/testdata/reflect.go +++ b/testdata/reflect.go @@ -148,6 +148,7 @@ func main() { assertSize(reflect.TypeOf(uintptr(0)).Size() == unsafe.Sizeof(uintptr(0)), "uintptr") assertSize(reflect.TypeOf("").Size() == unsafe.Sizeof(""), "string") assertSize(reflect.TypeOf(new(int)).Size() == unsafe.Sizeof(new(int)), "*int") + assertSize(reflect.TypeOf(zeroFunc).Size() == unsafe.Sizeof(zeroFunc), "func()") // SetBool rv := reflect.ValueOf(new(bool)).Elem()