mirror of
https://github.com/fumiama/gozel.git
synced 2026-06-05 00:10:24 +08:00
41 lines
1.2 KiB
Go
41 lines
1.2 KiB
Go
package zecall
|
|
|
|
import (
|
|
"errors"
|
|
"math"
|
|
"reflect"
|
|
"strconv"
|
|
)
|
|
|
|
// ReturnTypes constrains the set of numeric types that can be returned from a Level Zero call.
|
|
type ReturnTypes interface {
|
|
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 |
|
|
~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
|
|
}
|
|
|
|
// Call invokes a registered proc by name. For generated call only.
|
|
// The go:uintptrescapes directive tells the compiler that args may contain
|
|
// pointers converted to uintptr, so the GC will keep them alive during the call.
|
|
//
|
|
//go:uintptrescapes
|
|
func Call[T ReturnTypes](name string, args ...uintptr) (r T, err error) {
|
|
r1, r2, err := Syscall(name, args...)
|
|
if r1 != 0 {
|
|
err = errors.New("zecall " + name + ": non-zero return value 0x" + strconv.FormatUint(uint64(r1), 16))
|
|
}
|
|
k := reflect.TypeOf(r).Kind()
|
|
switch k {
|
|
case reflect.Int, reflect.Int8, reflect.Int16,
|
|
reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8,
|
|
reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
r = (T)(r1)
|
|
case reflect.Float32:
|
|
r = (T)(math.Float32frombits(uint32(r2)))
|
|
case reflect.Float64:
|
|
r = (T)(math.Float64frombits(uint64(r2)))
|
|
default:
|
|
err = errors.New("zecall unsupported kind " + k.String())
|
|
}
|
|
return
|
|
}
|