]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: move funcType to abi/type.go
authorDavid Chase <drchase@google.com>
Wed, 19 Apr 2023 17:49:04 +0000 (13:49 -0400)
committerDavid Chase <drchase@google.com>
Wed, 10 May 2023 22:56:31 +0000 (22:56 +0000)
Change-Id: I381229ba67a39487cdcc60da1c73d33b0a7d494a
Reviewed-on: https://go-review.googlesource.com/c/go/+/487556
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: David Chase <drchase@google.com>

src/reflect/abi.go
src/reflect/makefunc.go
src/reflect/type.go
src/reflect/value.go

index 21c435ae0bc07c341e232fa72d56c08d486574b0..8ae8964bfe46bd14ad917ff5d49e1285d562941c 100644 (file)
@@ -416,10 +416,10 @@ func newAbiDesc(t *funcType, rcvr *rtype) abiDesc {
                        spill += goarch.PtrSize
                }
        }
-       for i, arg := range t.in() {
-               stkStep := in.addArg(arg)
+       for i, arg := range t.InSlice() {
+               stkStep := in.addArg(toRType(arg))
                if stkStep != nil {
-                       addTypeBits(stackPtrs, stkStep.stkOff, arg)
+                       addTypeBits(stackPtrs, stkStep.stkOff, toRType(arg))
                } else {
                        spill = align(spill, uintptr(arg.Align()))
                        spill += arg.Size()
@@ -449,10 +449,10 @@ func newAbiDesc(t *funcType, rcvr *rtype) abiDesc {
        // Fake it by artificially extending stackBytes by
        // the return offset.
        out.stackBytes = retOffset
-       for i, res := range t.out() {
-               stkStep := out.addArg(res)
+       for i, res := range t.OutSlice() {
+               stkStep := out.addArg(toRType(res))
                if stkStep != nil {
-                       addTypeBits(stackPtrs, stkStep.stkOff, res)
+                       addTypeBits(stackPtrs, stkStep.stkOff, toRType(res))
                } else {
                        for _, st := range out.stepsForValue(i) {
                                if st.kind == abiStepPointer {
index ee0729903e38c8013e67ac2a6ef298adf703f84b..6e8aeafabe83d4bc1d55ac80034e44d3df3c0bca 100644 (file)
@@ -126,7 +126,7 @@ func makeMethodValue(op string, v Value) Value {
        // but we want Interface() and other operations to fail early.
        methodReceiver(op, fv.rcvr, fv.method)
 
-       return Value{&ftyp.rtype, unsafe.Pointer(fv), v.flag&flagRO | flag(Func)}
+       return Value{toRType(&ftyp.Type), unsafe.Pointer(fv), v.flag&flagRO | flag(Func)}
 }
 
 func methodValueCallCodePtr() uintptr {
index c9da9197f672bfdf0455c40df504392c21607370..618204780a6056d80616c9c547e529c76fd57825 100644 (file)
@@ -315,11 +315,7 @@ type chanType = abi.ChanType
 //             uncommonType
 //             [2]*rtype    // [0] is in, [1] is out
 //     }
-type funcType struct {
-       rtype
-       InCount  uint16
-       OutCount uint16 // top bit is set if last input parameter is ...
-}
+type funcType = abi.FuncType
 
 // interfaceType represents an interface type.
 type interfaceType struct {
@@ -582,14 +578,14 @@ func (t *rtype) Method(i int) (m Method) {
        fl := flag(Func)
        mtyp := t.typeOff(p.Mtyp)
        ft := (*funcType)(unsafe.Pointer(mtyp))
-       in := make([]Type, 0, 1+len(ft.in()))
+       in := make([]Type, 0, 1+ft.NumIn())
        in = append(in, t)
-       for _, arg := range ft.in() {
-               in = append(in, arg)
+       for _, arg := range ft.InSlice() {
+               in = append(in, toRType(arg))
        }
-       out := make([]Type, 0, len(ft.out()))
-       for _, ret := range ft.out() {
-               out = append(out, ret)
+       out := make([]Type, 0, ft.NumOut())
+       for _, ret := range ft.OutSlice() {
+               out = append(out, toRType(ret))
        }
        mt := FuncOf(in, out, ft.IsVariadic())
        m.Type = mt
@@ -671,18 +667,10 @@ func (t *rtype) ChanDir() ChanDir {
        if t.Kind() != Chan {
                panic("reflect: ChanDir of non-chan type " + t.String())
        }
-       tt := (*chanType)(unsafe.Pointer(t))
+       tt := (*abi.ChanType)(unsafe.Pointer(t))
        return ChanDir(tt.Dir)
 }
 
-func (t *rtype) IsVariadic() bool {
-       if t.Kind() != Func {
-               panic("reflect: IsVariadic of non-func type " + t.String())
-       }
-       tt := (*funcType)(unsafe.Pointer(t))
-       return tt.OutCount&(1<<15) != 0
-}
-
 func toRType(t *abi.Type) *rtype {
        return (*rtype)(unsafe.Pointer(t))
 }
@@ -740,14 +728,6 @@ func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
        return tt.FieldByNameFunc(match)
 }
 
-func (t *rtype) In(i int) Type {
-       if t.Kind() != Func {
-               panic("reflect: In of non-func type " + t.String())
-       }
-       tt := (*funcType)(unsafe.Pointer(t))
-       return toType(tt.in()[i])
-}
-
 func (t *rtype) Key() Type {
        if t.Kind() != Map {
                panic("reflect: Key of non-map type " + t.String())
@@ -772,51 +752,44 @@ func (t *rtype) NumField() int {
        return len(tt.Fields)
 }
 
+func (t *rtype) In(i int) Type {
+       if t.Kind() != Func {
+               panic("reflect: In of non-func type " + t.String())
+       }
+       tt := (*abi.FuncType)(unsafe.Pointer(t))
+       return toType(toRType(tt.InSlice()[i]))
+}
+
 func (t *rtype) NumIn() int {
        if t.Kind() != Func {
                panic("reflect: NumIn of non-func type " + t.String())
        }
-       tt := (*funcType)(unsafe.Pointer(t))
-       return int(tt.InCount)
+       tt := (*abi.FuncType)(unsafe.Pointer(t))
+       return tt.NumIn()
 }
 
 func (t *rtype) NumOut() int {
        if t.Kind() != Func {
                panic("reflect: NumOut of non-func type " + t.String())
        }
-       tt := (*funcType)(unsafe.Pointer(t))
-       return len(tt.out())
+       tt := (*abi.FuncType)(unsafe.Pointer(t))
+       return tt.NumOut()
 }
 
 func (t *rtype) Out(i int) Type {
        if t.Kind() != Func {
                panic("reflect: Out of non-func type " + t.String())
        }
-       tt := (*funcType)(unsafe.Pointer(t))
-       return toType(tt.out()[i])
-}
-
-func (t *funcType) in() []*rtype {
-       uadd := unsafe.Sizeof(*t)
-       if t.t.TFlag&abi.TFlagUncommon != 0 {
-               uadd += unsafe.Sizeof(uncommonType{})
-       }
-       if t.InCount == 0 {
-               return nil
-       }
-       return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.InCount:t.InCount]
+       tt := (*abi.FuncType)(unsafe.Pointer(t))
+       return toType(toRType(tt.OutSlice()[i]))
 }
 
-func (t *funcType) out() []*rtype {
-       uadd := unsafe.Sizeof(*t)
-       if t.t.TFlag&abi.TFlagUncommon != 0 {
-               uadd += unsafe.Sizeof(uncommonType{})
-       }
-       outCount := t.OutCount & (1<<15 - 1)
-       if outCount == 0 {
-               return nil
+func (t *rtype) IsVariadic() bool {
+       if t.Kind() != Func {
+               panic("reflect: IsVariadic of non-func type " + t.String())
        }
-       return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.InCount : t.InCount+outCount : t.InCount+outCount]
+       tt := (*abi.FuncType)(unsafe.Pointer(t))
+       return tt.IsVariadic()
 }
 
 // add returns p+x.
@@ -1437,12 +1410,12 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
                        return false
                }
                for i := 0; i < t.NumIn(); i++ {
-                       if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
+                       if !haveIdenticalType(toRType(t.In(i)), toRType(v.In(i)), cmpTags) {
                                return false
                        }
                }
                for i := 0; i < t.NumOut(); i++ {
-                       if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
+                       if !haveIdenticalType(toRType(t.Out(i)), toRType(v.Out(i)), cmpTags) {
                                return false
                        }
                }
@@ -1792,8 +1765,8 @@ func FuncOf(in, out []Type, variadic bool) Type {
                hash = fnv1(hash, byte(t.t.Hash>>24), byte(t.t.Hash>>16), byte(t.t.Hash>>8), byte(t.t.Hash))
        }
 
-       ft.t.TFlag = 0
-       ft.t.Hash = hash
+       ft.TFlag = 0
+       ft.Hash = hash
        ft.InCount = uint16(len(in))
        ft.OutCount = uint16(len(out))
        if variadic {
@@ -1803,7 +1776,7 @@ func FuncOf(in, out []Type, variadic bool) Type {
        // Look in cache.
        if ts, ok := funcLookupCache.m.Load(hash); ok {
                for _, t := range ts.([]*rtype) {
-                       if haveIdenticalUnderlyingType(&ft.rtype, t, true) {
+                       if haveIdenticalUnderlyingType(toRType(&ft.Type), t, true) {
                                return t
                        }
                }
@@ -1814,7 +1787,7 @@ func FuncOf(in, out []Type, variadic bool) Type {
        defer funcLookupCache.Unlock()
        if ts, ok := funcLookupCache.m.Load(hash); ok {
                for _, t := range ts.([]*rtype) {
-                       if haveIdenticalUnderlyingType(&ft.rtype, t, true) {
+                       if haveIdenticalUnderlyingType(toRType(&ft.Type), t, true) {
                                return t
                        }
                }
@@ -1832,22 +1805,25 @@ func FuncOf(in, out []Type, variadic bool) Type {
        // Look in known types for the same string representation.
        str := funcStr(ft)
        for _, tt := range typesByString(str) {
-               if haveIdenticalUnderlyingType(&ft.rtype, tt, true) {
+               if haveIdenticalUnderlyingType(toRType(&ft.Type), tt, true) {
                        return addToCache(tt)
                }
        }
 
        // Populate the remaining fields of ft and store in cache.
-       ft.t.Str = resolveReflectName(newName(str, "", false, false))
-       ft.t.PtrToThis = 0
-       return addToCache(&ft.rtype)
+       ft.Str = resolveReflectName(newName(str, "", false, false))
+       ft.PtrToThis = 0
+       return addToCache(toRType(&ft.Type))
+}
+func stringFor(t *abi.Type) string {
+       return toRType(t).String()
 }
 
 // funcStr builds a string representation of a funcType.
 func funcStr(ft *funcType) string {
        repr := make([]byte, 0, 64)
        repr = append(repr, "func("...)
-       for i, t := range ft.in() {
+       for i, t := range ft.InSlice() {
                if i > 0 {
                        repr = append(repr, ", "...)
                }
@@ -1855,11 +1831,11 @@ func funcStr(ft *funcType) string {
                        repr = append(repr, "..."...)
                        repr = append(repr, (*sliceType)(unsafe.Pointer(t)).Elem.String()...)
                } else {
-                       repr = append(repr, t.String()...)
+                       repr = append(repr, stringFor(t)...)
                }
        }
        repr = append(repr, ')')
-       out := ft.out()
+       out := ft.OutSlice()
        if len(out) == 1 {
                repr = append(repr, ' ')
        } else if len(out) > 1 {
@@ -1869,7 +1845,7 @@ func funcStr(ft *funcType) string {
                if i > 0 {
                        repr = append(repr, ", "...)
                }
-               repr = append(repr, t.String()...)
+               repr = append(repr, stringFor(t)...)
        }
        if len(out) > 1 {
                repr = append(repr, ')')
@@ -2802,8 +2778,8 @@ var layoutCache sync.Map // map[layoutKey]layoutType
 // Currently, that's just size and the GC program. We also fill in
 // the name for possible debugging use.
 func funcLayout(t *funcType, rcvr *rtype) (frametype *rtype, framePool *sync.Pool, abid abiDesc) {
-       if t.Kind() != Func {
-               panic("reflect: funcLayout of non-func type " + t.String())
+       if t.Kind() != abi.Func {
+               panic("reflect: funcLayout of non-func type " + stringFor(&t.Type))
        }
        if rcvr != nil && rcvr.Kind() == Interface {
                panic("reflect: funcLayout with interface receiver " + rcvr.String())
@@ -2833,9 +2809,9 @@ func funcLayout(t *funcType, rcvr *rtype) (frametype *rtype, framePool *sync.Poo
 
        var s string
        if rcvr != nil {
-               s = "methodargs(" + rcvr.String() + ")(" + t.String() + ")"
+               s = "methodargs(" + rcvr.String() + ")(" + stringFor(&t.Type) + ")"
        } else {
-               s = "funcargs(" + t.String() + ")"
+               s = "funcargs(" + stringFor(&t.Type) + ")"
        }
        x.t.Str = resolveReflectName(newName(s, "", false, false))
 
index 3997afaacbdcbe2e49531a3a93276a2ed51a0a57..c46d3865daccd30eedb8f77f5aa70c1239e09fb0 100644 (file)
@@ -438,15 +438,15 @@ func (v Value) call(op string, in []Value) []Value {
                }
        }
        for i := 0; i < n; i++ {
-               if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
-                       panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
+               if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(toRType(targ)) {
+                       panic("reflect: " + op + " using " + xt.String() + " as type " + stringFor(targ))
                }
        }
        if !isSlice && isVariadic {
                // prepare slice for remaining values
                m := len(in) - n
-               slice := MakeSlice(t.In(n), m, m)
-               elem := t.In(n).Elem()
+               slice := MakeSlice(toRType(t.In(n)), m, m)
+               elem := toRType(t.In(n)).Elem() // FIXME cast to slice type and Elem()
                for i := 0; i < m; i++ {
                        x := in[n+i]
                        if xt := x.Type(); !xt.AssignableTo(elem) {
@@ -486,7 +486,7 @@ func (v Value) call(op string, in []Value) []Value {
        frameSize := frametype.Size()
 
        if debugReflectCall {
-               println("reflect.call", t.String())
+               println("reflect.call", stringFor(&t.Type))
                abid.dump()
        }
 
@@ -517,7 +517,7 @@ func (v Value) call(op string, in []Value) []Value {
        // Handle arguments.
        for i, v := range in {
                v.mustBeExported()
-               targ := t.In(i).(*rtype)
+               targ := toRType(t.In(i))
                // TODO(mknyszek): Figure out if it's possible to get some
                // scratch space for this assignment check. Previously, it
                // was possible to use space in the argument frame.
@@ -611,7 +611,7 @@ func (v Value) call(op string, in []Value) []Value {
                        if tv.Size() == 0 {
                                // For zero-sized return value, args+off may point to the next object.
                                // In this case, return the zero value instead.
-                               ret[i] = Zero(tv)
+                               ret[i] = Zero(toRType(tv))
                                continue
                        }
                        steps := abid.ret.stepsForValue(i)
@@ -620,7 +620,7 @@ func (v Value) call(op string, in []Value) []Value {
                                // allocated, the entire value is according to the ABI. So
                                // just make an indirection into the allocated frame.
                                fl := flagIndir | flag(tv.Kind())
-                               ret[i] = Value{tv.common(), add(stackArgs, st.stkOff, "tv.Size() != 0"), fl}
+                               ret[i] = Value{toRType(tv), add(stackArgs, st.stkOff, "tv.Size() != 0"), fl}
                                // Note: this does introduce false sharing between results -
                                // if any result is live, they are all live.
                                // (And the space for the args is live as well, but as we've
@@ -629,14 +629,14 @@ func (v Value) call(op string, in []Value) []Value {
                        }
 
                        // Handle pointers passed in registers.
-                       if !ifaceIndir(tv.common()) {
+                       if !ifaceIndir(toRType(tv)) {
                                // Pointer-valued data gets put directly
                                // into v.ptr.
                                if steps[0].kind != abiStepPointer {
-                                       print("kind=", steps[0].kind, ", type=", tv.String(), "\n")
+                                       print("kind=", steps[0].kind, ", type=", stringFor(tv), "\n")
                                        panic("mismatch between ABI description and types")
                                }
-                               ret[i] = Value{tv.common(), regArgs.Ptrs[steps[0].ireg], flag(tv.Kind())}
+                               ret[i] = Value{toRType(tv), regArgs.Ptrs[steps[0].ireg], flag(tv.Kind())}
                                continue
                        }
 
@@ -649,7 +649,7 @@ func (v Value) call(op string, in []Value) []Value {
                        // additional space to the allocated stack frame and storing the
                        // register-allocated return values into the allocated stack frame and
                        // referring there in the resulting Value.
-                       s := unsafe_New(tv.common())
+                       s := unsafe_New(toRType(tv))
                        for _, st := range steps {
                                switch st.kind {
                                case abiStepIntReg:
@@ -667,7 +667,7 @@ func (v Value) call(op string, in []Value) []Value {
                                        panic("unknown ABI part kind")
                                }
                        }
-                       ret[i] = Value{tv.common(), s, flagIndir | flag(tv.Kind())}
+                       ret[i] = Value{toRType(tv), s, flagIndir | flag(tv.Kind())}
                }
        }
 
@@ -711,7 +711,8 @@ func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs
        // Copy arguments into Values.
        ptr := frame
        in := make([]Value, 0, int(ftyp.InCount))
-       for i, typ := range ftyp.in() {
+       for i, typ := range ftyp.InSlice() {
+               typ := toRType(typ) // FIXME cleanup this loop body
                if typ.Size() == 0 {
                        in = append(in, Zero(typ))
                        continue
@@ -777,7 +778,7 @@ func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs
 
        // Copy results back into argument frame and register space.
        if numOut > 0 {
-               for i, typ := range ftyp.out() {
+               for i, typ := range ftyp.OutSlice() {
                        v := out[i]
                        if v.typ == nil {
                                panic("reflect: function created by MakeFunc using " + funcName(f) +
@@ -805,7 +806,7 @@ func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs
                        // We must clear the destination before calling assignTo,
                        // in case assignTo writes (with memory barriers) to the
                        // target location used as scratch space. See issue 39541.
-                       v = v.assignTo("reflect.MakeFunc", typ, nil)
+                       v = v.assignTo("reflect.MakeFunc", toRType(typ), nil)
                stepsLoop:
                        for _, st := range abid.ret.stepsForValue(i) {
                                switch st.kind {
@@ -991,7 +992,7 @@ func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *a
        }
 
        // Translate the rest of the arguments.
-       for i, t := range valueFuncType.in() {
+       for i, t := range valueFuncType.InSlice() {
                valueSteps := valueABI.call.stepsForValue(i)
                methodSteps := methodABI.call.stepsForValue(i + 1)
 
@@ -1020,7 +1021,7 @@ func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *a
                                if vStep.size != mStep.size {
                                        panic("method ABI and value ABI do not align")
                                }
-                               typedmemmove(t,
+                               typedmemmove(toRType(t),
                                        add(methodFrame, mStep.stkOff, "precomputed stack offset"),
                                        add(valueFrame, vStep.stkOff, "precomputed stack offset"))
                                continue