all: reduce reflect usages

This commit is contained in:
Hajime Hoshi 2022-11-09 12:51:02 +09:00
parent f4b12462e6
commit 915fff96f8
4 changed files with 31 additions and 44 deletions

View File

@ -17,7 +17,6 @@ package directx
import (
"fmt"
"math"
"reflect"
"runtime"
"syscall"
"unsafe"
@ -2294,11 +2293,9 @@ func (i *_ID3DBlob) Release() uint32 {
}
func (i *_ID3DBlob) String() string {
var str string
h := (*reflect.StringHeader)(unsafe.Pointer(&str))
h.Data = i.GetBufferPointer()
h.Len = int(i.GetBufferSize())
return str
bs := make([]byte, int(i.GetBufferSize()))
copy(bs, unsafe.Slice((*byte)(unsafe.Pointer(i.GetBufferPointer())), i.GetBufferSize()))
return string(bs)
}
type _IDXGIAdapter struct {

View File

@ -4,8 +4,6 @@ package gl
import (
"fmt"
"reflect"
"strings"
"unsafe"
)
@ -14,7 +12,7 @@ import (
//
// For example:
//
// var data []uint8
// var data []byte
// ...
// gl.TexImage2D(glconst.TEXTURE_2D, ..., glconst.UNSIGNED_BYTE, gl.Ptr(&data[0]))
func Ptr(data any) unsafe.Pointer {
@ -40,14 +38,3 @@ func Ptr(data any) unsafe.Pointer {
}
return addr
}
// Str takes a null-terminated Go string and returns its GL-compatible address.
// This function reaches into Go string storage in an unsafe way so the caller
// must ensure the string is not garbage collected.
func Str(str string) *uint8 {
if !strings.HasSuffix(str, "\x00") {
panic("str argument missing null terminator: " + str)
}
header := (*reflect.StringHeader)(unsafe.Pointer(&str))
return (*uint8)(unsafe.Pointer(header.Data))
}

View File

@ -13,7 +13,7 @@ import "C"
// GoStr takes a null-terminated string returned by OpenGL and constructs a
// corresponding Go string.
func GoStr(cstr *uint8) string {
func GoStr(cstr *byte) string {
return C.GoString((*C.char)(unsafe.Pointer(cstr)))
}
@ -24,18 +24,18 @@ func GoStr(cstr *uint8) string {
// in order to free the memory.
//
// If no strings are provided as a parameter this function will panic.
func Strs(strs ...string) (cstrs **uint8, free func()) {
func Strs(strs ...string) (cstrs **byte, free func()) {
if len(strs) == 0 {
panic("Strs: expected at least 1 string")
panic("gl: expected at least 1 string at Strs")
}
css := make([]*uint8, 0, len(strs))
css := make([]*byte, 0, len(strs))
for _, str := range strs {
cs := C.CString(str)
css = append(css, (*uint8)(unsafe.Pointer(cs)))
css = append(css, (*byte)(unsafe.Pointer(cs)))
}
return (**uint8)(&css[0]), func() {
return (**byte)(&css[0]), func() {
for _, cs := range css {
C.free(unsafe.Pointer(cs))
}

View File

@ -6,22 +6,24 @@ package gl
import (
"runtime"
"strings"
"unsafe"
)
// GoStr takes a null-terminated string returned by OpenGL and constructs a
// corresponding Go string.
func GoStr(cstr *uint8) string {
str := ""
for {
if *cstr == 0 {
break
}
str += string(*cstr)
cstr = (*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(cstr)) + 1))
func GoStr(cstr *byte) string {
if cstr == nil {
return ""
}
return str
x := unsafe.Slice(cstr, 1e9)
for i, c := range x {
if c == 0 {
str := make([]byte, i)
copy(str, x[:i])
return string(str)
}
}
return ""
}
// Strs takes a list of Go strings (with or without null-termination) and
@ -31,19 +33,20 @@ func GoStr(cstr *uint8) string {
// in order to free the memory.
//
// If no strings are provided as a parameter this function will panic.
func Strs(strs ...string) (cstrs **uint8, free func()) {
func Strs(strs ...string) (cstrs **byte, free func()) {
if len(strs) == 0 {
panic("Strs: expected at least 1 string")
panic("gl: expected at least 1 string at Strs")
}
var pinned []string
var ptrs []*uint8
pinned := make([][]byte, 0, len(strs))
ptrs := make([]*byte, 0, len(strs))
for _, str := range strs {
if !strings.HasSuffix(str, "\x00") {
str += "\x00"
bs := []byte(str)
if len(bs) == 0 || bs[len(bs)-1] != 0 {
bs = append(bs, 0)
}
pinned = append(pinned, str)
ptrs = append(ptrs, Str(str))
pinned = append(pinned, bs)
ptrs = append(ptrs, &bs[0])
}
return &ptrs[0], func() {