purego: enumerate types that can be returned from callbacks (#58)
explicitly enumerates which types can be returned from a callback. It also adds support for returning reflect.Pointer and reflect.UnsafePointer
- commit
- 4f3e551a671be4b5946962a5ecd87f9cbb655cf9
- author
- TotallyGamerJet · · 2022-11-01 17:25 UTC
- committer
- GitHub · · 2022-11-01 17:25 UTC
- parent
- fbeb60f
- signature
- GPG Unverified
4AEE18F83AFDEB23The key is unknown
1 file · +16 -2
M syscall_darwin.go +16 -2
| @@ -75,8 +75,18 @@ func compileCallback(fn interface{}) uintptr { | |||
| 75 | 75 | panic("purego: unsupported argument type: " + in.Kind().String()) | |
| 76 | 76 | } | |
| 77 | 77 | } | |
| 78 | - | if ty.NumOut() > 1 || ty.NumOut() == 1 && ty.Out(0).Size() != ptrSize { | |
| 79 | - | panic("purego: callbacks can only have one pointer-sized return") | |
| 78 | + | output: | |
| 79 | + | switch { | |
| 80 | + | case ty.NumOut() == 1: | |
| 81 | + | switch ty.Out(0).Kind() { | |
| 82 | + | case reflect.Pointer, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, | |
| 83 | + | reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, | |
| 84 | + | reflect.Bool, reflect.UnsafePointer: | |
| 85 | + | break output | |
| 86 | + | } | |
| 87 | + | panic("purego: unsupported return type: " + ty.String()) | |
| 88 | + | case ty.NumOut() > 1: | |
| 89 | + | panic("purego: callbacks can only have one return") | |
| 80 | 90 | } | |
| 81 | 91 | cbs.lock.Lock() | |
| 82 | 92 | defer cbs.lock.Unlock() | |
| @@ -121,6 +131,10 @@ func callbackWrap(a *callbackArgs) { | |||
| 121 | 131 | } else { | |
| 122 | 132 | a.result = 0 | |
| 123 | 133 | } | |
| 134 | + | case reflect.Pointer: | |
| 135 | + | a.result = ret[0].Pointer() | |
| 136 | + | case reflect.UnsafePointer: | |
| 137 | + | a.result = ret[0].Pointer() | |
| 124 | 138 | default: | |
| 125 | 139 | panic("purego: unsupported kind: " + k.String()) | |
| 126 | 140 | } | |
| @@ -75,8 +75,18 @@ func compileCallback(fn interface{}) uintptr { | |||||
| 75 | panic("purego: unsupported argument type: " + in.Kind().String()) | 75 | panic("purego: unsupported argument type: " + in.Kind().String()) | ||
| 76 | } | 76 | } | ||
| 77 | } | 77 | } | ||
| 78 | - | if ty.NumOut() > 1 || ty.NumOut() == 1 && ty.Out(0).Size() != ptrSize { | 78 | + | output: |
| 79 | - | panic("purego: callbacks can only have one pointer-sized return") | 79 | + | switch { |
| 80 | + | case ty.NumOut() == 1: | |||
| 81 | + | switch ty.Out(0).Kind() { | |||
| 82 | + | case reflect.Pointer, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, | |||
| 83 | + | reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, | |||
| 84 | + | reflect.Bool, reflect.UnsafePointer: | |||
| 85 | + | break output | |||
| 86 | + | } | |||
| 87 | + | panic("purego: unsupported return type: " + ty.String()) | |||
| 88 | + | case ty.NumOut() > 1: | |||
| 89 | + | panic("purego: callbacks can only have one return") | |||
| 80 | } | 90 | } | ||
| 81 | cbs.lock.Lock() | 91 | cbs.lock.Lock() | ||
| 82 | defer cbs.lock.Unlock() | 92 | defer cbs.lock.Unlock() | ||
| @@ -121,6 +131,10 @@ func callbackWrap(a *callbackArgs) { | |||||
| 121 | } else { | 131 | } else { | ||
| 122 | a.result = 0 | 132 | a.result = 0 | ||
| 123 | } | 133 | } | ||
| 134 | + | case reflect.Pointer: | |||
| 135 | + | a.result = ret[0].Pointer() | |||
| 136 | + | case reflect.UnsafePointer: | |||
| 137 | + | a.result = ret[0].Pointer() | |||
| 124 | default: | 138 | default: | ||
| 125 | panic("purego: unsupported kind: " + k.String()) | 139 | panic("purego: unsupported kind: " + k.String()) | ||
| 126 | } | 140 | } | ||