func initializeSliceToGet(object *object, value reflect.Value) error { typo := value.Type() bid, ok := kindTypeMapping[typo.Elem().Kind()] if !ok { return errors.New("encountered an unsupported datatype") } if err := checkArrayType(object.tid, bid); err != nil { return err } length, err := computeArrayLength(object.tid) if err != nil { return err } buffer := reflect.MakeSlice(typo, int(length), int(length)) shadow := reflect.Indirect(reflect.New(typo)) shadow.Set(buffer) src := (*reflect.SliceHeader)(unsafe.Pointer(shadow.UnsafeAddr())) dst := (*reflect.SliceHeader)(unsafe.Pointer(value.UnsafeAddr())) dst.Data, src.Data = src.Data, dst.Data dst.Cap, src.Cap = src.Cap, dst.Cap dst.Len, src.Len = src.Len, dst.Len object.data = unsafe.Pointer(dst.Data) object.flag |= flagVariableLength return nil }
func valueHeader(v reflect.Value) (h *reflect.SliceHeader) { if v.IsValid() { size := int(v.Type().Size()) h = &reflect.SliceHeader{v.UnsafeAddr(), size, size} } return }
func (g *Group) scanSubGroupHandler(realval reflect.Value, sfield *reflect.StructField) (bool, error) { mtag := newMultiTag(string(sfield.Tag)) if err := mtag.Parse(); err != nil { return true, err } subgroup := mtag.Get("group") if len(subgroup) != 0 { ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr())) description := mtag.Get("description") group, err := g.AddGroup(subgroup, description, ptrval.Interface()) if err != nil { return true, err } group.Namespace = mtag.Get("namespace") group.Hidden = mtag.Get("hidden") != "" return true, nil } return false, nil }
//Ptr is simply a copy of the go-gl Ptr function, it takes in argument a slice, uintptr or pointer and makes an unsafe.Pointer with it. func Ptr(v interface{}) unsafe.Pointer { if v == nil { return unsafe.Pointer(nil) } rv := reflect.ValueOf(v) var et reflect.Value switch rv.Type().Kind() { case reflect.Uintptr: offset, _ := v.(uintptr) return unsafe.Pointer(offset) case reflect.Ptr: if rv.IsNil() { return unsafe.Pointer(nil) } et = rv.Elem() case reflect.Slice: if rv.IsNil() || rv.Len() == 0 { return unsafe.Pointer(nil) } et = rv.Index(0) default: panic("type must be a pointer, a slice, uintptr or nil") } return unsafe.Pointer(et.UnsafeAddr()) }
// Gob assumes it can call UnsafeAddr on any Value // in order to get a pointer it can copy data from. // Values that have just been created and do not point // into existing structs or slices cannot be addressed, // so simulate it by returning a pointer to a copy. // Each call allocates once. func unsafeAddr(v reflect.Value) uintptr { if v.CanAddr() { return v.UnsafeAddr() } x := reflect.New(v.Type()).Elem() x.Set(v) return x.UnsafeAddr() }
// Gob assumes it can call UnsafeAddr on any Value // in order to get a pointer it can copy data from. // Values that have just been created and do not point // into existing structs or slices cannot be addressed, // so simulate it by returning a pointer to a copy. // Each call allocates once. func unsafeAddr(v reflect.Value) unsafe.Pointer { if v.CanAddr() { return unsafe.Pointer(v.UnsafeAddr()) } x := reflect.New(v.Type()).Elem() x.Set(v) return unsafe.Pointer(x.UnsafeAddr()) }
// encodeReflectValue is a helper for maps. It encodes the value v. func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir int) { for i := 0; i < indir && v != nil; i++ { v = reflect.Indirect(v) } if v == nil { errorf("gob: encodeReflectValue: nil element") } op(nil, state, unsafe.Pointer(v.UnsafeAddr())) }
// Obtain a copy of a private byte slice. func copyPrivateByteSlice(value reflect.Value) []byte { newSlice := []byte{} _newSlice := (*reflect.SliceHeader)(unsafe.Pointer(&newSlice)) _origSlice := (*reflect.SliceHeader)(unsafe.Pointer(value.UnsafeAddr())) _newSlice.Data = _origSlice.Data _newSlice.Len = _origSlice.Len _newSlice.Cap = _origSlice.Cap return newSlice }
// Traverses recursively both values, assigning src's fields values to dst. // The map argument tracks comparisons that have already been seen, which allows // short circuiting on recursive types. func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int) error { if !src.IsValid() { return nil } if dst.CanAddr() { addr := dst.UnsafeAddr() h := 17 * addr seen := visited[h] typ := dst.Type() for p := seen; p != nil; p = p.next { if p.ptr == addr && p.typ == typ { return nil } } // Remember, remember... visited[h] = &visit{addr, typ, seen} } switch dst.Kind() { case reflect.Struct: for i, n := 0, dst.NumField(); i < n; i++ { if err := deepMerge(dst.Field(i), src.Field(i), visited, depth+1); err != nil { return err } } case reflect.Map: for _, key := range src.MapKeys() { srcElement := src.MapIndex(key) if !srcElement.IsValid() { continue } dstElement := dst.MapIndex(key) switch reflect.TypeOf(srcElement.Interface()).Kind() { case reflect.Struct: fallthrough case reflect.Map: if err := deepMerge(dstElement, srcElement, visited, depth+1); err != nil { return err } default: dst.SetMapIndex(key, srcElement) } if !dstElement.IsValid() { dst.SetMapIndex(key, srcElement) } } case reflect.Interface: if err := deepMerge(dst.Elem(), src.Elem(), visited, depth+1); err != nil { return err } default: if dst.CanSet() && isEmptyValue(dst) { dst.Set(src) } } return nil }
func injectIoc(target reflect.Value, basic *Basic) { for target.Kind() == reflect.Ptr { target = target.Elem() } typeIndex := getIocTypeIndex(target.Type()) targetAddr := target.UnsafeAddr() for _, singleIndex := range typeIndex { var pointer **Basic = (**Basic)(unsafe.Pointer(targetAddr + singleIndex)) *pointer = basic } }
//Encodes the value into to the writer in the msgpack format func (enc *Encoder) EncodeValue(value reflect.Value) error { if value.Kind() != reflect.Ptr { panic("Encode requires a pointer type") } value = value.Elem() eng := getEngine(value.Type()) if encode, ok := eng.encode.(encodeFunc); ok { return encode(enc, unsafe.Pointer(value.UnsafeAddr())) } else { encode := eng.encode.(encodeReflectFunc) return encode(enc, value) } }
//Decodes the value from the reader in the msgpack format func (dec *Decoder) DecodeValue(value reflect.Value) error { if value.Kind() != reflect.Ptr { panic("Decode requires a pointer type") } value = value.Elem() eng := getEngine(value.Type()) if decode, ok := eng.decode.(decodeFunc); ok { return decode(dec, unsafe.Pointer(value.UnsafeAddr())) } else { decode := eng.decode.(decodeReflectFunc) return decode(dec, value) } }
func sliceHeaderFromValue(v reflect.Value) (s *reflect.SliceHeader) { switch v.Kind() { case reflect.Slice: if !v.CanAddr() { x := reflect.New(v.Type()).Elem() x.Set(v) v = x } s = (*reflect.SliceHeader)(unsafe.Pointer(v.UnsafeAddr())) case reflect.Ptr, reflect.Interface: s = sliceHeaderFromValue(v.Elem()) } return }
func decode_value(cv *Value, rv reflect.Value) { //fmt.Printf("rv: %v\n",rv.Type()) kind := rv.Type().Kind() op := dec_op_table[kind] switch kind { default: //println("-->",kind.String()) op(cv, unsafe.Pointer(rv.UnsafeAddr())) //println("<--",kind.String()) case reflect.Array: op(cv, unsafe.Pointer(&rv)) case reflect.Ptr: //fmt.Printf("--> ptr\n") op(cv, unsafe.Pointer(rv.UnsafeAddr())) //fmt.Printf("<-- ptr\n") case reflect.Slice: op(cv, unsafe.Pointer(rv.UnsafeAddr())) case reflect.Struct: op(cv, unsafe.Pointer(&rv)) case reflect.String: //println("==>",kind.String()) op(cv, unsafe.Pointer(rv.UnsafeAddr())) //println("<==",kind.String()) } //fmt.Printf("rv: %v [done]\n", rv.Type()) }
func (enc *Encoder) encode(b *bytes.Buffer, value reflect.Value, ut *userTypeInfo) { defer catchError(&enc.err) engine := enc.lockAndGetEncEngine(ut) indir := ut.indir if ut.isGobEncoder { indir = int(ut.encIndir) } for i := 0; i < indir; i++ { value = reflect.Indirect(value) } if !ut.isGobEncoder && value.Type().Kind() == reflect.Struct { enc.encodeStruct(b, engine, value.UnsafeAddr()) } else { enc.encodeSingle(b, engine, value.UnsafeAddr()) } }
// Traverses recursively both values, assigning src's fields values to dst. // The map argument tracks comparisons that have already been seen, which allows // short circuiting on recursive types. func deeper(dst, src reflect.Value, visited map[uintptr]*visit, depth int) (err error) { if dst.CanAddr() { addr := dst.UnsafeAddr() h := 17 * addr seen := visited[h] typ := dst.Type() for p := seen; p != nil; p = p.next { if p.ptr == addr && p.typ == typ { return nil } } // Remember, remember... visited[h] = &visit{addr, typ, seen} } return // TODO refactor }
func readSlice(iv reflect.Value, p unsafe.Pointer, c C.size_t, s C.size_t) error { w := reflect.MakeSlice(iv.Type(), int(c), int(c)) C.memcpy(unsafe.Pointer(w.Pointer()), p, c*s) iw := reflect.Indirect(reflect.New(iv.Type())) iw.Set(w) // FIXME: Bad, bad, bad! But how else to fill in unexported fields? src := (*reflect.SliceHeader)(unsafe.Pointer(iw.UnsafeAddr())) dst := (*reflect.SliceHeader)(unsafe.Pointer(iv.UnsafeAddr())) dst.Data, src.Data = src.Data, dst.Data dst.Len, src.Len = src.Len, dst.Len dst.Cap, src.Cap = src.Cap, dst.Cap return nil }
func isCycle(x reflect.Value, seen map[comparison]bool) bool { if !x.IsValid() { return false } // cycle check if x.CanAddr() { xptr := unsafe.Pointer(x.UnsafeAddr()) c := comparison{xptr, x.Type()} if seen[c] { return true // already seen } seen[c] = true } switch x.Kind() { case reflect.Ptr, reflect.Interface: return isCycle(x.Elem(), seen) case reflect.Array, reflect.Slice: for i := 0; i < x.Len(); i++ { if isCycle(x.Index(i), seen) { return true } } return false case reflect.Struct: for i, n := 0, x.NumField(); i < n; i++ { if isCycle(x.Field(i), seen) { return true } } return false case reflect.Map: for _, k := range x.MapKeys() { if isCycle(x.MapIndex(k), seen) { return true } } return false } return false }
func getPointer(rv reflect.Value) uintptr { var rvptr uintptr switch rv.Kind() { case reflect.Map, reflect.Slice: rvptr = rv.Pointer() case reflect.Interface: // FIXME: still needed? return getPointer(rv.Elem()) case reflect.Ptr: rvptr = rv.Pointer() case reflect.String: ps := (*reflect.StringHeader)(unsafe.Pointer(rv.UnsafeAddr())) rvptr = ps.Data } return rvptr }
func valueDecoder(data interface{}) (unsafe.Pointer, typeDecoder, error) { var v reflect.Value switch d := reflect.ValueOf(data); d.Kind() { case reflect.Ptr: v = d.Elem() case reflect.Slice: v = d case reflect.Invalid: return nil, nil, errors.New("can't decode into nil") default: return nil, nil, errors.New("invalid type " + d.Type().String()) } dec, err := makeDecoder(v.Type()) if err != nil { return nil, nil, err } return unsafe.Pointer(v.UnsafeAddr()), dec, err }
func checkCircle(x reflect.Value, seen objInfoSet) bool { if !x.IsValid() { return false } if x.CanAddr() { objinfo := objInfo{unsafe.Pointer(x.UnsafeAddr()), x.Type()} if _, ok := seen[objinfo]; ok { return true } seen[objinfo] = true } switch x.Kind() { case reflect.Ptr, reflect.Interface: return checkCircle(x.Elem(), copyObjInfoSet(seen)) case reflect.Array, reflect.Slice: for i := 0; i < x.Len(); i++ { if checkCircle(x.Index(i), copyObjInfoSet(seen)) { return true } } return false case reflect.Struct: for i, n := 0, x.NumField(); i < n; i++ { if checkCircle(x.Field(i), copyObjInfoSet(seen)) { return true } } return false case reflect.Map: for _, k := range x.MapKeys() { if checkCircle(x.MapIndex(k), copyObjInfoSet(seen)) { return true } } return false } return false }
func setValue(value reflect.Value, s string) error { ptr := unsafe.Pointer(value.UnsafeAddr()) switch value.Type().Kind() { case reflect.Bool: return setBool(ptr, s) case reflect.Float64: return setFloat64(ptr, s) case reflect.Int64: return setInt64(ptr, s) case reflect.Int: return setInt(ptr, s) case reflect.String: return setString(ptr, s) case reflect.Uint64: return setUint64(ptr, s) case reflect.Uint: return setUint(ptr, s) default: panic(fmt.Sprintf("unsupported type: %v", value.Type())) } }
// Gets a node from value `src` and using `r` to search for previously visited // nodes. Returns true as a second parameter if node has already been graphed; // false if it still needs to. func getNode(src reflect.Value, r *resolver) (*node, bool) { n, ok := (*node)(nil), false if src.CanAddr() { // if we are addressable then make sure we get the node from // the resolver n, ok = r.resolveAddr(src.UnsafeAddr()) } else { // we aren't and have to recreate a fresh node n = newNode() } if !ok { // we are either a completely new node and we need to set our // value n.val = getVal(src) } // return the node return n, ok }
func cyclic(x reflect.Value, seen map[ptr]bool) bool { if x.CanAddr() { p := ptr{unsafe.Pointer(x.UnsafeAddr()), x.Type()} if seen[p] { return true } seen[p] = true } switch x.Kind() { case reflect.Ptr, reflect.Interface: return cyclic(x.Elem(), seen) case reflect.Array, reflect.Slice: for i := 0; i < x.Len(); i++ { if cyclic(x.Index(i), seen) { return true } } return false case reflect.Struct: for i, n := 0, x.NumField(); i < n; i++ { if cyclic(x.Field(i), seen) { return true } } return false case reflect.Map: for _, k := range x.MapKeys() { if cyclic(x.MapIndex(k), seen) || cyclic(k, seen) { return true } } return false default: return false } panic("unreachable") }
func addFieldFlag(field reflect.StructField, value reflect.Value, fs *flag.FlagSet) { name, usage := getFieldNameUsage(field) ptr := unsafe.Pointer(value.UnsafeAddr()) switch field.Type.Kind() { case reflect.Bool: fs.BoolVar((*bool)(ptr), name, *(*bool)(ptr), usage) case reflect.Float64: fs.Float64Var((*float64)(ptr), name, *(*float64)(ptr), usage) case reflect.Int64: fs.Int64Var((*int64)(ptr), name, *(*int64)(ptr), usage) case reflect.Int: fs.IntVar((*int)(ptr), name, *(*int)(ptr), usage) case reflect.String: fs.StringVar((*string)(ptr), name, *(*string)(ptr), usage) case reflect.Uint64: fs.Uint64Var((*uint64)(ptr), name, *(*uint64)(ptr), usage) case reflect.Uint: fs.UintVar((*uint)(ptr), name, *(*uint)(ptr), usage) default: panic(fmt.Sprintf("unsupported type: %v", field.Type)) } }
func f() { var x unsafe.Pointer var y uintptr x = unsafe.Pointer(y) // ERROR "possible misuse of unsafe.Pointer" y = uintptr(x) // only allowed pointer arithmetic is ptr +/-/&^ num. // num+ptr is technically okay but still flagged: write ptr+num instead. x = unsafe.Pointer(uintptr(x) + 1) x = unsafe.Pointer(1 + uintptr(x)) // ERROR "possible misuse of unsafe.Pointer" x = unsafe.Pointer(uintptr(x) + uintptr(x)) // ERROR "possible misuse of unsafe.Pointer" x = unsafe.Pointer(uintptr(x) - 1) x = unsafe.Pointer(1 - uintptr(x)) // ERROR "possible misuse of unsafe.Pointer" x = unsafe.Pointer(uintptr(x) &^ 3) x = unsafe.Pointer(1 &^ uintptr(x)) // ERROR "possible misuse of unsafe.Pointer" // certain uses of reflect are okay var v reflect.Value x = unsafe.Pointer(v.Pointer()) x = unsafe.Pointer(v.UnsafeAddr()) var s1 *reflect.StringHeader x = unsafe.Pointer(s1.Data) var s2 *reflect.SliceHeader x = unsafe.Pointer(s2.Data) var s3 reflect.StringHeader x = unsafe.Pointer(s3.Data) // ERROR "possible misuse of unsafe.Pointer" var s4 reflect.SliceHeader x = unsafe.Pointer(s4.Data) // ERROR "possible misuse of unsafe.Pointer" // but only in reflect var vv V x = unsafe.Pointer(vv.Pointer()) // ERROR "possible misuse of unsafe.Pointer" x = unsafe.Pointer(vv.UnsafeAddr()) // ERROR "possible misuse of unsafe.Pointer" var ss1 *StringHeader x = unsafe.Pointer(ss1.Data) // ERROR "possible misuse of unsafe.Pointer" var ss2 *SliceHeader x = unsafe.Pointer(ss2.Data) // ERROR "possible misuse of unsafe.Pointer" }
func ptr(v interface{}) unsafe.Pointer { if v == nil { return unsafe.Pointer(nil) } rv := reflect.ValueOf(v) var et reflect.Value switch rv.Type().Kind() { case reflect.Uintptr: offset, _ := v.(uintptr) return unsafe.Pointer(offset) case reflect.Ptr: et = rv.Elem() case reflect.Slice: et = rv.Index(0) default: panic(ErrorPointerType) } return unsafe.Pointer(et.UnsafeAddr()) }
func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, sptr uintptr, proceed bool) { // use a goto statement instead of a recursive function for ptr/interface. TOP: switch rv.Kind() { case reflect.Ptr: if rv.IsNil() { e.e.EncodeNil() return } rv = rv.Elem() if e.h.CheckCircularRef && rv.Kind() == reflect.Struct { // TODO: Movable pointers will be an issue here. Future problem. sptr = rv.UnsafeAddr() break TOP } goto TOP case reflect.Interface: if rv.IsNil() { e.e.EncodeNil() return } rv = rv.Elem() goto TOP case reflect.Slice, reflect.Map: if rv.IsNil() { e.e.EncodeNil() return } case reflect.Invalid, reflect.Func: e.e.EncodeNil() return } proceed = true rv2 = rv return }
func encode_value(cv *Value, rv reflect.Value) { kind := rv.Type().Kind() op := enc_op_table[kind] switch kind { default: op(cv, unsafe.Pointer(rv.UnsafeAddr())) case reflect.Array: op(cv, unsafe.Pointer(&rv)) case reflect.Ptr: op(cv, unsafe.Pointer(rv.Pointer())) case reflect.Slice: op(cv, unsafe.Pointer(rv.UnsafeAddr())) case reflect.Struct: op(cv, unsafe.Pointer(&rv)) case reflect.String: op(cv, unsafe.Pointer(rv.UnsafeAddr())) } }
func (p *printer) printValue(v reflect.Value, showType, quote bool) { if p.depth > 10 { io.WriteString(p, "!%v(DEPTH EXCEEDED)") return } switch v.Kind() { case reflect.Bool: p.printInline(v, v.Bool(), showType) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: p.printInline(v, v.Int(), showType) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: p.printInline(v, v.Uint(), showType) case reflect.Float32, reflect.Float64: p.printInline(v, v.Float(), showType) case reflect.Complex64, reflect.Complex128: fmt.Fprintf(p, "%#v", v.Complex()) case reflect.String: p.fmtString(v.String(), quote) case reflect.Map: t := v.Type() if showType { io.WriteString(p, t.String()) } writeByte(p, '{') if nonzero(v) { expand := !canInline(v.Type()) pp := p if expand { writeByte(p, '\n') pp = p.indent() } keys := v.MapKeys() for i := 0; i < v.Len(); i++ { showTypeInStruct := true k := keys[i] mv := v.MapIndex(k) pp.printValue(k, false, true) writeByte(pp, ':') if expand { writeByte(pp, '\t') } showTypeInStruct = t.Elem().Kind() == reflect.Interface pp.printValue(mv, showTypeInStruct, true) if expand { io.WriteString(pp, ",\n") } else if i < v.Len()-1 { io.WriteString(pp, ", ") } } if expand { pp.tw.Flush() } } writeByte(p, '}') case reflect.Struct: t := v.Type() if v.CanAddr() { addr := v.UnsafeAddr() vis := visit{addr, t} if vd, ok := p.visited[vis]; ok && vd < p.depth { p.fmtString(t.String()+"{(CYCLIC REFERENCE)}", false) break // don't print v again } p.visited[vis] = p.depth } if showType { io.WriteString(p, t.String()) } writeByte(p, '{') if nonzero(v) { expand := !canInline(v.Type()) pp := p if expand { writeByte(p, '\n') pp = p.indent() } for i := 0; i < v.NumField(); i++ { showTypeInStruct := true if f := t.Field(i); f.Name != "" { io.WriteString(pp, f.Name) writeByte(pp, ':') if expand { writeByte(pp, '\t') } showTypeInStruct = labelType(f.Type) } pp.printValue(getField(v, i), showTypeInStruct, true) if expand { io.WriteString(pp, ",\n") } else if i < v.NumField()-1 { io.WriteString(pp, ", ") } } if expand { pp.tw.Flush() } } writeByte(p, '}') case reflect.Interface: switch e := v.Elem(); { case e.Kind() == reflect.Invalid: io.WriteString(p, "nil") case e.IsValid(): pp := *p pp.depth++ pp.printValue(e, showType, true) default: io.WriteString(p, v.Type().String()) io.WriteString(p, "(nil)") } case reflect.Array, reflect.Slice: t := v.Type() if showType { io.WriteString(p, t.String()) } if v.Kind() == reflect.Slice && v.IsNil() && showType { io.WriteString(p, "(nil)") break } if v.Kind() == reflect.Slice && v.IsNil() { io.WriteString(p, "nil") break } writeByte(p, '{') expand := !canInline(v.Type()) pp := p if expand { writeByte(p, '\n') pp = p.indent() } for i := 0; i < v.Len(); i++ { showTypeInSlice := t.Elem().Kind() == reflect.Interface pp.printValue(v.Index(i), showTypeInSlice, true) if expand { io.WriteString(pp, ",\n") } else if i < v.Len()-1 { io.WriteString(pp, ", ") } } if expand { pp.tw.Flush() } writeByte(p, '}') case reflect.Ptr: e := v.Elem() if !e.IsValid() { writeByte(p, '(') io.WriteString(p, v.Type().String()) io.WriteString(p, ")(nil)") } else { pp := *p pp.depth++ writeByte(pp, '&') pp.printValue(e, true, true) } case reflect.Chan: x := v.Pointer() if showType { writeByte(p, '(') io.WriteString(p, v.Type().String()) fmt.Fprintf(p, ")(%#v)", x) } else { fmt.Fprintf(p, "%#v", x) } case reflect.Func: io.WriteString(p, v.Type().String()) io.WriteString(p, " {...}") case reflect.UnsafePointer: p.printInline(v, v.Pointer(), showType) case reflect.Invalid: io.WriteString(p, "nil") } }