From 85b48ece57e315e42266f4cc048c4fe11d24d928 Mon Sep 17 00:00:00 2001 From: liuqiang Date: Tue, 28 Apr 2026 12:44:37 +0800 Subject: [PATCH 1/2] chore: gofmt repository --- base64x.go | 104 +++--- base64x_subr_amd64.go | 2 - base64x_test.go | 345 +++++++++---------- bench/bench_test.go | 145 ++++---- faststr.go | 25 +- fuzz_test.go | 103 +++--- internal/native/avx2/b64decode.go | 7 +- internal/native/avx2/b64decode_subr.go | 48 +-- internal/native/avx2/b64decode_text_amd64.go | 15 +- internal/native/avx2/b64encode.go | 6 +- internal/native/avx2/b64encode_subr.go | 40 ++- internal/native/avx2/b64encode_text_amd64.go | 15 +- internal/native/avx2/native_export.go | 9 +- internal/native/dispatch.go | 12 +- internal/native/native_test.go | 101 +++--- internal/native/sse/b64decode.go | 7 +- internal/native/sse/b64decode_subr.go | 48 +-- internal/native/sse/b64decode_text_amd64.go | 13 +- internal/native/sse/b64encode.go | 6 +- internal/native/sse/b64encode_subr.go | 36 +- internal/native/sse/b64encode_text_amd64.go | 13 +- internal/native/sse/native_export.go | 9 +- internal/rt/fastmem.go | 8 +- 23 files changed, 561 insertions(+), 556 deletions(-) diff --git a/base64x.go b/base64x.go index 533e872..5df655f 100644 --- a/base64x.go +++ b/base64x.go @@ -17,9 +17,9 @@ package base64x import ( - `encoding/base64` + "encoding/base64" - "github.com/cloudwego/base64x/internal/native" + "github.com/cloudwego/base64x/internal/native" ) // An Encoding is a radix 64 encoding/decoding scheme, defined by a @@ -30,10 +30,10 @@ import ( type Encoding int const ( - _MODE_URL = 1 << 0 - _MODE_RAW = 1 << 1 - _MODE_AVX2 = 1 << 2 - _MODE_JSON = 1 << 3 + _MODE_URL = 1 << 0 + _MODE_RAW = 1 << 1 + _MODE_AVX2 = 1 << 2 + _MODE_JSON = 1 << 3 ) // StdEncoding is the standard base64 encoding, as defined in @@ -57,10 +57,10 @@ const RawStdEncoding Encoding = _MODE_RAW const RawURLEncoding Encoding = _MODE_RAW | _MODE_URL // JSONStdEncoding is the StdEncoding and encoded as JSON string as RFC 8259. -const JSONStdEncoding Encoding = _MODE_JSON; +const JSONStdEncoding Encoding = _MODE_JSON var ( - archFlags = 0 + archFlags = 0 ) /** Encoder Functions **/ @@ -75,13 +75,13 @@ var ( // If out is not large enough to contain the encoded result, // it will panic. func (self Encoding) Encode(out []byte, src []byte) { - if len(src) != 0 { - if buf := out[:0:len(out)]; self.EncodedLen(len(src)) <= len(out) { - self.EncodeUnsafe(&buf, src) - } else { - panic("encoder output buffer is too small") - } - } + if len(src) != 0 { + if buf := out[:0:len(out)]; self.EncodedLen(len(src)) <= len(out) { + self.EncodeUnsafe(&buf, src) + } else { + panic("encoder output buffer is too small") + } + } } // EncodeUnsafe behaves like Encode, except it does NOT check if @@ -89,27 +89,27 @@ func (self Encoding) Encode(out []byte, src []byte) { // // It will also update the length of out. func (self Encoding) EncodeUnsafe(out *[]byte, src []byte) { - native.B64Encode(out, &src, int(self) | archFlags) + native.B64Encode(out, &src, int(self)|archFlags) } // EncodeToString returns the base64 encoding of src. func (self Encoding) EncodeToString(src []byte) string { - nbs := len(src) - ret := make([]byte, 0, self.EncodedLen(nbs)) + nbs := len(src) + ret := make([]byte, 0, self.EncodedLen(nbs)) - /* encode in native code */ - self.EncodeUnsafe(&ret, src) - return mem2str(ret) + /* encode in native code */ + self.EncodeUnsafe(&ret, src) + return mem2str(ret) } // EncodedLen returns the length in bytes of the base64 encoding // of an input buffer of length n. func (self Encoding) EncodedLen(n int) int { - if (self & _MODE_RAW) == 0 { - return (n + 2) / 3 * 4 - } else { - return (n * 8 + 5) / 6 - } + if (self & _MODE_RAW) == 0 { + return (n + 2) / 3 * 4 + } else { + return (n*8 + 5) / 6 + } } /** Decoder Functions **/ @@ -124,13 +124,13 @@ func (self Encoding) EncodedLen(n int) int { // If out is not large enough to contain the encoded result, // it will panic. func (self Encoding) Decode(out []byte, src []byte) (int, error) { - if len(src) == 0 { - return 0, nil - } else if buf := out[:0:len(out)]; self.DecodedLen(len(src)) <= len(out) { - return self.DecodeUnsafe(&buf, src) - } else { - panic("decoder output buffer is too small") - } + if len(src) == 0 { + return 0, nil + } else if buf := out[:0:len(out)]; self.DecodedLen(len(src)) <= len(out) { + return self.DecodeUnsafe(&buf, src) + } else { + panic("decoder output buffer is too small") + } } // DecodeUnsafe behaves like Decode, except it does NOT check if @@ -138,32 +138,32 @@ func (self Encoding) Decode(out []byte, src []byte) (int, error) { // // It will also update the length of out. func (self Encoding) DecodeUnsafe(out *[]byte, src []byte) (int, error) { - if n := native.B64Decode(out, mem2addr(src), len(src), int(self) | archFlags); n >= 0 { - return n, nil - } else { - return 0, base64.CorruptInputError(-n - 1) - } + if n := native.B64Decode(out, mem2addr(src), len(src), int(self)|archFlags); n >= 0 { + return n, nil + } else { + return 0, base64.CorruptInputError(-n - 1) + } } // DecodeString returns the bytes represented by the base64 string s. func (self Encoding) DecodeString(s string) ([]byte, error) { - src := str2mem(s) - ret := make([]byte, 0, self.DecodedLen(len(s))) - - /* decode into the allocated buffer */ - if _, err := self.DecodeUnsafe(&ret, src); err != nil { - return nil, err - } else { - return ret, nil - } + src := str2mem(s) + ret := make([]byte, 0, self.DecodedLen(len(s))) + + /* decode into the allocated buffer */ + if _, err := self.DecodeUnsafe(&ret, src); err != nil { + return nil, err + } else { + return ret, nil + } } // DecodedLen returns the maximum length in bytes of the decoded data // corresponding to n bytes of base64-encoded data. func (self Encoding) DecodedLen(n int) int { - if (self & _MODE_RAW) == 0 { - return n / 4 * 3 - } else { - return n * 6 / 8 - } + if (self & _MODE_RAW) == 0 { + return n / 4 * 3 + } else { + return n * 6 / 8 + } } diff --git a/base64x_subr_amd64.go b/base64x_subr_amd64.go index 022984b..3801e5a 100644 --- a/base64x_subr_amd64.go +++ b/base64x_subr_amd64.go @@ -1,5 +1,3 @@ - - package base64x import ( diff --git a/base64x_test.go b/base64x_test.go index 04473a8..e3088e3 100644 --- a/base64x_test.go +++ b/base64x_test.go @@ -17,241 +17,240 @@ package base64x import ( - `encoding/base64` - `strings` - `testing` + "encoding/base64" + "strings" + "testing" ) type TestPair struct { - decoded string - encoded string + decoded string + encoded string } type EncodingTest struct { - enc Encoding // Encoding to test - conv func(string) string // Reference string converter + enc Encoding // Encoding to test + conv func(string) string // Reference string converter } var pairs = []TestPair{ - // RFC 3548 examples - {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+"}, - {"\x14\xfb\x9c\x03\xd9", "FPucA9k="}, - {"\x14\xfb\x9c\x03", "FPucAw=="}, + // RFC 3548 examples + {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+"}, + {"\x14\xfb\x9c\x03\xd9", "FPucA9k="}, + {"\x14\xfb\x9c\x03", "FPucAw=="}, - // RFC 4648 examples - {"", ""}, - {"f", "Zg=="}, - {"fo", "Zm8="}, - {"foo", "Zm9v"}, - {"foob", "Zm9vYg=="}, - {"fooba", "Zm9vYmE="}, - {"foobar", "Zm9vYmFy"}, + // RFC 4648 examples + {"", ""}, + {"f", "Zg=="}, + {"fo", "Zm8="}, + {"foo", "Zm9v"}, + {"foob", "Zm9vYg=="}, + {"fooba", "Zm9vYmE="}, + {"foobar", "Zm9vYmFy"}, - // Wikipedia examples - {"sure.", "c3VyZS4="}, - {"sure", "c3VyZQ=="}, - {"sur", "c3Vy"}, - {"su", "c3U="}, - {"leasure.", "bGVhc3VyZS4="}, - {"easure.", "ZWFzdXJlLg=="}, - {"asure.", "YXN1cmUu"}, - {"sure.", "c3VyZS4="}, + // Wikipedia examples + {"sure.", "c3VyZS4="}, + {"sure", "c3VyZQ=="}, + {"sur", "c3Vy"}, + {"su", "c3U="}, + {"leasure.", "bGVhc3VyZS4="}, + {"easure.", "ZWFzdXJlLg=="}, + {"asure.", "YXN1cmUu"}, + {"sure.", "c3VyZS4="}, - // Relatively long strings - { - "Twas brillig, and the slithy toves", - "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", - }, { - "\x9dyH\xd2Y\x9e^e\x9e\xb1\x9a\x9a\x12\xfe\x8a\x07\xc7\x07\xcc\xe8l\x81" + - "\xf2\xd9\xe3\x89\xb5\x98\xee\xbd\x8etQ`2>\\t:_\xd7w\xe6\xb5\x96\xc7\xff\x9c", - "nXlI0lmeXmWesZqaEv6KB8cHzOhsgfLZ44m1mO69jnRRYDI+XHQ6X9d35rWWx/+c", - }, + // Relatively long strings + { + "Twas brillig, and the slithy toves", + "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", + }, { + "\x9dyH\xd2Y\x9e^e\x9e\xb1\x9a\x9a\x12\xfe\x8a\x07\xc7\x07\xcc\xe8l\x81" + + "\xf2\xd9\xe3\x89\xb5\x98\xee\xbd\x8etQ`2>\\t:_\xd7w\xe6\xb5\x96\xc7\xff\x9c", + "nXlI0lmeXmWesZqaEv6KB8cHzOhsgfLZ44m1mO69jnRRYDI+XHQ6X9d35rWWx/+c", + }, } var crlf_pairs = []TestPair{ - // RFC 3548 examples - {"\x14\xfb\x9c\x03\xd9\x7e", "FPuc\r\nA9l+"}, - {"\x14\xfb\x9c\x03\xd9", "FP\r\r\r\rucA9k="}, - {"\x14\xfb\x9c\x03", "\r\nFPucAw=\r=\n"}, + // RFC 3548 examples + {"\x14\xfb\x9c\x03\xd9\x7e", "FPuc\r\nA9l+"}, + {"\x14\xfb\x9c\x03\xd9", "FP\r\r\r\rucA9k="}, + {"\x14\xfb\x9c\x03", "\r\nFPucAw=\r=\n"}, - // RFC 4648 examples - {"", "\r"}, - {"f", "Zg\r\n=="}, - {"fo", "Zm\r\n8="}, - {"fooba", "Zm\r\n9vY\r\nmE="}, + // RFC 4648 examples + {"", "\r"}, + {"f", "Zg\r\n=="}, + {"fo", "Zm\r\n8="}, + {"fooba", "Zm\r\n9vY\r\nmE="}, - // Wikipedia examples - {"su", "c3U\r="}, - {"leasure.", "bGVhc3VyZ\nS4="}, - {"easure.", "ZW\r\nFzdXJlLg=\r=\r\n"}, - {"asure.", "YXN1cmUu"}, - {"sure.", "c3VyZ\r\nS4="}, + // Wikipedia examples + {"su", "c3U\r="}, + {"leasure.", "bGVhc3VyZ\nS4="}, + {"easure.", "ZW\r\nFzdXJlLg=\r=\r\n"}, + {"asure.", "YXN1cmUu"}, + {"sure.", "c3VyZ\r\nS4="}, - // Relatively long strings - { - "Twas brillig, and the slithy toves", - "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw\r\n==\r\n", - }, { - "\x9dyH\xd2Y\x9e^e\x9e\xb1\x9a\x9a\x12\xfe\x8a\x07\xc7\x07\xcc\xe8l\x81" + - "\xf2\xd9\xe3\x89\xb5\x98\xee\xbd\x8etQ`2>\\t:_\xd7w\xe6\xb5\x96\xc7\xff\x9c", - "nXlI0lmeXmWesZqaEv6KB8cHzOhsg\r\nfLZ44m1mO69jnRRYDI+XH\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nQ6X9d35rWWx/\r\n+c", - }, + // Relatively long strings + { + "Twas brillig, and the slithy toves", + "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw\r\n==\r\n", + }, { + "\x9dyH\xd2Y\x9e^e\x9e\xb1\x9a\x9a\x12\xfe\x8a\x07\xc7\x07\xcc\xe8l\x81" + + "\xf2\xd9\xe3\x89\xb5\x98\xee\xbd\x8etQ`2>\\t:_\xd7w\xe6\xb5\x96\xc7\xff\x9c", + "nXlI0lmeXmWesZqaEv6KB8cHzOhsg\r\nfLZ44m1mO69jnRRYDI+XH\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nQ6X9d35rWWx/\r\n+c", + }, } var json_pairs = []TestPair{ - // RFC 3548 examples - {"\x14\xfb\x9c\x03\xd9\x7e", `FPu\rcA9l+\n`}, - {"\x14\xfb\x9c\x03\xd9\x7e", `FPuc\u00419l+`}, - {"\x14\xfb\x9c\x03\xd9", `FPucA9k\u003d`}, - {"\x14\xfb\x9c\x03\xd9", `FPucA\u0039k\u003d`}, - {"\x14\xfb\x9c\x03", `FPucAw\u003d\u003d`}, + // RFC 3548 examples + {"\x14\xfb\x9c\x03\xd9\x7e", `FPu\rcA9l+\n`}, + {"\x14\xfb\x9c\x03\xd9\x7e", `FPuc\u00419l+`}, + {"\x14\xfb\x9c\x03\xd9", `FPucA9k\u003d`}, + {"\x14\xfb\x9c\x03\xd9", `FPucA\u0039k\u003d`}, + {"\x14\xfb\x9c\x03", `FPucAw\u003d\u003d`}, - // RFC 4648 examples - {"", ""}, - {"f", "Zg=="}, - {"fo", "Zm8="}, - {"foo", "Zm9v"}, - {"foob", "Zm9vYg=="}, - {"fooba", "Zm9vYmE="}, - {"foobar", "Zm9vYmFy"}, + // RFC 4648 examples + {"", ""}, + {"f", "Zg=="}, + {"fo", "Zm8="}, + {"foo", "Zm9v"}, + {"foob", "Zm9vYg=="}, + {"fooba", "Zm9vYmE="}, + {"foobar", "Zm9vYmFy"}, - // Wikipedia examples - {"sure.", "c3VyZS4="}, - {"sure", "c3VyZQ=="}, - {"sur", "c3Vy"}, - {"su", "c3U="}, - {"leasure.", "bGVhc3VyZS4="}, - {"easure.", "ZWFzdXJlLg=="}, - {"asure.", "YXN1cmUu"}, - {"sure.", "c3VyZS4="}, + // Wikipedia examples + {"sure.", "c3VyZS4="}, + {"sure", "c3VyZQ=="}, + {"sur", "c3Vy"}, + {"su", "c3U="}, + {"leasure.", "bGVhc3VyZS4="}, + {"easure.", "ZWFzdXJlLg=="}, + {"asure.", "YXN1cmUu"}, + {"sure.", "c3VyZS4="}, - // Relatively long strings - { - "Twas brillig, and the slithy toves", - "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", - }, { - "\x9dyH\xd2Y\x9e^e\x9e\xb1\x9a\x9a\x12\xfe\x8a\x07\xc7\x07\xcc\xe8l\x81" + - "\xf2\xd9\xe3\x89\xb5\x98\xee\xbd\x8etQ`2>\\t:_\xd7w\xe6\xb5\x96\xc7\xff\x9c", - `nXlI0lmeXmWesZqaEv6KB8cHzOhsgfLZ44m1mO\u0036\u0039jnRRYDI+XHQ6X9d35rWWx\/+c`, - }, + // Relatively long strings + { + "Twas brillig, and the slithy toves", + "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", + }, { + "\x9dyH\xd2Y\x9e^e\x9e\xb1\x9a\x9a\x12\xfe\x8a\x07\xc7\x07\xcc\xe8l\x81" + + "\xf2\xd9\xe3\x89\xb5\x98\xee\xbd\x8etQ`2>\\t:_\xd7w\xe6\xb5\x96\xc7\xff\x9c", + `nXlI0lmeXmWesZqaEv6KB8cHzOhsgfLZ44m1mO\u0036\u0039jnRRYDI+XHQ6X9d35rWWx\/+c`, + }, } // Do nothing to a reference base64 string (leave in standard format) func stdRef(ref string) string { - return ref + return ref } // Convert a reference string to URL-encoding func urlRef(ref string) string { - ref = strings.ReplaceAll(ref, "+", "-") - ref = strings.ReplaceAll(ref, "/", "_") - return ref + ref = strings.ReplaceAll(ref, "+", "-") + ref = strings.ReplaceAll(ref, "/", "_") + return ref } // Convert a reference string to raw, unpadded format func rawRef(ref string) string { - return strings.ReplaceAll(ref, "=", "") + return strings.ReplaceAll(ref, "=", "") } // Both URL and unpadding conversions func rawURLRef(ref string) string { - return rawRef(urlRef(ref)) + return rawRef(urlRef(ref)) } var encodingTests = []EncodingTest{ - {StdEncoding, stdRef}, - {URLEncoding, urlRef}, - {RawStdEncoding, rawRef}, - {RawURLEncoding, rawURLRef}, + {StdEncoding, stdRef}, + {URLEncoding, urlRef}, + {RawStdEncoding, rawRef}, + {RawURLEncoding, rawURLRef}, } func testEqual(t *testing.T, msg string, args ...interface{}) bool { - t.Helper() - if args[len(args) - 2] != args[len(args) - 1] { - t.Errorf(msg, args...) - return false - } - return true + t.Helper() + if args[len(args)-2] != args[len(args)-1] { + t.Errorf(msg, args...) + return false + } + return true } func TestEncoder(t *testing.T) { - for _, p := range pairs { - for _, tt := range encodingTests { - got := tt.enc.EncodeToString([]byte(p.decoded)) - testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, tt.conv(p.encoded)) - } - } + for _, p := range pairs { + for _, tt := range encodingTests { + got := tt.enc.EncodeToString([]byte(p.decoded)) + testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, tt.conv(p.encoded)) + } + } } func TestDecoder(t *testing.T) { - for _, p := range pairs { - for _, tt := range encodingTests { - encoded := tt.conv(p.encoded) - dbuf := make([]byte, tt.enc.DecodedLen(len(encoded))) - count, err := tt.enc.Decode(dbuf, []byte(encoded)) - testEqual(t, "Decode(%q) = error %v, want %v", encoded, err, error(nil)) - testEqual(t, "Decode(%q) = length %v, want %v", encoded, count, len(p.decoded)) - testEqual(t, "Decode(%q) = %q, want %q", encoded, string(dbuf[0:count]), p.decoded) + for _, p := range pairs { + for _, tt := range encodingTests { + encoded := tt.conv(p.encoded) + dbuf := make([]byte, tt.enc.DecodedLen(len(encoded))) + count, err := tt.enc.Decode(dbuf, []byte(encoded)) + testEqual(t, "Decode(%q) = error %v, want %v", encoded, err, error(nil)) + testEqual(t, "Decode(%q) = length %v, want %v", encoded, count, len(p.decoded)) + testEqual(t, "Decode(%q) = %q, want %q", encoded, string(dbuf[0:count]), p.decoded) - dbuf, err = tt.enc.DecodeString(encoded) - testEqual(t, "DecodeString(%q) = error %v, want %v", encoded, err, error(nil)) - testEqual(t, "DecodeString(%q) = %q, want %q", encoded, string(dbuf), p.decoded) - } - } + dbuf, err = tt.enc.DecodeString(encoded) + testEqual(t, "DecodeString(%q) = error %v, want %v", encoded, err, error(nil)) + testEqual(t, "DecodeString(%q) = %q, want %q", encoded, string(dbuf), p.decoded) + } + } } - func TestDecoderCRLF(t *testing.T) { - for _, p := range crlf_pairs { - for _, tt := range encodingTests { - encoded := tt.conv(p.encoded) - dbuf := make([]byte, tt.enc.DecodedLen(len(encoded))) - count, err := tt.enc.Decode(dbuf, []byte(encoded)) - testEqual(t, "Decode(%q) = error %v, want %v", encoded, err, error(nil)) - testEqual(t, "Decode(%q) = length %v, want %v", encoded, count, len(p.decoded)) - testEqual(t, "Decode(%q) = %q, want %q", encoded, string(dbuf[0:count]), p.decoded) + for _, p := range crlf_pairs { + for _, tt := range encodingTests { + encoded := tt.conv(p.encoded) + dbuf := make([]byte, tt.enc.DecodedLen(len(encoded))) + count, err := tt.enc.Decode(dbuf, []byte(encoded)) + testEqual(t, "Decode(%q) = error %v, want %v", encoded, err, error(nil)) + testEqual(t, "Decode(%q) = length %v, want %v", encoded, count, len(p.decoded)) + testEqual(t, "Decode(%q) = %q, want %q", encoded, string(dbuf[0:count]), p.decoded) - dbuf, err = tt.enc.DecodeString(encoded) - testEqual(t, "DecodeString(%q) = error %v, want %v", encoded, err, error(nil)) - testEqual(t, "DecodeString(%q) = %q, want %q", encoded, string(dbuf), p.decoded) - } - } + dbuf, err = tt.enc.DecodeString(encoded) + testEqual(t, "DecodeString(%q) = error %v, want %v", encoded, err, error(nil)) + testEqual(t, "DecodeString(%q) = %q, want %q", encoded, string(dbuf), p.decoded) + } + } } func TestDecoderJSON(t *testing.T) { - for _, p := range json_pairs { - encoded := p.encoded - dbuf := make([]byte, JSONStdEncoding.DecodedLen(len(encoded))) - count, err := JSONStdEncoding.Decode(dbuf, []byte(encoded)) - testEqual(t, "Decode(%q) = error %v, want %v", encoded, err, error(nil)) - testEqual(t, "Decode(%q) = length %v, want %v", encoded, count, len(p.decoded)) - testEqual(t, "Decode(%q) = %q, want %q", encoded, string(dbuf[0:count]), p.decoded) + for _, p := range json_pairs { + encoded := p.encoded + dbuf := make([]byte, JSONStdEncoding.DecodedLen(len(encoded))) + count, err := JSONStdEncoding.Decode(dbuf, []byte(encoded)) + testEqual(t, "Decode(%q) = error %v, want %v", encoded, err, error(nil)) + testEqual(t, "Decode(%q) = length %v, want %v", encoded, count, len(p.decoded)) + testEqual(t, "Decode(%q) = %q, want %q", encoded, string(dbuf[0:count]), p.decoded) - dbuf, err = JSONStdEncoding.DecodeString(encoded) - testEqual(t, "DecodeString(%q) = error %v, want %v", encoded, err, error(nil)) - testEqual(t, "DecodeString(%q) = %q, want %q", encoded, string(dbuf), p.decoded) - } + dbuf, err = JSONStdEncoding.DecodeString(encoded) + testEqual(t, "DecodeString(%q) = error %v, want %v", encoded, err, error(nil)) + testEqual(t, "DecodeString(%q) = %q, want %q", encoded, string(dbuf), p.decoded) + } } func TestDecoderError(t *testing.T) { - _, err := StdEncoding.DecodeString("!aGVsbG8sIHdvcmxk") - if err != base64.CorruptInputError(0) { - panic(err) - } - _, err = StdEncoding.DecodeString("aGVsbG8!sIHdvcmxk") - if err != base64.CorruptInputError(7) { - panic(err) - } - _, err = StdEncoding.DecodeString("123456") - if err != base64.CorruptInputError(6) { - panic(err) - } - _, err = StdEncoding.DecodeString("1234;6") - if err != base64.CorruptInputError(4) { - panic(err) - } - _, err = StdEncoding.DecodeString("F\xaa\xaa\xaa\xaaDDDDDDDDDDDDD//z") - if err != base64.CorruptInputError(1) { - panic(err) - } + _, err := StdEncoding.DecodeString("!aGVsbG8sIHdvcmxk") + if err != base64.CorruptInputError(0) { + panic(err) + } + _, err = StdEncoding.DecodeString("aGVsbG8!sIHdvcmxk") + if err != base64.CorruptInputError(7) { + panic(err) + } + _, err = StdEncoding.DecodeString("123456") + if err != base64.CorruptInputError(6) { + panic(err) + } + _, err = StdEncoding.DecodeString("1234;6") + if err != base64.CorruptInputError(4) { + panic(err) + } + _, err = StdEncoding.DecodeString("F\xaa\xaa\xaa\xaaDDDDDDDDDDDDD//z") + if err != base64.CorruptInputError(1) { + panic(err) + } } diff --git a/bench/bench_test.go b/bench/bench_test.go index 9db80ec..d5a4ce7 100644 --- a/bench/bench_test.go +++ b/bench/bench_test.go @@ -1,101 +1,100 @@ package bench import ( - "testing" + "crypto/rand" "encoding/base64" - `crypto/rand` - `io` + "io" + "testing" . "github.com/cloudwego/base64x" cris "github.com/cristalhq/base64" ) func benchmarkStdlibDecoder(b *testing.B, v string) { - src := []byte(v) - dst := make([]byte, base64.StdEncoding.DecodedLen(len(v))) - b.SetBytes(int64(len(v))) - b.ResetTimer() - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - _, _ = base64.StdEncoding.Decode(dst, src) - } - }) + src := []byte(v) + dst := make([]byte, base64.StdEncoding.DecodedLen(len(v))) + b.SetBytes(int64(len(v))) + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, _ = base64.StdEncoding.Decode(dst, src) + } + }) } func benchmarkBase64xDecoder(b *testing.B, v string) { - src := []byte(v) - dst := make([]byte, StdEncoding.DecodedLen(len(v))) - b.SetBytes(int64(len(v))) - b.ResetTimer() - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - _, _ = StdEncoding.Decode(dst, src) - } - }) + src := []byte(v) + dst := make([]byte, StdEncoding.DecodedLen(len(v))) + b.SetBytes(int64(len(v))) + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, _ = StdEncoding.Decode(dst, src) + } + }) } - func benchmarkStdlibWithSize(b *testing.B, nb int) { - buf := make([]byte, nb) - dst := make([]byte, base64.StdEncoding.EncodedLen(nb)) - _, _ = io.ReadFull(rand.Reader, buf) - b.SetBytes(int64(nb)) - b.ResetTimer() - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - base64.StdEncoding.Encode(dst, buf) - } - }) + buf := make([]byte, nb) + dst := make([]byte, base64.StdEncoding.EncodedLen(nb)) + _, _ = io.ReadFull(rand.Reader, buf) + b.SetBytes(int64(nb)) + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + base64.StdEncoding.Encode(dst, buf) + } + }) } func benchmarkBase64xWithSize(b *testing.B, nb int) { - buf := make([]byte, nb) - dst := make([]byte, StdEncoding.EncodedLen(nb)) - _, _ = io.ReadFull(rand.Reader, buf) - b.SetBytes(int64(nb)) - b.ResetTimer() - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - StdEncoding.Encode(dst, buf) - } - }) + buf := make([]byte, nb) + dst := make([]byte, StdEncoding.EncodedLen(nb)) + _, _ = io.ReadFull(rand.Reader, buf) + b.SetBytes(int64(nb)) + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + StdEncoding.Encode(dst, buf) + } + }) } - func benchmarkCrisWithSize(b *testing.B, nb int) { - buf := make([]byte, nb) - dst := make([]byte, cris.StdEncoding.EncodedLen(nb)) - _, _ = io.ReadFull(rand.Reader, buf) - b.SetBytes(int64(nb)) - b.ResetTimer() - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - cris.StdEncoding.Encode(dst, buf) - } - }) + buf := make([]byte, nb) + dst := make([]byte, cris.StdEncoding.EncodedLen(nb)) + _, _ = io.ReadFull(rand.Reader, buf) + b.SetBytes(int64(nb)) + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + cris.StdEncoding.Encode(dst, buf) + } + }) } -func BenchmarkEncoderStdlib_16B (b *testing.B) { benchmarkStdlibWithSize(b, 16) } -func BenchmarkEncoderStdlib_56B (b *testing.B) { benchmarkStdlibWithSize(b, 56) } -func BenchmarkEncoderStdlib_128B (b *testing.B) { benchmarkStdlibWithSize(b, 128) } -func BenchmarkEncoderStdlib_4kB (b *testing.B) { benchmarkStdlibWithSize(b, 4 * 1024) } -func BenchmarkEncoderStdlib_256kB (b *testing.B) { benchmarkStdlibWithSize(b, 256 * 1024) } -func BenchmarkEncoderStdlib_1MB (b *testing.B) { benchmarkStdlibWithSize(b, 1024 * 1024) } +func BenchmarkEncoderStdlib_16B(b *testing.B) { benchmarkStdlibWithSize(b, 16) } +func BenchmarkEncoderStdlib_56B(b *testing.B) { benchmarkStdlibWithSize(b, 56) } +func BenchmarkEncoderStdlib_128B(b *testing.B) { benchmarkStdlibWithSize(b, 128) } +func BenchmarkEncoderStdlib_4kB(b *testing.B) { benchmarkStdlibWithSize(b, 4*1024) } +func BenchmarkEncoderStdlib_256kB(b *testing.B) { benchmarkStdlibWithSize(b, 256*1024) } +func BenchmarkEncoderStdlib_1MB(b *testing.B) { benchmarkStdlibWithSize(b, 1024*1024) } -func BenchmarkEncoderBase64x_16B (b *testing.B) { benchmarkBase64xWithSize(b, 16) } -func BenchmarkEncoderBase64x_56B (b *testing.B) { benchmarkBase64xWithSize(b, 56) } -func BenchmarkEncoderBase64x_128B (b *testing.B) { benchmarkBase64xWithSize(b, 128) } -func BenchmarkEncoderBase64x_4kB (b *testing.B) { benchmarkBase64xWithSize(b, 4 * 1024) } -func BenchmarkEncoderBase64x_256kB (b *testing.B) { benchmarkBase64xWithSize(b, 256 * 1024) } -func BenchmarkEncoderBase64x_1MB (b *testing.B) { benchmarkBase64xWithSize(b, 1024 * 1024) } +func BenchmarkEncoderBase64x_16B(b *testing.B) { benchmarkBase64xWithSize(b, 16) } +func BenchmarkEncoderBase64x_56B(b *testing.B) { benchmarkBase64xWithSize(b, 56) } +func BenchmarkEncoderBase64x_128B(b *testing.B) { benchmarkBase64xWithSize(b, 128) } +func BenchmarkEncoderBase64x_4kB(b *testing.B) { benchmarkBase64xWithSize(b, 4*1024) } +func BenchmarkEncoderBase64x_256kB(b *testing.B) { benchmarkBase64xWithSize(b, 256*1024) } +func BenchmarkEncoderBase64x_1MB(b *testing.B) { benchmarkBase64xWithSize(b, 1024*1024) } -func BenchmarkEncoderCris_16B (b *testing.B) { benchmarkCrisWithSize(b, 16) } -func BenchmarkEncoderCris_56B (b *testing.B) { benchmarkCrisWithSize(b, 56) } -func BenchmarkEncoderCris_128B (b *testing.B) { benchmarkCrisWithSize(b, 128) } -func BenchmarkEncoderCris_4kB (b *testing.B) { benchmarkCrisWithSize(b, 4 * 1024) } -func BenchmarkEncoderCris_256kB (b *testing.B) { benchmarkCrisWithSize(b, 256 * 1024) } -func BenchmarkEncoderCris_1MB (b *testing.B) { benchmarkCrisWithSize(b, 1024 * 1024) } +func BenchmarkEncoderCris_16B(b *testing.B) { benchmarkCrisWithSize(b, 16) } +func BenchmarkEncoderCris_56B(b *testing.B) { benchmarkCrisWithSize(b, 56) } +func BenchmarkEncoderCris_128B(b *testing.B) { benchmarkCrisWithSize(b, 128) } +func BenchmarkEncoderCris_4kB(b *testing.B) { benchmarkCrisWithSize(b, 4*1024) } +func BenchmarkEncoderCris_256kB(b *testing.B) { benchmarkCrisWithSize(b, 256*1024) } +func BenchmarkEncoderCris_1MB(b *testing.B) { benchmarkCrisWithSize(b, 1024*1024) } var data = `////////////////////////////////////////////////////////////////` -func BenchmarkDecoderStdLib (b *testing.B) { benchmarkStdlibDecoder(b, data) } -func BenchmarkDecoderBase64x (b *testing.B) { benchmarkBase64xDecoder(b, data) } + +func BenchmarkDecoderStdLib(b *testing.B) { benchmarkStdlibDecoder(b, data) } +func BenchmarkDecoderBase64x(b *testing.B) { benchmarkBase64xDecoder(b, data) } diff --git a/faststr.go b/faststr.go index 083d864..ac5b493 100644 --- a/faststr.go +++ b/faststr.go @@ -17,25 +17,25 @@ package base64x import ( - `reflect` - `unsafe` + "reflect" + "unsafe" ) func mem2str(v []byte) (s string) { - (*reflect.StringHeader)(unsafe.Pointer(&s)).Len = (*reflect.SliceHeader)(unsafe.Pointer(&v)).Len - (*reflect.StringHeader)(unsafe.Pointer(&s)).Data = (*reflect.SliceHeader)(unsafe.Pointer(&v)).Data - return + (*reflect.StringHeader)(unsafe.Pointer(&s)).Len = (*reflect.SliceHeader)(unsafe.Pointer(&v)).Len + (*reflect.StringHeader)(unsafe.Pointer(&s)).Data = (*reflect.SliceHeader)(unsafe.Pointer(&v)).Data + return } func str2mem(s string) (v []byte) { - (*reflect.SliceHeader)(unsafe.Pointer(&v)).Cap = (*reflect.StringHeader)(unsafe.Pointer(&s)).Len - (*reflect.SliceHeader)(unsafe.Pointer(&v)).Len = (*reflect.StringHeader)(unsafe.Pointer(&s)).Len - (*reflect.SliceHeader)(unsafe.Pointer(&v)).Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data - return + (*reflect.SliceHeader)(unsafe.Pointer(&v)).Cap = (*reflect.StringHeader)(unsafe.Pointer(&s)).Len + (*reflect.SliceHeader)(unsafe.Pointer(&v)).Len = (*reflect.StringHeader)(unsafe.Pointer(&s)).Len + (*reflect.SliceHeader)(unsafe.Pointer(&v)).Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data + return } func mem2addr(v []byte) unsafe.Pointer { - return *(*unsafe.Pointer)(unsafe.Pointer(&v)) + return *(*unsafe.Pointer)(unsafe.Pointer(&v)) } // NoEscape hides a pointer from escape analysis. NoEscape is @@ -43,9 +43,10 @@ func mem2addr(v []byte) unsafe.Pointer { // output depends on the input. NoEscape is inlined and currently // compiles down to zero instructions. // USE CAREFULLY! +// //go:nosplit //goland:noinspection GoVetUnsafePointer func noEscape(p unsafe.Pointer) unsafe.Pointer { - x := uintptr(p) - return unsafe.Pointer(x ^ 0) + x := uintptr(p) + return unsafe.Pointer(x ^ 0) } diff --git a/fuzz_test.go b/fuzz_test.go index cef15ea..ed1ad86 100644 --- a/fuzz_test.go +++ b/fuzz_test.go @@ -1,3 +1,4 @@ +//go:build go1.18 // +build go1.18 /* @@ -19,72 +20,72 @@ package base64x import ( - `encoding/base64` - `encoding/json` - `testing` - `github.com/stretchr/testify/require` - `github.com/davecgh/go-spew/spew` + "encoding/base64" + "encoding/json" + "github.com/davecgh/go-spew/spew" + "github.com/stretchr/testify/require" + "testing" ) func FuzzMain(f *testing.F) { - var corpus = []string { - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", - "=", - `\/`, - "\r\n", - `\r\n`, - `\u0036`, `\u0039`, `\u003d`, - `"\u0036"`, `"\u003d\u003d"`, - } - for _, c := range(corpus) { - f.Add([]byte(c)) - } - f.Fuzz(fuzzBase64Impl) + var corpus = []string{ + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", + "=", + `\/`, + "\r\n", + `\r\n`, + `\u0036`, `\u0039`, `\u003d`, + `"\u0036"`, `"\u003d\u003d"`, + } + for _, c := range corpus { + f.Add([]byte(c)) + } + f.Fuzz(fuzzBase64Impl) } func fuzzBase64Impl(t *testing.T, data []byte) { - fuzzBase64CommonImpl(t, data) - fuzzBase64JsonImpl(t, data) + fuzzBase64CommonImpl(t, data) + fuzzBase64JsonImpl(t, data) } type EncodeFuzzPairs struct { - ours Encoding - stdlib *base64.Encoding + ours Encoding + stdlib *base64.Encoding } -var fuzzPairs = []EncodeFuzzPairs { - {StdEncoding, base64.StdEncoding}, - {URLEncoding, base64.URLEncoding}, - {RawStdEncoding, base64.RawStdEncoding}, - {RawURLEncoding, base64.RawURLEncoding}, +var fuzzPairs = []EncodeFuzzPairs{ + {StdEncoding, base64.StdEncoding}, + {URLEncoding, base64.URLEncoding}, + {RawStdEncoding, base64.RawStdEncoding}, + {RawURLEncoding, base64.RawURLEncoding}, } func fuzzBase64CommonImpl(t *testing.T, data []byte) { - for _, fp := range(fuzzPairs) { - // fuzz encode - encoded0 := fp.ours.EncodeToString(data) - encoded1 := fp.stdlib.EncodeToString(data) - require.Equalf(t, encoded0, encoded1, "encode from %s", spew.Sdump(data)) - // fuzz decode - encoded := encoded1 - dbuf0 := make([]byte, fp.ours.DecodedLen(len(encoded))) - dbuf1 := make([]byte, fp.stdlib.DecodedLen(len(encoded))) - count0, err0 := fp.ours.Decode(dbuf0, []byte(encoded)) - count1, err1 := fp.stdlib.Decode(dbuf1, []byte(encoded)) - require.Equalf(t, dbuf0, dbuf1, "decode from %s", spew.Sdump(encoded)) - require.Equalf(t, err0 != nil, err1 != nil, "decode from %s", spew.Sdump(encoded)) - require.Equalf(t, count0, count1, "decode from %s", spew.Sdump(encoded)) - } + for _, fp := range fuzzPairs { + // fuzz encode + encoded0 := fp.ours.EncodeToString(data) + encoded1 := fp.stdlib.EncodeToString(data) + require.Equalf(t, encoded0, encoded1, "encode from %s", spew.Sdump(data)) + // fuzz decode + encoded := encoded1 + dbuf0 := make([]byte, fp.ours.DecodedLen(len(encoded))) + dbuf1 := make([]byte, fp.stdlib.DecodedLen(len(encoded))) + count0, err0 := fp.ours.Decode(dbuf0, []byte(encoded)) + count1, err1 := fp.stdlib.Decode(dbuf1, []byte(encoded)) + require.Equalf(t, dbuf0, dbuf1, "decode from %s", spew.Sdump(encoded)) + require.Equalf(t, err0 != nil, err1 != nil, "decode from %s", spew.Sdump(encoded)) + require.Equalf(t, count0, count1, "decode from %s", spew.Sdump(encoded)) + } } func fuzzBase64JsonImpl(t *testing.T, data []byte) { - // fuzz valid JSON-encoded base64 - jencoded, _ := json.Marshal(data) - var dbuf0, dbuf1 []byte - dbuf0 = make([]byte, JSONStdEncoding.DecodedLen(len(jencoded))) - count0, err0 := JSONStdEncoding.Decode(dbuf0, jencoded[1:len(jencoded) - 1]) - err1 := json.Unmarshal(jencoded, &dbuf1) - require.Equalf(t, dbuf0[:count0], dbuf1, "decode json from %s", spew.Sdump(jencoded)) - require.Equalf(t, err0 != nil, err1 != nil, "decode json from %s", spew.Sdump(jencoded)) + // fuzz valid JSON-encoded base64 + jencoded, _ := json.Marshal(data) + var dbuf0, dbuf1 []byte + dbuf0 = make([]byte, JSONStdEncoding.DecodedLen(len(jencoded))) + count0, err0 := JSONStdEncoding.Decode(dbuf0, jencoded[1:len(jencoded)-1]) + err1 := json.Unmarshal(jencoded, &dbuf1) + require.Equalf(t, dbuf0[:count0], dbuf1, "decode json from %s", spew.Sdump(jencoded)) + require.Equalf(t, err0 != nil, err1 != nil, "decode json from %s", spew.Sdump(jencoded)) } diff --git a/internal/native/avx2/b64decode.go b/internal/native/avx2/b64decode.go index e4f5de4..80445c8 100644 --- a/internal/native/avx2/b64decode.go +++ b/internal/native/avx2/b64decode.go @@ -19,9 +19,9 @@ package avx2 import ( - `unsafe` + "unsafe" - `github.com/cloudwego/base64x/internal/rt` + "github.com/cloudwego/base64x/internal/rt" ) var F_b64decode func(out unsafe.Pointer, src unsafe.Pointer, len int, mod int) (ret int) @@ -30,6 +30,5 @@ var S_b64decode uintptr //go:nosplit func B64decode(out *[]byte, src unsafe.Pointer, len int, mode int) (ret int) { - return F_b64decode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), len, mode) + return F_b64decode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), len, mode) } - diff --git a/internal/native/avx2/b64decode_subr.go b/internal/native/avx2/b64decode_subr.go index 373b8ac..779275c 100644 --- a/internal/native/avx2/b64decode_subr.go +++ b/internal/native/avx2/b64decode_subr.go @@ -1,45 +1,47 @@ +//go:build !noasm || !appengine // +build !noasm !appengine + // Code generated by asm2asm, DO NOT EDIT. package avx2 import ( - `github.com/bytedance/sonic/loader` + "github.com/bytedance/sonic/loader" ) const ( - _entry__b64decode = 464 + _entry__b64decode = 464 ) const ( - _stack__b64decode = 136 + _stack__b64decode = 136 ) const ( - _size__b64decode = 13488 + _size__b64decode = 13488 ) var ( - _pcsp__b64decode = [][2]uint32{ - {0x1, 0}, - {0x6, 8}, - {0x8, 16}, - {0xa, 24}, - {0xc, 32}, - {0xd, 40}, - {0x11, 48}, - {0x349e, 136}, - {0x349f, 48}, - {0x34a1, 40}, - {0x34a3, 32}, - {0x34a5, 24}, - {0x34a7, 16}, - {0x34a8, 8}, - {0x34b0, 0}, - } + _pcsp__b64decode = [][2]uint32{ + {0x1, 0}, + {0x6, 8}, + {0x8, 16}, + {0xa, 24}, + {0xc, 32}, + {0xd, 40}, + {0x11, 48}, + {0x349e, 136}, + {0x349f, 48}, + {0x34a1, 40}, + {0x34a3, 32}, + {0x34a5, 24}, + {0x34a7, 16}, + {0x34a8, 8}, + {0x34b0, 0}, + } ) var _cfunc_b64decode = []loader.CFunc{ - {"_b64decode_entry", 0, _entry__b64decode, 0, nil}, - {"_b64decode", _entry__b64decode, _size__b64decode, _stack__b64decode, _pcsp__b64decode}, + {"_b64decode_entry", 0, _entry__b64decode, 0, nil}, + {"_b64decode", _entry__b64decode, _size__b64decode, _stack__b64decode, _pcsp__b64decode}, } diff --git a/internal/native/avx2/b64decode_text_amd64.go b/internal/native/avx2/b64decode_text_amd64.go index 4513288..862916f 100644 --- a/internal/native/avx2/b64decode_text_amd64.go +++ b/internal/native/avx2/b64decode_text_amd64.go @@ -1,4 +1,6 @@ +//go:build amd64 // +build amd64 + // Code generated by asm2asm, DO NOT EDIT. package avx2 @@ -291,13 +293,13 @@ var _text_b64decode = []byte{ 0x06, //0x000001cf .byte 6 //0x000001d0 .p2align 4, 0x90 //0x000001d0 _b64decode - 0x55, //0x000001d0 pushq %rbp + 0x55, //0x000001d0 pushq %rbp 0x48, 0x89, 0xe5, //0x000001d1 movq %rsp, %rbp 0x41, 0x57, //0x000001d4 pushq %r15 0x41, 0x56, //0x000001d6 pushq %r14 0x41, 0x55, //0x000001d8 pushq %r13 0x41, 0x54, //0x000001da pushq %r12 - 0x53, //0x000001dc pushq %rbx + 0x53, //0x000001dc pushq %rbx 0x48, 0x83, 0xec, 0x58, //0x000001dd subq $88, %rsp 0x48, 0x85, 0xd2, //0x000001e1 testq %rdx, %rdx 0x0f, 0x84, 0x85, 0x00, 0x00, 0x00, //0x000001e4 je LBB0_6 @@ -3933,14 +3935,14 @@ var _text_b64decode = []byte{ 0x48, 0x29, 0xc8, //0x00003667 subq %rcx, %rax //0x0000366a LBB0_865 0x48, 0x83, 0xc4, 0x58, //0x0000366a addq $88, %rsp - 0x5b, //0x0000366e popq %rbx + 0x5b, //0x0000366e popq %rbx 0x41, 0x5c, //0x0000366f popq %r12 0x41, 0x5d, //0x00003671 popq %r13 0x41, 0x5e, //0x00003673 popq %r14 0x41, 0x5f, //0x00003675 popq %r15 - 0x5d, //0x00003677 popq %rbp - 0xc5, 0xf8, 0x77, //0x00003678 vzeroupper - 0xc3, //0x0000367b retq + 0x5d, //0x00003677 popq %rbp + 0xc5, 0xf8, 0x77, //0x00003678 vzeroupper + 0xc3, //0x0000367b retq 0x00, 0x00, 0x00, 0x00, //0x0000367c .p2align 4, 0x00 //0x00003680 _VecDecodeCharsetStd 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x00003680 QUAD $0xffffffffffffffff; QUAD $0xffffffffffffffff // .ascii 16, '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' @@ -3978,4 +3980,3 @@ var _text_b64decode = []byte{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x00003860 QUAD $0xffffffffffffffff; QUAD $0xffffffffffffffff // .ascii 16, '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x00003870 QUAD $0xffffffffffffffff; QUAD $0xffffffffffffffff // .ascii 16, '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' } - diff --git a/internal/native/avx2/b64encode.go b/internal/native/avx2/b64encode.go index e89c1bb..44821bd 100644 --- a/internal/native/avx2/b64encode.go +++ b/internal/native/avx2/b64encode.go @@ -19,9 +19,9 @@ package avx2 import ( - `unsafe` + "unsafe" - `github.com/cloudwego/base64x/internal/rt` + "github.com/cloudwego/base64x/internal/rt" ) var F_b64encode func(out unsafe.Pointer, src unsafe.Pointer, mod int) @@ -30,5 +30,5 @@ var S_b64encode uintptr //go:nosplit func B64encode(out *[]byte, src *[]byte, mode int) { - F_b64encode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), mode) + F_b64encode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), mode) } diff --git a/internal/native/avx2/b64encode_subr.go b/internal/native/avx2/b64encode_subr.go index 877737d..b0ab590 100644 --- a/internal/native/avx2/b64encode_subr.go +++ b/internal/native/avx2/b64encode_subr.go @@ -1,41 +1,43 @@ +//go:build !noasm || !appengine // +build !noasm !appengine + // Code generated by asm2asm, DO NOT EDIT. package avx2 import ( - `github.com/bytedance/sonic/loader` + "github.com/bytedance/sonic/loader" ) const ( - _entry__b64encode = 288 + _entry__b64encode = 288 ) const ( - _stack__b64encode = 40 + _stack__b64encode = 40 ) const ( - _size__b64encode = 832 + _size__b64encode = 832 ) var ( - _pcsp__b64encode = [][2]uint32{ - {0x1, 0}, - {0x6, 8}, - {0x8, 16}, - {0xa, 24}, - {0xb, 32}, - {0x32a, 40}, - {0x32c, 32}, - {0x32e, 24}, - {0x330, 16}, - {0x331, 8}, - {0x340, 0}, - } + _pcsp__b64encode = [][2]uint32{ + {0x1, 0}, + {0x6, 8}, + {0x8, 16}, + {0xa, 24}, + {0xb, 32}, + {0x32a, 40}, + {0x32c, 32}, + {0x32e, 24}, + {0x330, 16}, + {0x331, 8}, + {0x340, 0}, + } ) var _cfunc_b64encode = []loader.CFunc{ - {"_b64encode_entry", 0, _entry__b64encode, 0, nil}, - {"_b64encode", _entry__b64encode, _size__b64encode, _stack__b64encode, _pcsp__b64encode}, + {"_b64encode_entry", 0, _entry__b64encode, 0, nil}, + {"_b64encode", _entry__b64encode, _size__b64encode, _stack__b64encode, _pcsp__b64encode}, } diff --git a/internal/native/avx2/b64encode_text_amd64.go b/internal/native/avx2/b64encode_text_amd64.go index 7554bbe..ab7b494 100644 --- a/internal/native/avx2/b64encode_text_amd64.go +++ b/internal/native/avx2/b64encode_text_amd64.go @@ -1,4 +1,6 @@ +//go:build amd64 // +build amd64 + // Code generated by asm2asm, DO NOT EDIT. package avx2 @@ -166,12 +168,12 @@ var _text_b64encode = []byte{ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, //0x00000110 QUAD $0x0d0d0d0d0d0d0d0d; QUAD $0x0d0d0d0d0d0d0d0d // .space 16, '\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r' //0x00000120 .p2align 4, 0x90 //0x00000120 _b64encode - 0x55, //0x00000120 pushq %rbp + 0x55, //0x00000120 pushq %rbp 0x48, 0x89, 0xe5, //0x00000121 movq %rsp, %rbp 0x41, 0x57, //0x00000124 pushq %r15 0x41, 0x56, //0x00000126 pushq %r14 0x41, 0x54, //0x00000128 pushq %r12 - 0x53, //0x0000012a pushq %rbx + 0x53, //0x0000012a pushq %rbx 0x4c, 0x8b, 0x4e, 0x08, //0x0000012b movq $8(%rsi), %r9 0x4d, 0x85, 0xc9, //0x0000012f testq %r9, %r9 0x0f, 0x84, 0x11, 0x03, 0x00, 0x00, //0x00000132 je LBB0_26 @@ -364,13 +366,13 @@ var _text_b64encode = []byte{ 0x4d, 0x29, 0xc6, //0x00000442 subq %r8, %r14 0x4c, 0x01, 0x77, 0x08, //0x00000445 addq %r14, $8(%rdi) //0x00000449 LBB0_26 - 0x5b, //0x00000449 popq %rbx + 0x5b, //0x00000449 popq %rbx 0x41, 0x5c, //0x0000044a popq %r12 0x41, 0x5e, //0x0000044c popq %r14 0x41, 0x5f, //0x0000044e popq %r15 - 0x5d, //0x00000450 popq %rbp - 0xc5, 0xf8, 0x77, //0x00000451 vzeroupper - 0xc3, //0x00000454 retq + 0x5d, //0x00000450 popq %rbp + 0xc5, 0xf8, 0x77, //0x00000451 vzeroupper + 0xc3, //0x00000454 retq 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000455 .p2align 4, 0x00 //0x00000460 _TabEncodeCharsetStd 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, //0x00000460 QUAD $0x4847464544434241; QUAD $0x504f4e4d4c4b4a49 // .ascii 16, 'ABCDEFGHIJKLMNOP' @@ -384,4 +386,3 @@ var _text_b64encode = []byte{ 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, //0x000004c0 QUAD $0x6e6d6c6b6a696867; QUAD $0x767574737271706f // .ascii 16, 'ghijklmnopqrstuv' 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2d, 0x5f, //0x000004d0 QUAD $0x333231307a797877; QUAD $0x5f2d393837363534 // .ascii 16, 'wxyz0123456789-_' } - diff --git a/internal/native/avx2/native_export.go b/internal/native/avx2/native_export.go index 51f68fe..b51de8a 100644 --- a/internal/native/avx2/native_export.go +++ b/internal/native/avx2/native_export.go @@ -1,4 +1,3 @@ - // Code generated by Bash, DO NOT EDIT. /* @@ -20,10 +19,10 @@ package avx2 import ( - `github.com/bytedance/sonic/loader` + "github.com/bytedance/sonic/loader" ) func Use() { - loader.WrapGoC(_text_b64encode, _cfunc_b64encode, []loader.GoC{{"_b64encode", &S_b64encode, &F_b64encode}}, "avx2", "avx2/b64encode.c") - loader.WrapGoC(_text_b64decode, _cfunc_b64decode, []loader.GoC{{"_b64decode", &S_b64decode, &F_b64decode}}, "avx2", "avx2/b64decode.c") -} \ No newline at end of file + loader.WrapGoC(_text_b64encode, _cfunc_b64encode, []loader.GoC{{"_b64encode", &S_b64encode, &F_b64encode}}, "avx2", "avx2/b64encode.c") + loader.WrapGoC(_text_b64decode, _cfunc_b64decode, []loader.GoC{{"_b64decode", &S_b64decode, &F_b64decode}}, "avx2", "avx2/b64decode.c") +} diff --git a/internal/native/dispatch.go b/internal/native/dispatch.go index c4f489b..2f312a3 100644 --- a/internal/native/dispatch.go +++ b/internal/native/dispatch.go @@ -2,16 +2,16 @@ package native import ( "unsafe" - - `github.com/klauspost/cpuid/v2` - "github.com/cloudwego/base64x/internal/rt" + "github.com/cloudwego/base64x/internal/native/avx2" "github.com/cloudwego/base64x/internal/native/sse" + "github.com/cloudwego/base64x/internal/rt" + "github.com/klauspost/cpuid/v2" ) var ( - hasAVX2 = cpuid.CPU.Has(cpuid.AVX2) - hasSSE = cpuid.CPU.Has(cpuid.SSE) + hasAVX2 = cpuid.CPU.Has(cpuid.AVX2) + hasSSE = cpuid.CPU.Has(cpuid.SSE) ) var ( @@ -44,7 +44,7 @@ func useSSE() { //go:nosplit func B64Decode(out *[]byte, src unsafe.Pointer, len int, mod int) (ret int) { - return F_b64decode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), len, mod) + return F_b64decode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), len, mod) } //go:nosplit diff --git a/internal/native/native_test.go b/internal/native/native_test.go index 26d3546..7f56621 100644 --- a/internal/native/native_test.go +++ b/internal/native/native_test.go @@ -17,60 +17,59 @@ package native import ( - `reflect` - `testing` - `unsafe` + "reflect" + "testing" + "unsafe" ) func TestEncoderRecover(t *testing.T) { - t.Run("nil dst", func(t *testing.T) { - in := []byte("abc") - defer func(){ - if v := recover(); v != nil { - println("recover:", v) - } else { - t.Fatal("not recover") - } - }() - B64Encode(nil, &in, 0) - }) - t.Run("nil src", func(t *testing.T) { - in := []byte("abc") - (*reflect.SliceHeader)(unsafe.Pointer(&in)).Data = uintptr(0) - out := make([]byte, 0, 10) - defer func(){ - if v := recover(); v != nil { - println("recover:", v) - } else { - t.Fatal("not recover") - } - }() - B64Encode(&out, &in, 0) - }) + t.Run("nil dst", func(t *testing.T) { + in := []byte("abc") + defer func() { + if v := recover(); v != nil { + println("recover:", v) + } else { + t.Fatal("not recover") + } + }() + B64Encode(nil, &in, 0) + }) + t.Run("nil src", func(t *testing.T) { + in := []byte("abc") + (*reflect.SliceHeader)(unsafe.Pointer(&in)).Data = uintptr(0) + out := make([]byte, 0, 10) + defer func() { + if v := recover(); v != nil { + println("recover:", v) + } else { + t.Fatal("not recover") + } + }() + B64Encode(&out, &in, 0) + }) } - func TestDecoderRecover(t *testing.T) { - t.Run("nil dst", func(t *testing.T) { - in := []byte("abc") - defer func(){ - if v := recover(); v != nil { - println("recover:", v) - } else { - t.Fatal("not recover") - } - }() - B64Decode(nil, unsafe.Pointer(&in[0]), len(in), 0) - }) - t.Run("nil src", func(t *testing.T) { - out := make([]byte, 0, 10) - defer func(){ - if v := recover(); v != nil { - println("recover:", v) - } else { - t.Fatal("not recover") - } - }() - B64Decode(&out, nil, 5, 0) - }) -} \ No newline at end of file + t.Run("nil dst", func(t *testing.T) { + in := []byte("abc") + defer func() { + if v := recover(); v != nil { + println("recover:", v) + } else { + t.Fatal("not recover") + } + }() + B64Decode(nil, unsafe.Pointer(&in[0]), len(in), 0) + }) + t.Run("nil src", func(t *testing.T) { + out := make([]byte, 0, 10) + defer func() { + if v := recover(); v != nil { + println("recover:", v) + } else { + t.Fatal("not recover") + } + }() + B64Decode(&out, nil, 5, 0) + }) +} diff --git a/internal/native/sse/b64decode.go b/internal/native/sse/b64decode.go index 3e097f9..c313879 100644 --- a/internal/native/sse/b64decode.go +++ b/internal/native/sse/b64decode.go @@ -19,9 +19,9 @@ package sse import ( - `unsafe` + "unsafe" - `github.com/cloudwego/base64x/internal/rt` + "github.com/cloudwego/base64x/internal/rt" ) var F_b64decode func(out unsafe.Pointer, src unsafe.Pointer, len int, mod int) (ret int) @@ -30,6 +30,5 @@ var S_b64decode uintptr //go:nosplit func B64decode(out *[]byte, src unsafe.Pointer, len int, mode int) (ret int) { - return F_b64decode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), len, mode) + return F_b64decode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), len, mode) } - diff --git a/internal/native/sse/b64decode_subr.go b/internal/native/sse/b64decode_subr.go index 25ba980..6883671 100644 --- a/internal/native/sse/b64decode_subr.go +++ b/internal/native/sse/b64decode_subr.go @@ -1,45 +1,47 @@ +//go:build !noasm || !appengine // +build !noasm !appengine + // Code generated by asm2asm, DO NOT EDIT. package sse import ( - `github.com/bytedance/sonic/loader` + "github.com/bytedance/sonic/loader" ) const ( - _entry__b64decode = 0 + _entry__b64decode = 0 ) const ( - _stack__b64decode = 144 + _stack__b64decode = 144 ) const ( - _size__b64decode = 9968 + _size__b64decode = 9968 ) var ( - _pcsp__b64decode = [][2]uint32{ - {0x1, 0}, - {0x6, 8}, - {0x8, 16}, - {0xa, 24}, - {0xc, 32}, - {0xd, 40}, - {0x11, 48}, - {0x26e1, 144}, - {0x26e2, 48}, - {0x26e4, 40}, - {0x26e6, 32}, - {0x26e8, 24}, - {0x26ea, 16}, - {0x26eb, 8}, - {0x26f0, 0}, - } + _pcsp__b64decode = [][2]uint32{ + {0x1, 0}, + {0x6, 8}, + {0x8, 16}, + {0xa, 24}, + {0xc, 32}, + {0xd, 40}, + {0x11, 48}, + {0x26e1, 144}, + {0x26e2, 48}, + {0x26e4, 40}, + {0x26e6, 32}, + {0x26e8, 24}, + {0x26ea, 16}, + {0x26eb, 8}, + {0x26f0, 0}, + } ) var _cfunc_b64decode = []loader.CFunc{ - {"_b64decode_entry", 0, _entry__b64decode, 0, nil}, - {"_b64decode", _entry__b64decode, _size__b64decode, _stack__b64decode, _pcsp__b64decode}, + {"_b64decode_entry", 0, _entry__b64decode, 0, nil}, + {"_b64decode", _entry__b64decode, _size__b64decode, _stack__b64decode, _pcsp__b64decode}, } diff --git a/internal/native/sse/b64decode_text_amd64.go b/internal/native/sse/b64decode_text_amd64.go index 49569e0..78f5362 100644 --- a/internal/native/sse/b64decode_text_amd64.go +++ b/internal/native/sse/b64decode_text_amd64.go @@ -1,4 +1,6 @@ +//go:build amd64 // +build amd64 + // Code generated by asm2asm, DO NOT EDIT. package sse @@ -6,13 +8,13 @@ package sse var _text_b64decode = []byte{ // .p2align 4, 0x90 // _b64decode - 0x55, // pushq %rbp + 0x55, // pushq %rbp 0x48, 0x89, 0xe5, //0x00000001 movq %rsp, %rbp 0x41, 0x57, //0x00000004 pushq %r15 0x41, 0x56, //0x00000006 pushq %r14 0x41, 0x55, //0x00000008 pushq %r13 0x41, 0x54, //0x0000000a pushq %r12 - 0x53, //0x0000000c pushq %rbx + 0x53, //0x0000000c pushq %rbx 0x48, 0x83, 0xec, 0x60, //0x0000000d subq $96, %rsp 0x48, 0x85, 0xd2, //0x00000011 testq %rdx, %rdx 0x0f, 0x84, 0x54, 0x1a, 0x00, 0x00, //0x00000014 je LBB0_432 @@ -2744,13 +2746,13 @@ var _text_b64decode = []byte{ 0x48, 0x29, 0xc8, //0x000026da subq %rcx, %rax //0x000026dd LBB0_644 0x48, 0x83, 0xc4, 0x60, //0x000026dd addq $96, %rsp - 0x5b, //0x000026e1 popq %rbx + 0x5b, //0x000026e1 popq %rbx 0x41, 0x5c, //0x000026e2 popq %r12 0x41, 0x5d, //0x000026e4 popq %r13 0x41, 0x5e, //0x000026e6 popq %r14 0x41, 0x5f, //0x000026e8 popq %r15 - 0x5d, //0x000026ea popq %rbp - 0xc3, //0x000026eb retq + 0x5d, //0x000026ea popq %rbp + 0xc3, //0x000026eb retq 0x00, 0x00, 0x00, 0x00, //0x000026ec .p2align 4, 0x00 //0x000026f0 _VecDecodeCharsetStd 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x000026f0 QUAD $0xffffffffffffffff; QUAD $0xffffffffffffffff // .ascii 16, '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' @@ -2788,4 +2790,3 @@ var _text_b64decode = []byte{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x000028d0 QUAD $0xffffffffffffffff; QUAD $0xffffffffffffffff // .ascii 16, '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x000028e0 QUAD $0xffffffffffffffff; QUAD $0xffffffffffffffff // .ascii 16, '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' } - diff --git a/internal/native/sse/b64encode.go b/internal/native/sse/b64encode.go index e5f7a87..6c679fc 100644 --- a/internal/native/sse/b64encode.go +++ b/internal/native/sse/b64encode.go @@ -19,9 +19,9 @@ package sse import ( - `unsafe` + "unsafe" - `github.com/cloudwego/base64x/internal/rt` + "github.com/cloudwego/base64x/internal/rt" ) var F_b64encode func(out unsafe.Pointer, src unsafe.Pointer, mod int) @@ -30,5 +30,5 @@ var S_b64encode uintptr //go:nosplit func B64encode(out *[]byte, src *[]byte, mode int) { - F_b64encode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), mode) + F_b64encode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), mode) } diff --git a/internal/native/sse/b64encode_subr.go b/internal/native/sse/b64encode_subr.go index 720122e..c72b992 100644 --- a/internal/native/sse/b64encode_subr.go +++ b/internal/native/sse/b64encode_subr.go @@ -1,39 +1,41 @@ +//go:build !noasm || !appengine // +build !noasm !appengine + // Code generated by asm2asm, DO NOT EDIT. package sse import ( - `github.com/bytedance/sonic/loader` + "github.com/bytedance/sonic/loader" ) const ( - _entry__b64encode = 0 + _entry__b64encode = 0 ) const ( - _stack__b64encode = 32 + _stack__b64encode = 32 ) const ( - _size__b64encode = 448 + _size__b64encode = 448 ) var ( - _pcsp__b64encode = [][2]uint32{ - {0x1, 0}, - {0x6, 8}, - {0x8, 16}, - {0x9, 24}, - {0x1ab, 32}, - {0x1ad, 24}, - {0x1af, 16}, - {0x1b0, 8}, - {0x1c0, 0}, - } + _pcsp__b64encode = [][2]uint32{ + {0x1, 0}, + {0x6, 8}, + {0x8, 16}, + {0x9, 24}, + {0x1ab, 32}, + {0x1ad, 24}, + {0x1af, 16}, + {0x1b0, 8}, + {0x1c0, 0}, + } ) var _cfunc_b64encode = []loader.CFunc{ - {"_b64encode_entry", 0, _entry__b64encode, 0, nil}, - {"_b64encode", _entry__b64encode, _size__b64encode, _stack__b64encode, _pcsp__b64encode}, + {"_b64encode_entry", 0, _entry__b64encode, 0, nil}, + {"_b64encode", _entry__b64encode, _size__b64encode, _stack__b64encode, _pcsp__b64encode}, } diff --git a/internal/native/sse/b64encode_text_amd64.go b/internal/native/sse/b64encode_text_amd64.go index 2ce8624..59e603b 100644 --- a/internal/native/sse/b64encode_text_amd64.go +++ b/internal/native/sse/b64encode_text_amd64.go @@ -1,4 +1,6 @@ +//go:build amd64 // +build amd64 + // Code generated by asm2asm, DO NOT EDIT. package sse @@ -6,11 +8,11 @@ package sse var _text_b64encode = []byte{ // .p2align 4, 0x90 // _b64encode - 0x55, // pushq %rbp + 0x55, // pushq %rbp 0x48, 0x89, 0xe5, //0x00000001 movq %rsp, %rbp 0x41, 0x57, //0x00000004 pushq %r15 0x41, 0x56, //0x00000006 pushq %r14 - 0x53, //0x00000008 pushq %rbx + 0x53, //0x00000008 pushq %rbx 0x4c, 0x8b, 0x4e, 0x08, //0x00000009 movq $8(%rsi), %r9 0x4d, 0x85, 0xc9, //0x0000000d testq %r9, %r9 0x0f, 0x84, 0x94, 0x01, 0x00, 0x00, //0x00000010 je LBB0_15 @@ -127,11 +129,11 @@ var _text_b64encode = []byte{ 0x4d, 0x29, 0xc6, //0x000001a3 subq %r8, %r14 0x4c, 0x01, 0x77, 0x08, //0x000001a6 addq %r14, $8(%rdi) //0x000001aa LBB0_15 - 0x5b, //0x000001aa popq %rbx + 0x5b, //0x000001aa popq %rbx 0x41, 0x5e, //0x000001ab popq %r14 0x41, 0x5f, //0x000001ad popq %r15 - 0x5d, //0x000001af popq %rbp - 0xc3, //0x000001b0 retq + 0x5d, //0x000001af popq %rbp + 0xc3, //0x000001b0 retq 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000001b1 .p2align 4, 0x00 //0x000001c0 _TabEncodeCharsetStd 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, //0x000001c0 QUAD $0x4847464544434241; QUAD $0x504f4e4d4c4b4a49 // .ascii 16, 'ABCDEFGHIJKLMNOP' @@ -145,4 +147,3 @@ var _text_b64encode = []byte{ 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, //0x00000220 QUAD $0x6e6d6c6b6a696867; QUAD $0x767574737271706f // .ascii 16, 'ghijklmnopqrstuv' 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2d, 0x5f, //0x00000230 QUAD $0x333231307a797877; QUAD $0x5f2d393837363534 // .ascii 16, 'wxyz0123456789-_' } - diff --git a/internal/native/sse/native_export.go b/internal/native/sse/native_export.go index dd6ae11..756945f 100644 --- a/internal/native/sse/native_export.go +++ b/internal/native/sse/native_export.go @@ -1,4 +1,3 @@ - // Code generated by Bash, DO NOT EDIT. /* @@ -20,10 +19,10 @@ package sse import ( - `github.com/bytedance/sonic/loader` + "github.com/bytedance/sonic/loader" ) func Use() { - loader.WrapGoC(_text_b64encode, _cfunc_b64encode, []loader.GoC{{"_b64encode", &S_b64encode, &F_b64encode}}, "sse", "sse/b64encode.c") - loader.WrapGoC(_text_b64decode, _cfunc_b64decode, []loader.GoC{{"_b64decode", &S_b64decode, &F_b64decode}}, "sse", "sse/b64decode.c") -} \ No newline at end of file + loader.WrapGoC(_text_b64encode, _cfunc_b64encode, []loader.GoC{{"_b64encode", &S_b64encode, &F_b64encode}}, "sse", "sse/b64encode.c") + loader.WrapGoC(_text_b64decode, _cfunc_b64decode, []loader.GoC{{"_b64decode", &S_b64decode, &F_b64decode}}, "sse", "sse/b64decode.c") +} diff --git a/internal/rt/fastmem.go b/internal/rt/fastmem.go index e68ff41..247572f 100644 --- a/internal/rt/fastmem.go +++ b/internal/rt/fastmem.go @@ -20,17 +20,17 @@ import ( "unsafe" ) - // NoEscape hides a pointer from escape analysis. NoEscape is // the identity function but escape analysis doesn't think the // output depends on the input. NoEscape is inlined and currently // compiles down to zero instructions. // USE CAREFULLY! +// //go:nosplit //goland:noinspection GoVetUnsafePointer func NoEscape(p unsafe.Pointer) unsafe.Pointer { - x := uintptr(p) - return unsafe.Pointer(x ^ 0) + x := uintptr(p) + return unsafe.Pointer(x ^ 0) } //go:nosplit @@ -38,5 +38,5 @@ func MoreStack(size uintptr) //go:nosplit func Add(ptr unsafe.Pointer, off uintptr) unsafe.Pointer { - return unsafe.Pointer(uintptr(ptr) + off) + return unsafe.Pointer(uintptr(ptr) + off) } From 2c915796c8e389fa7bf33f5b8e281deaa12052a2 Mon Sep 17 00:00:00 2001 From: liuqiang Date: Tue, 28 Apr 2026 16:00:41 +0800 Subject: [PATCH 2/2] fix: support portable fallback builds Split native amd64 code from the stdlib fallback path, preserve amd64 linkname compatibility symbols for noasm/appengine builds, and cover fallback targets in CI. --- .github/workflows/pr-check.yml | 24 +++--- .github/workflows/tests.yml | 45 ++++++++++- _typos.toml | 12 +++ base64x.go | 14 +--- base64x_error_native_amd64_test.go | 24 ++++++ base64x_fallback.go | 83 ++++++++++++++++++++ base64x_fallback_test.go | 58 ++++++++++++++ base64x_native.go | 38 +++++++++ base64x_subr_amd64.go | 26 +++--- base64x_subr_amd64_test.go | 25 ++++++ base64x_subr_native_amd64.go | 27 +++++++ base64x_test.go | 2 +- bench/bench_test.go | 16 ++++ internal/native/avx2/b64decode.go | 3 + internal/native/avx2/b64decode_subr.go | 4 +- internal/native/avx2/b64decode_text_amd64.go | 4 +- internal/native/avx2/b64encode.go | 3 + internal/native/avx2/b64encode_subr.go | 4 +- internal/native/avx2/b64encode_text_amd64.go | 4 +- internal/native/avx2/native_export.go | 3 + internal/native/b64decode.tmpl | 4 +- internal/native/b64encode.tmpl | 3 + internal/native/dispatch.go | 17 ++++ internal/native/native_export.tmpl | 4 +- internal/native/native_test.go | 3 + internal/native/sse/b64decode.go | 3 + internal/native/sse/b64decode_subr.go | 4 +- internal/native/sse/b64decode_text_amd64.go | 4 +- internal/native/sse/b64encode.go | 3 + internal/native/sse/b64encode_subr.go | 4 +- internal/native/sse/b64encode_text_amd64.go | 4 +- internal/native/sse/native_export.go | 3 + internal/rt/asm_amd64.s | 14 ++++ internal/rt/asm_arm64.s | 14 ++++ 34 files changed, 447 insertions(+), 56 deletions(-) create mode 100644 base64x_error_native_amd64_test.go create mode 100644 base64x_fallback.go create mode 100644 base64x_fallback_test.go create mode 100644 base64x_native.go create mode 100644 base64x_subr_amd64_test.go create mode 100644 base64x_subr_native_amd64.go diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index a07b093..98c0e51 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -4,9 +4,9 @@ on: [ pull_request ] jobs: compliant: - runs-on: [ self-hosted, X64 ] + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Check License Header uses: apache/skywalking-eyes/header@v0.4.0 @@ -14,18 +14,18 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Check Spell - uses: crate-ci/typos@master + uses: crate-ci/typos@master staticcheck: - runs-on: [ self-hosted, X64 ] + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v6 with: - go-version: 1.20 + go-version: "1.20.x" - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/go/pkg/mod key: reviewdog-${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} @@ -46,13 +46,13 @@ jobs: # not ready: unknown issue related to the env, skip for now # lint: - # runs-on: [ self-hosted, X64 ] + # runs-on: ubuntu-24.04 # steps: - # - uses: actions/checkout@v3 + # - uses: actions/checkout@v6 # - name: Set up Go - # uses: actions/setup-go@v3 + # uses: actions/setup-go@v6 # with: - # go-version: 1.20 + # go-version: "1.20.x" # - name: Golangci Lint # # https://golangci-lint.run/ diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5f4fe6d..afd8a0e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,13 +7,12 @@ jobs: strategy: matrix: go: [ 1.17.x, 1.18.x, 1.19.x, 1.20.x, 1.21.x, 1.22.x, 1.23.x] - os: [ X64 ] - runs-on: ${{ matrix.os }} + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v6 with: go-version: ${{ matrix.go }} @@ -22,3 +21,41 @@ jobs: - name: Benchmark run: cd ./bench && go test -bench=. -benchmem -run=none ./... + + fallback-test: + strategy: + fail-fast: false + matrix: + include: + - name: ubuntu-x86 noasm + go: 1.20.x + os: ubuntu-24.04 + command: go test -tags noasm . + - name: ubuntu-x86 appengine + go: 1.20.x + os: ubuntu-24.04 + command: go test -tags appengine . + - name: macos arm64 + go: 1.20.x + os: macos-14 + command: go test . + - name: ubuntu arm64 + go: 1.20.x + os: ubuntu-24.04-arm + command: go test . + - name: riscv64 compile + go: 1.20.x + os: ubuntu-24.04 + command: GOOS=linux GOARCH=riscv64 CGO_ENABLED=0 go test -run '^$' -exec=/usr/bin/true . + name: Fallback Test (${{ matrix.name }}) + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v6 + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: ${{ matrix.go }} + + - name: Test fallback path + run: ${{ matrix.command }} diff --git a/_typos.toml b/_typos.toml index 47b5bea..e2a15fb 100644 --- a/_typos.toml +++ b/_typos.toml @@ -2,3 +2,15 @@ [files] extend-exclude = ["go.mod", "go.sum", "check_branch_name.sh"] + +[default.extend-words] +asure = "asure" +brillig = "brillig" +easure = "easure" +fo = "fo" +leasure = "leasure" +shll = "shll" +slithy = "slithy" +sur = "sur" +toves = "toves" +Twas = "Twas" diff --git a/base64x.go b/base64x.go index 5df655f..a40922d 100644 --- a/base64x.go +++ b/base64x.go @@ -16,12 +16,6 @@ package base64x -import ( - "encoding/base64" - - "github.com/cloudwego/base64x/internal/native" -) - // An Encoding is a radix 64 encoding/decoding scheme, defined by a // 64-character alphabet. The most common encoding is the "base64" // encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM @@ -89,7 +83,7 @@ func (self Encoding) Encode(out []byte, src []byte) { // // It will also update the length of out. func (self Encoding) EncodeUnsafe(out *[]byte, src []byte) { - native.B64Encode(out, &src, int(self)|archFlags) + encode(out, src, int(self)|archFlags) } // EncodeToString returns the base64 encoding of src. @@ -138,11 +132,7 @@ func (self Encoding) Decode(out []byte, src []byte) (int, error) { // // It will also update the length of out. func (self Encoding) DecodeUnsafe(out *[]byte, src []byte) (int, error) { - if n := native.B64Decode(out, mem2addr(src), len(src), int(self)|archFlags); n >= 0 { - return n, nil - } else { - return 0, base64.CorruptInputError(-n - 1) - } + return decode(out, src, int(self)|archFlags) } // DecodeString returns the bytes represented by the base64 string s. diff --git a/base64x_error_native_amd64_test.go b/base64x_error_native_amd64_test.go new file mode 100644 index 0000000..8b62c03 --- /dev/null +++ b/base64x_error_native_amd64_test.go @@ -0,0 +1,24 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + +package base64x + +import "encoding/base64" + +func missingPaddingDecodeError() base64.CorruptInputError { + return base64.CorruptInputError(6) +} diff --git a/base64x_fallback.go b/base64x_fallback.go new file mode 100644 index 0000000..3281666 --- /dev/null +++ b/base64x_fallback.go @@ -0,0 +1,83 @@ +//go:build !amd64 || noasm || appengine +// +build !amd64 noasm appengine + +/* + * Copyright 2024 CloudWeGo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package base64x + +import ( + "encoding/base64" + "encoding/json" +) + +func encodingForMode(mode int) *base64.Encoding { + switch mode & (_MODE_URL | _MODE_RAW) { + case _MODE_URL: + return base64.URLEncoding + case _MODE_RAW: + return base64.RawStdEncoding + case _MODE_URL | _MODE_RAW: + return base64.RawURLEncoding + default: + return base64.StdEncoding + } +} + +func encode(out *[]byte, src []byte, mode int) { + enc := encodingForMode(mode) + dst := *out + start := len(dst) + need := enc.EncodedLen(len(src)) + dst = dst[:start+need] + enc.Encode(dst[start:], src) + *out = dst +} + +func decode(out *[]byte, src []byte, mode int) (int, error) { + input := src + if mode&_MODE_JSON != 0 { + unquoted, err := unquoteJSONBase64(src) + if err != nil { + return 0, err + } + input = unquoted + } + + enc := encodingForMode(mode) + dst := *out + start := len(dst) + buf := dst[start:cap(dst)] + n, err := enc.Decode(buf, input) + if err != nil { + return 0, err + } + *out = dst[:start+n] + return n, nil +} + +func unquoteJSONBase64(src []byte) ([]byte, error) { + quoted := make([]byte, 0, len(src)+2) + quoted = append(quoted, '"') + quoted = append(quoted, src...) + quoted = append(quoted, '"') + + var decoded string + if err := json.Unmarshal(quoted, &decoded); err != nil { + return nil, err + } + return []byte(decoded), nil +} diff --git a/base64x_fallback_test.go b/base64x_fallback_test.go new file mode 100644 index 0000000..1447270 --- /dev/null +++ b/base64x_fallback_test.go @@ -0,0 +1,58 @@ +//go:build !amd64 || noasm || appengine +// +build !amd64 noasm appengine + +/* + * Copyright 2024 CloudWeGo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package base64x + +import ( + "encoding/base64" + "testing" +) + +func missingPaddingDecodeError() base64.CorruptInputError { + return base64.CorruptInputError(4) +} + +func TestUnquoteJSONBase64(t *testing.T) { + src := []byte("VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==") + got, err := unquoteJSONBase64(src) + if err != nil { + t.Fatalf("unquoteJSONBase64() error = %v", err) + } + if string(got) != string(src) { + t.Fatalf("unquoteJSONBase64() = %q, want %q", got, src) + } +} + +func TestUnquoteJSONBase64RejectsInvalidEscapes(t *testing.T) { + for _, src := range [][]byte{ + []byte(`FPuc\x419l+`), + []byte(`FPuc\'A9l+`), + } { + if _, err := unquoteJSONBase64(src); err == nil { + t.Fatalf("unquoteJSONBase64(%q) error = nil, want non-nil", src) + } + } +} + +func TestFallbackDecodeMissingPaddingReturnsStdlibError(t *testing.T) { + _, err := StdEncoding.DecodeString("123456") + if err != base64.CorruptInputError(4) { + t.Fatalf("DecodeString(%q) error = %v, want %v", "123456", err, base64.CorruptInputError(4)) + } +} diff --git a/base64x_native.go b/base64x_native.go new file mode 100644 index 0000000..5643729 --- /dev/null +++ b/base64x_native.go @@ -0,0 +1,38 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + +/* + * Copyright 2024 CloudWeGo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package base64x + +import ( + "encoding/base64" + + "github.com/cloudwego/base64x/internal/native" +) + +func encode(out *[]byte, src []byte, mode int) { + native.B64Encode(out, &src, mode) +} + +func decode(out *[]byte, src []byte, mode int) (int, error) { + n := native.B64Decode(out, mem2addr(src), len(src), mode) + if n >= 0 { + return n, nil + } + return 0, base64.CorruptInputError(-n - 1) +} diff --git a/base64x_subr_amd64.go b/base64x_subr_amd64.go index 3801e5a..06ae945 100644 --- a/base64x_subr_amd64.go +++ b/base64x_subr_amd64.go @@ -1,16 +1,24 @@ -package base64x +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -import ( - "github.com/cloudwego/base64x/internal/native" -) +//go:build amd64 +// +build amd64 + +package base64x // HACK: maintain these only to prevent breakchange, because sonic-go linkname these var ( _subr__b64decode uintptr _subr__b64encode uintptr ) - -func init() { - _subr__b64decode = native.S_b64decode - _subr__b64encode = native.S_b64encode -} diff --git a/base64x_subr_amd64_test.go b/base64x_subr_amd64_test.go new file mode 100644 index 0000000..49435e4 --- /dev/null +++ b/base64x_subr_amd64_test.go @@ -0,0 +1,25 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build amd64 +// +build amd64 + +package base64x + +import "testing" + +func TestSubrCompatibilitySymbols(t *testing.T) { + _ = _subr__b64decode + _ = _subr__b64encode +} diff --git a/base64x_subr_native_amd64.go b/base64x_subr_native_amd64.go new file mode 100644 index 0000000..094ad84 --- /dev/null +++ b/base64x_subr_native_amd64.go @@ -0,0 +1,27 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + +package base64x + +import ( + "github.com/cloudwego/base64x/internal/native" +) + +func init() { + _subr__b64decode = native.S_b64decode + _subr__b64encode = native.S_b64encode +} diff --git a/base64x_test.go b/base64x_test.go index e3088e3..7e4297b 100644 --- a/base64x_test.go +++ b/base64x_test.go @@ -242,7 +242,7 @@ func TestDecoderError(t *testing.T) { panic(err) } _, err = StdEncoding.DecodeString("123456") - if err != base64.CorruptInputError(6) { + if err != missingPaddingDecodeError() { panic(err) } _, err = StdEncoding.DecodeString("1234;6") diff --git a/bench/bench_test.go b/bench/bench_test.go index d5a4ce7..5143a34 100644 --- a/bench/bench_test.go +++ b/bench/bench_test.go @@ -1,3 +1,19 @@ +/* + * Copyright 2024 CloudWeGo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package bench import ( diff --git a/internal/native/avx2/b64decode.go b/internal/native/avx2/b64decode.go index 80445c8..cb5243c 100644 --- a/internal/native/avx2/b64decode.go +++ b/internal/native/avx2/b64decode.go @@ -1,3 +1,6 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + // Code generated by Bash, DO NOT EDIT. /* diff --git a/internal/native/avx2/b64decode_subr.go b/internal/native/avx2/b64decode_subr.go index 779275c..3d82251 100644 --- a/internal/native/avx2/b64decode_subr.go +++ b/internal/native/avx2/b64decode_subr.go @@ -1,5 +1,5 @@ -//go:build !noasm || !appengine -// +build !noasm !appengine +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine // Code generated by asm2asm, DO NOT EDIT. diff --git a/internal/native/avx2/b64decode_text_amd64.go b/internal/native/avx2/b64decode_text_amd64.go index 862916f..9173dd2 100644 --- a/internal/native/avx2/b64decode_text_amd64.go +++ b/internal/native/avx2/b64decode_text_amd64.go @@ -1,5 +1,5 @@ -//go:build amd64 -// +build amd64 +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine // Code generated by asm2asm, DO NOT EDIT. diff --git a/internal/native/avx2/b64encode.go b/internal/native/avx2/b64encode.go index 44821bd..eb17d88 100644 --- a/internal/native/avx2/b64encode.go +++ b/internal/native/avx2/b64encode.go @@ -1,3 +1,6 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + // Code generated by Bash, DO NOT EDIT. /* diff --git a/internal/native/avx2/b64encode_subr.go b/internal/native/avx2/b64encode_subr.go index b0ab590..736ef22 100644 --- a/internal/native/avx2/b64encode_subr.go +++ b/internal/native/avx2/b64encode_subr.go @@ -1,5 +1,5 @@ -//go:build !noasm || !appengine -// +build !noasm !appengine +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine // Code generated by asm2asm, DO NOT EDIT. diff --git a/internal/native/avx2/b64encode_text_amd64.go b/internal/native/avx2/b64encode_text_amd64.go index ab7b494..97a2f28 100644 --- a/internal/native/avx2/b64encode_text_amd64.go +++ b/internal/native/avx2/b64encode_text_amd64.go @@ -1,5 +1,5 @@ -//go:build amd64 -// +build amd64 +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine // Code generated by asm2asm, DO NOT EDIT. diff --git a/internal/native/avx2/native_export.go b/internal/native/avx2/native_export.go index b51de8a..39a7cba 100644 --- a/internal/native/avx2/native_export.go +++ b/internal/native/avx2/native_export.go @@ -1,3 +1,6 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + // Code generated by Bash, DO NOT EDIT. /* diff --git a/internal/native/b64decode.tmpl b/internal/native/b64decode.tmpl index 5b7ebeb..cd61808 100644 --- a/internal/native/b64decode.tmpl +++ b/internal/native/b64decode.tmpl @@ -1,3 +1,6 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + // Code generated by Bash, DO NOT EDIT. /* @@ -32,4 +35,3 @@ var S_b64decode uintptr func B64decode(out *[]byte, src unsafe.Pointer, len int, mode int) (ret int) { return F_b64decode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), len, mode) } - diff --git a/internal/native/b64encode.tmpl b/internal/native/b64encode.tmpl index edecd87..5cb3513 100644 --- a/internal/native/b64encode.tmpl +++ b/internal/native/b64encode.tmpl @@ -1,3 +1,6 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + // Code generated by Bash, DO NOT EDIT. /* diff --git a/internal/native/dispatch.go b/internal/native/dispatch.go index 2f312a3..73a9a18 100644 --- a/internal/native/dispatch.go +++ b/internal/native/dispatch.go @@ -1,3 +1,20 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + package native import ( diff --git a/internal/native/native_export.tmpl b/internal/native/native_export.tmpl index 06dd28a..984034f 100644 --- a/internal/native/native_export.tmpl +++ b/internal/native/native_export.tmpl @@ -1,3 +1,5 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine // Code generated by Bash, DO NOT EDIT. @@ -26,4 +28,4 @@ import ( func Use() { loader.WrapGoC(_text_b64encode, _cfunc_b64encode, []loader.GoC{{"_b64encode", &S_b64encode, &F_b64encode}}, "{{PACKAGE}}", "{{PACKAGE}}/b64encode.c") loader.WrapGoC(_text_b64decode, _cfunc_b64decode, []loader.GoC{{"_b64decode", &S_b64decode, &F_b64decode}}, "{{PACKAGE}}", "{{PACKAGE}}/b64decode.c") -} \ No newline at end of file +} diff --git a/internal/native/native_test.go b/internal/native/native_test.go index 7f56621..fc53a0d 100644 --- a/internal/native/native_test.go +++ b/internal/native/native_test.go @@ -1,3 +1,6 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + /* * Copyright 2025 CloudWeGo Authors * diff --git a/internal/native/sse/b64decode.go b/internal/native/sse/b64decode.go index c313879..7c01375 100644 --- a/internal/native/sse/b64decode.go +++ b/internal/native/sse/b64decode.go @@ -1,3 +1,6 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + // Code generated by Bash, DO NOT EDIT. /* diff --git a/internal/native/sse/b64decode_subr.go b/internal/native/sse/b64decode_subr.go index 6883671..b0774ee 100644 --- a/internal/native/sse/b64decode_subr.go +++ b/internal/native/sse/b64decode_subr.go @@ -1,5 +1,5 @@ -//go:build !noasm || !appengine -// +build !noasm !appengine +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine // Code generated by asm2asm, DO NOT EDIT. diff --git a/internal/native/sse/b64decode_text_amd64.go b/internal/native/sse/b64decode_text_amd64.go index 78f5362..b7fe722 100644 --- a/internal/native/sse/b64decode_text_amd64.go +++ b/internal/native/sse/b64decode_text_amd64.go @@ -1,5 +1,5 @@ -//go:build amd64 -// +build amd64 +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine // Code generated by asm2asm, DO NOT EDIT. diff --git a/internal/native/sse/b64encode.go b/internal/native/sse/b64encode.go index 6c679fc..9609ec9 100644 --- a/internal/native/sse/b64encode.go +++ b/internal/native/sse/b64encode.go @@ -1,3 +1,6 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + // Code generated by Bash, DO NOT EDIT. /* diff --git a/internal/native/sse/b64encode_subr.go b/internal/native/sse/b64encode_subr.go index c72b992..deb12c0 100644 --- a/internal/native/sse/b64encode_subr.go +++ b/internal/native/sse/b64encode_subr.go @@ -1,5 +1,5 @@ -//go:build !noasm || !appengine -// +build !noasm !appengine +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine // Code generated by asm2asm, DO NOT EDIT. diff --git a/internal/native/sse/b64encode_text_amd64.go b/internal/native/sse/b64encode_text_amd64.go index 59e603b..84cd54d 100644 --- a/internal/native/sse/b64encode_text_amd64.go +++ b/internal/native/sse/b64encode_text_amd64.go @@ -1,5 +1,5 @@ -//go:build amd64 -// +build amd64 +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine // Code generated by asm2asm, DO NOT EDIT. diff --git a/internal/native/sse/native_export.go b/internal/native/sse/native_export.go index 756945f..6a9d9e7 100644 --- a/internal/native/sse/native_export.go +++ b/internal/native/sse/native_export.go @@ -1,3 +1,6 @@ +//go:build amd64 && !noasm && !appengine +// +build amd64,!noasm,!appengine + // Code generated by Bash, DO NOT EDIT. /* diff --git a/internal/rt/asm_amd64.s b/internal/rt/asm_amd64.s index 86d2642..7783835 100644 --- a/internal/rt/asm_amd64.s +++ b/internal/rt/asm_amd64.s @@ -1,3 +1,17 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // +build !noasm !appengine // Code generated by asm2asm, DO NOT EDIT· diff --git a/internal/rt/asm_arm64.s b/internal/rt/asm_arm64.s index a168a82..646475c 100644 --- a/internal/rt/asm_arm64.s +++ b/internal/rt/asm_arm64.s @@ -1,3 +1,17 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // +build !noasm !appengine // Code generated by asm2asm, DO NOT EDIT.