From d4e7eb58880e1c7216e055155bfc546afd500f38 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 20 Jun 2024 14:31:05 +0800 Subject: [PATCH] bytealg.IndexByteString --- c/c.go | 6 ++++++ internal/lib/internal/bytealg/bytealg.go | 22 +++++++++++++++++++++- ssa/expr.go | 2 ++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/c/c.go b/c/c.go index 2e47383e..5e66959f 100644 --- a/c/c.go +++ b/c/c.go @@ -75,6 +75,12 @@ func Memmove(dst, src Pointer, n uintptr) Pointer //go:linkname Memset C.memset func Memset(s Pointer, c Int, n uintptr) Pointer +//go:linkname Memchr C.memchr +func Memchr(s Pointer, c Int, n uintptr) Pointer + +//go:linkname Memcmp C.memcmp +func Memcmp(s1, s2 Pointer, n uintptr) Int + // ----------------------------------------------------------------------------- //go:linkname Strlen C.strlen diff --git a/internal/lib/internal/bytealg/bytealg.go b/internal/lib/internal/bytealg/bytealg.go index 466b7271..c7cf2ac3 100644 --- a/internal/lib/internal/bytealg/bytealg.go +++ b/internal/lib/internal/bytealg/bytealg.go @@ -18,5 +18,25 @@ package bytealg // llgo:skip init import ( - _ "unsafe" + "unsafe" + + "github.com/goplus/llgo/c" ) + +func IndexByte(b []byte, ch byte) int { + ptr := unsafe.Pointer(unsafe.SliceData(b)) + ret := c.Memchr(ptr, c.Int(ch), uintptr(len(b))) + if ret != nil { + return int(uintptr(ret) - uintptr(ptr)) + } + return -1 +} + +func IndexByteString(s string, ch byte) int { + ptr := unsafe.Pointer(unsafe.StringData(s)) + ret := c.Memchr(ptr, c.Int(ch), uintptr(len(s))) + if ret != nil { + return int(uintptr(ret) - uintptr(ptr)) + } + return -1 +} diff --git a/ssa/expr.go b/ssa/expr.go index a9d9d1aa..ab6ecbfd 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -966,6 +966,8 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) { case "Slice": // unsafe.Slice size := args[1].impl return b.unsafeSlice(args[0], size, size) + case "StringData": + return b.StringData(args[0]) // TODO(xsw): check return type case "SliceData": return b.SliceData(args[0]) // TODO(xsw): check return type }