diff options
Diffstat (limited to 'src/pkg/reflect/value.go')
| -rw-r--r-- | src/pkg/reflect/value.go | 128 |
1 files changed, 38 insertions, 90 deletions
diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go index 5505c4624..56a5d69d8 100644 --- a/src/pkg/reflect/value.go +++ b/src/pkg/reflect/value.go @@ -75,6 +75,10 @@ type Value interface { getAddr() addr } +// value is the common implementation of most values. +// It is embedded in other, public struct types, but always +// with a unique tag like "uint" or "float" so that the client cannot +// convert from, say, *UintValue to *FloatValue. type value struct { typ Type addr addr @@ -113,7 +117,7 @@ func (v *value) CanSet() bool { return v.canSet } // BoolValue represents a bool value. type BoolValue struct { - value + value "bool" } // Get returns the underlying bool value. @@ -132,7 +136,7 @@ func (v *BoolValue) SetValue(x Value) { v.Set(x.(*BoolValue).Get()) } // FloatValue represents a float value. type FloatValue struct { - value + value "float" } // Get returns the underlying int value. @@ -181,7 +185,7 @@ func (v *FloatValue) SetValue(x Value) { v.Set(x.(*FloatValue).Get()) } // ComplexValue represents a complex value. type ComplexValue struct { - value + value "complex" } // Get returns the underlying complex value. @@ -217,47 +221,9 @@ func (v *ComplexValue) Set(x complex128) { // Set sets v to the value x. func (v *ComplexValue) SetValue(x Value) { v.Set(x.(*ComplexValue).Get()) } -// Complex64Value represents a complex64 value. -type Complex64Value struct { - value -} - -// Get returns the underlying complex64 value. -func (v *Complex64Value) Get() complex64 { return *(*complex64)(v.addr) } - -// Set sets v to the value x. -func (v *Complex64Value) Set(x complex64) { - if !v.canSet { - panic(cannotSet) - } - *(*complex64)(v.addr) = x -} - -// Set sets v to the value x. -func (v *Complex64Value) SetValue(x Value) { v.Set(x.(*Complex64Value).Get()) } - -// Complex128Value represents a complex128 value. -type Complex128Value struct { - value -} - -// Get returns the underlying complex128 value. -func (v *Complex128Value) Get() complex128 { return *(*complex128)(v.addr) } - -// Set sets v to the value x. -func (v *Complex128Value) Set(x complex128) { - if !v.canSet { - panic(cannotSet) - } - *(*complex128)(v.addr) = x -} - -// Set sets v to the value x. -func (v *Complex128Value) SetValue(x Value) { v.Set(x.(*Complex128Value).Get()) } - // IntValue represents an int value. type IntValue struct { - value + value "int" } // Get returns the underlying int value. @@ -303,7 +269,7 @@ func (v *IntValue) SetValue(x Value) { v.Set(x.(*IntValue).Get()) } // Overflow returns true if x cannot be represented by the type of v. func (v *IntValue) Overflow(x int64) bool { - bitSize := v.typ.Size() * 8 + bitSize := uint(v.typ.Bits()) trunc := (x << (64 - bitSize)) >> (64 - bitSize) return x != trunc } @@ -316,7 +282,7 @@ type StringHeader struct { // StringValue represents a string value. type StringValue struct { - value + value "string" } // Get returns the underlying string value. @@ -335,7 +301,7 @@ func (v *StringValue) SetValue(x Value) { v.Set(x.(*StringValue).Get()) } // UintValue represents a uint value. type UintValue struct { - value + value "uint" } // Get returns the underlying uuint value. @@ -382,7 +348,7 @@ func (v *UintValue) Set(x uint64) { // Overflow returns true if x cannot be represented by the type of v. func (v *UintValue) Overflow(x uint64) bool { - bitSize := v.typ.Size() * 8 + bitSize := uint(v.typ.Bits()) trunc := (x << (64 - bitSize)) >> (64 - bitSize) return x != trunc } @@ -392,7 +358,7 @@ func (v *UintValue) SetValue(x Value) { v.Set(x.(*UintValue).Get()) } // UnsafePointerValue represents an unsafe.Pointer value. type UnsafePointerValue struct { - value + value "unsafe.Pointer" } // Get returns the underlying uintptr value. @@ -454,7 +420,7 @@ func ArrayCopy(dst, src ArrayOrSliceValue) int { // An ArrayValue represents an array. type ArrayValue struct { - value + value "array" } // Len returns the length of the array. @@ -503,7 +469,7 @@ type SliceHeader struct { // A SliceValue represents a slice. type SliceValue struct { - value + value "slice" } func (v *SliceValue) slice() *SliceHeader { return (*SliceHeader)(v.value.addr) } @@ -593,7 +559,7 @@ func MakeSlice(typ *SliceType, len, cap int) *SliceValue { // A ChanValue represents a chan. type ChanValue struct { - value + value "chan" } // IsNil returns whether v is a nil channel. @@ -714,7 +680,7 @@ func MakeChan(typ *ChanType, buffer int) *ChanValue { // A FuncValue represents a function value. type FuncValue struct { - value + value "func" first *value isInterface bool } @@ -874,7 +840,7 @@ func (fv *FuncValue) Call(in []Value) []Value { // An InterfaceValue represents an interface value. type InterfaceValue struct { - value + value "interface" } // No Get because v.Interface() is available. @@ -939,7 +905,7 @@ func (v *InterfaceValue) Method(i int) *FuncValue { // A MapValue represents a map value. type MapValue struct { - value + value "map" } // IsNil returns whether v is a nil map value. @@ -1056,7 +1022,7 @@ func MakeMap(typ *MapType) *MapValue { // A PtrValue represents a pointer. type PtrValue struct { - value + value "ptr" } // IsNil returns whether v is a nil pointer. @@ -1127,7 +1093,7 @@ func Indirect(v Value) Value { // A StructValue represents a struct value. type StructValue struct { - value + value "struct" } // Set assigns x to v. @@ -1211,57 +1177,39 @@ func NewValue(i interface{}) Value { return newValue(toType(t), addr(a), true) } - -func newFuncValue(typ Type, addr addr, canSet bool) *FuncValue { - return &FuncValue{value: value{typ, addr, canSet}} -} - func newValue(typ Type, addr addr, canSet bool) Value { - // FuncValue has a different layout; - // it needs a extra space for the fixed receivers. - if _, ok := typ.(*FuncType); ok { - return newFuncValue(typ, addr, canSet) - } - - // All values have same memory layout; - // build once and convert. - v := &struct{ value }{value{typ, addr, canSet}} + v := value{typ, addr, canSet} switch typ.(type) { case *ArrayType: - // TODO(rsc): Something must prevent - // clients of the package from doing - // this same kind of cast. - // We should be allowed because - // they're our types. - // Something about implicit assignment - // to struct fields. - return (*ArrayValue)(v) + return &ArrayValue{v} case *BoolType: - return (*BoolValue)(v) + return &BoolValue{v} case *ChanType: - return (*ChanValue)(v) + return &ChanValue{v} case *FloatType: - return (*FloatValue)(v) + return &FloatValue{v} + case *FuncType: + return &FuncValue{value: v} case *ComplexType: - return (*ComplexValue)(v) + return &ComplexValue{v} case *IntType: - return (*IntValue)(v) + return &IntValue{v} case *InterfaceType: - return (*InterfaceValue)(v) + return &InterfaceValue{v} case *MapType: - return (*MapValue)(v) + return &MapValue{v} case *PtrType: - return (*PtrValue)(v) + return &PtrValue{v} case *SliceType: - return (*SliceValue)(v) + return &SliceValue{v} case *StringType: - return (*StringValue)(v) + return &StringValue{v} case *StructType: - return (*StructValue)(v) + return &StructValue{v} case *UintType: - return (*UintValue)(v) + return &UintValue{v} case *UnsafePointerType: - return (*UnsafePointerValue)(v) + return &UnsafePointerValue{v} } panic("newValue" + typ.String()) } |
