1
0
mirror of https://github.com/fumiama/gozel.git synced 2026-06-05 00:10:24 +08:00
Files
gozel/internal/zecall/generic.go
源文雨 9f94f92b50 fix: ci
2026-03-26 00:39:39 +08:00

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
}