aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/reflect/value.go
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2018-12-12 14:34:07 +0100
committerAyke van Laethem <[email protected]>2019-02-05 17:11:09 +0100
commitfb23e9c212241a0611a0d3cc7afe54696e7174f8 (patch)
treead3ad57d2c12fb92afc989f9ae04d1eead533b14 /src/reflect/value.go
parent222c4c75b17fd3f3d4d32dee9bdb9f9b4b433a5b (diff)
downloadtinygo-fb23e9c212241a0611a0d3cc7afe54696e7174f8.tar.gz
tinygo-fb23e9c212241a0611a0d3cc7afe54696e7174f8.zip
reflect: add support for non-named basic types
Diffstat (limited to 'src/reflect/value.go')
-rw-r--r--src/reflect/value.go134
1 files changed, 127 insertions, 7 deletions
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 35bb2a891..5747ca70c 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -33,7 +33,14 @@ func (v Value) IsNil() bool {
}
func (v Value) Pointer() uintptr {
- panic("unimplemented: (reflect.Value).Pointer()")
+ switch v.Type().Kind() {
+ case UnsafePointer:
+ return uintptr(v.value)
+ case Chan, Func, Map, Ptr, Slice:
+ panic("unimplemented: (reflect.Value).Pointer()")
+ default:
+ panic(&ValueError{"Pointer"})
+ }
}
func (v Value) IsValid() bool {
@@ -57,27 +64,132 @@ func (v Value) CanSet() bool {
}
func (v Value) Bool() bool {
- panic("unimplemented: (reflect.Value).Bool()")
+ switch v.Type().Kind() {
+ case Bool:
+ return uintptr(v.value) != 0
+ default:
+ panic(&ValueError{"Bool"})
+ }
}
func (v Value) Int() int64 {
- panic("unimplemented: (reflect.Value).Int()")
+ switch v.Type().Kind() {
+ case Int:
+ if unsafe.Sizeof(int(0)) <= unsafe.Sizeof(uintptr(0)) {
+ return int64(int(uintptr(v.value)))
+ } else {
+ return int64(*(*int)(v.value))
+ }
+ case Int8:
+ return int64(int8(uintptr(v.value)))
+ case Int16:
+ return int64(int16(uintptr(v.value)))
+ case Int32:
+ if unsafe.Sizeof(int32(0)) <= unsafe.Sizeof(uintptr(0)) {
+ return int64(int32(uintptr(v.value)))
+ } else {
+ return int64(*(*int32)(v.value))
+ }
+ return int64(uintptr(v.value))
+ case Int64:
+ if unsafe.Sizeof(int64(0)) <= unsafe.Sizeof(uintptr(0)) {
+ return int64(uintptr(v.value))
+ } else {
+ return *(*int64)(v.value)
+ }
+ default:
+ panic(&ValueError{"Int"})
+ }
}
func (v Value) Uint() uint64 {
- panic("unimplemented: (reflect.Value).Uint()")
+ switch v.Type().Kind() {
+ case Uintptr, Uint8, Uint16:
+ return uint64(uintptr(v.value))
+ case Uint:
+ if unsafe.Sizeof(uint(0)) <= unsafe.Sizeof(uintptr(0)) {
+ return uint64(uintptr(v.value))
+ } else {
+ // For systems with 16-bit pointers.
+ return uint64(*(*uint)(v.value))
+ }
+ case Uint32:
+ if unsafe.Sizeof(uint32(0)) <= unsafe.Sizeof(uintptr(0)) {
+ return uint64(uintptr(v.value))
+ } else {
+ // For systems with 16-bit pointers.
+ return uint64(*(*uint32)(v.value))
+ }
+ case Uint64:
+ if unsafe.Sizeof(uint64(0)) <= unsafe.Sizeof(uintptr(0)) {
+ return uint64(uintptr(v.value))
+ } else {
+ // For systems with 16-bit or 32-bit pointers.
+ return *(*uint64)(v.value)
+ }
+ default:
+ panic(&ValueError{"Uint"})
+ }
}
func (v Value) Float() float64 {
- panic("unimplemented: (reflect.Value).Float()")
+ switch v.Type().Kind() {
+ case Float32:
+ if unsafe.Sizeof(float32(0)) <= unsafe.Sizeof(uintptr(0)) {
+ // The float is directly stored in the interface value on systems
+ // with 32-bit and 64-bit pointers.
+ return float64(*(*float32)(unsafe.Pointer(&v.value)))
+ } else {
+ // The float is stored as an external value on systems with 16-bit
+ // pointers.
+ return float64(*(*float32)(v.value))
+ }
+ case Float64:
+ if unsafe.Sizeof(float64(0)) <= unsafe.Sizeof(uintptr(0)) {
+ // The float is directly stored in the interface value on systems
+ // with 64-bit pointers.
+ return *(*float64)(unsafe.Pointer(&v.value))
+ } else {
+ // For systems with 16-bit and 32-bit pointers.
+ return *(*float64)(v.value)
+ }
+ default:
+ panic(&ValueError{"Float"})
+ }
}
func (v Value) Complex() complex128 {
- panic("unimplemented: (reflect.Value).Complex()")
+ switch v.Type().Kind() {
+ case Complex64:
+ if unsafe.Sizeof(complex64(0)) <= unsafe.Sizeof(uintptr(0)) {
+ // The complex number is directly stored in the interface value on
+ // systems with 64-bit pointers.
+ return complex128(*(*complex64)(unsafe.Pointer(&v.value)))
+ } else {
+ // The complex number is stored as an external value on systems with
+ // 16-bit and 32-bit pointers.
+ return complex128(*(*complex64)(v.value))
+ }
+ case Complex128:
+ // This is a 128-bit value, which is always stored as an external value.
+ // It may be stored in the pointer directly on very uncommon
+ // architectures with 128-bit pointers, however.
+ return *(*complex128)(v.value)
+ default:
+ panic(&ValueError{"Complex"})
+ }
}
func (v Value) String() string {
- panic("unimplemented: (reflect.Value).String()")
+ switch v.Type().Kind() {
+ case String:
+ // A string value is always bigger than a pointer as it is made of a
+ // pointer and a length.
+ return *(*string)(v.value)
+ default:
+ // Special case because of the special treatment of .String() in Go.
+ return "<T>"
+ }
}
func (v Value) Bytes() []byte {
@@ -147,3 +259,11 @@ func (v Value) SetString(x string) {
func MakeSlice(typ Type, len, cap int) Value {
panic("unimplemented: reflect.MakeSlice()")
}
+
+type ValueError struct {
+ Method string
+}
+
+func (e *ValueError) Error() string {
+ return "reflect: call of reflect.Value." + e.Method + " on invalid type"
+}