diff --git a/internal/ch/compile.go b/internal/ch/compile.go index c4052ba..c72c504 100644 --- a/internal/ch/compile.go +++ b/internal/ch/compile.go @@ -129,6 +129,16 @@ func CompileMulti(p Patterns, mode CompileMode, info *hs.PlatformInfo) (Database return CompileExtMulti(p, mode, info, 0, 0) } +func castCArrayToSlice[T any](c *T, count int) []T { + var list []T + sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&list))) + sliceHeader.Cap = count + sliceHeader.Len = count + sliceHeader.Data = uintptr(unsafe.Pointer(c)) + + return list +} + // The multiple regular expression compiler. func CompileExtMulti(p Patterns, mode CompileMode, info *hs.PlatformInfo, matchLimit, matchLimitRecursion uint, @@ -144,13 +154,13 @@ func CompileExtMulti(p Patterns, mode CompileMode, info *hs.PlatformInfo, patterns := p.Patterns() cexprs := (**C.char)(C.calloc(C.size_t(len(patterns)), C.size_t(unsafe.Sizeof(uintptr(0))))) - exprs := (*[1 << 30]*C.char)(unsafe.Pointer(cexprs))[:len(patterns):len(patterns)] + exprs := castCArrayToSlice[*C.char](cexprs, len(patterns)) cflags := (*C.uint)(C.calloc(C.size_t(len(patterns)), C.size_t(unsafe.Sizeof(C.uint(0))))) - flags := (*[1 << 30]C.uint)(unsafe.Pointer(cflags))[:len(patterns):len(patterns)] + flags := castCArrayToSlice[C.uint](cflags, len(patterns)) cids := (*C.uint)(C.calloc(C.size_t(len(patterns)), C.size_t(unsafe.Sizeof(C.uint(0))))) - ids := (*[1 << 30]C.uint)(unsafe.Pointer(cids))[:len(patterns):len(patterns)] + ids := castCArrayToSlice[C.uint](cids, len(patterns)) for i, pattern := range patterns { exprs[i] = C.CString(pattern.Expression) diff --git a/internal/hs/compile.go b/internal/hs/compile.go index c248ac3..2080132 100644 --- a/internal/hs/compile.go +++ b/internal/hs/compile.go @@ -10,6 +10,7 @@ import "C" import ( "errors" "fmt" + "reflect" "runtime" "sort" "strings" @@ -391,6 +392,16 @@ type Patterns interface { Patterns() []*Pattern } +func castCArrayToSlice[T any](c *T, count int) []T { + var list []T + sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&list))) + sliceHeader.Cap = count + sliceHeader.Len = count + sliceHeader.Data = uintptr(unsafe.Pointer(c)) + + return list +} + func CompileMulti(input Patterns, mode ModeFlag, info *PlatformInfo) (Database, error) { var db *C.hs_database_t var err *C.hs_compile_error_t @@ -404,16 +415,16 @@ func CompileMulti(input Patterns, mode ModeFlag, info *PlatformInfo) (Database, count := len(patterns) cexprs := (**C.char)(C.calloc(C.size_t(count), C.size_t(unsafe.Sizeof(uintptr(0))))) - exprs := (*[1 << 30]*C.char)(unsafe.Pointer(cexprs))[:count:count] + exprs := castCArrayToSlice[*C.char](cexprs, count) cflags := (*C.uint)(C.calloc(C.size_t(count), C.size_t(unsafe.Sizeof(C.uint(0))))) - flags := (*[1 << 30]C.uint)(unsafe.Pointer(cflags))[:count:count] + flags := castCArrayToSlice[C.uint](cflags, count) cids := (*C.uint)(C.calloc(C.size_t(count), C.size_t(unsafe.Sizeof(C.uint(0))))) - ids := (*[1 << 30]C.uint)(unsafe.Pointer(cids))[:count:count] + ids := castCArrayToSlice[C.uint](cids, count) cexts := (**C.hs_expr_ext_t)(C.calloc(C.size_t(count), C.size_t(unsafe.Sizeof(uintptr(0))))) - exts := (*[1 << 30]*C.hs_expr_ext_t)(unsafe.Pointer(cexts))[:count:count] + exts := castCArrayToSlice[*C.hs_expr_ext_t](cexts, count) for i, pattern := range patterns { exprs[i] = C.CString(pattern.Expr) diff --git a/internal/hs/compile_v52.go b/internal/hs/compile_v52.go index f930038..37634e2 100644 --- a/internal/hs/compile_v52.go +++ b/internal/hs/compile_v52.go @@ -71,16 +71,16 @@ func CompileLitMulti(input Literals, mode ModeFlag, info *PlatformInfo) (Databas count := len(literals) cexprs := (**C.char)(C.calloc(C.size_t(len(literals)), C.size_t(unsafe.Sizeof(uintptr(0))))) - exprs := (*[1 << 30]*C.char)(unsafe.Pointer(cexprs))[:len(literals):len(literals)] + exprs := castCArrayToSlice[*C.char](cexprs, len(literals)) clens := (*C.size_t)(C.calloc(C.size_t(len(literals)), C.size_t(unsafe.Sizeof(uintptr(0))))) - lens := (*[1 << 30]C.size_t)(unsafe.Pointer(clens))[:len(literals):len(literals)] + lens := castCArrayToSlice[C.size_t](clens, len(literals)) cflags := (*C.uint)(C.calloc(C.size_t(len(literals)), C.size_t(unsafe.Sizeof(C.uint(0))))) - flags := (*[1 << 30]C.uint)(unsafe.Pointer(cflags))[:len(literals):len(literals)] + flags := castCArrayToSlice[C.uint](cflags, len(literals)) cids := (*C.uint)(C.calloc(C.size_t(len(literals)), C.size_t(unsafe.Sizeof(C.uint(0))))) - ids := (*[1 << 30]C.uint)(unsafe.Pointer(cids))[:len(literals):len(literals)] + ids := castCArrayToSlice[C.uint](cids, len(literals)) for i, lit := range literals { exprs[i] = C.CString(lit.Expr)