Browse Source

reflect: add valueFlagRO

pull/3624/head
Damian Gryski 2 years ago
committed by Ron Evans
parent
commit
0cd93a3a9e
  1. 45
      src/reflect/value.go

45
src/reflect/value.go

@ -14,6 +14,10 @@ type valueFlags uint8
const (
valueFlagIndirect valueFlags = 1 << iota
valueFlagExported
valueFlagEmbedRO
valueFlagStickyRO
valueFlagRO = valueFlagEmbedRO | valueFlagStickyRO
)
type Value struct {
@ -36,6 +40,16 @@ func (v Value) isExported() bool {
return v.flags&valueFlagExported != 0
}
func (v Value) isRO() bool {
return v.flags&(valueFlagRO) != 0
}
func (v Value) checkRO() {
if v.isRO() {
panic("reflect: value is not settable")
}
}
func Indirect(v Value) Value {
if v.Kind() != Ptr {
return v
@ -210,7 +224,7 @@ func (v Value) IsValid() bool {
}
func (v Value) CanInterface() bool {
return v.isExported()
return v.isExported() && !v.isRO()
}
func (v Value) CanAddr() bool {
@ -268,7 +282,7 @@ func (v Value) UnsafeAddr() uintptr {
}
func (v Value) CanSet() bool {
return v.flags&(valueFlagExported|valueFlagIndirect) == valueFlagExported|valueFlagIndirect
return v.flags&(valueFlagExported|valueFlagIndirect|valueFlagRO) == valueFlagExported|valueFlagIndirect
}
func (v Value) Bool() bool {
@ -668,11 +682,22 @@ func (v Value) Field(i int) Value {
panic(&ValueError{Method: "Field", Kind: v.Kind()})
}
structField := v.typecode.rawField(i)
flags := v.flags
// Copy flags but clear EmbedRO; we're not an embedded field anymore
flags := v.flags & ^valueFlagEmbedRO
if structField.PkgPath != "" {
// The fact that PkgPath is present means that this field is not
// exported.
// No PkgPath => not exported.
// Clear exported flag even if the parent was exported.
flags &^= valueFlagExported
// Update the RO flag
if structField.Anonymous {
// Embedded field
flags |= valueFlagEmbedRO
} else {
flags |= valueFlagStickyRO
}
} else {
// Parent field may not have been exported but we are
flags |= valueFlagExported
@ -1437,7 +1462,7 @@ func Zero(typ Type) Value {
return Value{
typecode: typ.(*rawType),
value: nil,
flags: valueFlagExported,
flags: valueFlagExported | valueFlagRO,
}
}
@ -1445,14 +1470,14 @@ func Zero(typ Type) Value {
return Value{
typecode: typ.(*rawType),
value: unsafe.Pointer(zerobuffer),
flags: valueFlagExported,
flags: valueFlagExported | valueFlagRO,
}
}
return Value{
typecode: typ.(*rawType),
value: alloc(typ.Size(), nil),
flags: valueFlagExported,
flags: valueFlagExported | valueFlagRO,
}
}
@ -1546,6 +1571,10 @@ func Copy(dst, src Value) int {
dstbuf, dstlen := buflen(dst)
srcbuf, srclen := buflen(src)
if srclen > 0 {
dst.checkRO()
}
return sliceCopy(dstbuf, srcbuf, dstlen, srclen, dst.typecode.elem().Size())
}

Loading…
Cancel
Save