mirror of
https://github.com/golang/go
synced 2024-09-29 21:34:28 -06:00
reflect: StructOf set abi.TFlagRegularMemory
Complete a TODO.
Change-Id: I791d27266ccee69c371524e298120765f5736cf8
GitHub-Last-Rev: 8878003efa
GitHub-Pull-Request: golang/go#64617
Reviewed-on: https://go-review.googlesource.com/c/go/+/548435
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
4605ce2d34
commit
99e12bee44
@ -166,3 +166,5 @@ func SetArgRegs(ints, floats int, floatSize uintptr) (oldInts, oldFloats int, ol
|
|||||||
var MethodValueCallCodePtr = methodValueCallCodePtr
|
var MethodValueCallCodePtr = methodValueCallCodePtr
|
||||||
|
|
||||||
var InternalIsZero = isZero
|
var InternalIsZero = isZero
|
||||||
|
|
||||||
|
var IsRegularMemory = isRegularMemory
|
||||||
|
@ -2152,6 +2152,47 @@ func isValidFieldName(fieldName string) bool {
|
|||||||
return len(fieldName) > 0
|
return len(fieldName) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This must match cmd/compile/internal/compare.IsRegularMemory
|
||||||
|
func isRegularMemory(t Type) bool {
|
||||||
|
switch t.Kind() {
|
||||||
|
case Array:
|
||||||
|
return isRegularMemory(t.Elem())
|
||||||
|
case Int8, Int16, Int32, Int64, Int, Uint8, Uint16, Uint32, Uint64, Uint, Uintptr, Chan, Pointer, Bool, UnsafePointer:
|
||||||
|
return true
|
||||||
|
case Struct:
|
||||||
|
num := t.NumField()
|
||||||
|
switch num {
|
||||||
|
case 0:
|
||||||
|
return true
|
||||||
|
case 1:
|
||||||
|
field := t.Field(0)
|
||||||
|
if field.Name == "_" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return isRegularMemory(field.Type)
|
||||||
|
default:
|
||||||
|
for i := range num {
|
||||||
|
field := t.Field(i)
|
||||||
|
if field.Name == "_" || !isRegularMemory(field.Type) || isPaddedField(t, i) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isPaddedField reports whether the i'th field of struct type t is followed
|
||||||
|
// by padding.
|
||||||
|
func isPaddedField(t Type, i int) bool {
|
||||||
|
field := t.Field(i)
|
||||||
|
if i+1 < t.NumField() {
|
||||||
|
return field.Offset+field.Type.Size() != t.Field(i+1).Offset
|
||||||
|
}
|
||||||
|
return field.Offset+field.Type.Size() != t.Size()
|
||||||
|
}
|
||||||
|
|
||||||
// StructOf returns the struct type containing fields.
|
// StructOf returns the struct type containing fields.
|
||||||
// The Offset and Index fields are ignored and computed as they would be
|
// The Offset and Index fields are ignored and computed as they would be
|
||||||
// by the compiler.
|
// by the compiler.
|
||||||
@ -2445,7 +2486,11 @@ func StructOf(fields []StructField) Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typ.Str = resolveReflectName(newName(str, "", false, false))
|
typ.Str = resolveReflectName(newName(str, "", false, false))
|
||||||
typ.TFlag = 0 // TODO: set tflagRegularMemory
|
if isRegularMemory(toType(&typ.Type)) {
|
||||||
|
typ.TFlag = abi.TFlagRegularMemory
|
||||||
|
} else {
|
||||||
|
typ.TFlag = 0
|
||||||
|
}
|
||||||
typ.Hash = hash
|
typ.Hash = hash
|
||||||
typ.Size_ = size
|
typ.Size_ = size
|
||||||
typ.PtrBytes = typeptrdata(&typ.Type)
|
typ.PtrBytes = typeptrdata(&typ.Type)
|
||||||
|
@ -57,3 +57,46 @@ func TestStructOfEmbeddedIfaceMethodCall(t *testing.T) {
|
|||||||
_ = x.Name()
|
_ = x.Name()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsRegularMemory(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
t reflect.Type
|
||||||
|
}
|
||||||
|
type S struct {
|
||||||
|
int
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{"struct{i int}", args{reflect.TypeOf(struct{ i int }{})}, true},
|
||||||
|
{"struct{}", args{reflect.TypeOf(struct{}{})}, true},
|
||||||
|
{"struct{i int; s S}", args{reflect.TypeOf(struct {
|
||||||
|
i int
|
||||||
|
s S
|
||||||
|
}{})}, true},
|
||||||
|
{"map[int][int]", args{reflect.TypeOf(map[int]int{})}, false},
|
||||||
|
{"[4]chan int", args{reflect.TypeOf([4]chan int{})}, true},
|
||||||
|
{"struct{i int; _ S}", args{reflect.TypeOf(struct {
|
||||||
|
i int
|
||||||
|
_ S
|
||||||
|
}{})}, false},
|
||||||
|
{"struct{a int16; b int32}", args{reflect.TypeOf(struct {
|
||||||
|
a int16
|
||||||
|
b int32
|
||||||
|
}{})}, false},
|
||||||
|
{"struct {x int32; y int16}", args{reflect.TypeOf(struct {
|
||||||
|
x int32
|
||||||
|
y int16
|
||||||
|
}{})}, false},
|
||||||
|
{"struct {_ int32 }", args{reflect.TypeOf(struct{ _ int32 }{})}, false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := reflect.IsRegularMemory(tt.args.t); got != tt.want {
|
||||||
|
t.Errorf("isRegularMemory() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user