2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00

fix: adapts to Mac M1 (#280)

* fix: adapts to Mac M1
* feat: add `noavx` mode
* fix: fix SSE4 segfault with latest asm2asm
* chore: remove excessive spaces
* chore: more compact assembly
* chore: re-indent with 4 spaces
* chore: remove excessive space

Co-authored-by: chenzhuoyu <chenzhuoyu@bytedance.com>
This commit is contained in:
cyn6315 2022-08-15 14:37:20 +08:00 committed by GitHub
parent d4024becca
commit a8311c6cde
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 25948 additions and 12412 deletions

View file

@ -14,24 +14,28 @@
# limitations under the License.
#
ARCH := avx avx2
ARCH := avx avx2 sse4
TMP_DIR := output
OUT_DIR := internal/native
SRC_FILE := native/native.c
CPU_avx := amd64
CPU_avx2 := amd64
CPU_sse4 := amd64
TMPL_avx := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64
TMPL_avx2 := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64
TMPL_sse4 := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64
CFLAGS_avx := -msse4 -mavx -mno-avx2 -DUSE_AVX=1 -DUSE_AVX2=0
CFLAGS_avx2 := -msse4 -mavx -mavx2 -DUSE_AVX=1 -DUSE_AVX2=1
CFLAGS_avx2 := -msse4 -mavx -mavx2 -DUSE_AVX=1 -DUSE_AVX2=1
CFLAGS_sse4 := -msse4 -mno-avx -mno-avx2
CC_amd64 := clang
ASM2ASM_amd64 := tools/asm2asm/asm2asm.py
CFLAGS := -mno-red-zone
CFLAGS += -arch x86_64
CFLAGS += -fno-asynchronous-unwind-tables
CFLAGS += -fno-builtin
CFLAGS += -fno-exceptions
@ -95,8 +99,8 @@ endef
all: ${ARCH}
clean:
rm -vfr ${TMP_DIR}/{sse,avx,avx2}
rm -vfr ${OUT_DIR}/{sse,avx,avx2}
rm -vfr ${TMP_DIR}/{sse4,avx,avx2}
rm -vfr ${OUT_DIR}/{sse4,avx,avx2}
$(foreach \
arch, \

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python3
# Copyright 2021 ByteDance Inc.
# Copyright 2022 ByteDance Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.

View file

@ -21,9 +21,9 @@ import (
`reflect`
`runtime`
`github.com/bytedance/sonic/internal/rt`
`github.com/bytedance/sonic/internal/native`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
`github.com/bytedance/sonic/option`
)
@ -203,7 +203,7 @@ func pretouchRec(vtm map[reflect.Type]bool, opts option.CompileOptions) error {
}
// Skip skips only one json value, and returns first non-blank character position and its ending position if it is valid.
// Otherwise returns negative error code using start and invalid character position using end
// Otherwise, returns negative error code using start and invalid character position using end
func Skip(data []byte) (start int, end int) {
s := rt.Mem2Str(data)
p := 0

View file

@ -6,7 +6,7 @@ fuzz:
file2fuzz -o ./testdata/fuzz/FuzzMain ./go-fuzz-corpus/json/corpus/* ./corpus/*
run:
go test -fuzz=Fuzz -v
GOARCH=amd64 go test -fuzz=Fuzz -v
clean:
rm -rf ./go-fuzz-corpus/

View file

@ -26,13 +26,15 @@ import (
var (
HasAVX = cpuid.CPU.Has(cpuid.AVX)
HasAVX2 = cpuid.CPU.Has(cpuid.AVX2)
HasSSE4 = cpuid.CPU.Has(cpuid.SSE4)
)
func init() {
switch v := os.Getenv("SONIC_MODE"); v {
case "" : break
case "auto" : break
case "noavx" : HasAVX = false; fallthrough
case "noavx2" : HasAVX2 = false
default : panic(fmt.Sprintf("invalid mode: '%s', should be one of 'auto', 'noavx2'", v))
default : panic(fmt.Sprintf("invalid mode: '%s', should be one of 'auto', 'noavx', 'noavx2'", v))
}
}

File diff suppressed because it is too large Load diff

View file

@ -9,44 +9,44 @@ package avx
func __native_entry__() uintptr
var (
_subr__f64toa = __native_entry__() + 570
_subr__html_escape = __native_entry__() + 9062
_subr__i64toa = __native_entry__() + 3205
_subr__lspace = __native_entry__() + 251
_subr__lzero = __native_entry__() + 13
_subr__quote = __native_entry__() + 4498
_subr__skip_array = __native_entry__() + 19852
_subr__skip_number = __native_entry__() + 21130
_subr__skip_object = __native_entry__() + 19887
_subr__skip_one = __native_entry__() + 18078
_subr__u64toa = __native_entry__() + 3300
_subr__unquote = __native_entry__() + 6037
_subr__validate_one = __native_entry__() + 21247
_subr__value = __native_entry__() + 11651
_subr__vnumber = __native_entry__() + 16191
_subr__vsigned = __native_entry__() + 17496
_subr__vstring = __native_entry__() + 13546
_subr__vunsigned = __native_entry__() + 17776
_subr__f64toa = __native_entry__() + 704
_subr__html_escape = __native_entry__() + 9920
_subr__i64toa = __native_entry__() + 3616
_subr__lspace = __native_entry__() + 320
_subr__lzero = __native_entry__() + 16
_subr__quote = __native_entry__() + 4992
_subr__skip_array = __native_entry__() + 22304
_subr__skip_number = __native_entry__() + 23776
_subr__skip_object = __native_entry__() + 22352
_subr__skip_one = __native_entry__() + 20432
_subr__u64toa = __native_entry__() + 3728
_subr__unquote = __native_entry__() + 6736
_subr__validate_one = __native_entry__() + 23920
_subr__value = __native_entry__() + 13168
_subr__vnumber = __native_entry__() + 18176
_subr__vsigned = __native_entry__() + 19728
_subr__vstring = __native_entry__() + 15248
_subr__vunsigned = __native_entry__() + 20080
)
const (
_stack__f64toa = 136
_stack__f64toa = 128
_stack__html_escape = 64
_stack__i64toa = 24
_stack__i64toa = 16
_stack__lspace = 8
_stack__lzero = 8
_stack__quote = 80
_stack__skip_array = 144
_stack__skip_number = 80
_stack__skip_object = 144
_stack__skip_one = 144
_stack__skip_array = 128
_stack__skip_number = 72
_stack__skip_object = 128
_stack__skip_one = 128
_stack__u64toa = 8
_stack__unquote = 72
_stack__validate_one = 144
_stack__value = 416
_stack__vnumber = 312
_stack__validate_one = 128
_stack__value = 336
_stack__vnumber = 248
_stack__vsigned = 16
_stack__vstring = 136
_stack__vstring = 128
_stack__vunsigned = 24
)

File diff suppressed because it is too large Load diff

View file

@ -9,44 +9,44 @@ package avx2
func __native_entry__() uintptr
var (
_subr__f64toa = __native_entry__() + 814
_subr__html_escape = __native_entry__() + 10717
_subr__i64toa = __native_entry__() + 3449
_subr__lspace = __native_entry__() + 379
_subr__lzero = __native_entry__() + 13
_subr__quote = __native_entry__() + 4842
_subr__skip_array = __native_entry__() + 22748
_subr__skip_number = __native_entry__() + 24641
_subr__skip_object = __native_entry__() + 22783
_subr__skip_one = __native_entry__() + 20939
_subr__u64toa = __native_entry__() + 3544
_subr__unquote = __native_entry__() + 7467
_subr__validate_one = __native_entry__() + 24758
_subr__value = __native_entry__() + 14548
_subr__vnumber = __native_entry__() + 19052
_subr__vsigned = __native_entry__() + 20357
_subr__vstring = __native_entry__() + 16711
_subr__vunsigned = __native_entry__() + 20637
_subr__f64toa = __native_entry__() + 960
_subr__html_escape = __native_entry__() + 11776
_subr__i64toa = __native_entry__() + 3872
_subr__lspace = __native_entry__() + 448
_subr__lzero = __native_entry__() + 16
_subr__quote = __native_entry__() + 5360
_subr__skip_array = __native_entry__() + 25568
_subr__skip_number = __native_entry__() + 27664
_subr__skip_object = __native_entry__() + 25616
_subr__skip_one = __native_entry__() + 23664
_subr__u64toa = __native_entry__() + 3984
_subr__unquote = __native_entry__() + 8304
_subr__validate_one = __native_entry__() + 27808
_subr__value = __native_entry__() + 16352
_subr__vnumber = __native_entry__() + 21408
_subr__vsigned = __native_entry__() + 22960
_subr__vstring = __native_entry__() + 18736
_subr__vunsigned = __native_entry__() + 23312
)
const (
_stack__f64toa = 136
_stack__f64toa = 128
_stack__html_escape = 72
_stack__i64toa = 24
_stack__i64toa = 16
_stack__lspace = 8
_stack__lzero = 8
_stack__quote = 72
_stack__skip_array = 152
_stack__skip_number = 88
_stack__skip_object = 152
_stack__skip_one = 152
_stack__skip_array = 136
_stack__skip_number = 80
_stack__skip_object = 136
_stack__skip_one = 136
_stack__u64toa = 8
_stack__unquote = 72
_stack__validate_one = 152
_stack__value = 416
_stack__vnumber = 312
_stack__validate_one = 136
_stack__value = 336
_stack__vnumber = 248
_stack__vsigned = 16
_stack__vstring = 136
_stack__vstring = 128
_stack__vunsigned = 24
)

View file

@ -22,6 +22,7 @@ import (
`github.com/bytedance/sonic/internal/cpu`
`github.com/bytedance/sonic/internal/native/avx`
`github.com/bytedance/sonic/internal/native/avx2`
`github.com/bytedance/sonic/internal/native/sse4`
`github.com/bytedance/sonic/internal/native/types`
)
@ -54,11 +55,6 @@ var (
S_skip_number uintptr
)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func Lzero(p unsafe.Pointer, n int) int
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
@ -135,11 +131,31 @@ func useAVX2() {
S_skip_number = avx2.S_skip_number
}
func useSSE4() {
S_f64toa = sse4.S_f64toa
S_i64toa = sse4.S_i64toa
S_u64toa = sse4.S_u64toa
S_lspace = sse4.S_lspace
S_quote = sse4.S_quote
S_unquote = sse4.S_unquote
S_value = sse4.S_value
S_vstring = sse4.S_vstring
S_vnumber = sse4.S_vnumber
S_vsigned = sse4.S_vsigned
S_vunsigned = sse4.S_vunsigned
S_skip_one = sse4.S_skip_one
S_skip_array = sse4.S_skip_array
S_skip_object = sse4.S_skip_object
S_skip_number = sse4.S_skip_number
}
func init() {
if cpu.HasAVX2 {
useAVX2()
} else if cpu.HasAVX {
useAVX()
} else if cpu.HasSSE4 {
useSSE4()
} else {
panic("Unsupported CPU, maybe it's too old to run Sonic.")
}

View file

@ -18,56 +18,76 @@
#include "funcdata.h"
#include "textflag.h"
TEXT ·Lzero(SB), NOSPLIT, $0 - 24
CMPB github·combytedancesonicinternalcpu·HasAVX2(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx2·__lzero(SB)
JMP github·combytedancesonicinternalnativeavx·__lzero(SB)
TEXT ·Quote(SB), NOSPLIT, $0 - 48
CMPB github·combytedancesonicinternalcpu·HasAVX2(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx2·__quote(SB)
CMPB github·combytedancesonicinternalcpu·HasAVX(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx·__quote(SB)
JMP github·combytedancesonicinternalnativesse4·__quote(SB)
TEXT ·Unquote(SB), NOSPLIT, $0 - 48
CMPB github·combytedancesonicinternalcpu·HasAVX2(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx2·__unquote(SB)
CMPB github·combytedancesonicinternalcpu·HasAVX(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx·__unquote(SB)
JMP github·combytedancesonicinternalnativesse4·__unquote(SB)
TEXT ·HTMLEscape(SB), NOSPLIT, $0 - 40
CMPB github·combytedancesonicinternalcpu·HasAVX2(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx2·__html_escape(SB)
CMPB github·combytedancesonicinternalcpu·HasAVX(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx·__html_escape(SB)
JMP github·combytedancesonicinternalnativesse4·__html_escape(SB)
TEXT ·Value(SB), NOSPLIT, $0 - 48
CMPB github·combytedancesonicinternalcpu·HasAVX2(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx2·__value(SB)
CMPB github·combytedancesonicinternalcpu·HasAVX(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx·__value(SB)
JMP github·combytedancesonicinternalnativesse4·__value(SB)
TEXT ·SkipOne(SB), NOSPLIT, $0 - 40
CMPB github·combytedancesonicinternalcpu·HasAVX2(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx2·__skip_one(SB)
CMPB github·combytedancesonicinternalcpu·HasAVX(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx·__skip_one(SB)
JMP github·combytedancesonicinternalnativesse4·__skip_one(SB)
TEXT ·ValidateOne(SB), NOSPLIT, $0 - 32
CMPB github·combytedancesonicinternalcpu·HasAVX2(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx2·__validate_one(SB)
CMPB github·combytedancesonicinternalcpu·HasAVX(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx·__validate_one(SB)
JMP github·combytedancesonicinternalnativesse4·__validate_one(SB)
TEXT ·I64toa(SB), NOSPLIT, $0 - 32
CMPB github·combytedancesonicinternalcpu·HasAVX2(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx2·__i64toa(SB)
CMPB github·combytedancesonicinternalcpu·HasAVX(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx·__i64toa(SB)
JMP github·combytedancesonicinternalnativesse4·__i64toa(SB)
TEXT ·U64toa(SB), NOSPLIT, $0 - 32
CMPB github·combytedancesonicinternalcpu·HasAVX2(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx2·__u64toa(SB)
CMPB github·combytedancesonicinternalcpu·HasAVX(SB), $0
JE 2(PC)
JMP github·combytedancesonicinternalnativeavx·__u64toa(SB)
JMP github·combytedancesonicinternalnativesse4·__u64toa(SB)

View file

@ -0,0 +1,84 @@
// Code generated by Makefile, DO NOT EDIT.
/*
* Copyright 2021 ByteDance Inc.
*
* 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 sse4
import (
`math`
`strconv`
`testing`
`github.com/stretchr/testify/assert`
)
func TestFastFloat_Encode(t *testing.T) {
var buf [64]byte
assert.Equal(t, "0" , string(buf[:__f64toa(&buf[0], 0)]))
assert.Equal(t, "-0" , string(buf[:__f64toa(&buf[0], math.Float64frombits(0x8000000000000000))]))
assert.Equal(t, "12340000000" , string(buf[:__f64toa(&buf[0], 1234e7)]))
assert.Equal(t, "12.34" , string(buf[:__f64toa(&buf[0], 1234e-2)]))
assert.Equal(t, "0.001234" , string(buf[:__f64toa(&buf[0], 1234e-6)]))
assert.Equal(t, "1e30" , string(buf[:__f64toa(&buf[0], 1e30)]))
assert.Equal(t, "1.234e33" , string(buf[:__f64toa(&buf[0], 1234e30)]))
assert.Equal(t, "1.234e308" , string(buf[:__f64toa(&buf[0], 1234e305)]))
assert.Equal(t, "1.234e-317" , string(buf[:__f64toa(&buf[0], 1234e-320)]))
assert.Equal(t, "1.7976931348623157e308" , string(buf[:__f64toa(&buf[0], 1.7976931348623157e308)]))
assert.Equal(t, "-12340000000" , string(buf[:__f64toa(&buf[0], -1234e7)]))
assert.Equal(t, "-12.34" , string(buf[:__f64toa(&buf[0], -1234e-2)]))
assert.Equal(t, "-0.001234" , string(buf[:__f64toa(&buf[0], -1234e-6)]))
assert.Equal(t, "-1e30" , string(buf[:__f64toa(&buf[0], -1e30)]))
assert.Equal(t, "-1.234e33" , string(buf[:__f64toa(&buf[0], -1234e30)]))
assert.Equal(t, "-1.234e308" , string(buf[:__f64toa(&buf[0], -1234e305)]))
assert.Equal(t, "-1.234e-317" , string(buf[:__f64toa(&buf[0], -1234e-320)]))
assert.Equal(t, "-2.2250738585072014e-308" , string(buf[:__f64toa(&buf[0], -2.2250738585072014e-308)]))
}
func BenchmarkFastFloat_Encode(b *testing.B) {
val := -2.2250738585072014e-308
benchmarks := []struct {
name string
test func(*testing.B)
}{{
name: "StdLib",
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
}, {
name: "FastFloat",
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
}}
for _, bm := range benchmarks {
b.Run(bm.name, bm.test)
}
}
func BenchmarkFastFloat_EncodeZero(b *testing.B) {
val := float64(0)
benchmarks := []struct {
name string
test func(*testing.B)
}{{
name: "StdLib",
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
}, {
name: "FastFloat",
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
}}
for _, bm := range benchmarks {
b.Run(bm.name, bm.test)
}
}

View file

@ -0,0 +1,135 @@
// Code generated by Makefile, DO NOT EDIT.
/*
* Copyright 2021 ByteDance Inc.
*
* 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 sse4
import (
`strconv`
`testing`
`github.com/stretchr/testify/assert`
)
func TestFastInt_IntToString(t *testing.T) {
var buf [32]byte
assert.Equal(t, "0" , string(buf[:__i64toa(&buf[0], 0)]))
assert.Equal(t, "1" , string(buf[:__i64toa(&buf[0], 1)]))
assert.Equal(t, "12" , string(buf[:__i64toa(&buf[0], 12)]))
assert.Equal(t, "123" , string(buf[:__i64toa(&buf[0], 123)]))
assert.Equal(t, "1234" , string(buf[:__i64toa(&buf[0], 1234)]))
assert.Equal(t, "12345" , string(buf[:__i64toa(&buf[0], 12345)]))
assert.Equal(t, "123456" , string(buf[:__i64toa(&buf[0], 123456)]))
assert.Equal(t, "1234567" , string(buf[:__i64toa(&buf[0], 1234567)]))
assert.Equal(t, "12345678" , string(buf[:__i64toa(&buf[0], 12345678)]))
assert.Equal(t, "123456789" , string(buf[:__i64toa(&buf[0], 123456789)]))
assert.Equal(t, "1234567890" , string(buf[:__i64toa(&buf[0], 1234567890)]))
assert.Equal(t, "12345678901" , string(buf[:__i64toa(&buf[0], 12345678901)]))
assert.Equal(t, "123456789012" , string(buf[:__i64toa(&buf[0], 123456789012)]))
assert.Equal(t, "1234567890123" , string(buf[:__i64toa(&buf[0], 1234567890123)]))
assert.Equal(t, "12345678901234" , string(buf[:__i64toa(&buf[0], 12345678901234)]))
assert.Equal(t, "123456789012345" , string(buf[:__i64toa(&buf[0], 123456789012345)]))
assert.Equal(t, "1234567890123456" , string(buf[:__i64toa(&buf[0], 1234567890123456)]))
assert.Equal(t, "12345678901234567" , string(buf[:__i64toa(&buf[0], 12345678901234567)]))
assert.Equal(t, "123456789012345678" , string(buf[:__i64toa(&buf[0], 123456789012345678)]))
assert.Equal(t, "1234567890123456789" , string(buf[:__i64toa(&buf[0], 1234567890123456789)]))
assert.Equal(t, "9223372036854775807" , string(buf[:__i64toa(&buf[0], 9223372036854775807)]))
assert.Equal(t, "-1" , string(buf[:__i64toa(&buf[0], -1)]))
assert.Equal(t, "-12" , string(buf[:__i64toa(&buf[0], -12)]))
assert.Equal(t, "-123" , string(buf[:__i64toa(&buf[0], -123)]))
assert.Equal(t, "-1234" , string(buf[:__i64toa(&buf[0], -1234)]))
assert.Equal(t, "-12345" , string(buf[:__i64toa(&buf[0], -12345)]))
assert.Equal(t, "-123456" , string(buf[:__i64toa(&buf[0], -123456)]))
assert.Equal(t, "-1234567" , string(buf[:__i64toa(&buf[0], -1234567)]))
assert.Equal(t, "-12345678" , string(buf[:__i64toa(&buf[0], -12345678)]))
assert.Equal(t, "-123456789" , string(buf[:__i64toa(&buf[0], -123456789)]))
assert.Equal(t, "-1234567890" , string(buf[:__i64toa(&buf[0], -1234567890)]))
assert.Equal(t, "-12345678901" , string(buf[:__i64toa(&buf[0], -12345678901)]))
assert.Equal(t, "-123456789012" , string(buf[:__i64toa(&buf[0], -123456789012)]))
assert.Equal(t, "-1234567890123" , string(buf[:__i64toa(&buf[0], -1234567890123)]))
assert.Equal(t, "-12345678901234" , string(buf[:__i64toa(&buf[0], -12345678901234)]))
assert.Equal(t, "-123456789012345" , string(buf[:__i64toa(&buf[0], -123456789012345)]))
assert.Equal(t, "-1234567890123456" , string(buf[:__i64toa(&buf[0], -1234567890123456)]))
assert.Equal(t, "-12345678901234567" , string(buf[:__i64toa(&buf[0], -12345678901234567)]))
assert.Equal(t, "-123456789012345678" , string(buf[:__i64toa(&buf[0], -123456789012345678)]))
assert.Equal(t, "-1234567890123456789" , string(buf[:__i64toa(&buf[0], -1234567890123456789)]))
assert.Equal(t, "-9223372036854775808" , string(buf[:__i64toa(&buf[0], -9223372036854775808)]))
}
func TestFastInt_UintToString(t *testing.T) {
var buf [32]byte
assert.Equal(t, "0" , string(buf[:__u64toa(&buf[0], 0)]))
assert.Equal(t, "1" , string(buf[:__u64toa(&buf[0], 1)]))
assert.Equal(t, "12" , string(buf[:__u64toa(&buf[0], 12)]))
assert.Equal(t, "123" , string(buf[:__u64toa(&buf[0], 123)]))
assert.Equal(t, "1234" , string(buf[:__u64toa(&buf[0], 1234)]))
assert.Equal(t, "12345" , string(buf[:__u64toa(&buf[0], 12345)]))
assert.Equal(t, "123456" , string(buf[:__u64toa(&buf[0], 123456)]))
assert.Equal(t, "1234567" , string(buf[:__u64toa(&buf[0], 1234567)]))
assert.Equal(t, "12345678" , string(buf[:__u64toa(&buf[0], 12345678)]))
assert.Equal(t, "123456789" , string(buf[:__u64toa(&buf[0], 123456789)]))
assert.Equal(t, "1234567890" , string(buf[:__u64toa(&buf[0], 1234567890)]))
assert.Equal(t, "12345678901" , string(buf[:__u64toa(&buf[0], 12345678901)]))
assert.Equal(t, "123456789012" , string(buf[:__u64toa(&buf[0], 123456789012)]))
assert.Equal(t, "1234567890123" , string(buf[:__u64toa(&buf[0], 1234567890123)]))
assert.Equal(t, "12345678901234" , string(buf[:__u64toa(&buf[0], 12345678901234)]))
assert.Equal(t, "123456789012345" , string(buf[:__u64toa(&buf[0], 123456789012345)]))
assert.Equal(t, "1234567890123456" , string(buf[:__u64toa(&buf[0], 1234567890123456)]))
assert.Equal(t, "12345678901234567" , string(buf[:__u64toa(&buf[0], 12345678901234567)]))
assert.Equal(t, "123456789012345678" , string(buf[:__u64toa(&buf[0], 123456789012345678)]))
assert.Equal(t, "1234567890123456789" , string(buf[:__u64toa(&buf[0], 1234567890123456789)]))
assert.Equal(t, "12345678901234567890" , string(buf[:__u64toa(&buf[0], 12345678901234567890)]))
assert.Equal(t, "18446744073709551615" , string(buf[:__u64toa(&buf[0], 18446744073709551615)]))
}
func BenchmarkFastInt_IntToString(b *testing.B) {
benchmarks := []struct {
name string
test func(*testing.B)
}{{
name: "StdLib-Positive",
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], int64(i), 10) }},
}, {
name: "StdLib-Negative",
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], -int64(i), 10) }},
}, {
name: "FastInt-Positive",
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __i64toa(&buf[0], int64(i)) }},
}, {
name: "FastInt-Negative",
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __i64toa(&buf[0], -int64(i)) }},
}}
for _, bm := range benchmarks {
b.Run(bm.name, bm.test)
}
}
func BenchmarkFastInt_UintToString(b *testing.B) {
benchmarks := []struct {
name string
test func(*testing.B)
}{{
name: "StdLib",
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendUint(buf[:], uint64(i), 10) }},
}, {
name: "FastInt",
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __u64toa(&buf[0], uint64(i)) }},
}}
for _, bm := range benchmarks {
b.Run(bm.name, bm.test)
}
}

View file

@ -0,0 +1,115 @@
// Code generated by Makefile, DO NOT EDIT.
/*
* Copyright 2021 ByteDance Inc.
*
* 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 sse4
import (
`unsafe`
`github.com/bytedance/sonic/internal/native/types`
)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __i64toa(out *byte, val int64) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __u64toa(out *byte, val uint64) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __f64toa(out *byte, val float64) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __lzero(p unsafe.Pointer, n int) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __lspace(sp unsafe.Pointer, nb int, off int) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __quote(sp unsafe.Pointer, nb int, dp unsafe.Pointer, dn *int, flags uint64) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __html_escape(sp unsafe.Pointer, nb int, dp unsafe.Pointer, dn *int) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __unquote(sp unsafe.Pointer, nb int, dp unsafe.Pointer, ep *int, flags uint64) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __value(s unsafe.Pointer, n int, p int, v *types.JsonState, flags uint64) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __vstring(s *string, p *int, v *types.JsonState, flags uint64)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __vnumber(s *string, p *int, v *types.JsonState)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __vsigned(s *string, p *int, v *types.JsonState)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __vunsigned(s *string, p *int, v *types.JsonState)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __skip_one(s *string, p *int, m *types.StateMachine, flags uint64) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __skip_array(s *string, p *int, m *types.StateMachine, flags uint64) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __skip_object(s *string, p *int, m *types.StateMachine, flags uint64) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __skip_number(s *string, p *int) (ret int)
//go:nosplit
//go:noescape
//goland:noinspection GoUnusedParameter
func __validate_one(s *string, p *int, m *types.StateMachine) (ret int)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,593 @@
// Code generated by Makefile, DO NOT EDIT.
/*
* Copyright 2021 ByteDance Inc.
*
* 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 sse4
import (
`encoding/hex`
`fmt`
`math`
`testing`
`unsafe`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
`github.com/davecgh/go-spew/spew`
`github.com/stretchr/testify/assert`
`github.com/stretchr/testify/require`
)
func TestNative_Value(t *testing.T) {
var v types.JsonState
s := ` -12345`
p := (*rt.GoString)(unsafe.Pointer(&s))
x := __value(p.Ptr, p.Len, 0, &v, 0)
assert.Equal(t, 9, x)
assert.Equal(t, types.V_INTEGER, v.Vt)
assert.Equal(t, int64(-12345), v.Iv)
assert.Equal(t, 3, v.Ep)
}
func TestNative_Value_OutOfBound(t *testing.T) {
var v types.JsonState
mem := []byte{'"', '"'}
s := rt.Mem2Str(mem[:1])
p := (*rt.GoString)(unsafe.Pointer(&s))
x := __value(p.Ptr, p.Len, 0, &v, 0)
assert.Equal(t, 1, x)
assert.Equal(t, -int(types.ERR_EOF), int(v.Vt))
}
func TestNative_Quote(t *testing.T) {
s := "hello\b\f\n\r\t\\\"\u666fworld"
d := make([]byte, 256)
dp := (*rt.GoSlice)(unsafe.Pointer(&d))
sp := (*rt.GoString)(unsafe.Pointer(&s))
rv := __quote(sp.Ptr, sp.Len, dp.Ptr, &dp.Len, 0)
if rv < 0 {
require.NoError(t, types.ParsingError(-rv))
}
assert.Equal(t, len(s), rv)
assert.Equal(t, 35, len(d))
assert.Equal(t, `hello\u0008\u000c\n\r\t\\\"景world`, string(d))
}
func TestNative_QuoteNoMem(t *testing.T) {
s := "hello\b\f\n\r\t\\\"\u666fworld"
d := make([]byte, 10)
dp := (*rt.GoSlice)(unsafe.Pointer(&d))
sp := (*rt.GoString)(unsafe.Pointer(&s))
rv := __quote(sp.Ptr, sp.Len, dp.Ptr, &dp.Len, 0)
assert.Equal(t, -6, rv)
assert.Equal(t, 5, len(d))
assert.Equal(t, `hello`, string(d))
}
func TestNative_DoubleQuote(t *testing.T) {
s := "hello\b\f\n\r\t\\\"\u666fworld"
d := make([]byte, 256)
dp := (*rt.GoSlice)(unsafe.Pointer(&d))
sp := (*rt.GoString)(unsafe.Pointer(&s))
rv := __quote(sp.Ptr, sp.Len, dp.Ptr, &dp.Len, types.F_DOUBLE_UNQUOTE)
if rv < 0 {
require.NoError(t, types.ParsingError(-rv))
}
assert.Equal(t, len(s), rv)
assert.Equal(t, 44, len(d))
assert.Equal(t, `hello\\u0008\\u000c\\n\\r\\t\\\\\\\"景world`, string(d))
}
func TestNative_Unquote(t *testing.T) {
s := `hello\b\f\n\r\t\\\"\u2333world`
d := make([]byte, 0, len(s))
ep := -1
dp := (*rt.GoSlice)(unsafe.Pointer(&d))
sp := (*rt.GoString)(unsafe.Pointer(&s))
rv := __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
if rv < 0 {
require.NoError(t, types.ParsingError(-rv))
}
dp.Len = rv
assert.Equal(t, -1, ep)
assert.Equal(t, "hello\b\f\n\r\t\\\"\u2333world", string(d))
}
func TestNative_UnquoteError(t *testing.T) {
s := `asdf\`
d := make([]byte, 0, len(s))
ep := -1
dp := (*rt.GoSlice)(unsafe.Pointer(&d))
sp := (*rt.GoString)(unsafe.Pointer(&s))
rv := __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
assert.Equal(t, -int(types.ERR_EOF), rv)
assert.Equal(t, 5, ep)
s = `asdf\gqwer`
d = make([]byte, 0, len(s))
ep = -1
dp = (*rt.GoSlice)(unsafe.Pointer(&d))
sp = (*rt.GoString)(unsafe.Pointer(&s))
rv = __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
assert.Equal(t, -int(types.ERR_INVALID_ESCAPE), rv)
assert.Equal(t, 5, ep)
s = `asdf\u1gggqwer`
d = make([]byte, 0, len(s))
ep = -1
dp = (*rt.GoSlice)(unsafe.Pointer(&d))
sp = (*rt.GoString)(unsafe.Pointer(&s))
rv = __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
assert.Equal(t, -int(types.ERR_INVALID_CHAR), rv)
assert.Equal(t, 7, ep)
s = `asdf\ud800qwer`
d = make([]byte, 0, len(s))
ep = -1
dp = (*rt.GoSlice)(unsafe.Pointer(&d))
sp = (*rt.GoString)(unsafe.Pointer(&s))
rv = __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
assert.Equal(t, -int(types.ERR_INVALID_UNICODE), rv)
assert.Equal(t, 6, ep)
s = `asdf\\ud800qwer`
d = make([]byte, 0, len(s))
ep = -1
dp = (*rt.GoSlice)(unsafe.Pointer(&d))
sp = (*rt.GoString)(unsafe.Pointer(&s))
rv = __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_DOUBLE_UNQUOTE)
assert.Equal(t, -int(types.ERR_INVALID_UNICODE), rv)
assert.Equal(t, 7, ep)
s = `asdf\ud800\ud800qwer`
d = make([]byte, 0, len(s))
ep = -1
dp = (*rt.GoSlice)(unsafe.Pointer(&d))
sp = (*rt.GoString)(unsafe.Pointer(&s))
rv = __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
assert.Equal(t, -int(types.ERR_INVALID_UNICODE), rv)
assert.Equal(t, 12, ep)
s = `asdf\\ud800\\ud800qwer`
d = make([]byte, 0, len(s))
ep = -1
dp = (*rt.GoSlice)(unsafe.Pointer(&d))
sp = (*rt.GoString)(unsafe.Pointer(&s))
rv = __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_DOUBLE_UNQUOTE)
assert.Equal(t, -int(types.ERR_INVALID_UNICODE), rv)
assert.Equal(t, 14, ep)
}
func TestNative_DoubleUnquote(t *testing.T) {
s := `hello\\b\\f\\n\\r\\t\\\\\\\"\\u2333world`
d := make([]byte, 0, len(s))
ep := -1
dp := (*rt.GoSlice)(unsafe.Pointer(&d))
sp := (*rt.GoString)(unsafe.Pointer(&s))
rv := __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_DOUBLE_UNQUOTE)
if rv < 0 {
require.NoError(t, types.ParsingError(-rv))
}
dp.Len = rv
assert.Equal(t, -1, ep)
assert.Equal(t, "hello\b\f\n\r\t\\\"\u2333world", string(d))
}
func TestNative_UnquoteUnicodeReplacement(t *testing.T) {
s := `hello\ud800world`
d := make([]byte, 0, len(s))
ep := -1
dp := (*rt.GoSlice)(unsafe.Pointer(&d))
sp := (*rt.GoString)(unsafe.Pointer(&s))
rv := __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_UNICODE_REPLACE)
if rv < 0 {
require.NoError(t, types.ParsingError(-rv))
}
dp.Len = rv
assert.Equal(t, -1, ep)
assert.Equal(t, "hello\ufffdworld", string(d))
s = `hello\ud800\ud800world`
d = make([]byte, 0, len(s))
ep = -1
dp = (*rt.GoSlice)(unsafe.Pointer(&d))
sp = (*rt.GoString)(unsafe.Pointer(&s))
rv = __unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_UNICODE_REPLACE)
if rv < 0 {
require.NoError(t, types.ParsingError(-rv))
}
dp.Len = rv
assert.Equal(t, -1, ep)
assert.Equal(t, "hello\ufffd\ufffdworld", string(d))
}
func TestNative_HTMLEscape(t *testing.T) {
s := "hello\u2029\u2028<&>world"
d := make([]byte, 256)
dp := (*rt.GoSlice)(unsafe.Pointer(&d))
sp := (*rt.GoString)(unsafe.Pointer(&s))
rv := __html_escape(sp.Ptr, sp.Len, dp.Ptr, &dp.Len)
if rv < 0 {
require.NoError(t, types.ParsingError(-rv))
}
assert.Equal(t, len(s), rv)
assert.Equal(t, 40, len(d))
assert.Equal(t, `hello\u2029\u2028\u003c\u0026\u003eworld`, string(d))
}
func TestNative_HTMLEscapeNoMem(t *testing.T) {
s := "hello\u2029\u2028<&>world"
d := make([]byte, 10)
dp := (*rt.GoSlice)(unsafe.Pointer(&d))
sp := (*rt.GoString)(unsafe.Pointer(&s))
rv := __html_escape(sp.Ptr, sp.Len, dp.Ptr, &dp.Len)
assert.Equal(t, -6, rv)
assert.Equal(t, 5, len(d))
assert.Equal(t, `hello`, string(d))
}
func TestNative_Vstring(t *testing.T) {
var v types.JsonState
i := 0
s := `test"test\n2"`
__vstring(&s, &i, &v, 0)
assert.Equal(t, 5, i)
assert.Equal(t, -1, v.Ep)
assert.Equal(t, int64(0), v.Iv)
__vstring(&s, &i, &v, 0)
assert.Equal(t, 13, i)
assert.Equal(t, 9, v.Ep)
assert.Equal(t, int64(5), v.Iv)
}
func TestNative_Vstring_ValidUnescapedChars(t *testing.T) {
var v types.JsonState
valid := uint64(types.F_VALIDATE_STRING)
i := 0
s := "test\x1f\""
__vstring(&s, &i, &v, valid)
assert.Equal(t, -int(types.ERR_INVALID_CHAR), int(v.Vt))
}
func TestNative_Vstring_ValidUtf8(t *testing.T) {
var v types.JsonState
valid := uint64(types.F_VALIDATE_STRING)
i := 0
s := "test\xff\""
__vstring(&s, &i, &v, valid)
assert.Equal(t, -int(types.ERR_INVALID_CHAR), int(v.Vt))
}
func TestNative_VstringEscapeEOF(t *testing.T) {
var v types.JsonState
i := 0
s := `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"x`
__vstring(&s, &i, &v, 0)
assert.Equal(t, 95, i)
assert.Equal(t, 63, v.Ep)
assert.Equal(t, int64(0), v.Iv)
}
func TestNative_ValidateOne(t *testing.T) {
{
p := 0
s := "\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\n\\r\\b\\f😁ſ景\xef\xbf\xbf\xf4\x8f\xbf\xbf\xc2\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\""
r := __validate_one(&s, &p, &types.StateMachine{})
assert.Equal(t, len(s), p)
assert.Equal(t, 0, r)
}
{
p := 0
s := "\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\bxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"x"
r := __validate_one(&s, &p, &types.StateMachine{})
assert.Equal(t, 64, p)
assert.Equal(t, -int(types.ERR_INVALID_CHAR), r)
}
{
p := 0
s := "\"\x00\"x"
r := __validate_one(&s, &p, &types.StateMachine{})
assert.Equal(t, 1, p)
assert.Equal(t, -int(types.ERR_INVALID_CHAR), r)
}
{
p := 0
s := "\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"x"
r := __validate_one(&s, &p, &types.StateMachine{})
assert.Equal(t, 64, p)
assert.Equal(t, -int(types.ERR_INVALID_CHAR), r)
}
{
p := 0
s := "\"\x80\"x"
r := __validate_one(&s, &p, &types.StateMachine{})
assert.Equal(t, 1, p)
assert.Equal(t, -int(types.ERR_INVALID_CHAR), r)
}
{
p := 0
s := "\"\xed\xbf\xbf\"x"
r := __validate_one(&s, &p, &types.StateMachine{})
assert.Equal(t, 1, p)
assert.Equal(t, -int(types.ERR_INVALID_CHAR), r)
}
}
func TestNative_VstringHangUpOnRandomData(t *testing.T) {
v, e := hex.DecodeString(
"228dc61efd54ef80a908fb6026b7f2d5f92a257ba8b347c995f259eb8685376a" +
"8c4500262d9c308b3f3ec2577689cf345d9f86f9b5d18d3e463bec5c22df2d2e" +
"4506010eba1dae7278",
)
assert.Nil(t, e)
p := 1
s := rt.Mem2Str(v)
var js types.JsonState
__vstring(&s, &p, &js, 0)
fmt.Printf("js: %s\n", spew.Sdump(js))
}
func TestNative_Vnumber(t *testing.T) {
var v types.JsonState
i := 0
s := "1234"
__vnumber(&s, &i, &v)
assert.Equal(t, 4, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, int64(1234), v.Iv)
assert.Equal(t, types.V_INTEGER, v.Vt)
i = 0
s = "1.234"
__vnumber(&s, &i, &v)
assert.Equal(t, 5, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, 1.234, v.Dv)
assert.Equal(t, types.V_DOUBLE, v.Vt)
i = 0
s = "1.234e5"
__vnumber(&s, &i, &v)
assert.Equal(t, 7, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, 1.234e5, v.Dv)
assert.Equal(t, types.V_DOUBLE, v.Vt)
i = 0
s = "0.0125"
__vnumber(&s, &i, &v)
assert.Equal(t, 6, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, 0.0125, v.Dv)
assert.Equal(t, types.V_DOUBLE, v.Vt)
i = 0
s = "100000000000000000000"
__vnumber(&s, &i, &v)
assert.Equal(t, 21, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, 100000000000000000000.0, v.Dv)
assert.Equal(t, types.V_DOUBLE, v.Vt)
i = 0
s = "999999999999999900000"
__vnumber(&s, &i, &v)
assert.Equal(t, 21, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, 999999999999999900000.0, v.Dv)
assert.Equal(t, types.V_DOUBLE, v.Vt)
i = 0
s = "-1.234"
__vnumber(&s, &i, &v)
assert.Equal(t, 6, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, -1.234, v.Dv)
assert.Equal(t, types.V_DOUBLE, v.Vt)
}
func TestNative_Vsigned(t *testing.T) {
var v types.JsonState
i := 0
s := "1234"
__vsigned(&s, &i, &v)
assert.Equal(t, 4, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, int64(1234), v.Iv)
assert.Equal(t, types.V_INTEGER, v.Vt)
i = 0
s = "-1234"
__vsigned(&s, &i, &v)
assert.Equal(t, 5, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, int64(-1234), v.Iv)
assert.Equal(t, types.V_INTEGER, v.Vt)
i = 0
s = "9223372036854775807"
__vsigned(&s, &i, &v)
assert.Equal(t, 19, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, int64(math.MaxInt64), v.Iv)
assert.Equal(t, types.V_INTEGER, v.Vt)
i = 0
s = "-9223372036854775808"
__vsigned(&s, &i, &v)
assert.Equal(t, 20, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, int64(math.MinInt64), v.Iv)
assert.Equal(t, types.V_INTEGER, v.Vt)
i = 0
s = "9223372036854775808"
__vsigned(&s, &i, &v)
assert.Equal(t, 18, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INTEGER_OVERFLOW)), v.Vt)
i = 0
s = "-9223372036854775809"
__vsigned(&s, &i, &v)
assert.Equal(t, 19, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INTEGER_OVERFLOW)), v.Vt)
i = 0
s = "1.234"
__vsigned(&s, &i, &v)
assert.Equal(t, 1, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
i = 0
s = "0.0125"
__vsigned(&s, &i, &v)
assert.Equal(t, 1, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
i = 0
s = "-1234e5"
__vsigned(&s, &i, &v)
assert.Equal(t, 5, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
i = 0
s = "-1234e-5"
__vsigned(&s, &i, &v)
assert.Equal(t, 5, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
}
func TestNative_Vunsigned(t *testing.T) {
var v types.JsonState
i := 0
s := "1234"
__vunsigned(&s, &i, &v)
assert.Equal(t, 4, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, int64(1234), v.Iv)
assert.Equal(t, types.V_INTEGER, v.Vt)
i = 0
s = "18446744073709551615"
__vunsigned(&s, &i, &v)
assert.Equal(t, 20, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, ^int64(0), v.Iv)
assert.Equal(t, types.V_INTEGER, v.Vt)
i = 0
s = "18446744073709551616"
__vunsigned(&s, &i, &v)
assert.Equal(t, 19, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INTEGER_OVERFLOW)), v.Vt)
i = 0
s = "-1234"
__vunsigned(&s, &i, &v)
assert.Equal(t, 0, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
i = 0
s = "1.234"
__vunsigned(&s, &i, &v)
assert.Equal(t, 1, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
i = 0
s = "0.0125"
__vunsigned(&s, &i, &v)
assert.Equal(t, 1, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
i = 0
s = "1234e5"
__vunsigned(&s, &i, &v)
assert.Equal(t, 4, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
i = 0
s = "-1234e5"
__vunsigned(&s, &i, &v)
assert.Equal(t, 0, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
i = 0
s = "-1.234e5"
__vunsigned(&s, &i, &v)
assert.Equal(t, 0, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
i = 0
s = "-1.234e-5"
__vunsigned(&s, &i, &v)
assert.Equal(t, 0, i)
assert.Equal(t, 0, v.Ep)
assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
}
func TestNative_SkipOne(t *testing.T) {
p := 0
s := ` {"asdf": [null, true, false, 1, 2.0, -3]}, 1234.5`
q := __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 42, p)
assert.Equal(t, 1, q)
p = 0
s = `1 2.5 -3 "asdf\nqwer" true false null {} []`
q = __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 1, p)
assert.Equal(t, 0, q)
q = __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 5, p)
assert.Equal(t, 2, q)
q = __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 8, p)
assert.Equal(t, 6, q)
q = __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 21, p)
assert.Equal(t, 9, q)
q = __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 26, p)
assert.Equal(t, 22, q)
q = __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 32, p)
assert.Equal(t, 27, q)
q = __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 37, p)
assert.Equal(t, 33, q)
q = __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 40, p)
assert.Equal(t, 38, q)
q = __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, 43, p)
assert.Equal(t, 41, q)
}
func TestNative_SkipOne_Error(t *testing.T) {
for _, s := range([]string{
"-", "+", "0.", "0. ", "+1", "0.0e ", "9e+", "0e-",
"tru", "fals", "nul", "trux", "fals ",
`"asdf`, `"\\\"`,
}) {
p := 0
q := __skip_one(&s, &p, &types.StateMachine{}, uint64(0))
assert.True(t, q < 0)
}
}
func TestNative_SkipArray(t *testing.T) {
p := 0
s := `null, true, false, 1, 2.0, -3, {"asdf": "wqer"}],`
__skip_array(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, p, 48)
}
func TestNative_SkipObject(t *testing.T) {
p := 0
s := `"asdf": "wqer"},`
__skip_object(&s, &p, &types.StateMachine{}, uint64(0))
assert.Equal(t, p, 15)
}
func TestNative_SkipNumber(t *testing.T) {
p := 0
s := `-1.23e+12`
q := __skip_number(&s, &p)
assert.Equal(t, 9, p)
assert.Equal(t, 0, q)
}

View file

@ -0,0 +1,46 @@
// Code generated by Makefile, DO NOT EDIT.
/*
* Copyright 2021 ByteDance Inc.
*
* 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 sse4
var (
S_f64toa = _subr__f64toa
S_i64toa = _subr__i64toa
S_u64toa = _subr__u64toa
S_lspace = _subr__lspace
)
var (
S_quote = _subr__quote
S_unquote = _subr__unquote
)
var (
S_value = _subr__value
S_vstring = _subr__vstring
S_vnumber = _subr__vnumber
S_vsigned = _subr__vsigned
S_vunsigned = _subr__vunsigned
)
var (
S_skip_one = _subr__skip_one
S_skip_array = _subr__skip_array
S_skip_object = _subr__skip_object
S_skip_number = _subr__skip_number
)

View file

@ -0,0 +1,93 @@
// +build !noasm !appengine
// Code generated by asm2asm, DO NOT EDIT.
package sse4
//go:nosplit
//go:noescape
//goland:noinspection ALL
func __native_entry__() uintptr
var (
_subr__f64toa = __native_entry__() + 640
_subr__html_escape = __native_entry__() + 9808
_subr__i64toa = __native_entry__() + 3440
_subr__lspace = __native_entry__() + 256
_subr__lzero = __native_entry__() + 16
_subr__quote = __native_entry__() + 4848
_subr__skip_array = __native_entry__() + 22320
_subr__skip_number = __native_entry__() + 23824
_subr__skip_object = __native_entry__() + 22368
_subr__skip_one = __native_entry__() + 20448
_subr__u64toa = __native_entry__() + 3568
_subr__unquote = __native_entry__() + 6624
_subr__validate_one = __native_entry__() + 23968
_subr__value = __native_entry__() + 13072
_subr__vnumber = __native_entry__() + 18192
_subr__vsigned = __native_entry__() + 19744
_subr__vstring = __native_entry__() + 15152
_subr__vunsigned = __native_entry__() + 20096
)
const (
_stack__f64toa = 128
_stack__html_escape = 64
_stack__i64toa = 16
_stack__lspace = 8
_stack__lzero = 8
_stack__quote = 80
_stack__skip_array = 128
_stack__skip_number = 72
_stack__skip_object = 128
_stack__skip_one = 128
_stack__u64toa = 8
_stack__unquote = 72
_stack__validate_one = 128
_stack__value = 336
_stack__vnumber = 248
_stack__vsigned = 16
_stack__vstring = 144
_stack__vunsigned = 24
)
var (
_ = _subr__f64toa
_ = _subr__html_escape
_ = _subr__i64toa
_ = _subr__lspace
_ = _subr__lzero
_ = _subr__quote
_ = _subr__skip_array
_ = _subr__skip_number
_ = _subr__skip_object
_ = _subr__skip_one
_ = _subr__u64toa
_ = _subr__unquote
_ = _subr__validate_one
_ = _subr__value
_ = _subr__vnumber
_ = _subr__vsigned
_ = _subr__vstring
_ = _subr__vunsigned
)
const (
_ = _stack__f64toa
_ = _stack__html_escape
_ = _stack__i64toa
_ = _stack__lspace
_ = _stack__lzero
_ = _stack__quote
_ = _stack__skip_array
_ = _stack__skip_number
_ = _stack__skip_object
_ = _stack__skip_one
_ = _stack__u64toa
_ = _stack__unquote
_ = _stack__validate_one
_ = _stack__value
_ = _stack__vnumber
_ = _stack__vsigned
_ = _stack__vstring
_ = _stack__vunsigned
)

@ -1 +1 @@
Subproject commit 5e85f0dbbd2eb4768d8413c326e5540612c86fae
Subproject commit 62deb479a1080dd92ee9ca8dbd9c53796828aa3e