Commit fc090a3a authored by Russ Cox's avatar Russ Cox

reflect: add Type.Bits method, add tags to prohibit conversions

gob: substitute slice for map

R=r
CC=golang-dev
https://golang.org/cl/1699045
parent 2fc0b4f0
...@@ -612,10 +612,10 @@ func (p *pp) fmtUintptrGetter(field interface{}, value reflect.Value, verb int, ...@@ -612,10 +612,10 @@ func (p *pp) fmtUintptrGetter(field interface{}, value reflect.Value, verb int,
} }
var ( var (
intBits = uintptr(reflect.Typeof(int(0)).Size() * 8) intBits = reflect.Typeof(0).Bits()
floatBits = uintptr(reflect.Typeof(float(0)).Size() * 8) floatBits = reflect.Typeof(0.0).Bits()
complexBits = uintptr(reflect.Typeof(complex(0+0i)).Size() * 8) complexBits = reflect.Typeof(1i).Bits()
uintptrBits = uintptr(reflect.Typeof(uintptr(0)).Size() * 8) uintptrBits = reflect.Typeof(uintptr(0)).Bits()
) )
func (p *pp) printField(field interface{}, verb int, plus, sharp bool, depth int) (was_string bool) { func (p *pp) printField(field interface{}, verb int, plus, sharp bool, depth int) (was_string bool) {
......
...@@ -456,9 +456,10 @@ func (s *ss) scanNumber(digits string) string { ...@@ -456,9 +456,10 @@ func (s *ss) scanNumber(digits string) string {
} }
// scanRune returns the next rune value in the input. // scanRune returns the next rune value in the input.
func (s *ss) scanRune(bitSize uintptr) int64 { func (s *ss) scanRune(bitSize int) int64 {
rune := int64(s.mustGetRune()) rune := int64(s.mustGetRune())
x := (rune << (64 - bitSize)) >> (64 - bitSize) n := uint(bitSize)
x := (rune << (64 - n)) >> (64 - n)
if x != rune { if x != rune {
s.errorString("overflow on character value " + string(rune)) s.errorString("overflow on character value " + string(rune))
} }
...@@ -467,7 +468,7 @@ func (s *ss) scanRune(bitSize uintptr) int64 { ...@@ -467,7 +468,7 @@ func (s *ss) scanRune(bitSize uintptr) int64 {
// scanInt returns the value of the integer represented by the next // scanInt returns the value of the integer represented by the next
// token, checking for overflow. Any error is stored in s.err. // token, checking for overflow. Any error is stored in s.err.
func (s *ss) scanInt(verb int, bitSize uintptr) int64 { func (s *ss) scanInt(verb int, bitSize int) int64 {
if verb == 'c' { if verb == 'c' {
return s.scanRune(bitSize) return s.scanRune(bitSize)
} }
...@@ -479,7 +480,8 @@ func (s *ss) scanInt(verb int, bitSize uintptr) int64 { ...@@ -479,7 +480,8 @@ func (s *ss) scanInt(verb int, bitSize uintptr) int64 {
if err != nil { if err != nil {
s.error(err) s.error(err)
} }
x := (i << (64 - bitSize)) >> (64 - bitSize) n := uint(bitSize)
x := (i << (64 - n)) >> (64 - n)
if x != i { if x != i {
s.errorString("integer overflow on token " + tok) s.errorString("integer overflow on token " + tok)
} }
...@@ -488,7 +490,7 @@ func (s *ss) scanInt(verb int, bitSize uintptr) int64 { ...@@ -488,7 +490,7 @@ func (s *ss) scanInt(verb int, bitSize uintptr) int64 {
// scanUint returns the value of the unsigned integer represented // scanUint returns the value of the unsigned integer represented
// by the next token, checking for overflow. Any error is stored in s.err. // by the next token, checking for overflow. Any error is stored in s.err.
func (s *ss) scanUint(verb int, bitSize uintptr) uint64 { func (s *ss) scanUint(verb int, bitSize int) uint64 {
if verb == 'c' { if verb == 'c' {
return uint64(s.scanRune(bitSize)) return uint64(s.scanRune(bitSize))
} }
...@@ -499,7 +501,8 @@ func (s *ss) scanUint(verb int, bitSize uintptr) uint64 { ...@@ -499,7 +501,8 @@ func (s *ss) scanUint(verb int, bitSize uintptr) uint64 {
if err != nil { if err != nil {
s.error(err) s.error(err)
} }
x := (i << (64 - bitSize)) >> (64 - bitSize) n := uint(bitSize)
x := (i << (64 - n)) >> (64 - n)
if x != i { if x != i {
s.errorString("unsigned integer overflow on token " + tok) s.errorString("unsigned integer overflow on token " + tok)
} }
...@@ -766,9 +769,9 @@ func (s *ss) scanOne(verb int, field interface{}) { ...@@ -766,9 +769,9 @@ func (s *ss) scanOne(verb int, field interface{}) {
case *reflect.BoolValue: case *reflect.BoolValue:
v.Set(s.scanBool(verb)) v.Set(s.scanBool(verb))
case *reflect.IntValue: case *reflect.IntValue:
v.Set(s.scanInt(verb, v.Type().Size()*8)) v.Set(s.scanInt(verb, v.Type().Bits()))
case *reflect.UintValue: case *reflect.UintValue:
v.Set(s.scanUint(verb, v.Type().Size()*8)) v.Set(s.scanUint(verb, v.Type().Bits()))
case *reflect.StringValue: case *reflect.StringValue:
v.Set(s.convertString(verb)) v.Set(s.convertString(verb))
case *reflect.SliceValue: case *reflect.SliceValue:
...@@ -784,9 +787,9 @@ func (s *ss) scanOne(verb int, field interface{}) { ...@@ -784,9 +787,9 @@ func (s *ss) scanOne(verb int, field interface{}) {
} }
case *reflect.FloatValue: case *reflect.FloatValue:
s.skipSpace() s.skipSpace()
v.Set(s.convertFloat(s.floatToken(), int(v.Type().Size()*8))) v.Set(s.convertFloat(s.floatToken(), v.Type().Bits()))
case *reflect.ComplexValue: case *reflect.ComplexValue:
v.Set(s.scanComplex(verb, int(v.Type().Size()*8))) v.Set(s.scanComplex(verb, v.Type().Bits()))
default: default:
CantHandle: CantHandle:
s.errorString("Scan: can't handle type: " + val.Type().String()) s.errorString("Scan: can't handle type: " + val.Type().String())
......
...@@ -540,7 +540,7 @@ func ignoreSlice(state *decodeState, elemOp decOp) os.Error { ...@@ -540,7 +540,7 @@ func ignoreSlice(state *decodeState, elemOp decOp) os.Error {
return ignoreArrayHelper(state, elemOp, int(decodeUint(state))) return ignoreArrayHelper(state, elemOp, int(decodeUint(state)))
} }
var decOpMap = map[reflect.Kind]decOp{ var decOpMap = []decOp{
reflect.Bool: decBool, reflect.Bool: decBool,
reflect.Int8: decInt8, reflect.Int8: decInt8,
reflect.Int16: decInt16, reflect.Int16: decInt16,
...@@ -568,8 +568,12 @@ var decIgnoreOpMap = map[typeId]decOp{ ...@@ -568,8 +568,12 @@ var decIgnoreOpMap = map[typeId]decOp{
// the indirection count to reach it. // the indirection count to reach it.
func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string) (decOp, int, os.Error) { func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string) (decOp, int, os.Error) {
typ, indir := indirect(rt) typ, indir := indirect(rt)
op, ok := decOpMap[typ.Kind()] var op decOp
if !ok { k := typ.Kind()
if int(k) < len(decOpMap) {
op = decOpMap[k]
}
if op == nil {
// Special cases // Special cases
switch t := typ.(type) { switch t := typ.(type) {
case *reflect.ArrayType: case *reflect.ArrayType:
......
...@@ -601,7 +601,7 @@ func encodeMap(b *bytes.Buffer, rt reflect.Type, p uintptr, keyOp, elemOp encOp, ...@@ -601,7 +601,7 @@ func encodeMap(b *bytes.Buffer, rt reflect.Type, p uintptr, keyOp, elemOp encOp,
return state.err return state.err
} }
var encOpMap = map[reflect.Kind]encOp{ var encOpMap = []encOp{
reflect.Bool: encBool, reflect.Bool: encBool,
reflect.Int: encInt, reflect.Int: encInt,
reflect.Int8: encInt8, reflect.Int8: encInt8,
...@@ -624,8 +624,12 @@ var encOpMap = map[reflect.Kind]encOp{ ...@@ -624,8 +624,12 @@ var encOpMap = map[reflect.Kind]encOp{
// the indirection count to reach it. // the indirection count to reach it.
func encOpFor(rt reflect.Type) (encOp, int, os.Error) { func encOpFor(rt reflect.Type) (encOp, int, os.Error) {
typ, indir := indirect(rt) typ, indir := indirect(rt)
op, ok := encOpMap[typ.Kind()] var op encOp
if !ok { k := typ.Kind()
if int(k) < len(encOpMap) {
op = encOpMap[k]
}
if op == nil {
// Special cases // Special cases
switch t := typ.(type) { switch t := typ.(type) {
case *reflect.SliceType: case *reflect.SliceType:
......
...@@ -588,7 +588,7 @@ func (d *decodeState) literal(v reflect.Value) { ...@@ -588,7 +588,7 @@ func (d *decodeState) literal(v reflect.Value) {
v.Set(n) v.Set(n)
case *reflect.FloatValue: case *reflect.FloatValue:
n, err := strconv.AtofN(s, int(v.Type().Size()*8)) n, err := strconv.AtofN(s, v.Type().Bits())
if err != nil || v.Overflow(n) { if err != nil || v.Overflow(n) {
d.saveError(&UnmarshalTypeError{"number " + s, v.Type()}) d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
break break
......
...@@ -162,7 +162,7 @@ func (e *encodeState) reflectValue(v reflect.Value) { ...@@ -162,7 +162,7 @@ func (e *encodeState) reflectValue(v reflect.Value) {
e.WriteString(strconv.Uitoa64(v.Get())) e.WriteString(strconv.Uitoa64(v.Get()))
case *reflect.FloatValue: case *reflect.FloatValue:
e.WriteString(strconv.FtoaN(v.Get(), 'g', -1, int(v.Type().Size()*8))) e.WriteString(strconv.FtoaN(v.Get(), 'g', -1, v.Type().Bits()))
case *reflect.StringValue: case *reflect.StringValue:
e.string(v.Get()) e.string(v.Get())
......
...@@ -34,6 +34,11 @@ import ( ...@@ -34,6 +34,11 @@ import (
* copy in order to access the private fields. * copy in order to access the private fields.
*/ */
// commonType 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, *UintType to *FloatType.
type commonType struct { type commonType struct {
size uintptr size uintptr
hash uint32 hash uint32
...@@ -62,42 +67,42 @@ type uncommonType struct { ...@@ -62,42 +67,42 @@ type uncommonType struct {
// BoolType represents a boolean type. // BoolType represents a boolean type.
type BoolType struct { type BoolType struct {
commonType commonType "bool"
} }
// FloatType represents a float type. // FloatType represents a float type.
type FloatType struct { type FloatType struct {
commonType commonType "float"
} }
// ComplexType represents a complex type. // ComplexType represents a complex type.
type ComplexType struct { type ComplexType struct {
commonType commonType "complex"
} }
// IntType represents a signed integer type. // IntType represents a signed integer type.
type IntType struct { type IntType struct {
commonType commonType "int"
} }
// UintType represents a uint type. // UintType represents a uint type.
type UintType struct { type UintType struct {
commonType commonType "uint"
} }
// StringType represents a string type. // StringType represents a string type.
type StringType struct { type StringType struct {
commonType commonType "string"
} }
// UnsafePointerType represents an unsafe.Pointer type. // UnsafePointerType represents an unsafe.Pointer type.
type UnsafePointerType struct { type UnsafePointerType struct {
commonType commonType "unsafe.Pointer"
} }
// ArrayType represents a fixed array type. // ArrayType represents a fixed array type.
type ArrayType struct { type ArrayType struct {
commonType commonType "array"
elem *runtime.Type elem *runtime.Type
len uintptr len uintptr
} }
...@@ -113,14 +118,14 @@ const ( ...@@ -113,14 +118,14 @@ const (
// ChanType represents a channel type. // ChanType represents a channel type.
type ChanType struct { type ChanType struct {
commonType commonType "chan"
elem *runtime.Type elem *runtime.Type
dir uintptr dir uintptr
} }
// FuncType represents a function type. // FuncType represents a function type.
type FuncType struct { type FuncType struct {
commonType commonType "func"
dotdotdot bool dotdotdot bool
in []*runtime.Type in []*runtime.Type
out []*runtime.Type out []*runtime.Type
...@@ -135,26 +140,26 @@ type imethod struct { ...@@ -135,26 +140,26 @@ type imethod struct {
// InterfaceType represents an interface type. // InterfaceType represents an interface type.
type InterfaceType struct { type InterfaceType struct {
commonType commonType "interface"
methods []imethod methods []imethod
} }
// MapType represents a map type. // MapType represents a map type.
type MapType struct { type MapType struct {
commonType commonType "map"
key *runtime.Type key *runtime.Type
elem *runtime.Type elem *runtime.Type
} }
// PtrType represents a pointer type. // PtrType represents a pointer type.
type PtrType struct { type PtrType struct {
commonType commonType "ptr"
elem *runtime.Type elem *runtime.Type
} }
// SliceType represents a slice type. // SliceType represents a slice type.
type SliceType struct { type SliceType struct {
commonType commonType "slice"
elem *runtime.Type elem *runtime.Type
} }
...@@ -169,7 +174,7 @@ type structField struct { ...@@ -169,7 +174,7 @@ type structField struct {
// StructType represents a struct type. // StructType represents a struct type.
type StructType struct { type StructType struct {
commonType commonType "struct"
fields []structField fields []structField
} }
...@@ -214,6 +219,11 @@ type Type interface { ...@@ -214,6 +219,11 @@ type Type interface {
// a value of the given type; it is analogous to unsafe.Sizeof. // a value of the given type; it is analogous to unsafe.Sizeof.
Size() uintptr Size() uintptr
// Bits returns the size of the type in bits.
// It is intended for use with numeric types and may overflow
// when used for composite types.
Bits() int
// Align returns the alignment of a value of this type // Align returns the alignment of a value of this type
// when allocated in memory. // when allocated in memory.
Align() int Align() int
...@@ -333,6 +343,8 @@ func (t *commonType) String() string { return *t.string } ...@@ -333,6 +343,8 @@ func (t *commonType) String() string { return *t.string }
func (t *commonType) Size() uintptr { return t.size } func (t *commonType) Size() uintptr { return t.size }
func (t *commonType) Bits() int { return int(t.size * 8) }
func (t *commonType) Align() int { return int(t.align) } func (t *commonType) Align() int { return int(t.align) }
func (t *commonType) FieldAlign() int { return int(t.fieldAlign) } func (t *commonType) FieldAlign() int { return int(t.fieldAlign) }
...@@ -352,7 +364,7 @@ func (t *uncommonType) Method(i int) (m Method) { ...@@ -352,7 +364,7 @@ func (t *uncommonType) Method(i int) (m Method) {
} }
m.Type = toType(*p.typ).(*FuncType) m.Type = toType(*p.typ).(*FuncType)
fn := p.tfn fn := p.tfn
m.Func = newFuncValue(m.Type, addr(&fn), true) m.Func = &FuncValue{value: value{m.Type, addr(&fn), true}}
return return
} }
......
...@@ -75,6 +75,10 @@ type Value interface { ...@@ -75,6 +75,10 @@ type Value interface {
getAddr() addr 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 { type value struct {
typ Type typ Type
addr addr addr addr
...@@ -113,7 +117,7 @@ func (v *value) CanSet() bool { return v.canSet } ...@@ -113,7 +117,7 @@ func (v *value) CanSet() bool { return v.canSet }
// BoolValue represents a bool value. // BoolValue represents a bool value.
type BoolValue struct { type BoolValue struct {
value value "bool"
} }
// Get returns the underlying bool value. // Get returns the underlying bool value.
...@@ -132,7 +136,7 @@ func (v *BoolValue) SetValue(x Value) { v.Set(x.(*BoolValue).Get()) } ...@@ -132,7 +136,7 @@ func (v *BoolValue) SetValue(x Value) { v.Set(x.(*BoolValue).Get()) }
// FloatValue represents a float value. // FloatValue represents a float value.
type FloatValue struct { type FloatValue struct {
value value "float"
} }
// Get returns the underlying int value. // Get returns the underlying int value.
...@@ -181,7 +185,7 @@ func (v *FloatValue) SetValue(x Value) { v.Set(x.(*FloatValue).Get()) } ...@@ -181,7 +185,7 @@ func (v *FloatValue) SetValue(x Value) { v.Set(x.(*FloatValue).Get()) }
// ComplexValue represents a complex value. // ComplexValue represents a complex value.
type ComplexValue struct { type ComplexValue struct {
value value "complex"
} }
// Get returns the underlying complex value. // Get returns the underlying complex value.
...@@ -217,47 +221,9 @@ func (v *ComplexValue) Set(x complex128) { ...@@ -217,47 +221,9 @@ func (v *ComplexValue) Set(x complex128) {
// Set sets v to the value x. // Set sets v to the value x.
func (v *ComplexValue) SetValue(x Value) { v.Set(x.(*ComplexValue).Get()) } 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. // IntValue represents an int value.
type IntValue struct { type IntValue struct {
value value "int"
} }
// Get returns the underlying int value. // Get returns the underlying int value.
...@@ -303,7 +269,7 @@ func (v *IntValue) SetValue(x Value) { v.Set(x.(*IntValue).Get()) } ...@@ -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. // Overflow returns true if x cannot be represented by the type of v.
func (v *IntValue) Overflow(x int64) bool { func (v *IntValue) Overflow(x int64) bool {
bitSize := v.typ.Size() * 8 bitSize := uint(v.typ.Bits())
trunc := (x << (64 - bitSize)) >> (64 - bitSize) trunc := (x << (64 - bitSize)) >> (64 - bitSize)
return x != trunc return x != trunc
} }
...@@ -316,7 +282,7 @@ type StringHeader struct { ...@@ -316,7 +282,7 @@ type StringHeader struct {
// StringValue represents a string value. // StringValue represents a string value.
type StringValue struct { type StringValue struct {
value value "string"
} }
// Get returns the underlying string value. // Get returns the underlying string value.
...@@ -335,7 +301,7 @@ func (v *StringValue) SetValue(x Value) { v.Set(x.(*StringValue).Get()) } ...@@ -335,7 +301,7 @@ func (v *StringValue) SetValue(x Value) { v.Set(x.(*StringValue).Get()) }
// UintValue represents a uint value. // UintValue represents a uint value.
type UintValue struct { type UintValue struct {
value value "uint"
} }
// Get returns the underlying uuint value. // Get returns the underlying uuint value.
...@@ -382,7 +348,7 @@ func (v *UintValue) Set(x uint64) { ...@@ -382,7 +348,7 @@ func (v *UintValue) Set(x uint64) {
// Overflow returns true if x cannot be represented by the type of v. // Overflow returns true if x cannot be represented by the type of v.
func (v *UintValue) Overflow(x uint64) bool { func (v *UintValue) Overflow(x uint64) bool {
bitSize := v.typ.Size() * 8 bitSize := uint(v.typ.Bits())
trunc := (x << (64 - bitSize)) >> (64 - bitSize) trunc := (x << (64 - bitSize)) >> (64 - bitSize)
return x != trunc return x != trunc
} }
...@@ -392,7 +358,7 @@ func (v *UintValue) SetValue(x Value) { v.Set(x.(*UintValue).Get()) } ...@@ -392,7 +358,7 @@ func (v *UintValue) SetValue(x Value) { v.Set(x.(*UintValue).Get()) }
// UnsafePointerValue represents an unsafe.Pointer value. // UnsafePointerValue represents an unsafe.Pointer value.
type UnsafePointerValue struct { type UnsafePointerValue struct {
value value "unsafe.Pointer"
} }
// Get returns the underlying uintptr value. // Get returns the underlying uintptr value.
...@@ -454,7 +420,7 @@ func ArrayCopy(dst, src ArrayOrSliceValue) int { ...@@ -454,7 +420,7 @@ func ArrayCopy(dst, src ArrayOrSliceValue) int {
// An ArrayValue represents an array. // An ArrayValue represents an array.
type ArrayValue struct { type ArrayValue struct {
value value "array"
} }
// Len returns the length of the array. // Len returns the length of the array.
...@@ -503,7 +469,7 @@ type SliceHeader struct { ...@@ -503,7 +469,7 @@ type SliceHeader struct {
// A SliceValue represents a slice. // A SliceValue represents a slice.
type SliceValue struct { type SliceValue struct {
value value "slice"
} }
func (v *SliceValue) slice() *SliceHeader { return (*SliceHeader)(v.value.addr) } func (v *SliceValue) slice() *SliceHeader { return (*SliceHeader)(v.value.addr) }
...@@ -593,7 +559,7 @@ func MakeSlice(typ *SliceType, len, cap int) *SliceValue { ...@@ -593,7 +559,7 @@ func MakeSlice(typ *SliceType, len, cap int) *SliceValue {
// A ChanValue represents a chan. // A ChanValue represents a chan.
type ChanValue struct { type ChanValue struct {
value value "chan"
} }
// IsNil returns whether v is a nil channel. // IsNil returns whether v is a nil channel.
...@@ -714,7 +680,7 @@ func MakeChan(typ *ChanType, buffer int) *ChanValue { ...@@ -714,7 +680,7 @@ func MakeChan(typ *ChanType, buffer int) *ChanValue {
// A FuncValue represents a function value. // A FuncValue represents a function value.
type FuncValue struct { type FuncValue struct {
value value "func"
first *value first *value
isInterface bool isInterface bool
} }
...@@ -874,7 +840,7 @@ func (fv *FuncValue) Call(in []Value) []Value { ...@@ -874,7 +840,7 @@ func (fv *FuncValue) Call(in []Value) []Value {
// An InterfaceValue represents an interface value. // An InterfaceValue represents an interface value.
type InterfaceValue struct { type InterfaceValue struct {
value value "interface"
} }
// No Get because v.Interface() is available. // No Get because v.Interface() is available.
...@@ -939,7 +905,7 @@ func (v *InterfaceValue) Method(i int) *FuncValue { ...@@ -939,7 +905,7 @@ func (v *InterfaceValue) Method(i int) *FuncValue {
// A MapValue represents a map value. // A MapValue represents a map value.
type MapValue struct { type MapValue struct {
value value "map"
} }
// IsNil returns whether v is a nil map value. // IsNil returns whether v is a nil map value.
...@@ -1056,7 +1022,7 @@ func MakeMap(typ *MapType) *MapValue { ...@@ -1056,7 +1022,7 @@ func MakeMap(typ *MapType) *MapValue {
// A PtrValue represents a pointer. // A PtrValue represents a pointer.
type PtrValue struct { type PtrValue struct {
value value "ptr"
} }
// IsNil returns whether v is a nil pointer. // IsNil returns whether v is a nil pointer.
...@@ -1127,7 +1093,7 @@ func Indirect(v Value) Value { ...@@ -1127,7 +1093,7 @@ func Indirect(v Value) Value {
// A StructValue represents a struct value. // A StructValue represents a struct value.
type StructValue struct { type StructValue struct {
value value "struct"
} }
// Set assigns x to v. // Set assigns x to v.
...@@ -1211,57 +1177,39 @@ func NewValue(i interface{}) Value { ...@@ -1211,57 +1177,39 @@ func NewValue(i interface{}) Value {
return newValue(toType(t), addr(a), true) 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 { func newValue(typ Type, addr addr, canSet bool) Value {
// FuncValue has a different layout; v := value{typ, addr, canSet}
// 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}}
switch typ.(type) { switch typ.(type) {
case *ArrayType: case *ArrayType:
// TODO(rsc): Something must prevent return &ArrayValue{v}
// 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)
case *BoolType: case *BoolType:
return (*BoolValue)(v) return &BoolValue{v}
case *ChanType: case *ChanType:
return (*ChanValue)(v) return &ChanValue{v}
case *FloatType: case *FloatType:
return (*FloatValue)(v) return &FloatValue{v}
case *FuncType:
return &FuncValue{value: v}
case *ComplexType: case *ComplexType:
return (*ComplexValue)(v) return &ComplexValue{v}
case *IntType: case *IntType:
return (*IntValue)(v) return &IntValue{v}
case *InterfaceType: case *InterfaceType:
return (*InterfaceValue)(v) return &InterfaceValue{v}
case *MapType: case *MapType:
return (*MapValue)(v) return &MapValue{v}
case *PtrType: case *PtrType:
return (*PtrValue)(v) return &PtrValue{v}
case *SliceType: case *SliceType:
return (*SliceValue)(v) return &SliceValue{v}
case *StringType: case *StringType:
return (*StringValue)(v) return &StringValue{v}
case *StructType: case *StructType:
return (*StructValue)(v) return &StructValue{v}
case *UintType: case *UintType:
return (*UintValue)(v) return &UintValue{v}
case *UnsafePointerType: case *UnsafePointerType:
return (*UnsafePointerValue)(v) return &UnsafePointerValue{v}
} }
panic("newValue" + typ.String()) panic("newValue" + typ.String())
} }
......
...@@ -30,9 +30,6 @@ func main() { ...@@ -30,9 +30,6 @@ func main() {
var a interface{} var a interface{}
switch c := reflect.NewValue(a).(type) { switch c := reflect.NewValue(a).(type) {
case *reflect.Complex64Value:
v := c.Get()
_, _ = complex64(v), true
case *reflect.ComplexValue: case *reflect.ComplexValue:
if complexBits == 64 { if complexBits == 64 {
v := c.Get() v := c.Get()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment