github.com/HaHadaxigua/yaegi@v1.0.1/stdlib/unsafe/unsafe_go1.17.go (about) 1 //go:build go1.17 2 // +build go1.17 3 4 // Package unsafe provides wrapper of standard library unsafe package to be imported natively in Yaegi. 5 package unsafe 6 7 import ( 8 "errors" 9 "reflect" 10 "unsafe" 11 ) 12 13 func init() { 14 // Add builtin functions to unsafe. 15 Symbols["unsafe/unsafe"]["Add"] = reflect.ValueOf(add) 16 Symbols["unsafe/unsafe"]["Slice"] = reflect.ValueOf(slice) 17 } 18 19 func add(ptr unsafe.Pointer, l int) unsafe.Pointer { 20 return unsafe.Pointer(uintptr(ptr) + uintptr(l)) 21 } 22 23 type emptyInterface struct { 24 _ uintptr 25 data unsafe.Pointer 26 } 27 28 func slice(i interface{}, l int) interface{} { 29 if l == 0 { 30 return nil 31 } 32 33 v := reflect.ValueOf(i) 34 if v.Kind() != reflect.Ptr { 35 panic(errors.New("first argument to unsafe.Slice must be pointer")) 36 } 37 if v.IsNil() { 38 panic(errors.New("unsafe.Slice: ptr is nil and len is not zero")) 39 } 40 41 if l < 0 { 42 panic(errors.New("unsafe.Slice: len out of range")) 43 } 44 45 ih := *(*emptyInterface)(unsafe.Pointer(&i)) 46 47 inter := reflect.MakeSlice(reflect.SliceOf(v.Type().Elem()), l, l).Interface() 48 ptr := (*emptyInterface)(unsafe.Pointer(&inter)).data 49 sh := (*reflect.SliceHeader)(ptr) 50 sh.Data = uintptr(ih.data) 51 sh.Len = l 52 sh.Cap = l 53 54 return inter 55 }