mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-02-08 22:00:17 +00:00
[chore]: Bump github.com/gin-contrib/gzip from 1.1.0 to 1.2.2 (#3693)
Bumps [github.com/gin-contrib/gzip](https://github.com/gin-contrib/gzip) from 1.1.0 to 1.2.2. - [Release notes](https://github.com/gin-contrib/gzip/releases) - [Changelog](https://github.com/gin-contrib/gzip/blob/master/.goreleaser.yaml) - [Commits](https://github.com/gin-contrib/gzip/compare/v1.1.0...v1.2.2) --- updated-dependencies: - dependency-name: github.com/gin-contrib/gzip dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
2a46681147
commit
5c96702cb5
17
go.mod
17
go.mod
|
@ -48,7 +48,7 @@ require (
|
|||
github.com/buckket/go-blurhash v1.1.0
|
||||
github.com/coreos/go-oidc/v3 v3.12.0
|
||||
github.com/gin-contrib/cors v1.7.3
|
||||
github.com/gin-contrib/gzip v1.1.0
|
||||
github.com/gin-contrib/gzip v1.2.2
|
||||
github.com/gin-contrib/sessions v1.0.2
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/go-playground/form/v4 v4.2.1
|
||||
|
@ -114,13 +114,12 @@ require (
|
|||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.12.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.1 // indirect
|
||||
github.com/bytedance/sonic v1.12.7 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.2 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cilium/ebpf v0.9.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.0.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
|
@ -133,8 +132,8 @@ require (
|
|||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.7 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/gin-contrib/sse v1.0.0 // indirect
|
||||
github.com/go-errors/errors v1.1.1 // indirect
|
||||
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
|
@ -154,7 +153,7 @@ require (
|
|||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.23.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.24.0 // indirect
|
||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect
|
||||
github.com/goccy/go-json v0.10.4 // indirect
|
||||
github.com/godbus/dbus/v5 v5.0.4 // indirect
|
||||
|
@ -230,7 +229,7 @@ require (
|
|||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.12.0 // indirect
|
||||
golang.org/x/arch v0.13.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
|
@ -239,7 +238,7 @@ require (
|
|||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/grpc v1.66.1 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
google.golang.org/protobuf v1.36.2 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||
|
|
35
go.sum
generated
35
go.sum
generated
|
@ -103,11 +103,11 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
|||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/buckket/go-blurhash v1.1.0 h1:X5M6r0LIvwdvKiUtiNcRL2YlmOfMzYobI3VCKCZc9Do=
|
||||
github.com/buckket/go-blurhash v1.1.0/go.mod h1:aT2iqo5W9vu9GpyoLErKfTHwgODsZp3bQfXjXJUxNb8=
|
||||
github.com/bytedance/sonic v1.12.6 h1:/isNmCUF2x3Sh8RAp/4mh4ZGkcFAX/hLrzrK3AvpRzk=
|
||||
github.com/bytedance/sonic v1.12.6/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||
github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q=
|
||||
github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
|
||||
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.2 h1:jxAJuN9fOot/cyz5Q6dUuMJF5OqQ6+5GfA8FjjQ0R4o=
|
||||
github.com/bytedance/sonic/loader v0.2.2/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
|
@ -121,7 +121,6 @@ github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnx
|
|||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdknSRMDrAr8mfxPCfSZolH+/qQnyQ=
|
||||
|
@ -175,18 +174,18 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
|
|||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fxamacker/cbor v1.5.1 h1:XjQWBgdmQyqimslUh5r4tUGmoqzHmBFQOImkWGi2awg=
|
||||
github.com/fxamacker/cbor v1.5.1/go.mod h1:3aPGItF174ni7dDzd6JZ206H8cmr4GDNBGpPa971zsU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=
|
||||
github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8=
|
||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||
github.com/gin-contrib/cors v1.7.3 h1:hV+a5xp8hwJoTw7OY+a70FsL8JkVVFTXw9EcfrYUdns=
|
||||
github.com/gin-contrib/cors v1.7.3/go.mod h1:M3bcKZhxzsvI+rlRSkkxHyljJt1ESd93COUvemZ79j4=
|
||||
github.com/gin-contrib/gzip v1.1.0 h1:kVw7Nr9M+Z6Ch4qo7aGMbiqxDeyQFru+07MgAcUF62M=
|
||||
github.com/gin-contrib/gzip v1.1.0/go.mod h1:iHJXCup4CWiKyPUEl+GwkHjchl+YyYuMKbOCiXujPIA=
|
||||
github.com/gin-contrib/gzip v1.2.2 h1:iUU/EYCM8ENfkjmZaVrxbjF/ZC267Iqv5S0MMCMEliI=
|
||||
github.com/gin-contrib/gzip v1.2.2/go.mod h1:C1a5cacjlDsS20cKnHlZRCPUu57D3qH6B2pV0rl+Y/s=
|
||||
github.com/gin-contrib/sessions v1.0.2 h1:UaIjUvTH1cMeOdj3in6dl+Xb6It8RiKRF9Z1anbUyCA=
|
||||
github.com/gin-contrib/sessions v1.0.2/go.mod h1:KxKxWqWP5LJVDCInulOl4WbLzK2KSPlLesfZ66wRvMs=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E=
|
||||
github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
|
@ -238,8 +237,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
|||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
|
||||
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg=
|
||||
github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
||||
github.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
|
@ -517,6 +516,7 @@ github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
|
@ -526,6 +526,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
|
@ -661,8 +662,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
|||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg=
|
||||
golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA=
|
||||
golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -959,8 +960,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
|
||||
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
5
vendor/github.com/bytedance/sonic/.codespellrc
generated
vendored
Normal file
5
vendor/github.com/bytedance/sonic/.codespellrc
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
[codespell]
|
||||
# ignore test files, go project names, binary files via `skip` and special var/regex via `ignore-words`
|
||||
skip = fuzz,*_test.tmpl,testdata,*_test.go,go.mod,go.sum,*.gz
|
||||
ignore-words = .github/workflows/.ignore_words
|
||||
check-filenames = true
|
11
vendor/github.com/bytedance/sonic/README.md
generated
vendored
11
vendor/github.com/bytedance/sonic/README.md
generated
vendored
|
@ -211,7 +211,7 @@ ret, err := Encode(v, EscapeHTML) // ret == `{"\u0026\u0026":{"X":"\u003c\u003e"
|
|||
|
||||
### Compact Format
|
||||
|
||||
Sonic encodes primitive objects (struct/map...) as compact-format JSON by default, except marshaling `json.RawMessage` or `json.Marshaler`: sonic ensures validating their output JSON but **DONOT** compacting them for performance concerns. We provide the option `encoder.CompactMarshaler` to add compacting process.
|
||||
Sonic encodes primitive objects (struct/map...) as compact-format JSON by default, except marshaling `json.RawMessage` or `json.Marshaler`: sonic ensures validating their output JSON but **DO NOT** compacting them for performance concerns. We provide the option `encoder.CompactMarshaler` to add compacting process.
|
||||
|
||||
### Print Error
|
||||
|
||||
|
@ -480,9 +480,9 @@ But `ast.Visitor` is not a very handy API. You might need to write a lot of code
|
|||
|
||||
### Buffer Size
|
||||
|
||||
Sonic use memory pool in many places like `encoder.Encode`, `ast.Node.MarshalJSON` to improve performace, which may produce more memory usage (in-use) when server's load is high. See [issue 614](https://github.com/bytedance/sonic/issues/614). Therefore, we introduce some options to let user control the behavior of memory pool. See [option](https://pkg.go.dev/github.com/bytedance/sonic@v1.11.9/option#pkg-variables) package.
|
||||
Sonic use memory pool in many places like `encoder.Encode`, `ast.Node.MarshalJSON` to improve performance, which may produce more memory usage (in-use) when server's load is high. See [issue 614](https://github.com/bytedance/sonic/issues/614). Therefore, we introduce some options to let user control the behavior of memory pool. See [option](https://pkg.go.dev/github.com/bytedance/sonic@v1.11.9/option#pkg-variables) package.
|
||||
|
||||
### Faster JSON skip
|
||||
### Faster JSON Skip
|
||||
|
||||
For security, sonic use [FSM](native/skip_one.c) algorithm to validate JSON when decoding raw JSON or encoding `json.Marshaler`, which is much slower (1~10x) than [SIMD-searching-pair](native/skip_one_fast.c) algorithm. If user has many redundant JSON value and DO NOT NEED to strictly validate JSON correctness, you can enable below options:
|
||||
|
||||
|
@ -490,6 +490,11 @@ For security, sonic use [FSM](native/skip_one.c) algorithm to validate JSON whe
|
|||
- `Config.NoValidateJSONMarshaler`: avoid validating JSON when encoding `json.Marshaler`
|
||||
- `SearchOption.ValidateJSON`: indicates if validate located JSON value when `Get`
|
||||
|
||||
## JSON-Path Support (GJSON)
|
||||
|
||||
[tidwall/gjson](https://github.com/tidwall/gjson) has provided a comprehensive and popular JSON-Path API, and
|
||||
a lot of older codes heavily relies on it. Therefore, we provides a wrapper library, which combines gjson's API with sonic's SIMD algorithm to boost up the performance. See [cloudwego/gjson](https://github.com/cloudwego/gjson).
|
||||
|
||||
## Community
|
||||
|
||||
Sonic is a subproject of [CloudWeGo](https://www.cloudwego.io/). We are committed to building a cloud native ecosystem.
|
||||
|
|
4
vendor/github.com/bytedance/sonic/api.go
generated
vendored
4
vendor/github.com/bytedance/sonic/api.go
generated
vendored
|
@ -77,7 +77,7 @@ type Config struct {
|
|||
// CopyString indicates decoder to decode string values by copying instead of referring.
|
||||
CopyString bool
|
||||
|
||||
// ValidateString indicates decoder and encoder to valid string values: decoder will return errors
|
||||
// ValidateString indicates decoder and encoder to validate string values: decoder will return errors
|
||||
// when unescaped control chars(\u0000-\u001f) in the string value of JSON.
|
||||
ValidateString bool
|
||||
|
||||
|
@ -120,7 +120,7 @@ type Config struct {
|
|||
|
||||
// API is a binding of specific config.
|
||||
// This interface is inspired by github.com/json-iterator/go,
|
||||
// and has same behaviors under equavilent config.
|
||||
// and has same behaviors under equivalent config.
|
||||
type API interface {
|
||||
// MarshalToString returns the JSON encoding string of v
|
||||
MarshalToString(v interface{}) (string, error)
|
||||
|
|
2
vendor/github.com/bytedance/sonic/ast/api_compat.go
generated
vendored
2
vendor/github.com/bytedance/sonic/ast/api_compat.go
generated
vendored
|
@ -34,7 +34,7 @@ func quote(buf *[]byte, val string) {
|
|||
quoteString(buf, val)
|
||||
}
|
||||
|
||||
// unquote unescapes a internal JSON string (it doesn't count quotas at the begining and end)
|
||||
// unquote unescapes an internal JSON string (it doesn't count quotas at the beginning and end)
|
||||
func unquote(src string) (string, types.ParsingError) {
|
||||
sp := rt.IndexChar(src, -1)
|
||||
out, ok := unquoteBytes(rt.BytesFrom(sp, len(src)+2, len(src)+2))
|
||||
|
|
2
vendor/github.com/bytedance/sonic/ast/decode.go
generated
vendored
2
vendor/github.com/bytedance/sonic/ast/decode.go
generated
vendored
|
@ -27,7 +27,7 @@
|
|||
"github.com/bytedance/sonic/internal/utils"
|
||||
)
|
||||
|
||||
// Hack: this is used for both checking space and cause firendly compile errors in 32-bit arch.
|
||||
// Hack: this is used for both checking space and cause friendly compile errors in 32-bit arch.
|
||||
const _Sonic_Not_Support_32Bit_Arch__Checking_32Bit_Arch_Here = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n')
|
||||
|
||||
var bytesNull = []byte("null")
|
||||
|
|
2
vendor/github.com/bytedance/sonic/ast/iterator.go
generated
vendored
2
vendor/github.com/bytedance/sonic/ast/iterator.go
generated
vendored
|
@ -173,7 +173,7 @@ func (s Sequence) String() string {
|
|||
// ForEach scans one V_OBJECT node's children from JSON head to tail,
|
||||
// and pass the Sequence and Node of corresponding JSON value.
|
||||
//
|
||||
// Especailly, if the node is not V_ARRAY or V_OBJECT,
|
||||
// Especially, if the node is not V_ARRAY or V_OBJECT,
|
||||
// the node itself will be returned and Sequence.Index == -1.
|
||||
//
|
||||
// NOTICE: A unsetted node WON'T trigger sc, but its index still counts into Path.Index
|
||||
|
|
22
vendor/github.com/bytedance/sonic/ast/node.go
generated
vendored
22
vendor/github.com/bytedance/sonic/ast/node.go
generated
vendored
|
@ -140,7 +140,7 @@ func (self *Node) Check() error {
|
|||
|
||||
// isRaw returns true if node's underlying value is raw json
|
||||
//
|
||||
// Deprecated: not concurent safe
|
||||
// Deprecated: not concurrent safe
|
||||
func (self Node) IsRaw() bool {
|
||||
return self.t & _V_RAW != 0
|
||||
}
|
||||
|
@ -440,7 +440,7 @@ func (self *Node) String() (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// StrictString returns string value (unescaped), includeing V_STRING, V_ANY of string.
|
||||
// StrictString returns string value (unescaped), including V_STRING, V_ANY of string.
|
||||
// In other cases, it will return empty string.
|
||||
func (self *Node) StrictString() (string, error) {
|
||||
if err := self.checkRaw(); err != nil {
|
||||
|
@ -509,7 +509,7 @@ func (self *Node) Float64() (float64, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Float64 exports underlying float64 value, includeing V_NUMBER, V_ANY
|
||||
// Float64 exports underlying float64 value, including V_NUMBER, V_ANY
|
||||
func (self *Node) StrictFloat64() (float64, error) {
|
||||
if err := self.checkRaw(); err != nil {
|
||||
return 0.0, err
|
||||
|
@ -527,7 +527,7 @@ func (self *Node) StrictFloat64() (float64, error) {
|
|||
}
|
||||
}
|
||||
|
||||
/** Sequencial Value Methods **/
|
||||
/** Sequential Value Methods **/
|
||||
|
||||
// Len returns children count of a array|object|string node
|
||||
// WARN: For partially loaded node, it also works but only counts the parsed children
|
||||
|
@ -611,7 +611,7 @@ func (self *Node) Unset(key string) (bool, error) {
|
|||
if err := self.should(types.V_OBJECT); err != nil {
|
||||
return false, err
|
||||
}
|
||||
// NOTICE: must get acurate length before deduct
|
||||
// NOTICE: must get accurate length before deduct
|
||||
if err := self.skipAllKey(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -657,7 +657,7 @@ func (self *Node) SetAnyByIndex(index int, val interface{}) (bool, error) {
|
|||
return self.SetByIndex(index, NewAny(val))
|
||||
}
|
||||
|
||||
// UnsetByIndex REOMVE (softly) the node of given index.
|
||||
// UnsetByIndex REMOVE (softly) the node of given index.
|
||||
//
|
||||
// WARN: this will change address of elements, which is a dangerous action.
|
||||
// Use Unset() for object or Pop() for array instead.
|
||||
|
@ -957,7 +957,7 @@ func (self *Node) MapUseNumber() (map[string]interface{}, error) {
|
|||
return self.toGenericObjectUseNumber()
|
||||
}
|
||||
|
||||
// MapUseNode scans both parsed and non-parsed chidren nodes,
|
||||
// MapUseNode scans both parsed and non-parsed children nodes,
|
||||
// and map them by their keys
|
||||
func (self *Node) MapUseNode() (map[string]Node, error) {
|
||||
if self.isAny() {
|
||||
|
@ -1102,7 +1102,7 @@ func (self *Node) ArrayUseNumber() ([]interface{}, error) {
|
|||
return self.toGenericArrayUseNumber()
|
||||
}
|
||||
|
||||
// ArrayUseNode copys both parsed and non-parsed chidren nodes,
|
||||
// ArrayUseNode copies both parsed and non-parsed children nodes,
|
||||
// and indexes them by original order
|
||||
func (self *Node) ArrayUseNode() ([]Node, error) {
|
||||
if self.isAny() {
|
||||
|
@ -1147,9 +1147,9 @@ func (self *Node) unsafeArray() (*linkedNodes, error) {
|
|||
return (*linkedNodes)(self.p), nil
|
||||
}
|
||||
|
||||
// Interface loads all children under all pathes from this node,
|
||||
// Interface loads all children under all paths from this node,
|
||||
// and converts itself as generic type.
|
||||
// WARN: all numberic nodes are casted to float64
|
||||
// WARN: all numeric nodes are casted to float64
|
||||
func (self *Node) Interface() (interface{}, error) {
|
||||
if err := self.checkRaw(); err != nil {
|
||||
return nil, err
|
||||
|
@ -1193,7 +1193,7 @@ func (self *Node) packAny() interface{} {
|
|||
}
|
||||
|
||||
// InterfaceUseNumber works same with Interface()
|
||||
// except numberic nodes are casted to json.Number
|
||||
// except numeric nodes are casted to json.Number
|
||||
func (self *Node) InterfaceUseNumber() (interface{}, error) {
|
||||
if err := self.checkRaw(); err != nil {
|
||||
return nil, err
|
||||
|
|
4
vendor/github.com/bytedance/sonic/decoder/decoder_compat.go
generated
vendored
4
vendor/github.com/bytedance/sonic/decoder/decoder_compat.go
generated
vendored
|
@ -192,5 +192,5 @@ func (s SyntaxError) Error() string {
|
|||
return (*json.SyntaxError)(unsafe.Pointer(&s)).Error()
|
||||
}
|
||||
|
||||
// MismatchTypeError represents dismatching between json and object
|
||||
type MismatchTypeError json.UnmarshalTypeError
|
||||
// MismatchTypeError represents mismatching between json and object
|
||||
type MismatchTypeError json.UnmarshalTypeError
|
||||
|
|
2
vendor/github.com/bytedance/sonic/decoder/decoder_native.go
generated
vendored
2
vendor/github.com/bytedance/sonic/decoder/decoder_native.go
generated
vendored
|
@ -30,7 +30,7 @@
|
|||
// SyntaxError represents json syntax error
|
||||
type SyntaxError = api.SyntaxError
|
||||
|
||||
// MismatchTypeError represents dismatching between json and object
|
||||
// MismatchTypeError represents mismatching between json and object
|
||||
type MismatchTypeError = api.MismatchTypeError
|
||||
|
||||
// Options for decode.
|
||||
|
|
2
vendor/github.com/bytedance/sonic/go.work.sum
generated
vendored
2
vendor/github.com/bytedance/sonic/go.work.sum
generated
vendored
|
@ -1 +1,3 @@
|
|||
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.2/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
|
|
2
vendor/github.com/bytedance/sonic/internal/decoder/api/decoder_arm64.go
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/decoder/api/decoder_arm64.go
generated
vendored
|
@ -30,7 +30,7 @@
|
|||
|
||||
|
||||
func init() {
|
||||
// whe in aarch64. we enable all optimize
|
||||
// when in aarch64, we enable all optimization
|
||||
envs.EnableOptDec()
|
||||
envs.EnableFastMap()
|
||||
}
|
||||
|
|
8
vendor/github.com/bytedance/sonic/internal/decoder/jitdec/assembler_regabi_amd64.go
generated
vendored
8
vendor/github.com/bytedance/sonic/internal/decoder/jitdec/assembler_regabi_amd64.go
generated
vendored
|
@ -67,7 +67,7 @@
|
|||
*/
|
||||
|
||||
const (
|
||||
_FP_args = 72 // 72 bytes to pass and spill register arguements
|
||||
_FP_args = 72 // 72 bytes to pass and spill register arguments
|
||||
_FP_fargs = 80 // 80 bytes for passing arguments to other Go functions
|
||||
_FP_saves = 48 // 48 bytes for saving the registers before CALL instructions
|
||||
_FP_locals = 144 // 144 bytes for local variables
|
||||
|
@ -203,9 +203,9 @@
|
|||
var _VAR_fl = jit.Ptr(_SP, _FP_fargs + _FP_saves + 112)
|
||||
|
||||
var (
|
||||
_VAR_et = jit.Ptr(_SP, _FP_fargs + _FP_saves + 120) // save dismatched type
|
||||
_VAR_et = jit.Ptr(_SP, _FP_fargs + _FP_saves + 120) // save mismatched type
|
||||
_VAR_pc = jit.Ptr(_SP, _FP_fargs + _FP_saves + 128) // save skip return pc
|
||||
_VAR_ic = jit.Ptr(_SP, _FP_fargs + _FP_saves + 136) // save dismatched position
|
||||
_VAR_ic = jit.Ptr(_SP, _FP_fargs + _FP_saves + 136) // save mismatched position
|
||||
)
|
||||
|
||||
type _Assembler struct {
|
||||
|
@ -1361,7 +1361,7 @@ func (self *_Assembler) _asm_OP_num(_ *_Instr) {
|
|||
self.Emit("MOVQ", _R9, _VAR_pc)
|
||||
self.Sjmp("JMP" , _LB_skip_one)
|
||||
|
||||
/* assgin string */
|
||||
/* assign string */
|
||||
self.Link("_num_next_{n}")
|
||||
self.slice_from_r(_AX, 0)
|
||||
self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv)
|
||||
|
|
2
vendor/github.com/bytedance/sonic/internal/decoder/jitdec/compiler.go
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/decoder/jitdec/compiler.go
generated
vendored
|
@ -736,7 +736,7 @@ func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) {
|
|||
self.tab[et] = true
|
||||
|
||||
/* not inline the pointer type
|
||||
* recursing the defined pointer type's elem will casue issue379.
|
||||
* recursing the defined pointer type's elem will cause issue379.
|
||||
*/
|
||||
self.compileOps(p, sp, et)
|
||||
}
|
||||
|
|
4
vendor/github.com/bytedance/sonic/internal/decoder/jitdec/pools.go
generated
vendored
4
vendor/github.com/bytedance/sonic/internal/decoder/jitdec/pools.go
generated
vendored
|
@ -63,8 +63,8 @@ type _Stack struct {
|
|||
vp unsafe.Pointer,
|
||||
sb *_Stack,
|
||||
fv uint64,
|
||||
sv string, // DO NOT pass value to this arguement, since it is only used for local _VAR_sv
|
||||
vk unsafe.Pointer, // DO NOT pass value to this arguement, since it is only used for local _VAR_vk
|
||||
sv string, // DO NOT pass value to this argument, since it is only used for local _VAR_sv
|
||||
vk unsafe.Pointer, // DO NOT pass value to this argument, since it is only used for local _VAR_vk
|
||||
) (int, error)
|
||||
|
||||
var _KeepAlive struct {
|
||||
|
|
4
vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go
generated
vendored
4
vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go
generated
vendored
|
@ -177,7 +177,7 @@ func (c *compiler) compilePtr(vt reflect.Type) decFunc {
|
|||
c.enter(vt)
|
||||
defer c.exit(vt)
|
||||
|
||||
// specail logic for Named Ptr, issue 379
|
||||
// special logic for Named Ptr, issue 379
|
||||
if reflect.PtrTo(vt.Elem()) != vt {
|
||||
c.namedPtr = true
|
||||
return &ptrDecoder{
|
||||
|
@ -432,7 +432,7 @@ func (c *compiler) tryCompilePtrUnmarshaler(vt reflect.Type, strOpt bool) decFun
|
|||
|
||||
/* check for `encoding.TextMarshaler` with pointer receiver */
|
||||
if pt.Implements(encodingTextUnmarshalerType) {
|
||||
/* TextUnmarshal not support ,strig tag */
|
||||
/* TextUnmarshal not support, string tag */
|
||||
if strOpt {
|
||||
panicForInvalidStrType(vt)
|
||||
}
|
||||
|
|
8
vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go
generated
vendored
8
vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go
generated
vendored
|
@ -11,7 +11,7 @@
|
|||
|
||||
|
||||
func SkipNumberFast(json string, start int) (int, bool) {
|
||||
// find the number ending, we pasred in native, it alway valid
|
||||
// find the number ending, we parsed in native, it always valid
|
||||
pos := start
|
||||
for pos < len(json) && json[pos] != ']' && json[pos] != '}' && json[pos] != ',' {
|
||||
if json[pos] >= '0' && json[pos] <= '9' || json[pos] == '.' || json[pos] == '-' || json[pos] == '+' || json[pos] == 'e' || json[pos] == 'E' {
|
||||
|
@ -40,7 +40,7 @@ func ValidNumberFast(raw string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// check trainling chars
|
||||
// check trailing chars
|
||||
for ret < len(raw) {
|
||||
return false
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ func ValidNumberFast(raw string) bool {
|
|||
}
|
||||
|
||||
func SkipOneFast2(json string, pos *int) (int, error) {
|
||||
// find the number ending, we pasred in sonic-cpp, it alway valid
|
||||
// find the number ending, we parsed in sonic-cpp, it always valid
|
||||
start := native.SkipOneFast(&json, pos)
|
||||
if start < 0 {
|
||||
return -1, error_syntax(*pos, json, types.ParsingError(-start).Error())
|
||||
|
@ -58,7 +58,7 @@ func SkipOneFast2(json string, pos *int) (int, error) {
|
|||
}
|
||||
|
||||
func SkipOneFast(json string, pos int) (string, error) {
|
||||
// find the number ending, we pasred in sonic-cpp, it alway valid
|
||||
// find the number ending, we parsed in sonic-cpp, it always valid
|
||||
start := native.SkipOneFast(&json, &pos)
|
||||
if start < 0 {
|
||||
// TODO: details error code
|
||||
|
|
6
vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go
generated
vendored
6
vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go
generated
vendored
|
@ -61,13 +61,13 @@ type node struct {
|
|||
val uint64
|
||||
}
|
||||
|
||||
// should consitent with native/parser.c
|
||||
// should consistent with native/parser.c
|
||||
type _nospaceBlock struct {
|
||||
_ [8]byte
|
||||
_ [8]byte
|
||||
}
|
||||
|
||||
// should consitent with native/parser.c
|
||||
// should consistent with native/parser.c
|
||||
type nodeBuf struct {
|
||||
ncur uintptr
|
||||
parent int64
|
||||
|
@ -84,7 +84,7 @@ func (self *nodeBuf) init(nodes []node) {
|
|||
self.parent = -1
|
||||
}
|
||||
|
||||
// should consitent with native/parser.c
|
||||
// should consistent with native/parser.c
|
||||
type Parser struct {
|
||||
Json string
|
||||
padded []byte
|
||||
|
|
4
vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go
generated
vendored
4
vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go
generated
vendored
|
@ -372,7 +372,7 @@ func (val Node) ParseF64(ctx *Context) (float64, bool) {
|
|||
}
|
||||
|
||||
func (val Node) ParseString(ctx *Context) (string, bool) {
|
||||
// shoud not use AsStrRef
|
||||
// should not use AsStrRef
|
||||
s, ok := val.AsStr(ctx)
|
||||
if !ok {
|
||||
return "", false
|
||||
|
@ -391,7 +391,7 @@ func (val Node) ParseString(ctx *Context) (string, bool) {
|
|||
|
||||
|
||||
func (val Node) ParseNumber(ctx *Context) (json.Number, bool) {
|
||||
// shoud not use AsStrRef
|
||||
// should not use AsStrRef
|
||||
s, ok := val.AsStr(ctx)
|
||||
if !ok {
|
||||
return json.Number(""), false
|
||||
|
|
2
vendor/github.com/bytedance/sonic/internal/encoder/alg/sort.go
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/encoder/alg/sort.go
generated
vendored
|
@ -46,7 +46,7 @@ func radixQsort(kvs []_MapPair, d, maxDepth int) {
|
|||
}
|
||||
|
||||
// kvs[0:lt] < v = kvs[lt:gt] < kvs[gt:len(kvs)]
|
||||
// Native implemention:
|
||||
// Native implementation:
|
||||
// radixQsort(kvs[:lt], d, maxDepth)
|
||||
// if p > -1 {
|
||||
// radixQsort(kvs[lt:gt], d+1, maxDepth)
|
||||
|
|
2
vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go
generated
vendored
|
@ -673,7 +673,7 @@ func (self *Assembler) encode_string(doubleQuote bool) {
|
|||
self.Sjmp("JMP", _LB_panic)
|
||||
self.Link("_str_next_{n}")
|
||||
|
||||
/* openning quote, check for double quote */
|
||||
/* opening quote, check for double quote */
|
||||
if !doubleQuote {
|
||||
self.check_size_r(_AX, 2) // SIZE $2
|
||||
self.add_char('"') // CHAR $'"'
|
||||
|
|
6
vendor/github.com/bytedance/sonic/internal/optcaching/fcache.go
generated
vendored
6
vendor/github.com/bytedance/sonic/internal/optcaching/fcache.go
generated
vendored
|
@ -84,7 +84,7 @@ func NewSmallFieldMap (hint int) *SmallFieldMap {
|
|||
|
||||
func (self *SmallFieldMap) Set(fields []resolver.FieldMeta) {
|
||||
if len(fields) > 8 {
|
||||
panic("small field map shoud use in small struct")
|
||||
panic("small field map should use in small struct")
|
||||
}
|
||||
|
||||
for i, f := range fields {
|
||||
|
@ -254,7 +254,7 @@ type keysInfo struct {
|
|||
|
||||
func (self *NormalFieldMap) Set(fields []resolver.FieldMeta) {
|
||||
if len(fields) <=8 || len(fields) > 128 {
|
||||
panic("normal field map shoud use in small struct")
|
||||
panic("normal field map should use in small struct")
|
||||
}
|
||||
|
||||
// allocate the flat map in []byte
|
||||
|
@ -278,7 +278,7 @@ func (self *NormalFieldMap) Set(fields []resolver.FieldMeta) {
|
|||
|
||||
}
|
||||
|
||||
// add a padding size at last to make it firendly for SIMD.
|
||||
// add a padding size at last to make it friendly for SIMD.
|
||||
self.keys = make([]byte, _HdrSize + 2 * kvLen, _HdrSize + 2 * kvLen + _PaddingSize)
|
||||
self.lowOffset = _HdrSize + kvLen
|
||||
|
||||
|
|
2
vendor/github.com/bytedance/sonic/internal/rt/stubs.go
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/rt/stubs.go
generated
vendored
|
@ -153,7 +153,7 @@ func MakeSlice(oldPtr unsafe.Pointer, et *GoType, newLen int) *GoSlice {
|
|||
|
||||
new := GrowSlice(et, *old, newLen)
|
||||
|
||||
// we sould clear the memory from [oldLen:newLen]
|
||||
// we should clear the memory from [oldLen:newLen]
|
||||
if et.PtrData == 0 {
|
||||
oldlenmem := uintptr(old.Len) * et.Size
|
||||
newlenmem := uintptr(newLen) * et.Size
|
||||
|
|
4
vendor/github.com/bytedance/sonic/loader/funcdata_compat.go
generated
vendored
4
vendor/github.com/bytedance/sonic/loader/funcdata_compat.go
generated
vendored
|
@ -329,7 +329,7 @@ funcs := *funcsp
|
|||
funcnametab, nameOffs := makeFuncnameTab(funcs)
|
||||
mod.funcnametab = funcnametab
|
||||
|
||||
// mmap() text and funcdata segements
|
||||
// mmap() text and funcdata segments
|
||||
p := os.Getpagesize()
|
||||
size := int(rnd(int64(len(text)), int64(p)))
|
||||
addr := mmap(size)
|
||||
|
@ -389,7 +389,7 @@ funcnameOffset: getOffsetOf(moduledata{}, "funcnametab"),
|
|||
pclnOffset: getOffsetOf(moduledata{}, "pclntable"),
|
||||
}
|
||||
|
||||
// sepecial case: gcdata and gcbss must by non-empty
|
||||
// special case: gcdata and gcbss must by non-empty
|
||||
mod.gcdata = uintptr(unsafe.Pointer(&emptyByte))
|
||||
mod.gcbss = uintptr(unsafe.Pointer(&emptyByte))
|
||||
|
||||
|
|
4
vendor/github.com/bytedance/sonic/loader/funcdata_go117.go
generated
vendored
4
vendor/github.com/bytedance/sonic/loader/funcdata_go117.go
generated
vendored
|
@ -330,7 +330,7 @@ funcs := *funcsp
|
|||
funcnametab, nameOffs := makeFuncnameTab(funcs)
|
||||
mod.funcnametab = funcnametab
|
||||
|
||||
// mmap() text and funcdata segements
|
||||
// mmap() text and funcdata segments
|
||||
p := os.Getpagesize()
|
||||
size := int(rnd(int64(len(text)), int64(p)))
|
||||
addr := mmap(size)
|
||||
|
@ -390,7 +390,7 @@ funcnameOffset: getOffsetOf(moduledata{}, "funcnametab"),
|
|||
pclnOffset: getOffsetOf(moduledata{}, "pclntable"),
|
||||
}
|
||||
|
||||
// sepecial case: gcdata and gcbss must by non-empty
|
||||
// special case: gcdata and gcbss must by non-empty
|
||||
mod.gcdata = uintptr(unsafe.Pointer(&emptyByte))
|
||||
mod.gcbss = uintptr(unsafe.Pointer(&emptyByte))
|
||||
|
||||
|
|
4
vendor/github.com/bytedance/sonic/loader/funcdata_latest.go
generated
vendored
4
vendor/github.com/bytedance/sonic/loader/funcdata_latest.go
generated
vendored
|
@ -222,7 +222,7 @@ funcs := *funcsp
|
|||
funcnametab, nameOffs := makeFuncnameTab(funcs)
|
||||
mod.funcnametab = funcnametab
|
||||
|
||||
// mmap() text and funcdata segements
|
||||
// mmap() text and funcdata segments
|
||||
p := os.Getpagesize()
|
||||
size := int(rnd(int64(len(text)), int64(p)))
|
||||
addr := mmap(size)
|
||||
|
@ -283,7 +283,7 @@ funcnameOffset: getOffsetOf(moduledata{}, "funcnametab"),
|
|||
pclnOffset: getOffsetOf(moduledata{}, "pclntable"),
|
||||
}
|
||||
|
||||
// sepecial case: gcdata and gcbss must by non-empty
|
||||
// special case: gcdata and gcbss must by non-empty
|
||||
mod.gcdata = uintptr(unsafe.Pointer(&emptyByte))
|
||||
mod.gcbss = uintptr(unsafe.Pointer(&emptyByte))
|
||||
|
||||
|
|
377
vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go
generated
vendored
377
vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go
generated
vendored
|
@ -17,266 +17,285 @@
|
|||
package abi
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
`reflect`
|
||||
`unsafe`
|
||||
"fmt"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
. `github.com/cloudwego/iasm/x86_64`
|
||||
x64 "github.com/bytedance/sonic/loader/internal/iasm/x86_64"
|
||||
)
|
||||
|
||||
type (
|
||||
Register = x64.Register
|
||||
Register64 = x64.Register64
|
||||
XMMRegister = x64.XMMRegister
|
||||
Program = x64.Program
|
||||
MemoryOperand = x64.MemoryOperand
|
||||
Label = x64.Label
|
||||
)
|
||||
|
||||
var (
|
||||
Ptr = x64.Ptr
|
||||
DefaultArch = x64.DefaultArch
|
||||
CreateLabel = x64.CreateLabel
|
||||
)
|
||||
|
||||
const (
|
||||
PtrSize = 8 // pointer size
|
||||
PtrAlign = 8 // pointer alignment
|
||||
RAX = x64.RAX
|
||||
RSP = x64.RSP
|
||||
RBP = x64.RBP
|
||||
R12 = x64.R12
|
||||
R14 = x64.R14
|
||||
R15 = x64.R15
|
||||
)
|
||||
|
||||
const (
|
||||
PtrSize = 8 // pointer size
|
||||
PtrAlign = 8 // pointer alignment
|
||||
)
|
||||
|
||||
var iregOrderC = []Register{
|
||||
RDI,
|
||||
RSI,
|
||||
RDX,
|
||||
RCX,
|
||||
R8,
|
||||
R9,
|
||||
x64.RDI,
|
||||
x64.RSI,
|
||||
x64.RDX,
|
||||
x64.RCX,
|
||||
x64.R8,
|
||||
x64.R9,
|
||||
}
|
||||
|
||||
var xregOrderC = []Register{
|
||||
XMM0,
|
||||
XMM1,
|
||||
XMM2,
|
||||
XMM3,
|
||||
XMM4,
|
||||
XMM5,
|
||||
XMM6,
|
||||
XMM7,
|
||||
x64.XMM0,
|
||||
x64.XMM1,
|
||||
x64.XMM2,
|
||||
x64.XMM3,
|
||||
x64.XMM4,
|
||||
x64.XMM5,
|
||||
x64.XMM6,
|
||||
x64.XMM7,
|
||||
}
|
||||
|
||||
var (
|
||||
intType = reflect.TypeOf(0)
|
||||
ptrType = reflect.TypeOf(unsafe.Pointer(nil))
|
||||
intType = reflect.TypeOf(0)
|
||||
ptrType = reflect.TypeOf(unsafe.Pointer(nil))
|
||||
)
|
||||
|
||||
func (self *Frame) argv(i int) *MemoryOperand {
|
||||
return Ptr(RSP, int32(self.Prev() + self.desc.Args[i].Mem))
|
||||
return Ptr(RSP, int32(self.Prev()+self.desc.Args[i].Mem))
|
||||
}
|
||||
|
||||
// spillv is used for growstack spill registers
|
||||
func (self *Frame) spillv(i int) *MemoryOperand {
|
||||
// remain one slot for caller return pc
|
||||
return Ptr(RSP, PtrSize + int32(self.desc.Args[i].Mem))
|
||||
// remain one slot for caller return pc
|
||||
return Ptr(RSP, PtrSize+int32(self.desc.Args[i].Mem))
|
||||
}
|
||||
|
||||
func (self *Frame) retv(i int) *MemoryOperand {
|
||||
return Ptr(RSP, int32(self.Prev() + self.desc.Rets[i].Mem))
|
||||
return Ptr(RSP, int32(self.Prev()+self.desc.Rets[i].Mem))
|
||||
}
|
||||
|
||||
func (self *Frame) resv(i int) *MemoryOperand {
|
||||
return Ptr(RSP, int32(self.Offs() - uint32((i+1) * PtrSize)))
|
||||
return Ptr(RSP, int32(self.Offs()-uint32((i+1)*PtrSize)))
|
||||
}
|
||||
|
||||
func (self *Frame) emitGrowStack(p *Program, entry *Label) {
|
||||
// spill all register arguments
|
||||
for i, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat == floatKind64 {
|
||||
p.MOVSD(v.Reg, self.spillv(i))
|
||||
} else if v.IsFloat == floatKind32 {
|
||||
p.MOVSS(v.Reg, self.spillv(i))
|
||||
}else {
|
||||
p.MOVQ(v.Reg, self.spillv(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
// spill all register arguments
|
||||
for i, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat == floatKind64 {
|
||||
p.MOVSD(v.Reg, self.spillv(i))
|
||||
} else if v.IsFloat == floatKind32 {
|
||||
p.MOVSS(v.Reg, self.spillv(i))
|
||||
} else {
|
||||
p.MOVQ(v.Reg, self.spillv(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call runtime.morestack_noctxt
|
||||
p.MOVQ(F_morestack_noctxt, R12)
|
||||
p.CALLQ(R12)
|
||||
// load all register arguments
|
||||
for i, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat == floatKind64 {
|
||||
p.MOVSD(self.spillv(i), v.Reg)
|
||||
} else if v.IsFloat == floatKind32 {
|
||||
p.MOVSS(self.spillv(i), v.Reg)
|
||||
}else {
|
||||
p.MOVQ(self.spillv(i), v.Reg)
|
||||
}
|
||||
}
|
||||
}
|
||||
// call runtime.morestack_noctxt
|
||||
p.MOVQ(F_morestack_noctxt, R12)
|
||||
p.CALLQ(R12)
|
||||
// load all register arguments
|
||||
for i, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat == floatKind64 {
|
||||
p.MOVSD(self.spillv(i), v.Reg)
|
||||
} else if v.IsFloat == floatKind32 {
|
||||
p.MOVSS(self.spillv(i), v.Reg)
|
||||
} else {
|
||||
p.MOVQ(self.spillv(i), v.Reg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// jump back to the function entry
|
||||
p.JMP(entry)
|
||||
// jump back to the function entry
|
||||
p.JMP(entry)
|
||||
}
|
||||
|
||||
func (self *Frame) GrowStackTextSize() uint32 {
|
||||
p := DefaultArch.CreateProgram()
|
||||
// spill all register arguments
|
||||
for i, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat == floatKind64 {
|
||||
p.MOVSD(v.Reg, self.spillv(i))
|
||||
} else if v.IsFloat == floatKind32 {
|
||||
p.MOVSS(v.Reg, self.spillv(i))
|
||||
}else {
|
||||
p.MOVQ(v.Reg, self.spillv(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
p := DefaultArch.CreateProgram()
|
||||
// spill all register arguments
|
||||
for i, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat == floatKind64 {
|
||||
p.MOVSD(v.Reg, self.spillv(i))
|
||||
} else if v.IsFloat == floatKind32 {
|
||||
p.MOVSS(v.Reg, self.spillv(i))
|
||||
} else {
|
||||
p.MOVQ(v.Reg, self.spillv(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call runtime.morestack_noctxt
|
||||
p.MOVQ(F_morestack_noctxt, R12)
|
||||
p.CALLQ(R12)
|
||||
// load all register arguments
|
||||
for i, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat == floatKind64 {
|
||||
p.MOVSD(self.spillv(i), v.Reg)
|
||||
} else if v.IsFloat == floatKind32 {
|
||||
p.MOVSS(self.spillv(i), v.Reg)
|
||||
} else {
|
||||
p.MOVQ(self.spillv(i), v.Reg)
|
||||
}
|
||||
}
|
||||
}
|
||||
// call runtime.morestack_noctxt
|
||||
p.MOVQ(F_morestack_noctxt, R12)
|
||||
p.CALLQ(R12)
|
||||
// load all register arguments
|
||||
for i, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat == floatKind64 {
|
||||
p.MOVSD(self.spillv(i), v.Reg)
|
||||
} else if v.IsFloat == floatKind32 {
|
||||
p.MOVSS(self.spillv(i), v.Reg)
|
||||
} else {
|
||||
p.MOVQ(self.spillv(i), v.Reg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// jump back to the function entry
|
||||
l := CreateLabel("")
|
||||
p.Link(l)
|
||||
p.JMP(l)
|
||||
// jump back to the function entry
|
||||
l := CreateLabel("")
|
||||
p.Link(l)
|
||||
p.JMP(l)
|
||||
|
||||
return uint32(len(p.Assemble(0)))
|
||||
return uint32(len(p.Assemble(0)))
|
||||
}
|
||||
|
||||
func (self *Frame) emitPrologue(p *Program) {
|
||||
p.SUBQ(self.Size(), RSP)
|
||||
p.MOVQ(RBP, Ptr(RSP, int32(self.Offs())))
|
||||
p.LEAQ(Ptr(RSP, int32(self.Offs())), RBP)
|
||||
p.SUBQ(self.Size(), RSP)
|
||||
p.MOVQ(RBP, Ptr(RSP, int32(self.Offs())))
|
||||
p.LEAQ(Ptr(RSP, int32(self.Offs())), RBP)
|
||||
}
|
||||
|
||||
func (self *Frame) emitEpilogue(p *Program) {
|
||||
p.MOVQ(Ptr(RSP, int32(self.Offs())), RBP)
|
||||
p.ADDQ(self.Size(), RSP)
|
||||
p.RET()
|
||||
p.MOVQ(Ptr(RSP, int32(self.Offs())), RBP)
|
||||
p.ADDQ(self.Size(), RSP)
|
||||
p.RET()
|
||||
}
|
||||
|
||||
func (self *Frame) emitReserveRegs(p *Program) {
|
||||
// spill reserved registers
|
||||
for i, r := range ReservedRegs(self.ccall) {
|
||||
switch r.(type) {
|
||||
case Register64:
|
||||
p.MOVQ(r, self.resv(i))
|
||||
case XMMRegister:
|
||||
p.MOVSD(r, self.resv(i))
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported register type %t to reserve", r))
|
||||
}
|
||||
}
|
||||
// spill reserved registers
|
||||
for i, r := range ReservedRegs(self.ccall) {
|
||||
switch r.(type) {
|
||||
case Register64:
|
||||
p.MOVQ(r, self.resv(i))
|
||||
case XMMRegister:
|
||||
p.MOVSD(r, self.resv(i))
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported register type %t to reserve", r))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Frame) emitSpillPtrs(p *Program) {
|
||||
// spill pointer argument registers
|
||||
for i, r := range self.desc.Args {
|
||||
if r.InRegister && r.IsPointer {
|
||||
p.MOVQ(r.Reg, self.argv(i))
|
||||
}
|
||||
}
|
||||
// spill pointer argument registers
|
||||
for i, r := range self.desc.Args {
|
||||
if r.InRegister && r.IsPointer {
|
||||
p.MOVQ(r.Reg, self.argv(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Frame) emitClearPtrs(p *Program) {
|
||||
// spill pointer argument registers
|
||||
for i, r := range self.desc.Args {
|
||||
if r.InRegister && r.IsPointer {
|
||||
p.MOVQ(int64(0), self.argv(i))
|
||||
}
|
||||
}
|
||||
// spill pointer argument registers
|
||||
for i, r := range self.desc.Args {
|
||||
if r.InRegister && r.IsPointer {
|
||||
p.MOVQ(int64(0), self.argv(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Frame) emitCallC(p *Program, addr uintptr) {
|
||||
p.MOVQ(addr, RAX)
|
||||
p.CALLQ(RAX)
|
||||
p.MOVQ(addr, RAX)
|
||||
p.CALLQ(RAX)
|
||||
}
|
||||
|
||||
type floatKind uint8
|
||||
|
||||
const (
|
||||
notFloatKind floatKind = iota
|
||||
floatKind32
|
||||
floatKind64
|
||||
notFloatKind floatKind = iota
|
||||
floatKind32
|
||||
floatKind64
|
||||
)
|
||||
|
||||
type Parameter struct {
|
||||
InRegister bool
|
||||
IsPointer bool
|
||||
IsFloat floatKind
|
||||
Reg Register
|
||||
Mem uint32
|
||||
Type reflect.Type
|
||||
InRegister bool
|
||||
IsPointer bool
|
||||
IsFloat floatKind
|
||||
Reg Register
|
||||
Mem uint32
|
||||
Type reflect.Type
|
||||
}
|
||||
|
||||
func mkIReg(vt reflect.Type, reg Register64) (p Parameter) {
|
||||
p.Reg = reg
|
||||
p.Type = vt
|
||||
p.InRegister = true
|
||||
p.IsPointer = isPointer(vt)
|
||||
return
|
||||
p.Reg = reg
|
||||
p.Type = vt
|
||||
p.InRegister = true
|
||||
p.IsPointer = isPointer(vt)
|
||||
return
|
||||
}
|
||||
|
||||
func isFloat(vt reflect.Type) floatKind {
|
||||
switch vt.Kind() {
|
||||
case reflect.Float32:
|
||||
return floatKind32
|
||||
case reflect.Float64:
|
||||
return floatKind64
|
||||
default:
|
||||
return notFloatKind
|
||||
}
|
||||
switch vt.Kind() {
|
||||
case reflect.Float32:
|
||||
return floatKind32
|
||||
case reflect.Float64:
|
||||
return floatKind64
|
||||
default:
|
||||
return notFloatKind
|
||||
}
|
||||
}
|
||||
|
||||
func mkXReg(vt reflect.Type, reg XMMRegister) (p Parameter) {
|
||||
p.Reg = reg
|
||||
p.Type = vt
|
||||
p.InRegister = true
|
||||
p.IsFloat = isFloat(vt)
|
||||
return
|
||||
p.Reg = reg
|
||||
p.Type = vt
|
||||
p.InRegister = true
|
||||
p.IsFloat = isFloat(vt)
|
||||
return
|
||||
}
|
||||
|
||||
func mkStack(vt reflect.Type, mem uint32) (p Parameter) {
|
||||
p.Mem = mem
|
||||
p.Type = vt
|
||||
p.InRegister = false
|
||||
p.IsPointer = isPointer(vt)
|
||||
p.IsFloat = isFloat(vt)
|
||||
return
|
||||
p.Mem = mem
|
||||
p.Type = vt
|
||||
p.InRegister = false
|
||||
p.IsPointer = isPointer(vt)
|
||||
p.IsFloat = isFloat(vt)
|
||||
return
|
||||
}
|
||||
|
||||
func (self Parameter) String() string {
|
||||
if self.InRegister {
|
||||
return fmt.Sprintf("[%%%s, Pointer(%v), Float(%v)]", self.Reg, self.IsPointer, self.IsFloat)
|
||||
} else {
|
||||
return fmt.Sprintf("[%d(FP), Pointer(%v), Float(%v)]", self.Mem, self.IsPointer, self.IsFloat)
|
||||
}
|
||||
if self.InRegister {
|
||||
return fmt.Sprintf("[%%%s, Pointer(%v), Float(%v)]", self.Reg, self.IsPointer, self.IsFloat)
|
||||
} else {
|
||||
return fmt.Sprintf("[%d(FP), Pointer(%v), Float(%v)]", self.Mem, self.IsPointer, self.IsFloat)
|
||||
}
|
||||
}
|
||||
|
||||
func CallC(addr uintptr, fr Frame, maxStack uintptr) []byte {
|
||||
p := DefaultArch.CreateProgram()
|
||||
p := DefaultArch.CreateProgram()
|
||||
|
||||
stack := CreateLabel("_stack_grow")
|
||||
entry := CreateLabel("_entry")
|
||||
p.Link(entry)
|
||||
fr.emitStackCheck(p, stack, maxStack)
|
||||
fr.emitPrologue(p)
|
||||
fr.emitReserveRegs(p)
|
||||
fr.emitSpillPtrs(p)
|
||||
fr.emitExchangeArgs(p)
|
||||
fr.emitCallC(p, addr)
|
||||
fr.emitExchangeRets(p)
|
||||
fr.emitRestoreRegs(p)
|
||||
fr.emitEpilogue(p)
|
||||
p.Link(stack)
|
||||
fr.emitGrowStack(p, entry)
|
||||
stack := CreateLabel("_stack_grow")
|
||||
entry := CreateLabel("_entry")
|
||||
p.Link(entry)
|
||||
fr.emitStackCheck(p, stack, maxStack)
|
||||
fr.emitPrologue(p)
|
||||
fr.emitReserveRegs(p)
|
||||
fr.emitSpillPtrs(p)
|
||||
fr.emitExchangeArgs(p)
|
||||
fr.emitCallC(p, addr)
|
||||
fr.emitExchangeRets(p)
|
||||
fr.emitRestoreRegs(p)
|
||||
fr.emitEpilogue(p)
|
||||
p.Link(stack)
|
||||
fr.emitGrowStack(p, entry)
|
||||
|
||||
return p.Assemble(0)
|
||||
return p.Assemble(0)
|
||||
}
|
||||
|
||||
|
||||
func (self *Frame) emitDebug(p *Program) {
|
||||
p.INT(3)
|
||||
}
|
291
vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go
generated
vendored
291
vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go
generated
vendored
|
@ -20,163 +20,196 @@
|
|||
package abi
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
`reflect`
|
||||
`runtime`
|
||||
|
||||
. `github.com/cloudwego/iasm/x86_64`
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func ReservedRegs(callc bool) []Register {
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func salloc(p []Parameter, sp uint32, vt reflect.Type) (uint32, []Parameter) {
|
||||
switch vt.Kind() {
|
||||
case reflect.Bool : return sp + 8, append(p, mkStack(reflect.TypeOf(false), sp))
|
||||
case reflect.Int : return sp + 8, append(p, mkStack(intType, sp))
|
||||
case reflect.Int8 : return sp + 8, append(p, mkStack(reflect.TypeOf(int8(0)), sp))
|
||||
case reflect.Int16 : return sp + 8, append(p, mkStack(reflect.TypeOf(int16(0)), sp))
|
||||
case reflect.Int32 : return sp + 8, append(p, mkStack(reflect.TypeOf(int32(0)), sp))
|
||||
case reflect.Int64 : return sp + 8, append(p, mkStack(reflect.TypeOf(int64(0)), sp))
|
||||
case reflect.Uint : return sp + 8, append(p, mkStack(reflect.TypeOf(uint(0)), sp))
|
||||
case reflect.Uint8 : return sp + 8, append(p, mkStack(reflect.TypeOf(uint8(0)), sp))
|
||||
case reflect.Uint16 : return sp + 8, append(p, mkStack(reflect.TypeOf(uint16(0)), sp))
|
||||
case reflect.Uint32 : return sp + 8, append(p, mkStack(reflect.TypeOf(uint32(0)), sp))
|
||||
case reflect.Uint64 : return sp + 8, append(p, mkStack(reflect.TypeOf(uint64(0)), sp))
|
||||
case reflect.Uintptr : return sp + 8, append(p, mkStack(reflect.TypeOf(uintptr(0)), sp))
|
||||
case reflect.Float32 : return sp + 8, append(p, mkStack(reflect.TypeOf(float32(0)), sp))
|
||||
case reflect.Float64 : return sp + 8, append(p, mkStack(reflect.TypeOf(float64(0)), sp))
|
||||
case reflect.Complex64 : panic("abi: go116: not implemented: complex64")
|
||||
case reflect.Complex128 : panic("abi: go116: not implemented: complex128")
|
||||
case reflect.Array : panic("abi: go116: not implemented: arrays")
|
||||
case reflect.Chan : return sp + 8, append(p, mkStack(reflect.TypeOf((chan int)(nil)), sp))
|
||||
case reflect.Func : return sp + 8, append(p, mkStack(reflect.TypeOf((func())(nil)), sp))
|
||||
case reflect.Map : return sp + 8, append(p, mkStack(reflect.TypeOf((map[int]int)(nil)), sp))
|
||||
case reflect.Ptr : return sp + 8, append(p, mkStack(reflect.TypeOf((*int)(nil)), sp))
|
||||
case reflect.UnsafePointer : return sp + 8, append(p, mkStack(ptrType, sp))
|
||||
case reflect.Interface : return sp + 16, append(p, mkStack(ptrType, sp), mkStack(ptrType, sp + 8))
|
||||
case reflect.Slice : return sp + 24, append(p, mkStack(ptrType, sp), mkStack(intType, sp + 8), mkStack(intType, sp + 16))
|
||||
case reflect.String : return sp + 16, append(p, mkStack(ptrType, sp), mkStack(intType, sp + 8))
|
||||
case reflect.Struct : panic("abi: go116: not implemented: structs")
|
||||
default : panic("abi: invalid value type")
|
||||
}
|
||||
switch vt.Kind() {
|
||||
case reflect.Bool:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(false), sp))
|
||||
case reflect.Int:
|
||||
return sp + 8, append(p, mkStack(intType, sp))
|
||||
case reflect.Int8:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(int8(0)), sp))
|
||||
case reflect.Int16:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(int16(0)), sp))
|
||||
case reflect.Int32:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(int32(0)), sp))
|
||||
case reflect.Int64:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(int64(0)), sp))
|
||||
case reflect.Uint:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(uint(0)), sp))
|
||||
case reflect.Uint8:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(uint8(0)), sp))
|
||||
case reflect.Uint16:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(uint16(0)), sp))
|
||||
case reflect.Uint32:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(uint32(0)), sp))
|
||||
case reflect.Uint64:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(uint64(0)), sp))
|
||||
case reflect.Uintptr:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(uintptr(0)), sp))
|
||||
case reflect.Float32:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(float32(0)), sp))
|
||||
case reflect.Float64:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf(float64(0)), sp))
|
||||
case reflect.Complex64:
|
||||
panic("abi: go116: not implemented: complex64")
|
||||
case reflect.Complex128:
|
||||
panic("abi: go116: not implemented: complex128")
|
||||
case reflect.Array:
|
||||
panic("abi: go116: not implemented: arrays")
|
||||
case reflect.Chan:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf((chan int)(nil)), sp))
|
||||
case reflect.Func:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf((func())(nil)), sp))
|
||||
case reflect.Map:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf((map[int]int)(nil)), sp))
|
||||
case reflect.Ptr:
|
||||
return sp + 8, append(p, mkStack(reflect.TypeOf((*int)(nil)), sp))
|
||||
case reflect.UnsafePointer:
|
||||
return sp + 8, append(p, mkStack(ptrType, sp))
|
||||
case reflect.Interface:
|
||||
return sp + 16, append(p, mkStack(ptrType, sp), mkStack(ptrType, sp+8))
|
||||
case reflect.Slice:
|
||||
return sp + 24, append(p, mkStack(ptrType, sp), mkStack(intType, sp+8), mkStack(intType, sp+16))
|
||||
case reflect.String:
|
||||
return sp + 16, append(p, mkStack(ptrType, sp), mkStack(intType, sp+8))
|
||||
case reflect.Struct:
|
||||
panic("abi: go116: not implemented: structs")
|
||||
default:
|
||||
panic("abi: invalid value type")
|
||||
}
|
||||
}
|
||||
|
||||
func NewFunctionLayout(ft reflect.Type) FunctionLayout {
|
||||
var sp uint32
|
||||
var fn FunctionLayout
|
||||
var sp uint32
|
||||
var fn FunctionLayout
|
||||
|
||||
/* assign every arguments */
|
||||
for i := 0; i < ft.NumIn(); i++ {
|
||||
sp, fn.Args = salloc(fn.Args, sp, ft.In(i))
|
||||
}
|
||||
/* assign every arguments */
|
||||
for i := 0; i < ft.NumIn(); i++ {
|
||||
sp, fn.Args = salloc(fn.Args, sp, ft.In(i))
|
||||
}
|
||||
|
||||
/* assign every return value */
|
||||
for i := 0; i < ft.NumOut(); i++ {
|
||||
sp, fn.Rets = salloc(fn.Rets, sp, ft.Out(i))
|
||||
}
|
||||
/* assign every return value */
|
||||
for i := 0; i < ft.NumOut(); i++ {
|
||||
sp, fn.Rets = salloc(fn.Rets, sp, ft.Out(i))
|
||||
}
|
||||
|
||||
/* update function ID and stack pointer */
|
||||
fn.FP = sp
|
||||
return fn
|
||||
/* update function ID and stack pointer */
|
||||
fn.FP = sp
|
||||
return fn
|
||||
}
|
||||
|
||||
func (self *Frame) emitExchangeArgs(p *Program) {
|
||||
iregArgs, xregArgs := 0, 0
|
||||
for _, v := range self.desc.Args {
|
||||
if v.IsFloat != notFloatKind {
|
||||
xregArgs += 1
|
||||
} else {
|
||||
iregArgs += 1
|
||||
}
|
||||
}
|
||||
iregArgs, xregArgs := 0, 0
|
||||
for _, v := range self.desc.Args {
|
||||
if v.IsFloat != notFloatKind {
|
||||
xregArgs += 1
|
||||
} else {
|
||||
iregArgs += 1
|
||||
}
|
||||
}
|
||||
|
||||
if iregArgs > len(iregOrderC) {
|
||||
panic("too many arguments, only support at most 6 integer arguments now")
|
||||
}
|
||||
if xregArgs > len(xregOrderC) {
|
||||
panic("too many arguments, only support at most 8 float arguments now")
|
||||
}
|
||||
if iregArgs > len(iregOrderC) {
|
||||
panic("too many arguments, only support at most 6 integer arguments now")
|
||||
}
|
||||
if xregArgs > len(xregOrderC) {
|
||||
panic("too many arguments, only support at most 8 float arguments now")
|
||||
}
|
||||
|
||||
ic, xc := iregArgs, xregArgs
|
||||
for i := 0; i < len(self.desc.Args); i++ {
|
||||
arg := self.desc.Args[i]
|
||||
if arg.IsFloat == floatKind64 {
|
||||
p.MOVSD(self.argv(i), xregOrderC[xregArgs - xc])
|
||||
xc -= 1
|
||||
} else if arg.IsFloat == floatKind32 {
|
||||
p.MOVSS(self.argv(i), xregOrderC[xregArgs - xc])
|
||||
xc -= 1
|
||||
} else {
|
||||
p.MOVQ(self.argv(i), iregOrderC[iregArgs - ic])
|
||||
ic -= 1
|
||||
}
|
||||
}
|
||||
ic, xc := iregArgs, xregArgs
|
||||
for i := 0; i < len(self.desc.Args); i++ {
|
||||
arg := self.desc.Args[i]
|
||||
if arg.IsFloat == floatKind64 {
|
||||
p.MOVSD(self.argv(i), xregOrderC[xregArgs-xc])
|
||||
xc -= 1
|
||||
} else if arg.IsFloat == floatKind32 {
|
||||
p.MOVSS(self.argv(i), xregOrderC[xregArgs-xc])
|
||||
xc -= 1
|
||||
} else {
|
||||
p.MOVQ(self.argv(i), iregOrderC[iregArgs-ic])
|
||||
ic -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Frame) emitStackCheck(p *Program, to *Label, maxStack uintptr) {
|
||||
// get the current goroutine
|
||||
switch runtime.GOOS {
|
||||
case "linux" : p.MOVQ(Abs(-8), R14).FS()
|
||||
case "darwin" : p.MOVQ(Abs(0x30), R14).GS()
|
||||
case "windows": break // windows always stores G pointer at R14
|
||||
default : panic("unsupported operating system")
|
||||
}
|
||||
|
||||
// check the stack guard
|
||||
p.LEAQ(Ptr(RSP, -int32(self.Size() + uint32(maxStack))), RAX)
|
||||
p.CMPQ(Ptr(R14, _G_stackguard0), RAX)
|
||||
p.JBE(to)
|
||||
// get the current goroutine
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
p.MOVQ(Abs(-8), R14).FS()
|
||||
case "darwin":
|
||||
p.MOVQ(Abs(0x30), R14).GS()
|
||||
case "windows":
|
||||
break // windows always stores G pointer at R14
|
||||
default:
|
||||
panic("unsupported operating system")
|
||||
}
|
||||
|
||||
// check the stack guard
|
||||
p.LEAQ(Ptr(RSP, -int32(self.Size()+uint32(maxStack))), RAX)
|
||||
p.CMPQ(Ptr(R14, _G_stackguard0), RAX)
|
||||
p.JBE(to)
|
||||
}
|
||||
|
||||
func (self *Frame) StackCheckTextSize() uint32 {
|
||||
p := DefaultArch.CreateProgram()
|
||||
p := DefaultArch.CreateProgram()
|
||||
|
||||
// get the current goroutine
|
||||
switch runtime.GOOS {
|
||||
case "linux" : p.MOVQ(Abs(-8), R14).FS()
|
||||
case "darwin" : p.MOVQ(Abs(0x30), R14).GS()
|
||||
case "windows": break // windows always stores G pointer at R14
|
||||
default : panic("unsupported operating system")
|
||||
}
|
||||
|
||||
// check the stack guard
|
||||
p.LEAQ(Ptr(RSP, -int32(self.Size())), RAX)
|
||||
p.CMPQ(Ptr(R14, _G_stackguard0), RAX)
|
||||
l := CreateLabel("")
|
||||
p.Link(l)
|
||||
p.JBE(l)
|
||||
// get the current goroutine
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
p.MOVQ(Abs(-8), R14).FS()
|
||||
case "darwin":
|
||||
p.MOVQ(Abs(0x30), R14).GS()
|
||||
case "windows":
|
||||
break // windows always stores G pointer at R14
|
||||
default:
|
||||
panic("unsupported operating system")
|
||||
}
|
||||
|
||||
return uint32(len(p.Assemble(0)))
|
||||
// check the stack guard
|
||||
p.LEAQ(Ptr(RSP, -int32(self.Size())), RAX)
|
||||
p.CMPQ(Ptr(R14, _G_stackguard0), RAX)
|
||||
l := CreateLabel("")
|
||||
p.Link(l)
|
||||
p.JBE(l)
|
||||
|
||||
return uint32(len(p.Assemble(0)))
|
||||
}
|
||||
|
||||
func (self *Frame) emitExchangeRets(p *Program) {
|
||||
if len(self.desc.Rets) > 1 {
|
||||
panic("too many results, only support one result now")
|
||||
}
|
||||
// store result
|
||||
if len(self.desc.Rets) ==1 {
|
||||
if self.desc.Rets[0].IsFloat == floatKind64 {
|
||||
p.MOVSD(xregOrderC[0], self.retv(0))
|
||||
} else if self.desc.Rets[0].IsFloat == floatKind32 {
|
||||
p.MOVSS(xregOrderC[0], self.retv(0))
|
||||
} else {
|
||||
p.MOVQ(RAX, self.retv(0))
|
||||
}
|
||||
}
|
||||
if len(self.desc.Rets) > 1 {
|
||||
panic("too many results, only support one result now")
|
||||
}
|
||||
// store result
|
||||
if len(self.desc.Rets) == 1 {
|
||||
if self.desc.Rets[0].IsFloat == floatKind64 {
|
||||
p.MOVSD(xregOrderC[0], self.retv(0))
|
||||
} else if self.desc.Rets[0].IsFloat == floatKind32 {
|
||||
p.MOVSS(xregOrderC[0], self.retv(0))
|
||||
} else {
|
||||
p.MOVQ(RAX, self.retv(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Frame) emitRestoreRegs(p *Program) {
|
||||
// load reserved registers
|
||||
for i, r := range ReservedRegs(self.ccall) {
|
||||
switch r.(type) {
|
||||
case Register64:
|
||||
p.MOVQ(self.resv(i), r)
|
||||
case XMMRegister:
|
||||
p.MOVSD(self.resv(i), r)
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported register type %t to reserve", r))
|
||||
}
|
||||
}
|
||||
}
|
||||
// load reserved registers
|
||||
for i, r := range ReservedRegs(self.ccall) {
|
||||
switch r.(type) {
|
||||
case Register64:
|
||||
p.MOVQ(self.resv(i), r)
|
||||
case XMMRegister:
|
||||
p.MOVSD(self.resv(i), r)
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported register type %t to reserve", r))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
431
vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go
generated
vendored
431
vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go
generated
vendored
|
@ -26,10 +26,10 @@
|
|||
package abi
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
`reflect`
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
. `github.com/cloudwego/iasm/x86_64`
|
||||
x64 "github.com/bytedance/sonic/loader/internal/iasm/x86_64"
|
||||
)
|
||||
|
||||
/** Frame Structure of the Generated Function
|
||||
|
@ -59,258 +59,287 @@
|
|||
RSP -------------------------------|↓ lower addresses
|
||||
*/
|
||||
|
||||
const zeroRegGo = XMM15
|
||||
const zeroRegGo = x64.XMM15
|
||||
|
||||
var iregOrderGo = [...]Register64 {
|
||||
RAX,// RDI
|
||||
RBX,// RSI
|
||||
RCX,// RDX
|
||||
RDI,// RCX
|
||||
RSI,// R8
|
||||
R8, // R9
|
||||
R9,
|
||||
R10,
|
||||
R11,
|
||||
var iregOrderGo = [...]Register64{
|
||||
x64.RAX, // RDI
|
||||
x64.RBX, // RSI
|
||||
x64.RCX, // RDX
|
||||
x64.RDI, // RCX
|
||||
x64.RSI, // R8
|
||||
x64.R8, // R9
|
||||
x64.R9,
|
||||
x64.R10,
|
||||
x64.R11,
|
||||
}
|
||||
|
||||
var xregOrderGo = [...]XMMRegister {
|
||||
XMM0,
|
||||
XMM1,
|
||||
XMM2,
|
||||
XMM3,
|
||||
XMM4,
|
||||
XMM5,
|
||||
XMM6,
|
||||
XMM7,
|
||||
XMM8,
|
||||
XMM9,
|
||||
XMM10,
|
||||
XMM11,
|
||||
XMM12,
|
||||
XMM13,
|
||||
XMM14,
|
||||
var xregOrderGo = [...]XMMRegister{
|
||||
x64.XMM0,
|
||||
x64.XMM1,
|
||||
x64.XMM2,
|
||||
x64.XMM3,
|
||||
x64.XMM4,
|
||||
x64.XMM5,
|
||||
x64.XMM6,
|
||||
x64.XMM7,
|
||||
x64.XMM8,
|
||||
x64.XMM9,
|
||||
x64.XMM10,
|
||||
x64.XMM11,
|
||||
x64.XMM12,
|
||||
x64.XMM13,
|
||||
x64.XMM14,
|
||||
}
|
||||
|
||||
func ReservedRegs(callc bool) []Register {
|
||||
if callc {
|
||||
return nil
|
||||
}
|
||||
return []Register {
|
||||
R14, // current goroutine
|
||||
R15, // GOT reference
|
||||
}
|
||||
if callc {
|
||||
return nil
|
||||
}
|
||||
return []Register{
|
||||
R14, // current goroutine
|
||||
R15, // GOT reference
|
||||
}
|
||||
}
|
||||
|
||||
type stackAlloc struct {
|
||||
s uint32
|
||||
i int
|
||||
x int
|
||||
s uint32
|
||||
i int
|
||||
x int
|
||||
}
|
||||
|
||||
func (self *stackAlloc) reset() {
|
||||
self.i, self.x = 0, 0
|
||||
self.i, self.x = 0, 0
|
||||
}
|
||||
|
||||
func (self *stackAlloc) ireg(vt reflect.Type) (p Parameter) {
|
||||
p = mkIReg(vt, iregOrderGo[self.i])
|
||||
self.i++
|
||||
return
|
||||
p = mkIReg(vt, iregOrderGo[self.i])
|
||||
self.i++
|
||||
return
|
||||
}
|
||||
|
||||
func (self *stackAlloc) xreg(vt reflect.Type) (p Parameter) {
|
||||
p = mkXReg(vt, xregOrderGo[self.x])
|
||||
self.x++
|
||||
return
|
||||
p = mkXReg(vt, xregOrderGo[self.x])
|
||||
self.x++
|
||||
return
|
||||
}
|
||||
|
||||
func (self *stackAlloc) stack(vt reflect.Type) (p Parameter) {
|
||||
p = mkStack(vt, self.s)
|
||||
self.s += uint32(vt.Size())
|
||||
return
|
||||
p = mkStack(vt, self.s)
|
||||
self.s += uint32(vt.Size())
|
||||
return
|
||||
}
|
||||
|
||||
func (self *stackAlloc) spill(n uint32, a int) uint32 {
|
||||
self.s = alignUp(self.s, a) + n
|
||||
return self.s
|
||||
self.s = alignUp(self.s, a) + n
|
||||
return self.s
|
||||
}
|
||||
|
||||
func (self *stackAlloc) alloc(p []Parameter, vt reflect.Type) []Parameter {
|
||||
nb := vt.Size()
|
||||
vk := vt.Kind()
|
||||
nb := vt.Size()
|
||||
vk := vt.Kind()
|
||||
|
||||
/* zero-sized objects are allocated on stack */
|
||||
if nb == 0 {
|
||||
return append(p, mkStack(intType, self.s))
|
||||
}
|
||||
/* zero-sized objects are allocated on stack */
|
||||
if nb == 0 {
|
||||
return append(p, mkStack(intType, self.s))
|
||||
}
|
||||
|
||||
/* check for value type */
|
||||
switch vk {
|
||||
case reflect.Bool : return self.valloc(p, reflect.TypeOf(false))
|
||||
case reflect.Int : return self.valloc(p, intType)
|
||||
case reflect.Int8 : return self.valloc(p, reflect.TypeOf(int8(0)))
|
||||
case reflect.Int16 : return self.valloc(p, reflect.TypeOf(int16(0)))
|
||||
case reflect.Int32 : return self.valloc(p, reflect.TypeOf(uint32(0)))
|
||||
case reflect.Int64 : return self.valloc(p, reflect.TypeOf(int64(0)))
|
||||
case reflect.Uint : return self.valloc(p, reflect.TypeOf(uint(0)))
|
||||
case reflect.Uint8 : return self.valloc(p, reflect.TypeOf(uint8(0)))
|
||||
case reflect.Uint16 : return self.valloc(p, reflect.TypeOf(uint16(0)))
|
||||
case reflect.Uint32 : return self.valloc(p, reflect.TypeOf(uint32(0)))
|
||||
case reflect.Uint64 : return self.valloc(p, reflect.TypeOf(uint64(0)))
|
||||
case reflect.Uintptr : return self.valloc(p, reflect.TypeOf(uintptr(0)))
|
||||
case reflect.Float32 : return self.valloc(p, reflect.TypeOf(float32(0)))
|
||||
case reflect.Float64 : return self.valloc(p, reflect.TypeOf(float64(0)))
|
||||
case reflect.Complex64 : panic("abi: go117: not implemented: complex64")
|
||||
case reflect.Complex128 : panic("abi: go117: not implemented: complex128")
|
||||
case reflect.Array : panic("abi: go117: not implemented: arrays")
|
||||
case reflect.Chan : return self.valloc(p, reflect.TypeOf((chan int)(nil)))
|
||||
case reflect.Func : return self.valloc(p, reflect.TypeOf((func())(nil)))
|
||||
case reflect.Map : return self.valloc(p, reflect.TypeOf((map[int]int)(nil)))
|
||||
case reflect.Ptr : return self.valloc(p, reflect.TypeOf((*int)(nil)))
|
||||
case reflect.UnsafePointer : return self.valloc(p, ptrType)
|
||||
case reflect.Interface : return self.valloc(p, ptrType, ptrType)
|
||||
case reflect.Slice : return self.valloc(p, ptrType, intType, intType)
|
||||
case reflect.String : return self.valloc(p, ptrType, intType)
|
||||
case reflect.Struct : panic("abi: go117: not implemented: structs")
|
||||
default : panic("abi: invalid value type")
|
||||
}
|
||||
/* check for value type */
|
||||
switch vk {
|
||||
case reflect.Bool:
|
||||
return self.valloc(p, reflect.TypeOf(false))
|
||||
case reflect.Int:
|
||||
return self.valloc(p, intType)
|
||||
case reflect.Int8:
|
||||
return self.valloc(p, reflect.TypeOf(int8(0)))
|
||||
case reflect.Int16:
|
||||
return self.valloc(p, reflect.TypeOf(int16(0)))
|
||||
case reflect.Int32:
|
||||
return self.valloc(p, reflect.TypeOf(uint32(0)))
|
||||
case reflect.Int64:
|
||||
return self.valloc(p, reflect.TypeOf(int64(0)))
|
||||
case reflect.Uint:
|
||||
return self.valloc(p, reflect.TypeOf(uint(0)))
|
||||
case reflect.Uint8:
|
||||
return self.valloc(p, reflect.TypeOf(uint8(0)))
|
||||
case reflect.Uint16:
|
||||
return self.valloc(p, reflect.TypeOf(uint16(0)))
|
||||
case reflect.Uint32:
|
||||
return self.valloc(p, reflect.TypeOf(uint32(0)))
|
||||
case reflect.Uint64:
|
||||
return self.valloc(p, reflect.TypeOf(uint64(0)))
|
||||
case reflect.Uintptr:
|
||||
return self.valloc(p, reflect.TypeOf(uintptr(0)))
|
||||
case reflect.Float32:
|
||||
return self.valloc(p, reflect.TypeOf(float32(0)))
|
||||
case reflect.Float64:
|
||||
return self.valloc(p, reflect.TypeOf(float64(0)))
|
||||
case reflect.Complex64:
|
||||
panic("abi: go117: not implemented: complex64")
|
||||
case reflect.Complex128:
|
||||
panic("abi: go117: not implemented: complex128")
|
||||
case reflect.Array:
|
||||
panic("abi: go117: not implemented: arrays")
|
||||
case reflect.Chan:
|
||||
return self.valloc(p, reflect.TypeOf((chan int)(nil)))
|
||||
case reflect.Func:
|
||||
return self.valloc(p, reflect.TypeOf((func())(nil)))
|
||||
case reflect.Map:
|
||||
return self.valloc(p, reflect.TypeOf((map[int]int)(nil)))
|
||||
case reflect.Ptr:
|
||||
return self.valloc(p, reflect.TypeOf((*int)(nil)))
|
||||
case reflect.UnsafePointer:
|
||||
return self.valloc(p, ptrType)
|
||||
case reflect.Interface:
|
||||
return self.valloc(p, ptrType, ptrType)
|
||||
case reflect.Slice:
|
||||
return self.valloc(p, ptrType, intType, intType)
|
||||
case reflect.String:
|
||||
return self.valloc(p, ptrType, intType)
|
||||
case reflect.Struct:
|
||||
panic("abi: go117: not implemented: structs")
|
||||
default:
|
||||
panic("abi: invalid value type")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *stackAlloc) valloc(p []Parameter, vts ...reflect.Type) []Parameter {
|
||||
for _, vt := range vts {
|
||||
enum := isFloat(vt)
|
||||
if enum != notFloatKind && self.x < len(xregOrderGo) {
|
||||
p = append(p, self.xreg(vt))
|
||||
} else if enum == notFloatKind && self.i < len(iregOrderGo) {
|
||||
p = append(p, self.ireg(vt))
|
||||
} else {
|
||||
p = append(p, self.stack(vt))
|
||||
}
|
||||
}
|
||||
return p
|
||||
for _, vt := range vts {
|
||||
enum := isFloat(vt)
|
||||
if enum != notFloatKind && self.x < len(xregOrderGo) {
|
||||
p = append(p, self.xreg(vt))
|
||||
} else if enum == notFloatKind && self.i < len(iregOrderGo) {
|
||||
p = append(p, self.ireg(vt))
|
||||
} else {
|
||||
p = append(p, self.stack(vt))
|
||||
}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func NewFunctionLayout(ft reflect.Type) FunctionLayout {
|
||||
var sa stackAlloc
|
||||
var fn FunctionLayout
|
||||
var sa stackAlloc
|
||||
var fn FunctionLayout
|
||||
|
||||
/* assign every arguments */
|
||||
for i := 0; i < ft.NumIn(); i++ {
|
||||
fn.Args = sa.alloc(fn.Args, ft.In(i))
|
||||
}
|
||||
/* assign every arguments */
|
||||
for i := 0; i < ft.NumIn(); i++ {
|
||||
fn.Args = sa.alloc(fn.Args, ft.In(i))
|
||||
}
|
||||
|
||||
/* reset the register counter, and add a pointer alignment field */
|
||||
sa.reset()
|
||||
/* reset the register counter, and add a pointer alignment field */
|
||||
sa.reset()
|
||||
|
||||
/* assign every return value */
|
||||
for i := 0; i < ft.NumOut(); i++ {
|
||||
fn.Rets = sa.alloc(fn.Rets, ft.Out(i))
|
||||
}
|
||||
/* assign every return value */
|
||||
for i := 0; i < ft.NumOut(); i++ {
|
||||
fn.Rets = sa.alloc(fn.Rets, ft.Out(i))
|
||||
}
|
||||
|
||||
sa.spill(0, PtrAlign)
|
||||
sa.spill(0, PtrAlign)
|
||||
|
||||
/* assign spill slots */
|
||||
for i := 0; i < len(fn.Args); i++ {
|
||||
if fn.Args[i].InRegister {
|
||||
fn.Args[i].Mem = sa.spill(PtrSize, PtrAlign) - PtrSize
|
||||
}
|
||||
}
|
||||
/* assign spill slots */
|
||||
for i := 0; i < len(fn.Args); i++ {
|
||||
if fn.Args[i].InRegister {
|
||||
fn.Args[i].Mem = sa.spill(PtrSize, PtrAlign) - PtrSize
|
||||
}
|
||||
}
|
||||
|
||||
/* add the final pointer alignment field */
|
||||
fn.FP = sa.spill(0, PtrAlign)
|
||||
return fn
|
||||
/* add the final pointer alignment field */
|
||||
fn.FP = sa.spill(0, PtrAlign)
|
||||
return fn
|
||||
}
|
||||
|
||||
func (self *Frame) emitExchangeArgs(p *Program) {
|
||||
iregArgs := make([]Parameter, 0, len(self.desc.Args))
|
||||
xregArgs := 0
|
||||
for _, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat != notFloatKind {
|
||||
xregArgs += 1
|
||||
} else {
|
||||
iregArgs = append(iregArgs, v)
|
||||
}
|
||||
} else {
|
||||
panic("not support stack-assgined arguments now")
|
||||
}
|
||||
}
|
||||
if xregArgs > len(xregOrderC) {
|
||||
panic("too many arguments, only support at most 8 integer register arguments now")
|
||||
}
|
||||
iregArgs := make([]Parameter, 0, len(self.desc.Args))
|
||||
xregArgs := 0
|
||||
for _, v := range self.desc.Args {
|
||||
if v.InRegister {
|
||||
if v.IsFloat != notFloatKind {
|
||||
xregArgs += 1
|
||||
} else {
|
||||
iregArgs = append(iregArgs, v)
|
||||
}
|
||||
} else {
|
||||
panic("not support stack-assgined arguments now")
|
||||
}
|
||||
}
|
||||
if xregArgs > len(xregOrderC) {
|
||||
panic("too many arguments, only support at most 8 integer register arguments now")
|
||||
}
|
||||
|
||||
switch len(iregArgs) {
|
||||
case 0, 1, 2, 3: {
|
||||
//Fast-Path: when arguments count are less than four, just exchange the registers
|
||||
for i := 0; i < len(iregArgs); i++ {
|
||||
p.MOVQ(iregOrderGo[i], iregOrderC[i])
|
||||
}
|
||||
}
|
||||
case 4, 5, 6: {
|
||||
// need to spill 3th ~ regArgs registers before exchange
|
||||
for i := 3; i < len(iregArgs); i++ {
|
||||
arg := iregArgs[i]
|
||||
// pointer args have already been spilled
|
||||
if !arg.IsPointer {
|
||||
p.MOVQ(iregOrderGo[i], Ptr(RSP, int32(self.Prev() + arg.Mem)))
|
||||
}
|
||||
}
|
||||
p.MOVQ(iregOrderGo[0], iregOrderC[0])
|
||||
p.MOVQ(iregOrderGo[1], iregOrderC[1])
|
||||
p.MOVQ(iregOrderGo[2], iregOrderC[2])
|
||||
for i := 3; i < len(iregArgs); i++ {
|
||||
arg := iregArgs[i]
|
||||
p.MOVQ(Ptr(RSP, int32(self.Prev() + arg.Mem)), iregOrderC[i])
|
||||
}
|
||||
}
|
||||
default:
|
||||
panic("too many arguments, only support at most 6 integer register arguments now")
|
||||
}
|
||||
switch len(iregArgs) {
|
||||
case 0, 1, 2, 3:
|
||||
{
|
||||
//Fast-Path: when arguments count are less than four, just exchange the registers
|
||||
for i := 0; i < len(iregArgs); i++ {
|
||||
p.MOVQ(iregOrderGo[i], iregOrderC[i])
|
||||
}
|
||||
}
|
||||
case 4, 5, 6:
|
||||
{
|
||||
// need to spill 3th ~ regArgs registers before exchange
|
||||
for i := 3; i < len(iregArgs); i++ {
|
||||
arg := iregArgs[i]
|
||||
// pointer args have already been spilled
|
||||
if !arg.IsPointer {
|
||||
p.MOVQ(iregOrderGo[i], Ptr(RSP, int32(self.Prev()+arg.Mem)))
|
||||
}
|
||||
}
|
||||
p.MOVQ(iregOrderGo[0], iregOrderC[0])
|
||||
p.MOVQ(iregOrderGo[1], iregOrderC[1])
|
||||
p.MOVQ(iregOrderGo[2], iregOrderC[2])
|
||||
for i := 3; i < len(iregArgs); i++ {
|
||||
arg := iregArgs[i]
|
||||
p.MOVQ(Ptr(RSP, int32(self.Prev()+arg.Mem)), iregOrderC[i])
|
||||
}
|
||||
}
|
||||
default:
|
||||
panic("too many arguments, only support at most 6 integer register arguments now")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Frame) emitStackCheck(p *Program, to *Label, maxStack uintptr) {
|
||||
p.LEAQ(Ptr(RSP, int32(-(self.Size() + uint32(maxStack)))), R12)
|
||||
p.CMPQ(Ptr(R14, _G_stackguard0), R12)
|
||||
p.JBE(to)
|
||||
p.LEAQ(Ptr(RSP, int32(-(self.Size()+uint32(maxStack)))), R12)
|
||||
p.CMPQ(Ptr(R14, _G_stackguard0), R12)
|
||||
p.JBE(to)
|
||||
}
|
||||
|
||||
func (self *Frame) StackCheckTextSize() uint32 {
|
||||
p := DefaultArch.CreateProgram()
|
||||
p.LEAQ(Ptr(RSP, int32(-(self.Size()))), R12)
|
||||
p.CMPQ(Ptr(R14, _G_stackguard0), R12)
|
||||
to := CreateLabel("")
|
||||
p.Link(to)
|
||||
p.JBE(to)
|
||||
return uint32(len(p.Assemble(0)))
|
||||
p := DefaultArch.CreateProgram()
|
||||
p.LEAQ(Ptr(RSP, int32(-(self.Size()))), R12)
|
||||
p.CMPQ(Ptr(R14, _G_stackguard0), R12)
|
||||
to := CreateLabel("")
|
||||
p.Link(to)
|
||||
p.JBE(to)
|
||||
return uint32(len(p.Assemble(0)))
|
||||
}
|
||||
|
||||
func (self *Frame) emitExchangeRets(p *Program) {
|
||||
if len(self.desc.Rets) > 1 {
|
||||
panic("too many results, only support one result now")
|
||||
}
|
||||
// store result
|
||||
if len(self.desc.Rets) == 1 && !self.desc.Rets[0].InRegister {
|
||||
if self.desc.Rets[0].IsFloat == floatKind64 {
|
||||
p.MOVSD(xregOrderC[0], self.retv(0))
|
||||
} else if self.desc.Rets[0].IsFloat == floatKind32 {
|
||||
p.MOVSS(xregOrderC[0], self.retv(0))
|
||||
} else {
|
||||
p.MOVQ(RAX, self.retv(0))
|
||||
}
|
||||
}
|
||||
if len(self.desc.Rets) > 1 {
|
||||
panic("too many results, only support one result now")
|
||||
}
|
||||
// store result
|
||||
if len(self.desc.Rets) == 1 && !self.desc.Rets[0].InRegister {
|
||||
if self.desc.Rets[0].IsFloat == floatKind64 {
|
||||
p.MOVSD(xregOrderC[0], self.retv(0))
|
||||
} else if self.desc.Rets[0].IsFloat == floatKind32 {
|
||||
p.MOVSS(xregOrderC[0], self.retv(0))
|
||||
} else {
|
||||
p.MOVQ(RAX, self.retv(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Frame) emitRestoreRegs(p *Program) {
|
||||
// load reserved registers
|
||||
for i, r := range ReservedRegs(self.ccall) {
|
||||
switch r.(type) {
|
||||
case Register64:
|
||||
p.MOVQ(self.resv(i), r)
|
||||
case XMMRegister:
|
||||
p.MOVSD(self.resv(i), r)
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported register type %t to reserve", r))
|
||||
}
|
||||
}
|
||||
// zero xmm15 for go abi
|
||||
p.XORPS(zeroRegGo, zeroRegGo)
|
||||
}
|
||||
// load reserved registers
|
||||
for i, r := range ReservedRegs(self.ccall) {
|
||||
switch r.(type) {
|
||||
case Register64:
|
||||
p.MOVQ(self.resv(i), r)
|
||||
case XMMRegister:
|
||||
p.MOVSD(self.resv(i), r)
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported register type %t to reserve", r))
|
||||
}
|
||||
}
|
||||
// zero xmm15 for go abi
|
||||
p.XORPS(zeroRegGo, zeroRegGo)
|
||||
}
|
||||
|
|
273
vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ast.go
generated
vendored
Normal file
273
vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ast.go
generated
vendored
Normal file
|
@ -0,0 +1,273 @@
|
|||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Type is tyep expression type.
|
||||
type Type int
|
||||
|
||||
const (
|
||||
// CONST indicates that the expression is a constant.
|
||||
CONST Type = iota
|
||||
|
||||
// TERM indicates that the expression is a Term reference.
|
||||
TERM
|
||||
|
||||
// EXPR indicates that the expression is a unary or binary expression.
|
||||
EXPR
|
||||
)
|
||||
|
||||
var typeNames = map[Type]string{
|
||||
EXPR: "Expr",
|
||||
TERM: "Term",
|
||||
CONST: "Const",
|
||||
}
|
||||
|
||||
// String returns the string representation of a Type.
|
||||
func (self Type) String() string {
|
||||
if v, ok := typeNames[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
return fmt.Sprintf("expr.Type(%d)", self)
|
||||
}
|
||||
}
|
||||
|
||||
// Operator represents an operation to perform when Type is EXPR.
|
||||
type Operator uint8
|
||||
|
||||
const (
|
||||
// ADD performs "Add Expr.Left and Expr.Right".
|
||||
ADD Operator = iota
|
||||
|
||||
// SUB performs "Subtract Expr.Left by Expr.Right".
|
||||
SUB
|
||||
|
||||
// MUL performs "Multiply Expr.Left by Expr.Right".
|
||||
MUL
|
||||
|
||||
// DIV performs "Divide Expr.Left by Expr.Right".
|
||||
DIV
|
||||
|
||||
// MOD performs "Modulo Expr.Left by Expr.Right".
|
||||
MOD
|
||||
|
||||
// AND performs "Bitwise AND Expr.Left and Expr.Right".
|
||||
AND
|
||||
|
||||
// OR performs "Bitwise OR Expr.Left and Expr.Right".
|
||||
OR
|
||||
|
||||
// XOR performs "Bitwise XOR Expr.Left and Expr.Right".
|
||||
XOR
|
||||
|
||||
// SHL performs "Bitwise Shift Expr.Left to the Left by Expr.Right Bits".
|
||||
SHL
|
||||
|
||||
// SHR performs "Bitwise Shift Expr.Left to the Right by Expr.Right Bits".
|
||||
SHR
|
||||
|
||||
// POW performs "Raise Expr.Left to the power of Expr.Right"
|
||||
POW
|
||||
|
||||
// NOT performs "Bitwise Invert Expr.Left".
|
||||
NOT
|
||||
|
||||
// NEG performs "Negate Expr.Left".
|
||||
NEG
|
||||
)
|
||||
|
||||
var operatorNames = map[Operator]string{
|
||||
ADD: "Add",
|
||||
SUB: "Subtract",
|
||||
MUL: "Multiply",
|
||||
DIV: "Divide",
|
||||
MOD: "Modulo",
|
||||
AND: "And",
|
||||
OR: "Or",
|
||||
XOR: "ExclusiveOr",
|
||||
SHL: "ShiftLeft",
|
||||
SHR: "ShiftRight",
|
||||
POW: "Power",
|
||||
NOT: "Invert",
|
||||
NEG: "Negate",
|
||||
}
|
||||
|
||||
// String returns the string representation of a Type.
|
||||
func (self Operator) String() string {
|
||||
if v, ok := operatorNames[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
return fmt.Sprintf("expr.Operator(%d)", self)
|
||||
}
|
||||
}
|
||||
|
||||
// Expr represents an expression node.
|
||||
type Expr struct {
|
||||
Type Type
|
||||
Term Term
|
||||
Op Operator
|
||||
Left *Expr
|
||||
Right *Expr
|
||||
Const int64
|
||||
}
|
||||
|
||||
// Ref creates an expression from a Term.
|
||||
func Ref(t Term) (p *Expr) {
|
||||
p = newExpression()
|
||||
p.Term = t
|
||||
p.Type = TERM
|
||||
return
|
||||
}
|
||||
|
||||
// Int creates an expression from an integer.
|
||||
func Int(v int64) (p *Expr) {
|
||||
p = newExpression()
|
||||
p.Type = CONST
|
||||
p.Const = v
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Expr) clear() {
|
||||
if self.Term != nil {
|
||||
self.Term.Free()
|
||||
}
|
||||
if self.Left != nil {
|
||||
self.Left.Free()
|
||||
}
|
||||
if self.Right != nil {
|
||||
self.Right.Free()
|
||||
}
|
||||
}
|
||||
|
||||
// Free returns the Expr into pool.
|
||||
// Any operation performed after Free is undefined behavior.
|
||||
func (self *Expr) Free() {
|
||||
self.clear()
|
||||
freeExpression(self)
|
||||
}
|
||||
|
||||
// Evaluate evaluates the expression into an integer.
|
||||
// It also implements the Term interface.
|
||||
func (self *Expr) Evaluate() (int64, error) {
|
||||
switch self.Type {
|
||||
case EXPR:
|
||||
return self.eval()
|
||||
case TERM:
|
||||
return self.Term.Evaluate()
|
||||
case CONST:
|
||||
return self.Const, nil
|
||||
default:
|
||||
panic("invalid expression type: " + self.Type.String())
|
||||
}
|
||||
}
|
||||
|
||||
/** Expression Combinator **/
|
||||
|
||||
func combine(a *Expr, op Operator, b *Expr) (r *Expr) {
|
||||
r = newExpression()
|
||||
r.Op = op
|
||||
r.Type = EXPR
|
||||
r.Left = a
|
||||
r.Right = b
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Expr) Add(v *Expr) *Expr { return combine(self, ADD, v) }
|
||||
func (self *Expr) Sub(v *Expr) *Expr { return combine(self, SUB, v) }
|
||||
func (self *Expr) Mul(v *Expr) *Expr { return combine(self, MUL, v) }
|
||||
func (self *Expr) Div(v *Expr) *Expr { return combine(self, DIV, v) }
|
||||
func (self *Expr) Mod(v *Expr) *Expr { return combine(self, MOD, v) }
|
||||
func (self *Expr) And(v *Expr) *Expr { return combine(self, AND, v) }
|
||||
func (self *Expr) Or(v *Expr) *Expr { return combine(self, OR, v) }
|
||||
func (self *Expr) Xor(v *Expr) *Expr { return combine(self, XOR, v) }
|
||||
func (self *Expr) Shl(v *Expr) *Expr { return combine(self, SHL, v) }
|
||||
func (self *Expr) Shr(v *Expr) *Expr { return combine(self, SHR, v) }
|
||||
func (self *Expr) Pow(v *Expr) *Expr { return combine(self, POW, v) }
|
||||
func (self *Expr) Not() *Expr { return combine(self, NOT, nil) }
|
||||
func (self *Expr) Neg() *Expr { return combine(self, NEG, nil) }
|
||||
|
||||
/** Expression Evaluator **/
|
||||
|
||||
var binaryEvaluators = [256]func(int64, int64) (int64, error){
|
||||
ADD: func(a, b int64) (int64, error) { return a + b, nil },
|
||||
SUB: func(a, b int64) (int64, error) { return a - b, nil },
|
||||
MUL: func(a, b int64) (int64, error) { return a * b, nil },
|
||||
DIV: idiv,
|
||||
MOD: imod,
|
||||
AND: func(a, b int64) (int64, error) { return a & b, nil },
|
||||
OR: func(a, b int64) (int64, error) { return a | b, nil },
|
||||
XOR: func(a, b int64) (int64, error) { return a ^ b, nil },
|
||||
SHL: func(a, b int64) (int64, error) { return a << b, nil },
|
||||
SHR: func(a, b int64) (int64, error) { return a >> b, nil },
|
||||
POW: ipow,
|
||||
}
|
||||
|
||||
func (self *Expr) eval() (int64, error) {
|
||||
var lhs int64
|
||||
var rhs int64
|
||||
var err error
|
||||
var vfn func(int64, int64) (int64, error)
|
||||
|
||||
/* evaluate LHS */
|
||||
if lhs, err = self.Left.Evaluate(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
/* check for unary operators */
|
||||
switch self.Op {
|
||||
case NOT:
|
||||
return self.unaryNot(lhs)
|
||||
case NEG:
|
||||
return self.unaryNeg(lhs)
|
||||
}
|
||||
|
||||
/* check for operators */
|
||||
if vfn = binaryEvaluators[self.Op]; vfn == nil {
|
||||
panic("invalid operator: " + self.Op.String())
|
||||
}
|
||||
|
||||
/* must be a binary expression */
|
||||
if self.Right == nil {
|
||||
panic("operator " + self.Op.String() + " is a binary operator")
|
||||
}
|
||||
|
||||
/* evaluate RHS, and call the operator */
|
||||
if rhs, err = self.Right.Evaluate(); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return vfn(lhs, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Expr) unaryNot(v int64) (int64, error) {
|
||||
if self.Right == nil {
|
||||
return ^v, nil
|
||||
} else {
|
||||
panic("operator Invert is an unary operator")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Expr) unaryNeg(v int64) (int64, error) {
|
||||
if self.Right == nil {
|
||||
return -v, nil
|
||||
} else {
|
||||
panic("operator Negate is an unary operator")
|
||||
}
|
||||
}
|
|
@ -17,37 +17,37 @@
|
|||
package expr
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// SyntaxError represents a syntax error in the expression.
|
||||
type SyntaxError struct {
|
||||
Pos int
|
||||
Reason string
|
||||
Pos int
|
||||
Reason string
|
||||
}
|
||||
|
||||
func newSyntaxError(pos int, reason string) *SyntaxError {
|
||||
return &SyntaxError {
|
||||
Pos : pos,
|
||||
Reason : reason,
|
||||
}
|
||||
return &SyntaxError{
|
||||
Pos: pos,
|
||||
Reason: reason,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SyntaxError) Error() string {
|
||||
return fmt.Sprintf("Syntax error at position %d: %s", self.Pos, self.Reason)
|
||||
return fmt.Sprintf("Syntax error at position %d: %s", self.Pos, self.Reason)
|
||||
}
|
||||
|
||||
// RuntimeError is an error which would occure at run time.
|
||||
type RuntimeError struct {
|
||||
Reason string
|
||||
Reason string
|
||||
}
|
||||
|
||||
func newRuntimeError(reason string) *RuntimeError {
|
||||
return &RuntimeError {
|
||||
Reason: reason,
|
||||
}
|
||||
return &RuntimeError{
|
||||
Reason: reason,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *RuntimeError) Error() string {
|
||||
return "Runtime error: " + self.Reason
|
||||
return "Runtime error: " + self.Reason
|
||||
}
|
67
vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ops.go
generated
vendored
Normal file
67
vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ops.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func idiv(v int64, d int64) (int64, error) {
|
||||
if d != 0 {
|
||||
return v / d, nil
|
||||
} else {
|
||||
return 0, newRuntimeError("division by zero")
|
||||
}
|
||||
}
|
||||
|
||||
func imod(v int64, d int64) (int64, error) {
|
||||
if d != 0 {
|
||||
return v % d, nil
|
||||
} else {
|
||||
return 0, newRuntimeError("division by zero")
|
||||
}
|
||||
}
|
||||
|
||||
func ipow(v int64, e int64) (int64, error) {
|
||||
mul := v
|
||||
ret := int64(1)
|
||||
|
||||
/* value must be 0 or positive */
|
||||
if v < 0 {
|
||||
return 0, newRuntimeError(fmt.Sprintf("negative base value: %d", v))
|
||||
}
|
||||
|
||||
/* exponent must be non-negative */
|
||||
if e < 0 {
|
||||
return 0, newRuntimeError(fmt.Sprintf("negative exponent: %d", e))
|
||||
}
|
||||
|
||||
/* fast power first round */
|
||||
if (e & 1) != 0 {
|
||||
ret *= mul
|
||||
}
|
||||
|
||||
/* fast power remaining rounds */
|
||||
for e >>= 1; e != 0; e >>= 1 {
|
||||
if mul *= mul; (e & 1) != 0 {
|
||||
ret *= mul
|
||||
}
|
||||
}
|
||||
|
||||
/* all done */
|
||||
return ret, nil
|
||||
}
|
331
vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/parser.go
generated
vendored
Normal file
331
vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/parser.go
generated
vendored
Normal file
|
@ -0,0 +1,331 @@
|
|||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"unicode"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type _TokenKind uint8
|
||||
|
||||
const (
|
||||
_T_end _TokenKind = iota + 1
|
||||
_T_int
|
||||
_T_punc
|
||||
_T_name
|
||||
)
|
||||
|
||||
const (
|
||||
_OP2 = 0x80
|
||||
_POW = _OP2 | '*'
|
||||
_SHL = _OP2 | '<'
|
||||
_SHR = _OP2 | '>'
|
||||
)
|
||||
|
||||
type _Slice struct {
|
||||
p unsafe.Pointer
|
||||
n int
|
||||
c int
|
||||
}
|
||||
|
||||
type _Token struct {
|
||||
pos int
|
||||
ptr *rune
|
||||
u64 uint64
|
||||
tag _TokenKind
|
||||
}
|
||||
|
||||
func (self _Token) str() (v string) {
|
||||
return string(self.rbuf())
|
||||
}
|
||||
|
||||
func (self _Token) rbuf() (v []rune) {
|
||||
(*_Slice)(unsafe.Pointer(&v)).c = int(self.u64)
|
||||
(*_Slice)(unsafe.Pointer(&v)).n = int(self.u64)
|
||||
(*_Slice)(unsafe.Pointer(&v)).p = unsafe.Pointer(self.ptr)
|
||||
return
|
||||
}
|
||||
|
||||
func tokenEnd(p int) _Token {
|
||||
return _Token{
|
||||
pos: p,
|
||||
tag: _T_end,
|
||||
}
|
||||
}
|
||||
|
||||
func tokenInt(p int, v uint64) _Token {
|
||||
return _Token{
|
||||
pos: p,
|
||||
u64: v,
|
||||
tag: _T_int,
|
||||
}
|
||||
}
|
||||
|
||||
func tokenPunc(p int, v rune) _Token {
|
||||
return _Token{
|
||||
pos: p,
|
||||
tag: _T_punc,
|
||||
u64: uint64(v),
|
||||
}
|
||||
}
|
||||
|
||||
func tokenName(p int, v []rune) _Token {
|
||||
return _Token{
|
||||
pos: p,
|
||||
ptr: &v[0],
|
||||
tag: _T_name,
|
||||
u64: uint64(len(v)),
|
||||
}
|
||||
}
|
||||
|
||||
// Repository represents a repository of Term's.
|
||||
type Repository interface {
|
||||
Get(name string) (Term, error)
|
||||
}
|
||||
|
||||
// Parser parses an expression string to it's AST representation.
|
||||
type Parser struct {
|
||||
pos int
|
||||
src []rune
|
||||
}
|
||||
|
||||
var binaryOps = [...]func(*Expr, *Expr) *Expr{
|
||||
'+': (*Expr).Add,
|
||||
'-': (*Expr).Sub,
|
||||
'*': (*Expr).Mul,
|
||||
'/': (*Expr).Div,
|
||||
'%': (*Expr).Mod,
|
||||
'&': (*Expr).And,
|
||||
'^': (*Expr).Xor,
|
||||
'|': (*Expr).Or,
|
||||
_SHL: (*Expr).Shl,
|
||||
_SHR: (*Expr).Shr,
|
||||
_POW: (*Expr).Pow,
|
||||
}
|
||||
|
||||
var precedence = [...]map[int]bool{
|
||||
{_SHL: true, _SHR: true},
|
||||
{'|': true},
|
||||
{'^': true},
|
||||
{'&': true},
|
||||
{'+': true, '-': true},
|
||||
{'*': true, '/': true, '%': true},
|
||||
{_POW: true},
|
||||
}
|
||||
|
||||
func (self *Parser) ch() rune {
|
||||
return self.src[self.pos]
|
||||
}
|
||||
|
||||
func (self *Parser) eof() bool {
|
||||
return self.pos >= len(self.src)
|
||||
}
|
||||
|
||||
func (self *Parser) rch() (v rune) {
|
||||
v, self.pos = self.src[self.pos], self.pos+1
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Parser) hex(ss []rune) bool {
|
||||
if len(ss) == 1 && ss[0] == '0' {
|
||||
return unicode.ToLower(self.ch()) == 'x'
|
||||
} else if len(ss) <= 1 || unicode.ToLower(ss[1]) != 'x' {
|
||||
return unicode.IsDigit(self.ch())
|
||||
} else {
|
||||
return ishexdigit(self.ch())
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) int(p int, ss []rune) (_Token, error) {
|
||||
var err error
|
||||
var val uint64
|
||||
|
||||
/* find all the digits */
|
||||
for !self.eof() && self.hex(ss) {
|
||||
ss = append(ss, self.rch())
|
||||
}
|
||||
|
||||
/* parse the value */
|
||||
if val, err = strconv.ParseUint(string(ss), 0, 64); err != nil {
|
||||
return _Token{}, err
|
||||
} else {
|
||||
return tokenInt(p, val), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) name(p int, ss []rune) _Token {
|
||||
for !self.eof() && isident(self.ch()) {
|
||||
ss = append(ss, self.rch())
|
||||
}
|
||||
return tokenName(p, ss)
|
||||
}
|
||||
|
||||
func (self *Parser) read(p int, ch rune) (_Token, error) {
|
||||
if isdigit(ch) {
|
||||
return self.int(p, []rune{ch})
|
||||
} else if isident0(ch) {
|
||||
return self.name(p, []rune{ch}), nil
|
||||
} else if isop2ch(ch) && !self.eof() && self.ch() == ch {
|
||||
return tokenPunc(p, _OP2|self.rch()), nil
|
||||
} else if isop1ch(ch) {
|
||||
return tokenPunc(p, ch), nil
|
||||
} else {
|
||||
return _Token{}, newSyntaxError(self.pos, "invalid character "+strconv.QuoteRuneToASCII(ch))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) next() (_Token, error) {
|
||||
for {
|
||||
var p int
|
||||
var c rune
|
||||
|
||||
/* check for EOF */
|
||||
if self.eof() {
|
||||
return tokenEnd(self.pos), nil
|
||||
}
|
||||
|
||||
/* read the next char */
|
||||
p = self.pos
|
||||
c = self.rch()
|
||||
|
||||
/* parse the token if not a space */
|
||||
if !unicode.IsSpace(c) {
|
||||
return self.read(p, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) grab(tk _Token, repo Repository) (*Expr, error) {
|
||||
if repo == nil {
|
||||
return nil, newSyntaxError(tk.pos, "unresolved symbol: "+tk.str())
|
||||
} else if term, err := repo.Get(tk.str()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return Ref(term), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) nest(nest int, repo Repository) (*Expr, error) {
|
||||
var err error
|
||||
var ret *Expr
|
||||
var ntk _Token
|
||||
|
||||
/* evaluate the nested expression */
|
||||
if ret, err = self.expr(0, nest+1, repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* must follows with a ')' */
|
||||
if ntk, err = self.next(); err != nil {
|
||||
return nil, err
|
||||
} else if ntk.tag != _T_punc || ntk.u64 != ')' {
|
||||
return nil, newSyntaxError(ntk.pos, "')' expected")
|
||||
} else {
|
||||
return ret, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) unit(nest int, repo Repository) (*Expr, error) {
|
||||
if tk, err := self.next(); err != nil {
|
||||
return nil, err
|
||||
} else if tk.tag == _T_int {
|
||||
return Int(int64(tk.u64)), nil
|
||||
} else if tk.tag == _T_name {
|
||||
return self.grab(tk, repo)
|
||||
} else if tk.tag == _T_punc && tk.u64 == '(' {
|
||||
return self.nest(nest, repo)
|
||||
} else if tk.tag == _T_punc && tk.u64 == '+' {
|
||||
return self.unit(nest, repo)
|
||||
} else if tk.tag == _T_punc && tk.u64 == '-' {
|
||||
return neg2(self.unit(nest, repo))
|
||||
} else if tk.tag == _T_punc && tk.u64 == '~' {
|
||||
return not2(self.unit(nest, repo))
|
||||
} else {
|
||||
return nil, newSyntaxError(tk.pos, "integer, unary operator or nested expression expected")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) term(prec int, nest int, repo Repository) (*Expr, error) {
|
||||
var err error
|
||||
var val *Expr
|
||||
|
||||
/* parse the LHS operand */
|
||||
if val, err = self.expr(prec+1, nest, repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* parse all the operators of the same precedence */
|
||||
for {
|
||||
var op int
|
||||
var rv *Expr
|
||||
var tk _Token
|
||||
|
||||
/* peek the next token */
|
||||
pp := self.pos
|
||||
tk, err = self.next()
|
||||
|
||||
/* check for errors */
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* encountered EOF */
|
||||
if tk.tag == _T_end {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
/* must be an operator */
|
||||
if tk.tag != _T_punc {
|
||||
return nil, newSyntaxError(tk.pos, "operators expected")
|
||||
}
|
||||
|
||||
/* check for the operator precedence */
|
||||
if op = int(tk.u64); !precedence[prec][op] {
|
||||
self.pos = pp
|
||||
return val, nil
|
||||
}
|
||||
|
||||
/* evaluate the RHS operand, and combine the value */
|
||||
if rv, err = self.expr(prec+1, nest, repo); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
val = binaryOps[op](val, rv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) expr(prec int, nest int, repo Repository) (*Expr, error) {
|
||||
if prec >= len(precedence) {
|
||||
return self.unit(nest, repo)
|
||||
} else {
|
||||
return self.term(prec, nest, repo)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse parses the expression, and returns it's AST tree.
|
||||
func (self *Parser) Parse(repo Repository) (*Expr, error) {
|
||||
return self.expr(0, 0, repo)
|
||||
}
|
||||
|
||||
// SetSource resets the expression parser and sets the expression source.
|
||||
func (self *Parser) SetSource(src string) *Parser {
|
||||
self.pos = 0
|
||||
self.src = []rune(src)
|
||||
return self
|
||||
}
|
|
@ -17,26 +17,26 @@
|
|||
package expr
|
||||
|
||||
import (
|
||||
`sync`
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
expressionPool sync.Pool
|
||||
expressionPool sync.Pool
|
||||
)
|
||||
|
||||
func newExpression() *Expr {
|
||||
if v := expressionPool.Get(); v == nil {
|
||||
return new(Expr)
|
||||
} else {
|
||||
return resetExpression(v.(*Expr))
|
||||
}
|
||||
if v := expressionPool.Get(); v == nil {
|
||||
return new(Expr)
|
||||
} else {
|
||||
return resetExpression(v.(*Expr))
|
||||
}
|
||||
}
|
||||
|
||||
func freeExpression(p *Expr) {
|
||||
expressionPool.Put(p)
|
||||
expressionPool.Put(p)
|
||||
}
|
||||
|
||||
func resetExpression(p *Expr) *Expr {
|
||||
*p = Expr{}
|
||||
return p
|
||||
*p = Expr{}
|
||||
return p
|
||||
}
|
|
@ -18,6 +18,6 @@
|
|||
|
||||
// Term represents a value that can Evaluate() into an integer.
|
||||
type Term interface {
|
||||
Free()
|
||||
Evaluate() (int64, error)
|
||||
Free()
|
||||
Evaluate() (int64, error)
|
||||
}
|
|
@ -16,62 +16,62 @@
|
|||
|
||||
package expr
|
||||
|
||||
var op1ch = [...]bool {
|
||||
'+': true,
|
||||
'-': true,
|
||||
'*': true,
|
||||
'/': true,
|
||||
'%': true,
|
||||
'&': true,
|
||||
'|': true,
|
||||
'^': true,
|
||||
'~': true,
|
||||
'(': true,
|
||||
')': true,
|
||||
var op1ch = [...]bool{
|
||||
'+': true,
|
||||
'-': true,
|
||||
'*': true,
|
||||
'/': true,
|
||||
'%': true,
|
||||
'&': true,
|
||||
'|': true,
|
||||
'^': true,
|
||||
'~': true,
|
||||
'(': true,
|
||||
')': true,
|
||||
}
|
||||
|
||||
var op2ch = [...]bool {
|
||||
'*': true,
|
||||
'<': true,
|
||||
'>': true,
|
||||
var op2ch = [...]bool{
|
||||
'*': true,
|
||||
'<': true,
|
||||
'>': true,
|
||||
}
|
||||
|
||||
func neg2(v *Expr, err error) (*Expr, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return v.Neg(), nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return v.Neg(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func not2(v *Expr, err error) (*Expr, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return v.Not(), nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return v.Not(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func isop1ch(ch rune) bool {
|
||||
return ch >= 0 && int(ch) < len(op1ch) && op1ch[ch]
|
||||
return ch >= 0 && int(ch) < len(op1ch) && op1ch[ch]
|
||||
}
|
||||
|
||||
func isop2ch(ch rune) bool {
|
||||
return ch >= 0 && int(ch) < len(op2ch) && op2ch[ch]
|
||||
return ch >= 0 && int(ch) < len(op2ch) && op2ch[ch]
|
||||
}
|
||||
|
||||
func isdigit(ch rune) bool {
|
||||
return ch >= '0' && ch <= '9'
|
||||
return ch >= '0' && ch <= '9'
|
||||
}
|
||||
|
||||
func isident(ch rune) bool {
|
||||
return isdigit(ch) || isident0(ch)
|
||||
return isdigit(ch) || isident0(ch)
|
||||
}
|
||||
|
||||
func isident0(ch rune) bool {
|
||||
return (ch == '_') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
|
||||
return (ch == '_') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
|
||||
}
|
||||
|
||||
func ishexdigit(ch rune) bool {
|
||||
return isdigit(ch) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')
|
||||
return isdigit(ch) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')
|
||||
}
|
251
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/arch.go
generated
vendored
Normal file
251
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/arch.go
generated
vendored
Normal file
|
@ -0,0 +1,251 @@
|
|||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ISA represents an extension to x86-64 instruction set.
|
||||
type ISA uint64
|
||||
|
||||
const (
|
||||
ISA_CPUID ISA = 1 << iota
|
||||
ISA_RDTSC
|
||||
ISA_RDTSCP
|
||||
ISA_CMOV
|
||||
ISA_MOVBE
|
||||
ISA_POPCNT
|
||||
ISA_LZCNT
|
||||
ISA_TBM
|
||||
ISA_BMI
|
||||
ISA_BMI2
|
||||
ISA_ADX
|
||||
ISA_MMX
|
||||
ISA_MMX_PLUS
|
||||
ISA_FEMMS
|
||||
ISA_3DNOW
|
||||
ISA_3DNOW_PLUS
|
||||
ISA_SSE
|
||||
ISA_SSE2
|
||||
ISA_SSE3
|
||||
ISA_SSSE3
|
||||
ISA_SSE4A
|
||||
ISA_SSE4_1
|
||||
ISA_SSE4_2
|
||||
ISA_FMA3
|
||||
ISA_FMA4
|
||||
ISA_XOP
|
||||
ISA_F16C
|
||||
ISA_AVX
|
||||
ISA_AVX2
|
||||
ISA_AVX512F
|
||||
ISA_AVX512BW
|
||||
ISA_AVX512DQ
|
||||
ISA_AVX512VL
|
||||
ISA_AVX512PF
|
||||
ISA_AVX512ER
|
||||
ISA_AVX512CD
|
||||
ISA_AVX512VBMI
|
||||
ISA_AVX512IFMA
|
||||
ISA_AVX512VPOPCNTDQ
|
||||
ISA_AVX512_4VNNIW
|
||||
ISA_AVX512_4FMAPS
|
||||
ISA_PREFETCH
|
||||
ISA_PREFETCHW
|
||||
ISA_PREFETCHWT1
|
||||
ISA_CLFLUSH
|
||||
ISA_CLFLUSHOPT
|
||||
ISA_CLWB
|
||||
ISA_CLZERO
|
||||
ISA_RDRAND
|
||||
ISA_RDSEED
|
||||
ISA_PCLMULQDQ
|
||||
ISA_AES
|
||||
ISA_SHA
|
||||
ISA_MONITOR
|
||||
ISA_MONITORX
|
||||
ISA_ALL = ^ISA(0)
|
||||
)
|
||||
|
||||
var _ISA_NAMES = map[ISA]string{
|
||||
ISA_CPUID: "CPUID",
|
||||
ISA_RDTSC: "RDTSC",
|
||||
ISA_RDTSCP: "RDTSCP",
|
||||
ISA_CMOV: "CMOV",
|
||||
ISA_MOVBE: "MOVBE",
|
||||
ISA_POPCNT: "POPCNT",
|
||||
ISA_LZCNT: "LZCNT",
|
||||
ISA_TBM: "TBM",
|
||||
ISA_BMI: "BMI",
|
||||
ISA_BMI2: "BMI2",
|
||||
ISA_ADX: "ADX",
|
||||
ISA_MMX: "MMX",
|
||||
ISA_MMX_PLUS: "MMX+",
|
||||
ISA_FEMMS: "FEMMS",
|
||||
ISA_3DNOW: "3dnow!",
|
||||
ISA_3DNOW_PLUS: "3dnow!+",
|
||||
ISA_SSE: "SSE",
|
||||
ISA_SSE2: "SSE2",
|
||||
ISA_SSE3: "SSE3",
|
||||
ISA_SSSE3: "SSSE3",
|
||||
ISA_SSE4A: "SSE4A",
|
||||
ISA_SSE4_1: "SSE4.1",
|
||||
ISA_SSE4_2: "SSE4.2",
|
||||
ISA_FMA3: "FMA3",
|
||||
ISA_FMA4: "FMA4",
|
||||
ISA_XOP: "XOP",
|
||||
ISA_F16C: "F16C",
|
||||
ISA_AVX: "AVX",
|
||||
ISA_AVX2: "AVX2",
|
||||
ISA_AVX512F: "AVX512F",
|
||||
ISA_AVX512BW: "AVX512BW",
|
||||
ISA_AVX512DQ: "AVX512DQ",
|
||||
ISA_AVX512VL: "AVX512VL",
|
||||
ISA_AVX512PF: "AVX512PF",
|
||||
ISA_AVX512ER: "AVX512ER",
|
||||
ISA_AVX512CD: "AVX512CD",
|
||||
ISA_AVX512VBMI: "AVX512VBMI",
|
||||
ISA_AVX512IFMA: "AVX512IFMA",
|
||||
ISA_AVX512VPOPCNTDQ: "AVX512VPOPCNTDQ",
|
||||
ISA_AVX512_4VNNIW: "AVX512_4VNNIW",
|
||||
ISA_AVX512_4FMAPS: "AVX512_4FMAPS",
|
||||
ISA_PREFETCH: "PREFETCH",
|
||||
ISA_PREFETCHW: "PREFETCHW",
|
||||
ISA_PREFETCHWT1: "PREFETCHWT1",
|
||||
ISA_CLFLUSH: "CLFLUSH",
|
||||
ISA_CLFLUSHOPT: "CLFLUSHOPT",
|
||||
ISA_CLWB: "CLWB",
|
||||
ISA_CLZERO: "CLZERO",
|
||||
ISA_RDRAND: "RDRAND",
|
||||
ISA_RDSEED: "RDSEED",
|
||||
ISA_PCLMULQDQ: "PCLMULQDQ",
|
||||
ISA_AES: "AES",
|
||||
ISA_SHA: "SHA",
|
||||
ISA_MONITOR: "MONITOR",
|
||||
ISA_MONITORX: "MONITORX",
|
||||
}
|
||||
|
||||
var _ISA_MAPPING = map[string]ISA{
|
||||
"CPUID": ISA_CPUID,
|
||||
"RDTSC": ISA_RDTSC,
|
||||
"RDTSCP": ISA_RDTSCP,
|
||||
"CMOV": ISA_CMOV,
|
||||
"MOVBE": ISA_MOVBE,
|
||||
"POPCNT": ISA_POPCNT,
|
||||
"LZCNT": ISA_LZCNT,
|
||||
"TBM": ISA_TBM,
|
||||
"BMI": ISA_BMI,
|
||||
"BMI2": ISA_BMI2,
|
||||
"ADX": ISA_ADX,
|
||||
"MMX": ISA_MMX,
|
||||
"MMX+": ISA_MMX_PLUS,
|
||||
"FEMMS": ISA_FEMMS,
|
||||
"3dnow!": ISA_3DNOW,
|
||||
"3dnow!+": ISA_3DNOW_PLUS,
|
||||
"SSE": ISA_SSE,
|
||||
"SSE2": ISA_SSE2,
|
||||
"SSE3": ISA_SSE3,
|
||||
"SSSE3": ISA_SSSE3,
|
||||
"SSE4A": ISA_SSE4A,
|
||||
"SSE4.1": ISA_SSE4_1,
|
||||
"SSE4.2": ISA_SSE4_2,
|
||||
"FMA3": ISA_FMA3,
|
||||
"FMA4": ISA_FMA4,
|
||||
"XOP": ISA_XOP,
|
||||
"F16C": ISA_F16C,
|
||||
"AVX": ISA_AVX,
|
||||
"AVX2": ISA_AVX2,
|
||||
"AVX512F": ISA_AVX512F,
|
||||
"AVX512BW": ISA_AVX512BW,
|
||||
"AVX512DQ": ISA_AVX512DQ,
|
||||
"AVX512VL": ISA_AVX512VL,
|
||||
"AVX512PF": ISA_AVX512PF,
|
||||
"AVX512ER": ISA_AVX512ER,
|
||||
"AVX512CD": ISA_AVX512CD,
|
||||
"AVX512VBMI": ISA_AVX512VBMI,
|
||||
"AVX512IFMA": ISA_AVX512IFMA,
|
||||
"AVX512VPOPCNTDQ": ISA_AVX512VPOPCNTDQ,
|
||||
"AVX512_4VNNIW": ISA_AVX512_4VNNIW,
|
||||
"AVX512_4FMAPS": ISA_AVX512_4FMAPS,
|
||||
"PREFETCH": ISA_PREFETCH,
|
||||
"PREFETCHW": ISA_PREFETCHW,
|
||||
"PREFETCHWT1": ISA_PREFETCHWT1,
|
||||
"CLFLUSH": ISA_CLFLUSH,
|
||||
"CLFLUSHOPT": ISA_CLFLUSHOPT,
|
||||
"CLWB": ISA_CLWB,
|
||||
"CLZERO": ISA_CLZERO,
|
||||
"RDRAND": ISA_RDRAND,
|
||||
"RDSEED": ISA_RDSEED,
|
||||
"PCLMULQDQ": ISA_PCLMULQDQ,
|
||||
"AES": ISA_AES,
|
||||
"SHA": ISA_SHA,
|
||||
"MONITOR": ISA_MONITOR,
|
||||
"MONITORX": ISA_MONITORX,
|
||||
}
|
||||
|
||||
func (self ISA) String() string {
|
||||
if v, ok := _ISA_NAMES[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
return fmt.Sprintf("(invalid: %#x)", uint64(self))
|
||||
}
|
||||
}
|
||||
|
||||
// ParseISA parses name into ISA, it will panic if the name is invalid.
|
||||
func ParseISA(name string) ISA {
|
||||
if v, ok := _ISA_MAPPING[name]; ok {
|
||||
return v
|
||||
} else {
|
||||
panic("invalid ISA name: " + name)
|
||||
}
|
||||
}
|
||||
|
||||
// Arch represents the x86_64 architecture.
|
||||
type Arch struct {
|
||||
isa ISA
|
||||
}
|
||||
|
||||
// DefaultArch is the default architecture with all ISA enabled.
|
||||
var DefaultArch = CreateArch()
|
||||
|
||||
// CreateArch creates a new Arch with all ISA enabled.
|
||||
func CreateArch() *Arch {
|
||||
return new(Arch).EnableISA(ISA_ALL)
|
||||
}
|
||||
|
||||
// HasISA checks if a particular ISA was enabled.
|
||||
func (self *Arch) HasISA(isa ISA) bool {
|
||||
return (self.isa & isa) != 0
|
||||
}
|
||||
|
||||
// EnableISA enables a particular ISA.
|
||||
func (self *Arch) EnableISA(isa ISA) *Arch {
|
||||
self.isa |= isa
|
||||
return self
|
||||
}
|
||||
|
||||
// DisableISA disables a particular ISA.
|
||||
func (self *Arch) DisableISA(isa ISA) *Arch {
|
||||
self.isa &^= isa
|
||||
return self
|
||||
}
|
||||
|
||||
// CreateProgram creates a new empty program.
|
||||
func (self *Arch) CreateProgram() *Program {
|
||||
return newProgram(self)
|
||||
}
|
|
@ -17,63 +17,63 @@
|
|||
package x86_64
|
||||
|
||||
import (
|
||||
`reflect`
|
||||
`unsafe`
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type _GoType struct {
|
||||
size uintptr
|
||||
pdata uintptr
|
||||
hash uint32
|
||||
flags uint8
|
||||
align uint8
|
||||
falign uint8
|
||||
kflags uint8
|
||||
traits unsafe.Pointer
|
||||
gcdata *byte
|
||||
str int32
|
||||
ptrx int32
|
||||
size uintptr
|
||||
pdata uintptr
|
||||
hash uint32
|
||||
flags uint8
|
||||
align uint8
|
||||
falign uint8
|
||||
kflags uint8
|
||||
traits unsafe.Pointer
|
||||
gcdata *byte
|
||||
str int32
|
||||
ptrx int32
|
||||
}
|
||||
|
||||
const (
|
||||
_KindMask = (1 << 5) - 1
|
||||
_KindMask = (1 << 5) - 1
|
||||
)
|
||||
|
||||
func (self *_GoType) kind() reflect.Kind {
|
||||
return reflect.Kind(self.kflags & _KindMask)
|
||||
return reflect.Kind(self.kflags & _KindMask)
|
||||
}
|
||||
|
||||
type _GoSlice struct {
|
||||
ptr unsafe.Pointer
|
||||
len int
|
||||
cap int
|
||||
ptr unsafe.Pointer
|
||||
len int
|
||||
cap int
|
||||
}
|
||||
|
||||
type _GoEface struct {
|
||||
vt *_GoType
|
||||
ptr unsafe.Pointer
|
||||
vt *_GoType
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
func (self *_GoEface) kind() reflect.Kind {
|
||||
if self.vt != nil {
|
||||
return self.vt.kind()
|
||||
} else {
|
||||
return reflect.Invalid
|
||||
}
|
||||
if self.vt != nil {
|
||||
return self.vt.kind()
|
||||
} else {
|
||||
return reflect.Invalid
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_GoEface) toInt64() int64 {
|
||||
if self.vt.size == 8 {
|
||||
return *(*int64)(self.ptr)
|
||||
} else if self.vt.size == 4 {
|
||||
return int64(*(*int32)(self.ptr))
|
||||
} else if self.vt.size == 2 {
|
||||
return int64(*(*int16)(self.ptr))
|
||||
} else {
|
||||
return int64(*(*int8)(self.ptr))
|
||||
}
|
||||
if self.vt.size == 8 {
|
||||
return *(*int64)(self.ptr)
|
||||
} else if self.vt.size == 4 {
|
||||
return int64(*(*int32)(self.ptr))
|
||||
} else if self.vt.size == 2 {
|
||||
return int64(*(*int16)(self.ptr))
|
||||
} else {
|
||||
return int64(*(*int8)(self.ptr))
|
||||
}
|
||||
}
|
||||
|
||||
func efaceOf(v interface{}) _GoEface {
|
||||
return *(*_GoEface)(unsafe.Pointer(&v))
|
||||
return *(*_GoEface)(unsafe.Pointer(&v))
|
||||
}
|
836
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/encodings.go
generated
vendored
Normal file
836
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/encodings.go
generated
vendored
Normal file
|
@ -0,0 +1,836 @@
|
|||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
)
|
||||
|
||||
/** Operand Encoding Helpers **/
|
||||
|
||||
func imml(v interface{}) byte {
|
||||
return byte(toImmAny(v) & 0x0f)
|
||||
}
|
||||
|
||||
func relv(v interface{}) int64 {
|
||||
switch r := v.(type) {
|
||||
case *Label:
|
||||
return 0
|
||||
case RelativeOffset:
|
||||
return int64(r)
|
||||
default:
|
||||
panic("invalid relative offset")
|
||||
}
|
||||
}
|
||||
|
||||
func addr(v interface{}) interface{} {
|
||||
switch a := v.(*MemoryOperand).Addr; a.Type {
|
||||
case Memory:
|
||||
return a.Memory
|
||||
case Offset:
|
||||
return a.Offset
|
||||
case Reference:
|
||||
return a.Reference
|
||||
default:
|
||||
panic("invalid memory operand type")
|
||||
}
|
||||
}
|
||||
|
||||
func bcode(v interface{}) byte {
|
||||
if m, ok := v.(*MemoryOperand); !ok {
|
||||
panic("v is not a memory operand")
|
||||
} else if m.Broadcast == 0 {
|
||||
return 0
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func vcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case XMMRegister:
|
||||
return byte(r)
|
||||
case YMMRegister:
|
||||
return byte(r)
|
||||
case ZMMRegister:
|
||||
return byte(r)
|
||||
case MaskedRegister:
|
||||
return vcode(r.Reg)
|
||||
default:
|
||||
panic("v is not a vector register")
|
||||
}
|
||||
}
|
||||
|
||||
func kcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case KRegister:
|
||||
return byte(r)
|
||||
case XMMRegister:
|
||||
return 0
|
||||
case YMMRegister:
|
||||
return 0
|
||||
case ZMMRegister:
|
||||
return 0
|
||||
case RegisterMask:
|
||||
return byte(r.K)
|
||||
case MaskedRegister:
|
||||
return byte(r.Mask.K)
|
||||
case *MemoryOperand:
|
||||
return toKcodeMem(r)
|
||||
default:
|
||||
panic("v is not a maskable operand")
|
||||
}
|
||||
}
|
||||
|
||||
func zcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case KRegister:
|
||||
return 0
|
||||
case XMMRegister:
|
||||
return 0
|
||||
case YMMRegister:
|
||||
return 0
|
||||
case ZMMRegister:
|
||||
return 0
|
||||
case RegisterMask:
|
||||
return toZcodeRegM(r)
|
||||
case MaskedRegister:
|
||||
return toZcodeRegM(r.Mask)
|
||||
case *MemoryOperand:
|
||||
return toZcodeMem(r)
|
||||
default:
|
||||
panic("v is not a maskable operand")
|
||||
}
|
||||
}
|
||||
|
||||
func lcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8:
|
||||
return byte(r & 0x07)
|
||||
case Register16:
|
||||
return byte(r & 0x07)
|
||||
case Register32:
|
||||
return byte(r & 0x07)
|
||||
case Register64:
|
||||
return byte(r & 0x07)
|
||||
case KRegister:
|
||||
return byte(r & 0x07)
|
||||
case MMRegister:
|
||||
return byte(r & 0x07)
|
||||
case XMMRegister:
|
||||
return byte(r & 0x07)
|
||||
case YMMRegister:
|
||||
return byte(r & 0x07)
|
||||
case ZMMRegister:
|
||||
return byte(r & 0x07)
|
||||
case MaskedRegister:
|
||||
return lcode(r.Reg)
|
||||
default:
|
||||
panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func hcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8:
|
||||
return byte(r>>3) & 1
|
||||
case Register16:
|
||||
return byte(r>>3) & 1
|
||||
case Register32:
|
||||
return byte(r>>3) & 1
|
||||
case Register64:
|
||||
return byte(r>>3) & 1
|
||||
case KRegister:
|
||||
return byte(r>>3) & 1
|
||||
case MMRegister:
|
||||
return byte(r>>3) & 1
|
||||
case XMMRegister:
|
||||
return byte(r>>3) & 1
|
||||
case YMMRegister:
|
||||
return byte(r>>3) & 1
|
||||
case ZMMRegister:
|
||||
return byte(r>>3) & 1
|
||||
case MaskedRegister:
|
||||
return hcode(r.Reg)
|
||||
default:
|
||||
panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func ecode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8:
|
||||
return byte(r>>4) & 1
|
||||
case Register16:
|
||||
return byte(r>>4) & 1
|
||||
case Register32:
|
||||
return byte(r>>4) & 1
|
||||
case Register64:
|
||||
return byte(r>>4) & 1
|
||||
case KRegister:
|
||||
return byte(r>>4) & 1
|
||||
case MMRegister:
|
||||
return byte(r>>4) & 1
|
||||
case XMMRegister:
|
||||
return byte(r>>4) & 1
|
||||
case YMMRegister:
|
||||
return byte(r>>4) & 1
|
||||
case ZMMRegister:
|
||||
return byte(r>>4) & 1
|
||||
case MaskedRegister:
|
||||
return ecode(r.Reg)
|
||||
default:
|
||||
panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func hlcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8:
|
||||
return toHLcodeReg8(r)
|
||||
case Register16:
|
||||
return byte(r & 0x0f)
|
||||
case Register32:
|
||||
return byte(r & 0x0f)
|
||||
case Register64:
|
||||
return byte(r & 0x0f)
|
||||
case KRegister:
|
||||
return byte(r & 0x0f)
|
||||
case MMRegister:
|
||||
return byte(r & 0x0f)
|
||||
case XMMRegister:
|
||||
return byte(r & 0x0f)
|
||||
case YMMRegister:
|
||||
return byte(r & 0x0f)
|
||||
case ZMMRegister:
|
||||
return byte(r & 0x0f)
|
||||
case MaskedRegister:
|
||||
return hlcode(r.Reg)
|
||||
default:
|
||||
panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func ehcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8:
|
||||
return byte(r>>3) & 0x03
|
||||
case Register16:
|
||||
return byte(r>>3) & 0x03
|
||||
case Register32:
|
||||
return byte(r>>3) & 0x03
|
||||
case Register64:
|
||||
return byte(r>>3) & 0x03
|
||||
case KRegister:
|
||||
return byte(r>>3) & 0x03
|
||||
case MMRegister:
|
||||
return byte(r>>3) & 0x03
|
||||
case XMMRegister:
|
||||
return byte(r>>3) & 0x03
|
||||
case YMMRegister:
|
||||
return byte(r>>3) & 0x03
|
||||
case ZMMRegister:
|
||||
return byte(r>>3) & 0x03
|
||||
case MaskedRegister:
|
||||
return ehcode(r.Reg)
|
||||
default:
|
||||
panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func toImmAny(v interface{}) int64 {
|
||||
if x, ok := asInt64(v); ok {
|
||||
return x
|
||||
} else {
|
||||
panic("value is not an integer")
|
||||
}
|
||||
}
|
||||
|
||||
func toHcodeOpt(v interface{}) byte {
|
||||
if v == nil {
|
||||
return 0
|
||||
} else {
|
||||
return hcode(v)
|
||||
}
|
||||
}
|
||||
|
||||
func toEcodeVMM(v interface{}, x byte) byte {
|
||||
switch r := v.(type) {
|
||||
case XMMRegister:
|
||||
return ecode(r)
|
||||
case YMMRegister:
|
||||
return ecode(r)
|
||||
case ZMMRegister:
|
||||
return ecode(r)
|
||||
default:
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
||||
func toKcodeMem(v *MemoryOperand) byte {
|
||||
if !v.Masked {
|
||||
return 0
|
||||
} else {
|
||||
return byte(v.Mask.K)
|
||||
}
|
||||
}
|
||||
|
||||
func toZcodeMem(v *MemoryOperand) byte {
|
||||
if !v.Masked || v.Mask.Z {
|
||||
return 0
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func toZcodeRegM(v RegisterMask) byte {
|
||||
if v.Z {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func toHLcodeReg8(v Register8) byte {
|
||||
switch v {
|
||||
case AH:
|
||||
fallthrough
|
||||
case BH:
|
||||
fallthrough
|
||||
case CH:
|
||||
fallthrough
|
||||
case DH:
|
||||
panic("ah/bh/ch/dh registers never use 4-bit encoding")
|
||||
default:
|
||||
return byte(v & 0x0f)
|
||||
}
|
||||
}
|
||||
|
||||
/** Instruction Encoding Helpers **/
|
||||
|
||||
const (
|
||||
_N_inst = 16
|
||||
)
|
||||
|
||||
const (
|
||||
_F_rel1 = 1 << iota
|
||||
_F_rel4
|
||||
)
|
||||
|
||||
type _Encoding struct {
|
||||
len int
|
||||
flags int
|
||||
bytes [_N_inst]byte
|
||||
encoder func(m *_Encoding, v []interface{})
|
||||
}
|
||||
|
||||
// buf ensures len + n <= len(bytes).
|
||||
func (self *_Encoding) buf(n int) []byte {
|
||||
if i := self.len; i+n > _N_inst {
|
||||
panic("instruction too long")
|
||||
} else {
|
||||
return self.bytes[i:]
|
||||
}
|
||||
}
|
||||
|
||||
// emit encodes a single byte.
|
||||
func (self *_Encoding) emit(v byte) {
|
||||
self.buf(1)[0] = v
|
||||
self.len++
|
||||
}
|
||||
|
||||
// imm1 encodes a single byte immediate value.
|
||||
func (self *_Encoding) imm1(v int64) {
|
||||
self.emit(byte(v))
|
||||
}
|
||||
|
||||
// imm2 encodes a two-byte immediate value in little-endian.
|
||||
func (self *_Encoding) imm2(v int64) {
|
||||
binary.LittleEndian.PutUint16(self.buf(2), uint16(v))
|
||||
self.len += 2
|
||||
}
|
||||
|
||||
// imm4 encodes a 4-byte immediate value in little-endian.
|
||||
func (self *_Encoding) imm4(v int64) {
|
||||
binary.LittleEndian.PutUint32(self.buf(4), uint32(v))
|
||||
self.len += 4
|
||||
}
|
||||
|
||||
// imm8 encodes an 8-byte immediate value in little-endian.
|
||||
func (self *_Encoding) imm8(v int64) {
|
||||
binary.LittleEndian.PutUint64(self.buf(8), uint64(v))
|
||||
self.len += 8
|
||||
}
|
||||
|
||||
// vex2 encodes a 2-byte or 3-byte VEX prefix.
|
||||
//
|
||||
// 2-byte VEX prefix:
|
||||
//
|
||||
// Requires: VEX.W = 0, VEX.mmmmm = 0b00001 and VEX.B = VEX.X = 0
|
||||
//
|
||||
// +----------------+
|
||||
//
|
||||
// Byte 0: | Bits 0-7: 0xc5 |
|
||||
//
|
||||
// +----------------+
|
||||
//
|
||||
// +-----------+----------------+----------+--------------+
|
||||
//
|
||||
// Byte 1: | Bit 7: ~R | Bits 3-6 ~vvvv | Bit 2: L | Bits 0-1: pp |
|
||||
//
|
||||
// +-----------+----------------+----------+--------------+
|
||||
//
|
||||
// 3-byte VEX prefix:
|
||||
// +----------------+
|
||||
//
|
||||
// Byte 0: | Bits 0-7: 0xc4 |
|
||||
//
|
||||
// +----------------+
|
||||
//
|
||||
// +-----------+-----------+-----------+-------------------+
|
||||
//
|
||||
// Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: 0b00001 |
|
||||
//
|
||||
// +-----------+-----------+-----------+-------------------+
|
||||
//
|
||||
// +----------+-----------------+----------+--------------+
|
||||
//
|
||||
// Byte 2: | Bit 7: 0 | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
|
||||
//
|
||||
// +----------+-----------------+----------+--------------+
|
||||
func (self *_Encoding) vex2(lpp byte, r byte, rm interface{}, vvvv byte) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* VEX.R must be a single-bit mask */
|
||||
if r > 1 {
|
||||
panic("VEX.R must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* VEX.Lpp must be a 3-bit mask */
|
||||
if lpp&^0b111 != 0 {
|
||||
panic("VEX.Lpp must be a 3-bit mask")
|
||||
}
|
||||
|
||||
/* VEX.vvvv must be a 4-bit mask */
|
||||
if vvvv&^0b1111 != 0 {
|
||||
panic("VEX.vvvv must be a 4-bit mask")
|
||||
}
|
||||
|
||||
/* encode the RM bits if any */
|
||||
if rm != nil {
|
||||
switch v := rm.(type) {
|
||||
case *Label:
|
||||
break
|
||||
case Register:
|
||||
b = hcode(v)
|
||||
case MemoryAddress:
|
||||
b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset:
|
||||
break
|
||||
default:
|
||||
panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
}
|
||||
|
||||
/* if VEX.B and VEX.X are zeroes, 2-byte VEX prefix can be used */
|
||||
if x == 0 && b == 0 {
|
||||
self.emit(0xc5)
|
||||
self.emit(0xf8 ^ (r << 7) ^ (vvvv << 3) ^ lpp)
|
||||
} else {
|
||||
self.emit(0xc4)
|
||||
self.emit(0xe1 ^ (r << 7) ^ (x << 6) ^ (b << 5))
|
||||
self.emit(0x78 ^ (vvvv << 3) ^ lpp)
|
||||
}
|
||||
}
|
||||
|
||||
// vex3 encodes a 3-byte VEX or XOP prefix.
|
||||
//
|
||||
// 3-byte VEX/XOP prefix
|
||||
// +-----------------------------------+
|
||||
//
|
||||
// Byte 0: | Bits 0-7: 0xc4 (VEX) / 0x8f (XOP) |
|
||||
//
|
||||
// +-----------------------------------+
|
||||
//
|
||||
// +-----------+-----------+-----------+-----------------+
|
||||
//
|
||||
// Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: mmmmm |
|
||||
//
|
||||
// +-----------+-----------+-----------+-----------------+
|
||||
//
|
||||
// +----------+-----------------+----------+--------------+
|
||||
//
|
||||
// Byte 2: | Bit 7: W | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
|
||||
//
|
||||
// +----------+-----------------+----------+--------------+
|
||||
func (self *_Encoding) vex3(esc byte, mmmmm byte, wlpp byte, r byte, rm interface{}, vvvv byte) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* VEX.R must be a single-bit mask */
|
||||
if r > 1 {
|
||||
panic("VEX.R must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* VEX.vvvv must be a 4-bit mask */
|
||||
if vvvv&^0b1111 != 0 {
|
||||
panic("VEX.vvvv must be a 4-bit mask")
|
||||
}
|
||||
|
||||
/* escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix */
|
||||
if esc != 0xc4 && esc != 0x8f {
|
||||
panic("escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix")
|
||||
}
|
||||
|
||||
/* VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7 */
|
||||
if wlpp&^0b10000111 != 0 {
|
||||
panic("VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7")
|
||||
}
|
||||
|
||||
/* VEX.m-mmmm is expected to be a 5-bit mask */
|
||||
if mmmmm&^0b11111 != 0 {
|
||||
panic("VEX.m-mmmm is expected to be a 5-bit mask")
|
||||
}
|
||||
|
||||
/* encode the RM bits */
|
||||
switch v := rm.(type) {
|
||||
case *Label:
|
||||
break
|
||||
case MemoryAddress:
|
||||
b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset:
|
||||
break
|
||||
default:
|
||||
panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
|
||||
/* encode the 3-byte VEX or XOP prefix */
|
||||
self.emit(esc)
|
||||
self.emit(0xe0 ^ (r << 7) ^ (x << 6) ^ (b << 5) ^ mmmmm)
|
||||
self.emit(0x78 ^ (vvvv << 3) ^ wlpp)
|
||||
}
|
||||
|
||||
// evex encodes a 4-byte EVEX prefix.
|
||||
func (self *_Encoding) evex(mm byte, w1pp byte, ll byte, rr byte, rm interface{}, vvvvv byte, aaa byte, zz byte, bb byte) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* EVEX.b must be a single-bit mask */
|
||||
if bb > 1 {
|
||||
panic("EVEX.b must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.z must be a single-bit mask */
|
||||
if zz > 1 {
|
||||
panic("EVEX.z must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.mm must be a 2-bit mask */
|
||||
if mm&^0b11 != 0 {
|
||||
panic("EVEX.mm must be a 2-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.L'L must be a 2-bit mask */
|
||||
if ll&^0b11 != 0 {
|
||||
panic("EVEX.L'L must be a 2-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.R'R must be a 2-bit mask */
|
||||
if rr&^0b11 != 0 {
|
||||
panic("EVEX.R'R must be a 2-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.aaa must be a 3-bit mask */
|
||||
if aaa&^0b111 != 0 {
|
||||
panic("EVEX.aaa must be a 3-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.v'vvvv must be a 5-bit mask */
|
||||
if vvvvv&^0b11111 != 0 {
|
||||
panic("EVEX.v'vvvv must be a 5-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7 */
|
||||
if w1pp&^0b10000011 != 0b100 {
|
||||
panic("EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7")
|
||||
}
|
||||
|
||||
/* extract bits from EVEX.R'R and EVEX.v'vvvv */
|
||||
r1, r0 := rr>>1, rr&1
|
||||
v1, v0 := vvvvv>>4, vvvvv&0b1111
|
||||
|
||||
/* encode the RM bits if any */
|
||||
if rm != nil {
|
||||
switch m := rm.(type) {
|
||||
case *Label:
|
||||
break
|
||||
case Register:
|
||||
b, x = hcode(m), ecode(m)
|
||||
case MemoryAddress:
|
||||
b, x, v1 = toHcodeOpt(m.Base), toHcodeOpt(m.Index), toEcodeVMM(m.Index, v1)
|
||||
case RelativeOffset:
|
||||
break
|
||||
default:
|
||||
panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
}
|
||||
|
||||
/* EVEX prefix bytes */
|
||||
p0 := (r0 << 7) | (x << 6) | (b << 5) | (r1 << 4) | mm
|
||||
p1 := (v0 << 3) | w1pp
|
||||
p2 := (zz << 7) | (ll << 5) | (b << 4) | (v1 << 3) | aaa
|
||||
|
||||
/* p0: invert RXBR' (bits 4-7)
|
||||
* p1: invert vvvv (bits 3-6)
|
||||
* p2: invert V' (bit 3) */
|
||||
self.emit(0x62)
|
||||
self.emit(p0 ^ 0xf0)
|
||||
self.emit(p1 ^ 0x78)
|
||||
self.emit(p2 ^ 0x08)
|
||||
}
|
||||
|
||||
// rexm encodes a mandatory REX prefix.
|
||||
func (self *_Encoding) rexm(w byte, r byte, rm interface{}) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* REX.R must be 0 or 1 */
|
||||
if r != 0 && r != 1 {
|
||||
panic("REX.R must be 0 or 1")
|
||||
}
|
||||
|
||||
/* REX.W must be 0 or 1 */
|
||||
if w != 0 && w != 1 {
|
||||
panic("REX.W must be 0 or 1")
|
||||
}
|
||||
|
||||
/* encode the RM bits */
|
||||
switch v := rm.(type) {
|
||||
case *Label:
|
||||
break
|
||||
case MemoryAddress:
|
||||
b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset:
|
||||
break
|
||||
default:
|
||||
panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
|
||||
/* encode the REX prefix */
|
||||
self.emit(0x40 | (w << 3) | (r << 2) | (x << 1) | b)
|
||||
}
|
||||
|
||||
// rexo encodes an optional REX prefix.
|
||||
func (self *_Encoding) rexo(r byte, rm interface{}, force bool) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* REX.R must be 0 or 1 */
|
||||
if r != 0 && r != 1 {
|
||||
panic("REX.R must be 0 or 1")
|
||||
}
|
||||
|
||||
/* encode the RM bits */
|
||||
switch v := rm.(type) {
|
||||
case *Label:
|
||||
break
|
||||
case Register:
|
||||
b = hcode(v)
|
||||
case MemoryAddress:
|
||||
b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset:
|
||||
break
|
||||
default:
|
||||
panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
|
||||
/* if REX.R, REX.X, and REX.B are all zeroes, REX prefix can be omitted */
|
||||
if force || r != 0 || x != 0 || b != 0 {
|
||||
self.emit(0x40 | (r << 2) | (x << 1) | b)
|
||||
}
|
||||
}
|
||||
|
||||
// mrsd encodes ModR/M, SIB and Displacement.
|
||||
//
|
||||
// ModR/M byte
|
||||
//
|
||||
// +----------------+---------------+---------------+
|
||||
// | Bits 6-7: Mode | Bits 3-5: Reg | Bits 0-2: R/M |
|
||||
// +----------------+---------------+---------------+
|
||||
//
|
||||
// SIB byte
|
||||
//
|
||||
// +-----------------+-----------------+----------------+
|
||||
// | Bits 6-7: Scale | Bits 3-5: Index | Bits 0-2: Base |
|
||||
// +-----------------+-----------------+----------------+
|
||||
func (self *_Encoding) mrsd(reg byte, rm interface{}, disp8v int32) {
|
||||
var ok bool
|
||||
var mm MemoryAddress
|
||||
var ro RelativeOffset
|
||||
|
||||
/* ModRM encodes the lower 3-bit of the register */
|
||||
if reg > 7 {
|
||||
panic("invalid register bits")
|
||||
}
|
||||
|
||||
/* check the displacement scale */
|
||||
switch disp8v {
|
||||
case 1:
|
||||
break
|
||||
case 2:
|
||||
break
|
||||
case 4:
|
||||
break
|
||||
case 8:
|
||||
break
|
||||
case 16:
|
||||
break
|
||||
case 32:
|
||||
break
|
||||
case 64:
|
||||
break
|
||||
default:
|
||||
panic("invalid displacement size")
|
||||
}
|
||||
|
||||
/* special case: unresolved labels, assuming a zero offset */
|
||||
if _, ok = rm.(*Label); ok {
|
||||
self.emit(0x05 | (reg << 3))
|
||||
self.imm4(0)
|
||||
return
|
||||
}
|
||||
|
||||
/* special case: RIP-relative offset
|
||||
* ModRM.Mode == 0 and ModeRM.R/M == 5 indicates (rip + disp32) addressing */
|
||||
if ro, ok = rm.(RelativeOffset); ok {
|
||||
self.emit(0x05 | (reg << 3))
|
||||
self.imm4(int64(ro))
|
||||
return
|
||||
}
|
||||
|
||||
/* must be a generic memory address */
|
||||
if mm, ok = rm.(MemoryAddress); !ok {
|
||||
panic("rm must be a memory address")
|
||||
}
|
||||
|
||||
/* absolute addressing, encoded as disp(%rbp,%rsp,1) */
|
||||
if mm.Base == nil && mm.Index == nil {
|
||||
self.emit(0x04 | (reg << 3))
|
||||
self.emit(0x25)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
return
|
||||
}
|
||||
|
||||
/* no SIB byte */
|
||||
if mm.Index == nil && lcode(mm.Base) != 0b100 {
|
||||
cc := lcode(mm.Base)
|
||||
dv := mm.Displacement
|
||||
|
||||
/* ModRM.Mode == 0 (no displacement) */
|
||||
if dv == 0 && mm.Base != RBP && mm.Base != R13 {
|
||||
if cc == 0b101 {
|
||||
panic("rbp/r13 is not encodable as a base register (interpreted as disp32 address)")
|
||||
} else {
|
||||
self.emit((reg << 3) | cc)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 1 (8-bit displacement) */
|
||||
if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv%disp8v == 0 {
|
||||
self.emit(0x40 | (reg << 3) | cc)
|
||||
self.imm1(int64(dq))
|
||||
return
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 2 (32-bit displacement) */
|
||||
self.emit(0x80 | (reg << 3) | cc)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
return
|
||||
}
|
||||
|
||||
/* all encodings below use ModRM.R/M = 4 (0b100) to indicate the presence of SIB */
|
||||
if mm.Index == RSP {
|
||||
panic("rsp is not encodable as an index register (interpreted as no index)")
|
||||
}
|
||||
|
||||
/* index = 4 (0b100) denotes no-index encoding */
|
||||
var scale byte
|
||||
var index byte = 0x04
|
||||
|
||||
/* encode the scale byte */
|
||||
if mm.Scale != 0 {
|
||||
switch mm.Scale {
|
||||
case 1:
|
||||
scale = 0
|
||||
case 2:
|
||||
scale = 1
|
||||
case 4:
|
||||
scale = 2
|
||||
case 8:
|
||||
scale = 3
|
||||
default:
|
||||
panic("invalid scale value")
|
||||
}
|
||||
}
|
||||
|
||||
/* encode the index byte */
|
||||
if mm.Index != nil {
|
||||
index = lcode(mm.Index)
|
||||
}
|
||||
|
||||
/* SIB.Base = 5 (0b101) and ModRM.Mode = 0 indicates no-base encoding with disp32 */
|
||||
if mm.Base == nil {
|
||||
self.emit((reg << 3) | 0b100)
|
||||
self.emit((scale << 6) | (index << 3) | 0b101)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
return
|
||||
}
|
||||
|
||||
/* base L-code & displacement value */
|
||||
cc := lcode(mm.Base)
|
||||
dv := mm.Displacement
|
||||
|
||||
/* ModRM.Mode == 0 (no displacement) */
|
||||
if dv == 0 && cc != 0b101 {
|
||||
self.emit((reg << 3) | 0b100)
|
||||
self.emit((scale << 6) | (index << 3) | cc)
|
||||
return
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 1 (8-bit displacement) */
|
||||
if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv%disp8v == 0 {
|
||||
self.emit(0x44 | (reg << 3))
|
||||
self.emit((scale << 6) | (index << 3) | cc)
|
||||
self.imm1(int64(dq))
|
||||
return
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 2 (32-bit displacement) */
|
||||
self.emit(0x84 | (reg << 3))
|
||||
self.emit((scale << 6) | (index << 3) | cc)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
}
|
||||
|
||||
// encode invokes the encoder to encode this instruction.
|
||||
func (self *_Encoding) encode(v []interface{}) int {
|
||||
self.len = 0
|
||||
self.encoder(self, v)
|
||||
return self.len
|
||||
}
|
1077
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions.go
generated
vendored
Normal file
1077
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
24
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions_table.go
generated
vendored
Normal file
24
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions_table.go
generated
vendored
Normal file
|
@ -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.
|
||||
//
|
||||
|
||||
// Code generated by "mkasm_amd64.py", DO NOT EDIT.
|
||||
|
||||
package x86_64
|
||||
|
||||
const (
|
||||
_N_args = 5
|
||||
_N_forms = 23
|
||||
)
|
|
@ -21,7 +21,7 @@
|
|||
"math"
|
||||
"math/bits"
|
||||
|
||||
"github.com/cloudwego/iasm/expr"
|
||||
"github.com/bytedance/sonic/loader/internal/iasm/expr"
|
||||
)
|
||||
|
||||
type (
|
747
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/registers.go
generated
vendored
Normal file
747
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/registers.go
generated
vendored
Normal file
|
@ -0,0 +1,747 @@
|
|||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Register represents a hardware register.
|
||||
type Register interface {
|
||||
fmt.Stringer
|
||||
implRegister()
|
||||
}
|
||||
|
||||
type (
|
||||
Register8 byte
|
||||
Register16 byte
|
||||
Register32 byte
|
||||
Register64 byte
|
||||
)
|
||||
|
||||
type (
|
||||
KRegister byte
|
||||
MMRegister byte
|
||||
XMMRegister byte
|
||||
YMMRegister byte
|
||||
ZMMRegister byte
|
||||
)
|
||||
|
||||
// RegisterMask is a KRegister used to mask another register.
|
||||
type RegisterMask struct {
|
||||
Z bool
|
||||
K KRegister
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self RegisterMask) String() string {
|
||||
if !self.Z {
|
||||
return fmt.Sprintf("{%%%s}", self.K)
|
||||
} else {
|
||||
return fmt.Sprintf("{%%%s}{z}", self.K)
|
||||
}
|
||||
}
|
||||
|
||||
// MaskedRegister is a Register masked by a RegisterMask.
|
||||
type MaskedRegister struct {
|
||||
Reg Register
|
||||
Mask RegisterMask
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self MaskedRegister) String() string {
|
||||
return self.Reg.String() + self.Mask.String()
|
||||
}
|
||||
|
||||
const (
|
||||
AL Register8 = iota
|
||||
CL
|
||||
DL
|
||||
BL
|
||||
SPL
|
||||
BPL
|
||||
SIL
|
||||
DIL
|
||||
R8b
|
||||
R9b
|
||||
R10b
|
||||
R11b
|
||||
R12b
|
||||
R13b
|
||||
R14b
|
||||
R15b
|
||||
)
|
||||
|
||||
const (
|
||||
AH = SPL | 0x80
|
||||
CH = BPL | 0x80
|
||||
DH = SIL | 0x80
|
||||
BH = DIL | 0x80
|
||||
)
|
||||
|
||||
const (
|
||||
AX Register16 = iota
|
||||
CX
|
||||
DX
|
||||
BX
|
||||
SP
|
||||
BP
|
||||
SI
|
||||
DI
|
||||
R8w
|
||||
R9w
|
||||
R10w
|
||||
R11w
|
||||
R12w
|
||||
R13w
|
||||
R14w
|
||||
R15w
|
||||
)
|
||||
|
||||
const (
|
||||
EAX Register32 = iota
|
||||
ECX
|
||||
EDX
|
||||
EBX
|
||||
ESP
|
||||
EBP
|
||||
ESI
|
||||
EDI
|
||||
R8d
|
||||
R9d
|
||||
R10d
|
||||
R11d
|
||||
R12d
|
||||
R13d
|
||||
R14d
|
||||
R15d
|
||||
)
|
||||
|
||||
const (
|
||||
RAX Register64 = iota
|
||||
RCX
|
||||
RDX
|
||||
RBX
|
||||
RSP
|
||||
RBP
|
||||
RSI
|
||||
RDI
|
||||
R8
|
||||
R9
|
||||
R10
|
||||
R11
|
||||
R12
|
||||
R13
|
||||
R14
|
||||
R15
|
||||
)
|
||||
|
||||
const (
|
||||
K0 KRegister = iota
|
||||
K1
|
||||
K2
|
||||
K3
|
||||
K4
|
||||
K5
|
||||
K6
|
||||
K7
|
||||
)
|
||||
|
||||
const (
|
||||
MM0 MMRegister = iota
|
||||
MM1
|
||||
MM2
|
||||
MM3
|
||||
MM4
|
||||
MM5
|
||||
MM6
|
||||
MM7
|
||||
)
|
||||
|
||||
const (
|
||||
XMM0 XMMRegister = iota
|
||||
XMM1
|
||||
XMM2
|
||||
XMM3
|
||||
XMM4
|
||||
XMM5
|
||||
XMM6
|
||||
XMM7
|
||||
XMM8
|
||||
XMM9
|
||||
XMM10
|
||||
XMM11
|
||||
XMM12
|
||||
XMM13
|
||||
XMM14
|
||||
XMM15
|
||||
XMM16
|
||||
XMM17
|
||||
XMM18
|
||||
XMM19
|
||||
XMM20
|
||||
XMM21
|
||||
XMM22
|
||||
XMM23
|
||||
XMM24
|
||||
XMM25
|
||||
XMM26
|
||||
XMM27
|
||||
XMM28
|
||||
XMM29
|
||||
XMM30
|
||||
XMM31
|
||||
)
|
||||
|
||||
const (
|
||||
YMM0 YMMRegister = iota
|
||||
YMM1
|
||||
YMM2
|
||||
YMM3
|
||||
YMM4
|
||||
YMM5
|
||||
YMM6
|
||||
YMM7
|
||||
YMM8
|
||||
YMM9
|
||||
YMM10
|
||||
YMM11
|
||||
YMM12
|
||||
YMM13
|
||||
YMM14
|
||||
YMM15
|
||||
YMM16
|
||||
YMM17
|
||||
YMM18
|
||||
YMM19
|
||||
YMM20
|
||||
YMM21
|
||||
YMM22
|
||||
YMM23
|
||||
YMM24
|
||||
YMM25
|
||||
YMM26
|
||||
YMM27
|
||||
YMM28
|
||||
YMM29
|
||||
YMM30
|
||||
YMM31
|
||||
)
|
||||
|
||||
const (
|
||||
ZMM0 ZMMRegister = iota
|
||||
ZMM1
|
||||
ZMM2
|
||||
ZMM3
|
||||
ZMM4
|
||||
ZMM5
|
||||
ZMM6
|
||||
ZMM7
|
||||
ZMM8
|
||||
ZMM9
|
||||
ZMM10
|
||||
ZMM11
|
||||
ZMM12
|
||||
ZMM13
|
||||
ZMM14
|
||||
ZMM15
|
||||
ZMM16
|
||||
ZMM17
|
||||
ZMM18
|
||||
ZMM19
|
||||
ZMM20
|
||||
ZMM21
|
||||
ZMM22
|
||||
ZMM23
|
||||
ZMM24
|
||||
ZMM25
|
||||
ZMM26
|
||||
ZMM27
|
||||
ZMM28
|
||||
ZMM29
|
||||
ZMM30
|
||||
ZMM31
|
||||
)
|
||||
|
||||
func (self Register8) implRegister() {}
|
||||
func (self Register16) implRegister() {}
|
||||
func (self Register32) implRegister() {}
|
||||
func (self Register64) implRegister() {}
|
||||
|
||||
func (self KRegister) implRegister() {}
|
||||
func (self MMRegister) implRegister() {}
|
||||
func (self XMMRegister) implRegister() {}
|
||||
func (self YMMRegister) implRegister() {}
|
||||
func (self ZMMRegister) implRegister() {}
|
||||
|
||||
func (self Register8) String() string {
|
||||
if int(self) >= len(r8names) {
|
||||
return "???"
|
||||
} else {
|
||||
return r8names[self]
|
||||
}
|
||||
}
|
||||
func (self Register16) String() string {
|
||||
if int(self) >= len(r16names) {
|
||||
return "???"
|
||||
} else {
|
||||
return r16names[self]
|
||||
}
|
||||
}
|
||||
func (self Register32) String() string {
|
||||
if int(self) >= len(r32names) {
|
||||
return "???"
|
||||
} else {
|
||||
return r32names[self]
|
||||
}
|
||||
}
|
||||
func (self Register64) String() string {
|
||||
if int(self) >= len(r64names) {
|
||||
return "???"
|
||||
} else {
|
||||
return r64names[self]
|
||||
}
|
||||
}
|
||||
|
||||
func (self KRegister) String() string {
|
||||
if int(self) >= len(knames) {
|
||||
return "???"
|
||||
} else {
|
||||
return knames[self]
|
||||
}
|
||||
}
|
||||
func (self MMRegister) String() string {
|
||||
if int(self) >= len(mmnames) {
|
||||
return "???"
|
||||
} else {
|
||||
return mmnames[self]
|
||||
}
|
||||
}
|
||||
func (self XMMRegister) String() string {
|
||||
if int(self) >= len(xmmnames) {
|
||||
return "???"
|
||||
} else {
|
||||
return xmmnames[self]
|
||||
}
|
||||
}
|
||||
func (self YMMRegister) String() string {
|
||||
if int(self) >= len(ymmnames) {
|
||||
return "???"
|
||||
} else {
|
||||
return ymmnames[self]
|
||||
}
|
||||
}
|
||||
func (self ZMMRegister) String() string {
|
||||
if int(self) >= len(zmmnames) {
|
||||
return "???"
|
||||
} else {
|
||||
return zmmnames[self]
|
||||
}
|
||||
}
|
||||
|
||||
// Registers maps register name into Register instances.
|
||||
var Registers = map[string]Register{
|
||||
"al": AL,
|
||||
"cl": CL,
|
||||
"dl": DL,
|
||||
"bl": BL,
|
||||
"spl": SPL,
|
||||
"bpl": BPL,
|
||||
"sil": SIL,
|
||||
"dil": DIL,
|
||||
"r8b": R8b,
|
||||
"r9b": R9b,
|
||||
"r10b": R10b,
|
||||
"r11b": R11b,
|
||||
"r12b": R12b,
|
||||
"r13b": R13b,
|
||||
"r14b": R14b,
|
||||
"r15b": R15b,
|
||||
"ah": AH,
|
||||
"ch": CH,
|
||||
"dh": DH,
|
||||
"bh": BH,
|
||||
"ax": AX,
|
||||
"cx": CX,
|
||||
"dx": DX,
|
||||
"bx": BX,
|
||||
"sp": SP,
|
||||
"bp": BP,
|
||||
"si": SI,
|
||||
"di": DI,
|
||||
"r8w": R8w,
|
||||
"r9w": R9w,
|
||||
"r10w": R10w,
|
||||
"r11w": R11w,
|
||||
"r12w": R12w,
|
||||
"r13w": R13w,
|
||||
"r14w": R14w,
|
||||
"r15w": R15w,
|
||||
"eax": EAX,
|
||||
"ecx": ECX,
|
||||
"edx": EDX,
|
||||
"ebx": EBX,
|
||||
"esp": ESP,
|
||||
"ebp": EBP,
|
||||
"esi": ESI,
|
||||
"edi": EDI,
|
||||
"r8d": R8d,
|
||||
"r9d": R9d,
|
||||
"r10d": R10d,
|
||||
"r11d": R11d,
|
||||
"r12d": R12d,
|
||||
"r13d": R13d,
|
||||
"r14d": R14d,
|
||||
"r15d": R15d,
|
||||
"rax": RAX,
|
||||
"rcx": RCX,
|
||||
"rdx": RDX,
|
||||
"rbx": RBX,
|
||||
"rsp": RSP,
|
||||
"rbp": RBP,
|
||||
"rsi": RSI,
|
||||
"rdi": RDI,
|
||||
"r8": R8,
|
||||
"r9": R9,
|
||||
"r10": R10,
|
||||
"r11": R11,
|
||||
"r12": R12,
|
||||
"r13": R13,
|
||||
"r14": R14,
|
||||
"r15": R15,
|
||||
"k0": K0,
|
||||
"k1": K1,
|
||||
"k2": K2,
|
||||
"k3": K3,
|
||||
"k4": K4,
|
||||
"k5": K5,
|
||||
"k6": K6,
|
||||
"k7": K7,
|
||||
"mm0": MM0,
|
||||
"mm1": MM1,
|
||||
"mm2": MM2,
|
||||
"mm3": MM3,
|
||||
"mm4": MM4,
|
||||
"mm5": MM5,
|
||||
"mm6": MM6,
|
||||
"mm7": MM7,
|
||||
"xmm0": XMM0,
|
||||
"xmm1": XMM1,
|
||||
"xmm2": XMM2,
|
||||
"xmm3": XMM3,
|
||||
"xmm4": XMM4,
|
||||
"xmm5": XMM5,
|
||||
"xmm6": XMM6,
|
||||
"xmm7": XMM7,
|
||||
"xmm8": XMM8,
|
||||
"xmm9": XMM9,
|
||||
"xmm10": XMM10,
|
||||
"xmm11": XMM11,
|
||||
"xmm12": XMM12,
|
||||
"xmm13": XMM13,
|
||||
"xmm14": XMM14,
|
||||
"xmm15": XMM15,
|
||||
"xmm16": XMM16,
|
||||
"xmm17": XMM17,
|
||||
"xmm18": XMM18,
|
||||
"xmm19": XMM19,
|
||||
"xmm20": XMM20,
|
||||
"xmm21": XMM21,
|
||||
"xmm22": XMM22,
|
||||
"xmm23": XMM23,
|
||||
"xmm24": XMM24,
|
||||
"xmm25": XMM25,
|
||||
"xmm26": XMM26,
|
||||
"xmm27": XMM27,
|
||||
"xmm28": XMM28,
|
||||
"xmm29": XMM29,
|
||||
"xmm30": XMM30,
|
||||
"xmm31": XMM31,
|
||||
"ymm0": YMM0,
|
||||
"ymm1": YMM1,
|
||||
"ymm2": YMM2,
|
||||
"ymm3": YMM3,
|
||||
"ymm4": YMM4,
|
||||
"ymm5": YMM5,
|
||||
"ymm6": YMM6,
|
||||
"ymm7": YMM7,
|
||||
"ymm8": YMM8,
|
||||
"ymm9": YMM9,
|
||||
"ymm10": YMM10,
|
||||
"ymm11": YMM11,
|
||||
"ymm12": YMM12,
|
||||
"ymm13": YMM13,
|
||||
"ymm14": YMM14,
|
||||
"ymm15": YMM15,
|
||||
"ymm16": YMM16,
|
||||
"ymm17": YMM17,
|
||||
"ymm18": YMM18,
|
||||
"ymm19": YMM19,
|
||||
"ymm20": YMM20,
|
||||
"ymm21": YMM21,
|
||||
"ymm22": YMM22,
|
||||
"ymm23": YMM23,
|
||||
"ymm24": YMM24,
|
||||
"ymm25": YMM25,
|
||||
"ymm26": YMM26,
|
||||
"ymm27": YMM27,
|
||||
"ymm28": YMM28,
|
||||
"ymm29": YMM29,
|
||||
"ymm30": YMM30,
|
||||
"ymm31": YMM31,
|
||||
"zmm0": ZMM0,
|
||||
"zmm1": ZMM1,
|
||||
"zmm2": ZMM2,
|
||||
"zmm3": ZMM3,
|
||||
"zmm4": ZMM4,
|
||||
"zmm5": ZMM5,
|
||||
"zmm6": ZMM6,
|
||||
"zmm7": ZMM7,
|
||||
"zmm8": ZMM8,
|
||||
"zmm9": ZMM9,
|
||||
"zmm10": ZMM10,
|
||||
"zmm11": ZMM11,
|
||||
"zmm12": ZMM12,
|
||||
"zmm13": ZMM13,
|
||||
"zmm14": ZMM14,
|
||||
"zmm15": ZMM15,
|
||||
"zmm16": ZMM16,
|
||||
"zmm17": ZMM17,
|
||||
"zmm18": ZMM18,
|
||||
"zmm19": ZMM19,
|
||||
"zmm20": ZMM20,
|
||||
"zmm21": ZMM21,
|
||||
"zmm22": ZMM22,
|
||||
"zmm23": ZMM23,
|
||||
"zmm24": ZMM24,
|
||||
"zmm25": ZMM25,
|
||||
"zmm26": ZMM26,
|
||||
"zmm27": ZMM27,
|
||||
"zmm28": ZMM28,
|
||||
"zmm29": ZMM29,
|
||||
"zmm30": ZMM30,
|
||||
"zmm31": ZMM31,
|
||||
}
|
||||
|
||||
/** Register Name Tables **/
|
||||
|
||||
var r8names = [...]string{
|
||||
AL: "al",
|
||||
CL: "cl",
|
||||
DL: "dl",
|
||||
BL: "bl",
|
||||
SPL: "spl",
|
||||
BPL: "bpl",
|
||||
SIL: "sil",
|
||||
DIL: "dil",
|
||||
R8b: "r8b",
|
||||
R9b: "r9b",
|
||||
R10b: "r10b",
|
||||
R11b: "r11b",
|
||||
R12b: "r12b",
|
||||
R13b: "r13b",
|
||||
R14b: "r14b",
|
||||
R15b: "r15b",
|
||||
AH: "ah",
|
||||
CH: "ch",
|
||||
DH: "dh",
|
||||
BH: "bh",
|
||||
}
|
||||
|
||||
var r16names = [...]string{
|
||||
AX: "ax",
|
||||
CX: "cx",
|
||||
DX: "dx",
|
||||
BX: "bx",
|
||||
SP: "sp",
|
||||
BP: "bp",
|
||||
SI: "si",
|
||||
DI: "di",
|
||||
R8w: "r8w",
|
||||
R9w: "r9w",
|
||||
R10w: "r10w",
|
||||
R11w: "r11w",
|
||||
R12w: "r12w",
|
||||
R13w: "r13w",
|
||||
R14w: "r14w",
|
||||
R15w: "r15w",
|
||||
}
|
||||
|
||||
var r32names = [...]string{
|
||||
EAX: "eax",
|
||||
ECX: "ecx",
|
||||
EDX: "edx",
|
||||
EBX: "ebx",
|
||||
ESP: "esp",
|
||||
EBP: "ebp",
|
||||
ESI: "esi",
|
||||
EDI: "edi",
|
||||
R8d: "r8d",
|
||||
R9d: "r9d",
|
||||
R10d: "r10d",
|
||||
R11d: "r11d",
|
||||
R12d: "r12d",
|
||||
R13d: "r13d",
|
||||
R14d: "r14d",
|
||||
R15d: "r15d",
|
||||
}
|
||||
|
||||
var r64names = [...]string{
|
||||
RAX: "rax",
|
||||
RCX: "rcx",
|
||||
RDX: "rdx",
|
||||
RBX: "rbx",
|
||||
RSP: "rsp",
|
||||
RBP: "rbp",
|
||||
RSI: "rsi",
|
||||
RDI: "rdi",
|
||||
R8: "r8",
|
||||
R9: "r9",
|
||||
R10: "r10",
|
||||
R11: "r11",
|
||||
R12: "r12",
|
||||
R13: "r13",
|
||||
R14: "r14",
|
||||
R15: "r15",
|
||||
}
|
||||
|
||||
var knames = [...]string{
|
||||
K0: "k0",
|
||||
K1: "k1",
|
||||
K2: "k2",
|
||||
K3: "k3",
|
||||
K4: "k4",
|
||||
K5: "k5",
|
||||
K6: "k6",
|
||||
K7: "k7",
|
||||
}
|
||||
|
||||
var mmnames = [...]string{
|
||||
MM0: "mm0",
|
||||
MM1: "mm1",
|
||||
MM2: "mm2",
|
||||
MM3: "mm3",
|
||||
MM4: "mm4",
|
||||
MM5: "mm5",
|
||||
MM6: "mm6",
|
||||
MM7: "mm7",
|
||||
}
|
||||
|
||||
var xmmnames = [...]string{
|
||||
XMM0: "xmm0",
|
||||
XMM1: "xmm1",
|
||||
XMM2: "xmm2",
|
||||
XMM3: "xmm3",
|
||||
XMM4: "xmm4",
|
||||
XMM5: "xmm5",
|
||||
XMM6: "xmm6",
|
||||
XMM7: "xmm7",
|
||||
XMM8: "xmm8",
|
||||
XMM9: "xmm9",
|
||||
XMM10: "xmm10",
|
||||
XMM11: "xmm11",
|
||||
XMM12: "xmm12",
|
||||
XMM13: "xmm13",
|
||||
XMM14: "xmm14",
|
||||
XMM15: "xmm15",
|
||||
XMM16: "xmm16",
|
||||
XMM17: "xmm17",
|
||||
XMM18: "xmm18",
|
||||
XMM19: "xmm19",
|
||||
XMM20: "xmm20",
|
||||
XMM21: "xmm21",
|
||||
XMM22: "xmm22",
|
||||
XMM23: "xmm23",
|
||||
XMM24: "xmm24",
|
||||
XMM25: "xmm25",
|
||||
XMM26: "xmm26",
|
||||
XMM27: "xmm27",
|
||||
XMM28: "xmm28",
|
||||
XMM29: "xmm29",
|
||||
XMM30: "xmm30",
|
||||
XMM31: "xmm31",
|
||||
}
|
||||
|
||||
var ymmnames = [...]string{
|
||||
YMM0: "ymm0",
|
||||
YMM1: "ymm1",
|
||||
YMM2: "ymm2",
|
||||
YMM3: "ymm3",
|
||||
YMM4: "ymm4",
|
||||
YMM5: "ymm5",
|
||||
YMM6: "ymm6",
|
||||
YMM7: "ymm7",
|
||||
YMM8: "ymm8",
|
||||
YMM9: "ymm9",
|
||||
YMM10: "ymm10",
|
||||
YMM11: "ymm11",
|
||||
YMM12: "ymm12",
|
||||
YMM13: "ymm13",
|
||||
YMM14: "ymm14",
|
||||
YMM15: "ymm15",
|
||||
YMM16: "ymm16",
|
||||
YMM17: "ymm17",
|
||||
YMM18: "ymm18",
|
||||
YMM19: "ymm19",
|
||||
YMM20: "ymm20",
|
||||
YMM21: "ymm21",
|
||||
YMM22: "ymm22",
|
||||
YMM23: "ymm23",
|
||||
YMM24: "ymm24",
|
||||
YMM25: "ymm25",
|
||||
YMM26: "ymm26",
|
||||
YMM27: "ymm27",
|
||||
YMM28: "ymm28",
|
||||
YMM29: "ymm29",
|
||||
YMM30: "ymm30",
|
||||
YMM31: "ymm31",
|
||||
}
|
||||
|
||||
var zmmnames = [...]string{
|
||||
ZMM0: "zmm0",
|
||||
ZMM1: "zmm1",
|
||||
ZMM2: "zmm2",
|
||||
ZMM3: "zmm3",
|
||||
ZMM4: "zmm4",
|
||||
ZMM5: "zmm5",
|
||||
ZMM6: "zmm6",
|
||||
ZMM7: "zmm7",
|
||||
ZMM8: "zmm8",
|
||||
ZMM9: "zmm9",
|
||||
ZMM10: "zmm10",
|
||||
ZMM11: "zmm11",
|
||||
ZMM12: "zmm12",
|
||||
ZMM13: "zmm13",
|
||||
ZMM14: "zmm14",
|
||||
ZMM15: "zmm15",
|
||||
ZMM16: "zmm16",
|
||||
ZMM17: "zmm17",
|
||||
ZMM18: "zmm18",
|
||||
ZMM19: "zmm19",
|
||||
ZMM20: "zmm20",
|
||||
ZMM21: "zmm21",
|
||||
ZMM22: "zmm22",
|
||||
ZMM23: "zmm23",
|
||||
ZMM24: "zmm24",
|
||||
ZMM25: "zmm25",
|
||||
ZMM26: "zmm26",
|
||||
ZMM27: "zmm27",
|
||||
ZMM28: "zmm28",
|
||||
ZMM29: "zmm29",
|
||||
ZMM30: "zmm30",
|
||||
ZMM31: "zmm31",
|
||||
}
|
147
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/utils.go
generated
vendored
Normal file
147
vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/utils.go
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
_CC_digit = 1 << iota
|
||||
_CC_ident
|
||||
_CC_ident0
|
||||
_CC_number
|
||||
)
|
||||
|
||||
func ispow2(v uint64) bool {
|
||||
return (v & (v - 1)) == 0
|
||||
}
|
||||
|
||||
func isdigit(cc rune) bool {
|
||||
return '0' <= cc && cc <= '9'
|
||||
}
|
||||
|
||||
func isalpha(cc rune) bool {
|
||||
return (cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z')
|
||||
}
|
||||
|
||||
func isident(cc rune) bool {
|
||||
return cc == '_' || isalpha(cc) || isdigit(cc)
|
||||
}
|
||||
|
||||
func isident0(cc rune) bool {
|
||||
return cc == '_' || isalpha(cc)
|
||||
}
|
||||
|
||||
func isnumber(cc rune) bool {
|
||||
return (cc == 'b' || cc == 'B') ||
|
||||
(cc == 'o' || cc == 'O') ||
|
||||
(cc == 'x' || cc == 'X') ||
|
||||
(cc >= '0' && cc <= '9') ||
|
||||
(cc >= 'a' && cc <= 'f') ||
|
||||
(cc >= 'A' && cc <= 'F')
|
||||
}
|
||||
|
||||
func align(v int, n int) int {
|
||||
return (((v - 1) >> n) + 1) << n
|
||||
}
|
||||
|
||||
func append8(m *[]byte, v byte) {
|
||||
*m = append(*m, v)
|
||||
}
|
||||
|
||||
func append16(m *[]byte, v uint16) {
|
||||
p := len(*m)
|
||||
*m = append(*m, 0, 0)
|
||||
binary.LittleEndian.PutUint16((*m)[p:], v)
|
||||
}
|
||||
|
||||
func append32(m *[]byte, v uint32) {
|
||||
p := len(*m)
|
||||
*m = append(*m, 0, 0, 0, 0)
|
||||
binary.LittleEndian.PutUint32((*m)[p:], v)
|
||||
}
|
||||
|
||||
func append64(m *[]byte, v uint64) {
|
||||
p := len(*m)
|
||||
*m = append(*m, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
binary.LittleEndian.PutUint64((*m)[p:], v)
|
||||
}
|
||||
|
||||
func expandmm(m *[]byte, n int, v byte) {
|
||||
sl := (*_GoSlice)(unsafe.Pointer(m))
|
||||
nb := sl.len + n
|
||||
|
||||
/* grow as needed */
|
||||
if nb > cap(*m) {
|
||||
*m = growslice(byteType, *m, nb)
|
||||
}
|
||||
|
||||
/* fill the new area */
|
||||
memset(unsafe.Pointer(uintptr(sl.ptr)+uintptr(sl.len)), v, uintptr(n))
|
||||
sl.len = nb
|
||||
}
|
||||
|
||||
func memset(p unsafe.Pointer, c byte, n uintptr) {
|
||||
if c != 0 {
|
||||
memsetv(p, c, n)
|
||||
} else {
|
||||
memclrNoHeapPointers(p, n)
|
||||
}
|
||||
}
|
||||
|
||||
func memsetv(p unsafe.Pointer, c byte, n uintptr) {
|
||||
for i := uintptr(0); i < n; i++ {
|
||||
*(*byte)(unsafe.Pointer(uintptr(p) + i)) = c
|
||||
}
|
||||
}
|
||||
|
||||
func literal64(v string) (uint64, error) {
|
||||
var nb int
|
||||
var ch rune
|
||||
var ex error
|
||||
var mm [12]byte
|
||||
|
||||
/* unquote the runes */
|
||||
for v != "" {
|
||||
if ch, _, v, ex = strconv.UnquoteChar(v, '\''); ex != nil {
|
||||
return 0, ex
|
||||
} else if nb += utf8.EncodeRune(mm[nb:], ch); nb > 8 {
|
||||
return 0, errors.New("multi-char constant too large")
|
||||
}
|
||||
}
|
||||
|
||||
/* convert to uint64 */
|
||||
return *(*uint64)(unsafe.Pointer(&mm)), nil
|
||||
}
|
||||
|
||||
var (
|
||||
byteWrap = reflect.TypeOf(byte(0))
|
||||
byteType = (*_GoType)(efaceOf(byteWrap).ptr)
|
||||
)
|
||||
|
||||
//go:linkname growslice runtime.growslice
|
||||
func growslice(_ *_GoType, _ []byte, _ int) []byte
|
||||
|
||||
//go:noescape
|
||||
//go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
|
||||
func memclrNoHeapPointers(_ unsafe.Pointer, _ uintptr)
|
2
vendor/github.com/bytedance/sonic/option/option.go
generated
vendored
2
vendor/github.com/bytedance/sonic/option/option.go
generated
vendored
|
@ -68,7 +68,7 @@ func DefaultCompileOptions() CompileOptions {
|
|||
//
|
||||
// For deep nested struct (depth exceeds MaxInlineDepth),
|
||||
// try to set more loops to completely compile,
|
||||
// thus reduce JIT unstability in the first hit.
|
||||
// thus reduce JIT instability in the first hit.
|
||||
func WithCompileRecursiveDepth(loop int) CompileOption {
|
||||
return func(o *CompileOptions) {
|
||||
if loop < 0 {
|
||||
|
|
4
vendor/github.com/bytedance/sonic/unquote/unquote.go
generated
vendored
4
vendor/github.com/bytedance/sonic/unquote/unquote.go
generated
vendored
|
@ -25,7 +25,7 @@
|
|||
`github.com/bytedance/sonic/internal/rt`
|
||||
)
|
||||
|
||||
// String unescapes a escaped string (not including `"` at begining and end)
|
||||
// String unescapes an escaped string (not including `"` at beginning and end)
|
||||
// It validates invalid UTF8 and replace with `\ufffd`
|
||||
func String(s string) (ret string, err types.ParsingError) {
|
||||
mm := make([]byte, 0, len(s))
|
||||
|
@ -43,7 +43,7 @@ func IntoBytes(s string, m *[]byte) types.ParsingError {
|
|||
}
|
||||
}
|
||||
|
||||
// String unescapes a escaped string (not including `"` at begining and end)
|
||||
// String unescapes an escaped string (not including `"` at beginning and end)
|
||||
// - replace enables replacing invalid utf8 escaped char with `\uffd`
|
||||
func _String(s string, replace bool) (ret string, err error) {
|
||||
mm := make([]byte, 0, len(s))
|
||||
|
|
2
vendor/github.com/bytedance/sonic/utf8/utf8.go
generated
vendored
2
vendor/github.com/bytedance/sonic/utf8/utf8.go
generated
vendored
|
@ -29,7 +29,7 @@ func CorrectWith(dst []byte, src []byte, repl string) []byte {
|
|||
sstr := rt.Mem2Str(src)
|
||||
sidx := 0
|
||||
|
||||
/* state machine records the invalid postions */
|
||||
/* state machine records the invalid positions */
|
||||
m := types.NewStateMachine()
|
||||
m.Sp = 0 // invalid utf8 numbers
|
||||
|
||||
|
|
177
vendor/github.com/cloudwego/iasm/LICENSE-APACHE
generated
vendored
177
vendor/github.com/cloudwego/iasm/LICENSE-APACHE
generated
vendored
|
@ -1,177 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
261
vendor/github.com/cloudwego/iasm/expr/ast.go
generated
vendored
261
vendor/github.com/cloudwego/iasm/expr/ast.go
generated
vendored
|
@ -1,261 +0,0 @@
|
|||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
)
|
||||
|
||||
// Type is tyep expression type.
|
||||
type Type int
|
||||
|
||||
const (
|
||||
// CONST indicates that the expression is a constant.
|
||||
CONST Type = iota
|
||||
|
||||
// TERM indicates that the expression is a Term reference.
|
||||
TERM
|
||||
|
||||
// EXPR indicates that the expression is a unary or binary expression.
|
||||
EXPR
|
||||
)
|
||||
|
||||
var typeNames = map[Type]string {
|
||||
EXPR : "Expr",
|
||||
TERM : "Term",
|
||||
CONST : "Const",
|
||||
}
|
||||
|
||||
// String returns the string representation of a Type.
|
||||
func (self Type) String() string {
|
||||
if v, ok := typeNames[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
return fmt.Sprintf("expr.Type(%d)", self)
|
||||
}
|
||||
}
|
||||
|
||||
// Operator represents an operation to perform when Type is EXPR.
|
||||
type Operator uint8
|
||||
|
||||
const (
|
||||
// ADD performs "Add Expr.Left and Expr.Right".
|
||||
ADD Operator = iota
|
||||
|
||||
// SUB performs "Subtract Expr.Left by Expr.Right".
|
||||
SUB
|
||||
|
||||
// MUL performs "Multiply Expr.Left by Expr.Right".
|
||||
MUL
|
||||
|
||||
// DIV performs "Divide Expr.Left by Expr.Right".
|
||||
DIV
|
||||
|
||||
// MOD performs "Modulo Expr.Left by Expr.Right".
|
||||
MOD
|
||||
|
||||
// AND performs "Bitwise AND Expr.Left and Expr.Right".
|
||||
AND
|
||||
|
||||
// OR performs "Bitwise OR Expr.Left and Expr.Right".
|
||||
OR
|
||||
|
||||
// XOR performs "Bitwise XOR Expr.Left and Expr.Right".
|
||||
XOR
|
||||
|
||||
// SHL performs "Bitwise Shift Expr.Left to the Left by Expr.Right Bits".
|
||||
SHL
|
||||
|
||||
// SHR performs "Bitwise Shift Expr.Left to the Right by Expr.Right Bits".
|
||||
SHR
|
||||
|
||||
// POW performs "Raise Expr.Left to the power of Expr.Right"
|
||||
POW
|
||||
|
||||
// NOT performs "Bitwise Invert Expr.Left".
|
||||
NOT
|
||||
|
||||
// NEG performs "Negate Expr.Left".
|
||||
NEG
|
||||
)
|
||||
|
||||
var operatorNames = map[Operator]string {
|
||||
ADD : "Add",
|
||||
SUB : "Subtract",
|
||||
MUL : "Multiply",
|
||||
DIV : "Divide",
|
||||
MOD : "Modulo",
|
||||
AND : "And",
|
||||
OR : "Or",
|
||||
XOR : "ExclusiveOr",
|
||||
SHL : "ShiftLeft",
|
||||
SHR : "ShiftRight",
|
||||
POW : "Power",
|
||||
NOT : "Invert",
|
||||
NEG : "Negate",
|
||||
}
|
||||
|
||||
// String returns the string representation of a Type.
|
||||
func (self Operator) String() string {
|
||||
if v, ok := operatorNames[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
return fmt.Sprintf("expr.Operator(%d)", self)
|
||||
}
|
||||
}
|
||||
|
||||
// Expr represents an expression node.
|
||||
type Expr struct {
|
||||
Type Type
|
||||
Term Term
|
||||
Op Operator
|
||||
Left *Expr
|
||||
Right *Expr
|
||||
Const int64
|
||||
}
|
||||
|
||||
// Ref creates an expression from a Term.
|
||||
func Ref(t Term) (p *Expr) {
|
||||
p = newExpression()
|
||||
p.Term = t
|
||||
p.Type = TERM
|
||||
return
|
||||
}
|
||||
|
||||
// Int creates an expression from an integer.
|
||||
func Int(v int64) (p *Expr) {
|
||||
p = newExpression()
|
||||
p.Type = CONST
|
||||
p.Const = v
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Expr) clear() {
|
||||
if self.Term != nil { self.Term.Free() }
|
||||
if self.Left != nil { self.Left.Free() }
|
||||
if self.Right != nil { self.Right.Free() }
|
||||
}
|
||||
|
||||
// Free returns the Expr into pool.
|
||||
// Any operation performed after Free is undefined behavior.
|
||||
func (self *Expr) Free() {
|
||||
self.clear()
|
||||
freeExpression(self)
|
||||
}
|
||||
|
||||
// Evaluate evaluates the expression into an integer.
|
||||
// It also implements the Term interface.
|
||||
func (self *Expr) Evaluate() (int64, error) {
|
||||
switch self.Type {
|
||||
case EXPR : return self.eval()
|
||||
case TERM : return self.Term.Evaluate()
|
||||
case CONST : return self.Const, nil
|
||||
default : panic("invalid expression type: " + self.Type.String())
|
||||
}
|
||||
}
|
||||
|
||||
/** Expression Combinator **/
|
||||
|
||||
func combine(a *Expr, op Operator, b *Expr) (r *Expr) {
|
||||
r = newExpression()
|
||||
r.Op = op
|
||||
r.Type = EXPR
|
||||
r.Left = a
|
||||
r.Right = b
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Expr) Add(v *Expr) *Expr { return combine(self, ADD, v) }
|
||||
func (self *Expr) Sub(v *Expr) *Expr { return combine(self, SUB, v) }
|
||||
func (self *Expr) Mul(v *Expr) *Expr { return combine(self, MUL, v) }
|
||||
func (self *Expr) Div(v *Expr) *Expr { return combine(self, DIV, v) }
|
||||
func (self *Expr) Mod(v *Expr) *Expr { return combine(self, MOD, v) }
|
||||
func (self *Expr) And(v *Expr) *Expr { return combine(self, AND, v) }
|
||||
func (self *Expr) Or (v *Expr) *Expr { return combine(self, OR , v) }
|
||||
func (self *Expr) Xor(v *Expr) *Expr { return combine(self, XOR, v) }
|
||||
func (self *Expr) Shl(v *Expr) *Expr { return combine(self, SHL, v) }
|
||||
func (self *Expr) Shr(v *Expr) *Expr { return combine(self, SHR, v) }
|
||||
func (self *Expr) Pow(v *Expr) *Expr { return combine(self, POW, v) }
|
||||
func (self *Expr) Not() *Expr { return combine(self, NOT, nil) }
|
||||
func (self *Expr) Neg() *Expr { return combine(self, NEG, nil) }
|
||||
|
||||
/** Expression Evaluator **/
|
||||
|
||||
var binaryEvaluators = [256]func(int64, int64) (int64, error) {
|
||||
ADD: func(a, b int64) (int64, error) { return a + b, nil },
|
||||
SUB: func(a, b int64) (int64, error) { return a - b, nil },
|
||||
MUL: func(a, b int64) (int64, error) { return a * b, nil },
|
||||
DIV: idiv,
|
||||
MOD: imod,
|
||||
AND: func(a, b int64) (int64, error) { return a & b, nil },
|
||||
OR: func(a, b int64) (int64, error) { return a | b, nil },
|
||||
XOR: func(a, b int64) (int64, error) { return a ^ b, nil },
|
||||
SHL: func(a, b int64) (int64, error) { return a << b, nil },
|
||||
SHR: func(a, b int64) (int64, error) { return a >> b, nil },
|
||||
POW: ipow,
|
||||
}
|
||||
|
||||
func (self *Expr) eval() (int64, error) {
|
||||
var lhs int64
|
||||
var rhs int64
|
||||
var err error
|
||||
var vfn func(int64, int64) (int64, error)
|
||||
|
||||
/* evaluate LHS */
|
||||
if lhs, err = self.Left.Evaluate(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
/* check for unary operators */
|
||||
switch self.Op {
|
||||
case NOT: return self.unaryNot(lhs)
|
||||
case NEG: return self.unaryNeg(lhs)
|
||||
}
|
||||
|
||||
/* check for operators */
|
||||
if vfn = binaryEvaluators[self.Op]; vfn == nil {
|
||||
panic("invalid operator: " + self.Op.String())
|
||||
}
|
||||
|
||||
/* must be a binary expression */
|
||||
if self.Right == nil {
|
||||
panic("operator " + self.Op.String() + " is a binary operator")
|
||||
}
|
||||
|
||||
/* evaluate RHS, and call the operator */
|
||||
if rhs, err = self.Right.Evaluate(); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return vfn(lhs, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Expr) unaryNot(v int64) (int64, error) {
|
||||
if self.Right == nil {
|
||||
return ^v, nil
|
||||
} else {
|
||||
panic("operator Invert is an unary operator")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Expr) unaryNeg(v int64) (int64, error) {
|
||||
if self.Right == nil {
|
||||
return -v, nil
|
||||
} else {
|
||||
panic("operator Negate is an unary operator")
|
||||
}
|
||||
}
|
67
vendor/github.com/cloudwego/iasm/expr/ops.go
generated
vendored
67
vendor/github.com/cloudwego/iasm/expr/ops.go
generated
vendored
|
@ -1,67 +0,0 @@
|
|||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
)
|
||||
|
||||
func idiv(v int64, d int64) (int64, error) {
|
||||
if d != 0 {
|
||||
return v / d, nil
|
||||
} else {
|
||||
return 0, newRuntimeError("division by zero")
|
||||
}
|
||||
}
|
||||
|
||||
func imod(v int64, d int64) (int64, error) {
|
||||
if d != 0 {
|
||||
return v % d, nil
|
||||
} else {
|
||||
return 0, newRuntimeError("division by zero")
|
||||
}
|
||||
}
|
||||
|
||||
func ipow(v int64, e int64) (int64, error) {
|
||||
mul := v
|
||||
ret := int64(1)
|
||||
|
||||
/* value must be 0 or positive */
|
||||
if v < 0 {
|
||||
return 0, newRuntimeError(fmt.Sprintf("negative base value: %d", v))
|
||||
}
|
||||
|
||||
/* exponent must be non-negative */
|
||||
if e < 0 {
|
||||
return 0, newRuntimeError(fmt.Sprintf("negative exponent: %d", e))
|
||||
}
|
||||
|
||||
/* fast power first round */
|
||||
if (e & 1) != 0 {
|
||||
ret *= mul
|
||||
}
|
||||
|
||||
/* fast power remaining rounds */
|
||||
for e >>= 1; e != 0; e >>= 1 {
|
||||
if mul *= mul; (e & 1) != 0 {
|
||||
ret *= mul
|
||||
}
|
||||
}
|
||||
|
||||
/* all done */
|
||||
return ret, nil
|
||||
}
|
329
vendor/github.com/cloudwego/iasm/expr/parser.go
generated
vendored
329
vendor/github.com/cloudwego/iasm/expr/parser.go
generated
vendored
|
@ -1,329 +0,0 @@
|
|||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
`strconv`
|
||||
`unicode`
|
||||
`unsafe`
|
||||
)
|
||||
|
||||
type _TokenKind uint8
|
||||
|
||||
const (
|
||||
_T_end _TokenKind = iota + 1
|
||||
_T_int
|
||||
_T_punc
|
||||
_T_name
|
||||
)
|
||||
|
||||
const (
|
||||
_OP2 = 0x80
|
||||
_POW = _OP2 | '*'
|
||||
_SHL = _OP2 | '<'
|
||||
_SHR = _OP2 | '>'
|
||||
)
|
||||
|
||||
type _Slice struct {
|
||||
p unsafe.Pointer
|
||||
n int
|
||||
c int
|
||||
}
|
||||
|
||||
type _Token struct {
|
||||
pos int
|
||||
ptr *rune
|
||||
u64 uint64
|
||||
tag _TokenKind
|
||||
}
|
||||
|
||||
func (self _Token) str() (v string) {
|
||||
return string(self.rbuf())
|
||||
}
|
||||
|
||||
func (self _Token) rbuf() (v []rune) {
|
||||
(*_Slice)(unsafe.Pointer(&v)).c = int(self.u64)
|
||||
(*_Slice)(unsafe.Pointer(&v)).n = int(self.u64)
|
||||
(*_Slice)(unsafe.Pointer(&v)).p = unsafe.Pointer(self.ptr)
|
||||
return
|
||||
}
|
||||
|
||||
func tokenEnd(p int) _Token {
|
||||
return _Token {
|
||||
pos: p,
|
||||
tag: _T_end,
|
||||
}
|
||||
}
|
||||
|
||||
func tokenInt(p int, v uint64) _Token {
|
||||
return _Token {
|
||||
pos: p,
|
||||
u64: v,
|
||||
tag: _T_int,
|
||||
}
|
||||
}
|
||||
|
||||
func tokenPunc(p int, v rune) _Token {
|
||||
return _Token {
|
||||
pos: p,
|
||||
tag: _T_punc,
|
||||
u64: uint64(v),
|
||||
}
|
||||
}
|
||||
|
||||
func tokenName(p int, v []rune) _Token {
|
||||
return _Token {
|
||||
pos: p,
|
||||
ptr: &v[0],
|
||||
tag: _T_name,
|
||||
u64: uint64(len(v)),
|
||||
}
|
||||
}
|
||||
|
||||
// Repository represents a repository of Term's.
|
||||
type Repository interface {
|
||||
Get(name string) (Term, error)
|
||||
}
|
||||
|
||||
// Parser parses an expression string to it's AST representation.
|
||||
type Parser struct {
|
||||
pos int
|
||||
src []rune
|
||||
}
|
||||
|
||||
var binaryOps = [...]func(*Expr, *Expr) *Expr {
|
||||
'+' : (*Expr).Add,
|
||||
'-' : (*Expr).Sub,
|
||||
'*' : (*Expr).Mul,
|
||||
'/' : (*Expr).Div,
|
||||
'%' : (*Expr).Mod,
|
||||
'&' : (*Expr).And,
|
||||
'^' : (*Expr).Xor,
|
||||
'|' : (*Expr).Or,
|
||||
_SHL : (*Expr).Shl,
|
||||
_SHR : (*Expr).Shr,
|
||||
_POW : (*Expr).Pow,
|
||||
}
|
||||
|
||||
var precedence = [...]map[int]bool {
|
||||
{_SHL: true, _SHR: true},
|
||||
{'|' : true},
|
||||
{'^' : true},
|
||||
{'&' : true},
|
||||
{'+' : true, '-': true},
|
||||
{'*' : true, '/': true, '%': true},
|
||||
{_POW: true},
|
||||
}
|
||||
|
||||
func (self *Parser) ch() rune {
|
||||
return self.src[self.pos]
|
||||
}
|
||||
|
||||
func (self *Parser) eof() bool {
|
||||
return self.pos >= len(self.src)
|
||||
}
|
||||
|
||||
func (self *Parser) rch() (v rune) {
|
||||
v, self.pos = self.src[self.pos], self.pos + 1
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Parser) hex(ss []rune) bool {
|
||||
if len(ss) == 1 && ss[0] == '0' {
|
||||
return unicode.ToLower(self.ch()) == 'x'
|
||||
} else if len(ss) <= 1 || unicode.ToLower(ss[1]) != 'x' {
|
||||
return unicode.IsDigit(self.ch())
|
||||
} else {
|
||||
return ishexdigit(self.ch())
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) int(p int, ss []rune) (_Token, error) {
|
||||
var err error
|
||||
var val uint64
|
||||
|
||||
/* find all the digits */
|
||||
for !self.eof() && self.hex(ss) {
|
||||
ss = append(ss, self.rch())
|
||||
}
|
||||
|
||||
/* parse the value */
|
||||
if val, err = strconv.ParseUint(string(ss), 0, 64); err != nil {
|
||||
return _Token{}, err
|
||||
} else {
|
||||
return tokenInt(p, val), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) name(p int, ss []rune) _Token {
|
||||
for !self.eof() && isident(self.ch()) { ss = append(ss, self.rch()) }
|
||||
return tokenName(p, ss)
|
||||
}
|
||||
|
||||
func (self *Parser) read(p int, ch rune) (_Token, error) {
|
||||
if isdigit(ch) {
|
||||
return self.int(p, []rune { ch })
|
||||
} else if isident0(ch) {
|
||||
return self.name(p, []rune { ch }), nil
|
||||
} else if isop2ch(ch) && !self.eof() && self.ch() == ch {
|
||||
return tokenPunc(p, _OP2 | self.rch()), nil
|
||||
} else if isop1ch(ch) {
|
||||
return tokenPunc(p, ch), nil
|
||||
} else {
|
||||
return _Token{}, newSyntaxError(self.pos, "invalid character " + strconv.QuoteRuneToASCII(ch))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) next() (_Token, error) {
|
||||
for {
|
||||
var p int
|
||||
var c rune
|
||||
|
||||
/* check for EOF */
|
||||
if self.eof() {
|
||||
return tokenEnd(self.pos), nil
|
||||
}
|
||||
|
||||
/* read the next char */
|
||||
p = self.pos
|
||||
c = self.rch()
|
||||
|
||||
/* parse the token if not a space */
|
||||
if !unicode.IsSpace(c) {
|
||||
return self.read(p, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) grab(tk _Token, repo Repository) (*Expr, error) {
|
||||
if repo == nil {
|
||||
return nil, newSyntaxError(tk.pos, "unresolved symbol: " + tk.str())
|
||||
} else if term, err := repo.Get(tk.str()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return Ref(term), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) nest(nest int, repo Repository) (*Expr, error) {
|
||||
var err error
|
||||
var ret *Expr
|
||||
var ntk _Token
|
||||
|
||||
/* evaluate the nested expression */
|
||||
if ret, err = self.expr(0, nest + 1, repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* must follows with a ')' */
|
||||
if ntk, err = self.next(); err != nil {
|
||||
return nil, err
|
||||
} else if ntk.tag != _T_punc || ntk.u64 != ')' {
|
||||
return nil, newSyntaxError(ntk.pos, "')' expected")
|
||||
} else {
|
||||
return ret, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) unit(nest int, repo Repository) (*Expr, error) {
|
||||
if tk, err := self.next(); err != nil {
|
||||
return nil, err
|
||||
} else if tk.tag == _T_int {
|
||||
return Int(int64(tk.u64)), nil
|
||||
} else if tk.tag == _T_name {
|
||||
return self.grab(tk, repo)
|
||||
} else if tk.tag == _T_punc && tk.u64 == '(' {
|
||||
return self.nest(nest, repo)
|
||||
} else if tk.tag == _T_punc && tk.u64 == '+' {
|
||||
return self.unit(nest, repo)
|
||||
} else if tk.tag == _T_punc && tk.u64 == '-' {
|
||||
return neg2(self.unit(nest, repo))
|
||||
} else if tk.tag == _T_punc && tk.u64 == '~' {
|
||||
return not2(self.unit(nest, repo))
|
||||
} else {
|
||||
return nil, newSyntaxError(tk.pos, "integer, unary operator or nested expression expected")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) term(prec int, nest int, repo Repository) (*Expr, error) {
|
||||
var err error
|
||||
var val *Expr
|
||||
|
||||
/* parse the LHS operand */
|
||||
if val, err = self.expr(prec + 1, nest, repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* parse all the operators of the same precedence */
|
||||
for {
|
||||
var op int
|
||||
var rv *Expr
|
||||
var tk _Token
|
||||
|
||||
/* peek the next token */
|
||||
pp := self.pos
|
||||
tk, err = self.next()
|
||||
|
||||
/* check for errors */
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* encountered EOF */
|
||||
if tk.tag == _T_end {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
/* must be an operator */
|
||||
if tk.tag != _T_punc {
|
||||
return nil, newSyntaxError(tk.pos, "operators expected")
|
||||
}
|
||||
|
||||
/* check for the operator precedence */
|
||||
if op = int(tk.u64); !precedence[prec][op] {
|
||||
self.pos = pp
|
||||
return val, nil
|
||||
}
|
||||
|
||||
/* evaluate the RHS operand, and combine the value */
|
||||
if rv, err = self.expr(prec + 1, nest, repo); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
val = binaryOps[op](val, rv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) expr(prec int, nest int, repo Repository) (*Expr, error) {
|
||||
if prec >= len(precedence) {
|
||||
return self.unit(nest, repo)
|
||||
} else {
|
||||
return self.term(prec, nest, repo)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse parses the expression, and returns it's AST tree.
|
||||
func (self *Parser) Parse(repo Repository) (*Expr, error) {
|
||||
return self.expr(0, 0, repo)
|
||||
}
|
||||
|
||||
// SetSource resets the expression parser and sets the expression source.
|
||||
func (self *Parser) SetSource(src string) *Parser {
|
||||
self.pos = 0
|
||||
self.src = []rune(src)
|
||||
return self
|
||||
}
|
251
vendor/github.com/cloudwego/iasm/x86_64/arch.go
generated
vendored
251
vendor/github.com/cloudwego/iasm/x86_64/arch.go
generated
vendored
|
@ -1,251 +0,0 @@
|
|||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
)
|
||||
|
||||
// ISA represents an extension to x86-64 instruction set.
|
||||
type ISA uint64
|
||||
|
||||
const (
|
||||
ISA_CPUID ISA = 1 << iota
|
||||
ISA_RDTSC
|
||||
ISA_RDTSCP
|
||||
ISA_CMOV
|
||||
ISA_MOVBE
|
||||
ISA_POPCNT
|
||||
ISA_LZCNT
|
||||
ISA_TBM
|
||||
ISA_BMI
|
||||
ISA_BMI2
|
||||
ISA_ADX
|
||||
ISA_MMX
|
||||
ISA_MMX_PLUS
|
||||
ISA_FEMMS
|
||||
ISA_3DNOW
|
||||
ISA_3DNOW_PLUS
|
||||
ISA_SSE
|
||||
ISA_SSE2
|
||||
ISA_SSE3
|
||||
ISA_SSSE3
|
||||
ISA_SSE4A
|
||||
ISA_SSE4_1
|
||||
ISA_SSE4_2
|
||||
ISA_FMA3
|
||||
ISA_FMA4
|
||||
ISA_XOP
|
||||
ISA_F16C
|
||||
ISA_AVX
|
||||
ISA_AVX2
|
||||
ISA_AVX512F
|
||||
ISA_AVX512BW
|
||||
ISA_AVX512DQ
|
||||
ISA_AVX512VL
|
||||
ISA_AVX512PF
|
||||
ISA_AVX512ER
|
||||
ISA_AVX512CD
|
||||
ISA_AVX512VBMI
|
||||
ISA_AVX512IFMA
|
||||
ISA_AVX512VPOPCNTDQ
|
||||
ISA_AVX512_4VNNIW
|
||||
ISA_AVX512_4FMAPS
|
||||
ISA_PREFETCH
|
||||
ISA_PREFETCHW
|
||||
ISA_PREFETCHWT1
|
||||
ISA_CLFLUSH
|
||||
ISA_CLFLUSHOPT
|
||||
ISA_CLWB
|
||||
ISA_CLZERO
|
||||
ISA_RDRAND
|
||||
ISA_RDSEED
|
||||
ISA_PCLMULQDQ
|
||||
ISA_AES
|
||||
ISA_SHA
|
||||
ISA_MONITOR
|
||||
ISA_MONITORX
|
||||
ISA_ALL = ^ISA(0)
|
||||
)
|
||||
|
||||
var _ISA_NAMES = map[ISA]string {
|
||||
ISA_CPUID : "CPUID",
|
||||
ISA_RDTSC : "RDTSC",
|
||||
ISA_RDTSCP : "RDTSCP",
|
||||
ISA_CMOV : "CMOV",
|
||||
ISA_MOVBE : "MOVBE",
|
||||
ISA_POPCNT : "POPCNT",
|
||||
ISA_LZCNT : "LZCNT",
|
||||
ISA_TBM : "TBM",
|
||||
ISA_BMI : "BMI",
|
||||
ISA_BMI2 : "BMI2",
|
||||
ISA_ADX : "ADX",
|
||||
ISA_MMX : "MMX",
|
||||
ISA_MMX_PLUS : "MMX+",
|
||||
ISA_FEMMS : "FEMMS",
|
||||
ISA_3DNOW : "3dnow!",
|
||||
ISA_3DNOW_PLUS : "3dnow!+",
|
||||
ISA_SSE : "SSE",
|
||||
ISA_SSE2 : "SSE2",
|
||||
ISA_SSE3 : "SSE3",
|
||||
ISA_SSSE3 : "SSSE3",
|
||||
ISA_SSE4A : "SSE4A",
|
||||
ISA_SSE4_1 : "SSE4.1",
|
||||
ISA_SSE4_2 : "SSE4.2",
|
||||
ISA_FMA3 : "FMA3",
|
||||
ISA_FMA4 : "FMA4",
|
||||
ISA_XOP : "XOP",
|
||||
ISA_F16C : "F16C",
|
||||
ISA_AVX : "AVX",
|
||||
ISA_AVX2 : "AVX2",
|
||||
ISA_AVX512F : "AVX512F",
|
||||
ISA_AVX512BW : "AVX512BW",
|
||||
ISA_AVX512DQ : "AVX512DQ",
|
||||
ISA_AVX512VL : "AVX512VL",
|
||||
ISA_AVX512PF : "AVX512PF",
|
||||
ISA_AVX512ER : "AVX512ER",
|
||||
ISA_AVX512CD : "AVX512CD",
|
||||
ISA_AVX512VBMI : "AVX512VBMI",
|
||||
ISA_AVX512IFMA : "AVX512IFMA",
|
||||
ISA_AVX512VPOPCNTDQ : "AVX512VPOPCNTDQ",
|
||||
ISA_AVX512_4VNNIW : "AVX512_4VNNIW",
|
||||
ISA_AVX512_4FMAPS : "AVX512_4FMAPS",
|
||||
ISA_PREFETCH : "PREFETCH",
|
||||
ISA_PREFETCHW : "PREFETCHW",
|
||||
ISA_PREFETCHWT1 : "PREFETCHWT1",
|
||||
ISA_CLFLUSH : "CLFLUSH",
|
||||
ISA_CLFLUSHOPT : "CLFLUSHOPT",
|
||||
ISA_CLWB : "CLWB",
|
||||
ISA_CLZERO : "CLZERO",
|
||||
ISA_RDRAND : "RDRAND",
|
||||
ISA_RDSEED : "RDSEED",
|
||||
ISA_PCLMULQDQ : "PCLMULQDQ",
|
||||
ISA_AES : "AES",
|
||||
ISA_SHA : "SHA",
|
||||
ISA_MONITOR : "MONITOR",
|
||||
ISA_MONITORX : "MONITORX",
|
||||
}
|
||||
|
||||
var _ISA_MAPPING = map[string]ISA {
|
||||
"CPUID" : ISA_CPUID,
|
||||
"RDTSC" : ISA_RDTSC,
|
||||
"RDTSCP" : ISA_RDTSCP,
|
||||
"CMOV" : ISA_CMOV,
|
||||
"MOVBE" : ISA_MOVBE,
|
||||
"POPCNT" : ISA_POPCNT,
|
||||
"LZCNT" : ISA_LZCNT,
|
||||
"TBM" : ISA_TBM,
|
||||
"BMI" : ISA_BMI,
|
||||
"BMI2" : ISA_BMI2,
|
||||
"ADX" : ISA_ADX,
|
||||
"MMX" : ISA_MMX,
|
||||
"MMX+" : ISA_MMX_PLUS,
|
||||
"FEMMS" : ISA_FEMMS,
|
||||
"3dnow!" : ISA_3DNOW,
|
||||
"3dnow!+" : ISA_3DNOW_PLUS,
|
||||
"SSE" : ISA_SSE,
|
||||
"SSE2" : ISA_SSE2,
|
||||
"SSE3" : ISA_SSE3,
|
||||
"SSSE3" : ISA_SSSE3,
|
||||
"SSE4A" : ISA_SSE4A,
|
||||
"SSE4.1" : ISA_SSE4_1,
|
||||
"SSE4.2" : ISA_SSE4_2,
|
||||
"FMA3" : ISA_FMA3,
|
||||
"FMA4" : ISA_FMA4,
|
||||
"XOP" : ISA_XOP,
|
||||
"F16C" : ISA_F16C,
|
||||
"AVX" : ISA_AVX,
|
||||
"AVX2" : ISA_AVX2,
|
||||
"AVX512F" : ISA_AVX512F,
|
||||
"AVX512BW" : ISA_AVX512BW,
|
||||
"AVX512DQ" : ISA_AVX512DQ,
|
||||
"AVX512VL" : ISA_AVX512VL,
|
||||
"AVX512PF" : ISA_AVX512PF,
|
||||
"AVX512ER" : ISA_AVX512ER,
|
||||
"AVX512CD" : ISA_AVX512CD,
|
||||
"AVX512VBMI" : ISA_AVX512VBMI,
|
||||
"AVX512IFMA" : ISA_AVX512IFMA,
|
||||
"AVX512VPOPCNTDQ" : ISA_AVX512VPOPCNTDQ,
|
||||
"AVX512_4VNNIW" : ISA_AVX512_4VNNIW,
|
||||
"AVX512_4FMAPS" : ISA_AVX512_4FMAPS,
|
||||
"PREFETCH" : ISA_PREFETCH,
|
||||
"PREFETCHW" : ISA_PREFETCHW,
|
||||
"PREFETCHWT1" : ISA_PREFETCHWT1,
|
||||
"CLFLUSH" : ISA_CLFLUSH,
|
||||
"CLFLUSHOPT" : ISA_CLFLUSHOPT,
|
||||
"CLWB" : ISA_CLWB,
|
||||
"CLZERO" : ISA_CLZERO,
|
||||
"RDRAND" : ISA_RDRAND,
|
||||
"RDSEED" : ISA_RDSEED,
|
||||
"PCLMULQDQ" : ISA_PCLMULQDQ,
|
||||
"AES" : ISA_AES,
|
||||
"SHA" : ISA_SHA,
|
||||
"MONITOR" : ISA_MONITOR,
|
||||
"MONITORX" : ISA_MONITORX,
|
||||
}
|
||||
|
||||
func (self ISA) String() string {
|
||||
if v, ok := _ISA_NAMES[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
return fmt.Sprintf("(invalid: %#x)", uint64(self))
|
||||
}
|
||||
}
|
||||
|
||||
// ParseISA parses name into ISA, it will panic if the name is invalid.
|
||||
func ParseISA(name string) ISA {
|
||||
if v, ok := _ISA_MAPPING[name]; ok {
|
||||
return v
|
||||
} else {
|
||||
panic("invalid ISA name: " + name)
|
||||
}
|
||||
}
|
||||
|
||||
// Arch represents the x86_64 architecture.
|
||||
type Arch struct {
|
||||
isa ISA
|
||||
}
|
||||
|
||||
// DefaultArch is the default architecture with all ISA enabled.
|
||||
var DefaultArch = CreateArch()
|
||||
|
||||
// CreateArch creates a new Arch with all ISA enabled.
|
||||
func CreateArch() *Arch {
|
||||
return new(Arch).EnableISA(ISA_ALL)
|
||||
}
|
||||
|
||||
// HasISA checks if a particular ISA was enabled.
|
||||
func (self *Arch) HasISA(isa ISA) bool {
|
||||
return (self.isa & isa) != 0
|
||||
}
|
||||
|
||||
// EnableISA enables a particular ISA.
|
||||
func (self *Arch) EnableISA(isa ISA) *Arch {
|
||||
self.isa |= isa
|
||||
return self
|
||||
}
|
||||
|
||||
// DisableISA disables a particular ISA.
|
||||
func (self *Arch) DisableISA(isa ISA) *Arch {
|
||||
self.isa &^= isa
|
||||
return self
|
||||
}
|
||||
|
||||
// CreateProgram creates a new empty program.
|
||||
func (self *Arch) CreateProgram() *Program {
|
||||
return newProgram(self)
|
||||
}
|
1819
vendor/github.com/cloudwego/iasm/x86_64/assembler.go
generated
vendored
1819
vendor/github.com/cloudwego/iasm/x86_64/assembler.go
generated
vendored
File diff suppressed because it is too large
Load diff
49
vendor/github.com/cloudwego/iasm/x86_64/assembler_alias.go
generated
vendored
49
vendor/github.com/cloudwego/iasm/x86_64/assembler_alias.go
generated
vendored
|
@ -1,49 +0,0 @@
|
|||
//
|
||||
// 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 x86_64
|
||||
|
||||
func alias_INT3(p *Program, vv ...interface{}) *Instruction {
|
||||
if len(vv) == 0 {
|
||||
return p.INT(3)
|
||||
} else {
|
||||
panic("instruction INT3 takes no operands")
|
||||
}
|
||||
}
|
||||
|
||||
func alias_VCMPEQPS(p *Program, vv ...interface{}) *Instruction {
|
||||
if len(vv) >= 3 {
|
||||
return p.VCMPPS(0x00, vv[0], vv[1], vv[2], vv[3:]...)
|
||||
} else {
|
||||
panic("instruction VCMPEQPS takes 3 or 4 operands")
|
||||
}
|
||||
}
|
||||
|
||||
func alias_VCMPTRUEPS(p *Program, vv ...interface{}) *Instruction {
|
||||
if len(vv) >= 3 {
|
||||
return p.VCMPPS(0x0f, vv[0], vv[1], vv[2], vv[3:]...)
|
||||
} else {
|
||||
panic("instruction VCMPTRUEPS takes 3 or 4 operands")
|
||||
}
|
||||
}
|
||||
|
||||
var _InstructionAliases = map[string]_InstructionEncoder {
|
||||
"int3" : alias_INT3,
|
||||
"retq" : Instructions["ret"],
|
||||
"movabsq" : Instructions["movq"],
|
||||
"vcmpeqps" : alias_VCMPEQPS,
|
||||
"vcmptrueps" : alias_VCMPTRUEPS,
|
||||
}
|
691
vendor/github.com/cloudwego/iasm/x86_64/encodings.go
generated
vendored
691
vendor/github.com/cloudwego/iasm/x86_64/encodings.go
generated
vendored
|
@ -1,691 +0,0 @@
|
|||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
`encoding/binary`
|
||||
`math`
|
||||
)
|
||||
|
||||
/** Operand Encoding Helpers **/
|
||||
|
||||
func imml(v interface{}) byte {
|
||||
return byte(toImmAny(v) & 0x0f)
|
||||
}
|
||||
|
||||
func relv(v interface{}) int64 {
|
||||
switch r := v.(type) {
|
||||
case *Label : return 0
|
||||
case RelativeOffset : return int64(r)
|
||||
default : panic("invalid relative offset")
|
||||
}
|
||||
}
|
||||
|
||||
func addr(v interface{}) interface{} {
|
||||
switch a := v.(*MemoryOperand).Addr; a.Type {
|
||||
case Memory : return a.Memory
|
||||
case Offset : return a.Offset
|
||||
case Reference : return a.Reference
|
||||
default : panic("invalid memory operand type")
|
||||
}
|
||||
}
|
||||
|
||||
func bcode(v interface{}) byte {
|
||||
if m, ok := v.(*MemoryOperand); !ok {
|
||||
panic("v is not a memory operand")
|
||||
} else if m.Broadcast == 0 {
|
||||
return 0
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func vcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case XMMRegister : return byte(r)
|
||||
case YMMRegister : return byte(r)
|
||||
case ZMMRegister : return byte(r)
|
||||
case MaskedRegister : return vcode(r.Reg)
|
||||
default : panic("v is not a vector register")
|
||||
}
|
||||
}
|
||||
|
||||
func kcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case KRegister : return byte(r)
|
||||
case XMMRegister : return 0
|
||||
case YMMRegister : return 0
|
||||
case ZMMRegister : return 0
|
||||
case RegisterMask : return byte(r.K)
|
||||
case MaskedRegister : return byte(r.Mask.K)
|
||||
case *MemoryOperand : return toKcodeMem(r)
|
||||
default : panic("v is not a maskable operand")
|
||||
}
|
||||
}
|
||||
|
||||
func zcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case KRegister : return 0
|
||||
case XMMRegister : return 0
|
||||
case YMMRegister : return 0
|
||||
case ZMMRegister : return 0
|
||||
case RegisterMask : return toZcodeRegM(r)
|
||||
case MaskedRegister : return toZcodeRegM(r.Mask)
|
||||
case *MemoryOperand : return toZcodeMem(r)
|
||||
default : panic("v is not a maskable operand")
|
||||
}
|
||||
}
|
||||
|
||||
func lcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return byte(r & 0x07)
|
||||
case Register16 : return byte(r & 0x07)
|
||||
case Register32 : return byte(r & 0x07)
|
||||
case Register64 : return byte(r & 0x07)
|
||||
case KRegister : return byte(r & 0x07)
|
||||
case MMRegister : return byte(r & 0x07)
|
||||
case XMMRegister : return byte(r & 0x07)
|
||||
case YMMRegister : return byte(r & 0x07)
|
||||
case ZMMRegister : return byte(r & 0x07)
|
||||
case MaskedRegister : return lcode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func hcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return byte(r >> 3) & 1
|
||||
case Register16 : return byte(r >> 3) & 1
|
||||
case Register32 : return byte(r >> 3) & 1
|
||||
case Register64 : return byte(r >> 3) & 1
|
||||
case KRegister : return byte(r >> 3) & 1
|
||||
case MMRegister : return byte(r >> 3) & 1
|
||||
case XMMRegister : return byte(r >> 3) & 1
|
||||
case YMMRegister : return byte(r >> 3) & 1
|
||||
case ZMMRegister : return byte(r >> 3) & 1
|
||||
case MaskedRegister : return hcode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func ecode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return byte(r >> 4) & 1
|
||||
case Register16 : return byte(r >> 4) & 1
|
||||
case Register32 : return byte(r >> 4) & 1
|
||||
case Register64 : return byte(r >> 4) & 1
|
||||
case KRegister : return byte(r >> 4) & 1
|
||||
case MMRegister : return byte(r >> 4) & 1
|
||||
case XMMRegister : return byte(r >> 4) & 1
|
||||
case YMMRegister : return byte(r >> 4) & 1
|
||||
case ZMMRegister : return byte(r >> 4) & 1
|
||||
case MaskedRegister : return ecode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func hlcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return toHLcodeReg8(r)
|
||||
case Register16 : return byte(r & 0x0f)
|
||||
case Register32 : return byte(r & 0x0f)
|
||||
case Register64 : return byte(r & 0x0f)
|
||||
case KRegister : return byte(r & 0x0f)
|
||||
case MMRegister : return byte(r & 0x0f)
|
||||
case XMMRegister : return byte(r & 0x0f)
|
||||
case YMMRegister : return byte(r & 0x0f)
|
||||
case ZMMRegister : return byte(r & 0x0f)
|
||||
case MaskedRegister : return hlcode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func ehcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return byte(r >> 3) & 0x03
|
||||
case Register16 : return byte(r >> 3) & 0x03
|
||||
case Register32 : return byte(r >> 3) & 0x03
|
||||
case Register64 : return byte(r >> 3) & 0x03
|
||||
case KRegister : return byte(r >> 3) & 0x03
|
||||
case MMRegister : return byte(r >> 3) & 0x03
|
||||
case XMMRegister : return byte(r >> 3) & 0x03
|
||||
case YMMRegister : return byte(r >> 3) & 0x03
|
||||
case ZMMRegister : return byte(r >> 3) & 0x03
|
||||
case MaskedRegister : return ehcode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func toImmAny(v interface{}) int64 {
|
||||
if x, ok := asInt64(v); ok {
|
||||
return x
|
||||
} else {
|
||||
panic("value is not an integer")
|
||||
}
|
||||
}
|
||||
|
||||
func toHcodeOpt(v interface{}) byte {
|
||||
if v == nil {
|
||||
return 0
|
||||
} else {
|
||||
return hcode(v)
|
||||
}
|
||||
}
|
||||
|
||||
func toEcodeVMM(v interface{}, x byte) byte {
|
||||
switch r := v.(type) {
|
||||
case XMMRegister : return ecode(r)
|
||||
case YMMRegister : return ecode(r)
|
||||
case ZMMRegister : return ecode(r)
|
||||
default : return x
|
||||
}
|
||||
}
|
||||
|
||||
func toKcodeMem(v *MemoryOperand) byte {
|
||||
if !v.Masked {
|
||||
return 0
|
||||
} else {
|
||||
return byte(v.Mask.K)
|
||||
}
|
||||
}
|
||||
|
||||
func toZcodeMem(v *MemoryOperand) byte {
|
||||
if !v.Masked || v.Mask.Z {
|
||||
return 0
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func toZcodeRegM(v RegisterMask) byte {
|
||||
if v.Z {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func toHLcodeReg8(v Register8) byte {
|
||||
switch v {
|
||||
case AH: fallthrough
|
||||
case BH: fallthrough
|
||||
case CH: fallthrough
|
||||
case DH: panic("ah/bh/ch/dh registers never use 4-bit encoding")
|
||||
default: return byte(v & 0x0f)
|
||||
}
|
||||
}
|
||||
|
||||
/** Instruction Encoding Helpers **/
|
||||
|
||||
const (
|
||||
_N_inst = 16
|
||||
)
|
||||
|
||||
const (
|
||||
_F_rel1 = 1 << iota
|
||||
_F_rel4
|
||||
)
|
||||
|
||||
type _Encoding struct {
|
||||
len int
|
||||
flags int
|
||||
bytes [_N_inst]byte
|
||||
encoder func(m *_Encoding, v []interface{})
|
||||
}
|
||||
|
||||
// buf ensures len + n <= len(bytes).
|
||||
func (self *_Encoding) buf(n int) []byte {
|
||||
if i := self.len; i + n > _N_inst {
|
||||
panic("instruction too long")
|
||||
} else {
|
||||
return self.bytes[i:]
|
||||
}
|
||||
}
|
||||
|
||||
// emit encodes a single byte.
|
||||
func (self *_Encoding) emit(v byte) {
|
||||
self.buf(1)[0] = v
|
||||
self.len++
|
||||
}
|
||||
|
||||
// imm1 encodes a single byte immediate value.
|
||||
func (self *_Encoding) imm1(v int64) {
|
||||
self.emit(byte(v))
|
||||
}
|
||||
|
||||
// imm2 encodes a two-byte immediate value in little-endian.
|
||||
func (self *_Encoding) imm2(v int64) {
|
||||
binary.LittleEndian.PutUint16(self.buf(2), uint16(v))
|
||||
self.len += 2
|
||||
}
|
||||
|
||||
// imm4 encodes a 4-byte immediate value in little-endian.
|
||||
func (self *_Encoding) imm4(v int64) {
|
||||
binary.LittleEndian.PutUint32(self.buf(4), uint32(v))
|
||||
self.len += 4
|
||||
}
|
||||
|
||||
// imm8 encodes an 8-byte immediate value in little-endian.
|
||||
func (self *_Encoding) imm8(v int64) {
|
||||
binary.LittleEndian.PutUint64(self.buf(8), uint64(v))
|
||||
self.len += 8
|
||||
}
|
||||
|
||||
// vex2 encodes a 2-byte or 3-byte VEX prefix.
|
||||
//
|
||||
// 2-byte VEX prefix:
|
||||
// Requires: VEX.W = 0, VEX.mmmmm = 0b00001 and VEX.B = VEX.X = 0
|
||||
// +----------------+
|
||||
// Byte 0: | Bits 0-7: 0xc5 |
|
||||
// +----------------+
|
||||
//
|
||||
// +-----------+----------------+----------+--------------+
|
||||
// Byte 1: | Bit 7: ~R | Bits 3-6 ~vvvv | Bit 2: L | Bits 0-1: pp |
|
||||
// +-----------+----------------+----------+--------------+
|
||||
//
|
||||
// 3-byte VEX prefix:
|
||||
// +----------------+
|
||||
// Byte 0: | Bits 0-7: 0xc4 |
|
||||
// +----------------+
|
||||
//
|
||||
// +-----------+-----------+-----------+-------------------+
|
||||
// Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: 0b00001 |
|
||||
// +-----------+-----------+-----------+-------------------+
|
||||
//
|
||||
// +----------+-----------------+----------+--------------+
|
||||
// Byte 2: | Bit 7: 0 | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
|
||||
// +----------+-----------------+----------+--------------+
|
||||
//
|
||||
func (self *_Encoding) vex2(lpp byte, r byte, rm interface{}, vvvv byte) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* VEX.R must be a single-bit mask */
|
||||
if r > 1 {
|
||||
panic("VEX.R must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* VEX.Lpp must be a 3-bit mask */
|
||||
if lpp &^ 0b111 != 0 {
|
||||
panic("VEX.Lpp must be a 3-bit mask")
|
||||
}
|
||||
|
||||
/* VEX.vvvv must be a 4-bit mask */
|
||||
if vvvv &^ 0b1111 != 0 {
|
||||
panic("VEX.vvvv must be a 4-bit mask")
|
||||
}
|
||||
|
||||
/* encode the RM bits if any */
|
||||
if rm != nil {
|
||||
switch v := rm.(type) {
|
||||
case *Label : break
|
||||
case Register : b = hcode(v)
|
||||
case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
}
|
||||
|
||||
/* if VEX.B and VEX.X are zeroes, 2-byte VEX prefix can be used */
|
||||
if x == 0 && b == 0 {
|
||||
self.emit(0xc5)
|
||||
self.emit(0xf8 ^ (r << 7) ^ (vvvv << 3) ^ lpp)
|
||||
} else {
|
||||
self.emit(0xc4)
|
||||
self.emit(0xe1 ^ (r << 7) ^ (x << 6) ^ (b << 5))
|
||||
self.emit(0x78 ^ (vvvv << 3) ^ lpp)
|
||||
}
|
||||
}
|
||||
|
||||
// vex3 encodes a 3-byte VEX or XOP prefix.
|
||||
//
|
||||
// 3-byte VEX/XOP prefix
|
||||
// +-----------------------------------+
|
||||
// Byte 0: | Bits 0-7: 0xc4 (VEX) / 0x8f (XOP) |
|
||||
// +-----------------------------------+
|
||||
//
|
||||
// +-----------+-----------+-----------+-----------------+
|
||||
// Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: mmmmm |
|
||||
// +-----------+-----------+-----------+-----------------+
|
||||
//
|
||||
// +----------+-----------------+----------+--------------+
|
||||
// Byte 2: | Bit 7: W | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
|
||||
// +----------+-----------------+----------+--------------+
|
||||
//
|
||||
func (self *_Encoding) vex3(esc byte, mmmmm byte, wlpp byte, r byte, rm interface{}, vvvv byte) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* VEX.R must be a single-bit mask */
|
||||
if r > 1 {
|
||||
panic("VEX.R must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* VEX.vvvv must be a 4-bit mask */
|
||||
if vvvv &^ 0b1111 != 0 {
|
||||
panic("VEX.vvvv must be a 4-bit mask")
|
||||
}
|
||||
|
||||
/* escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix */
|
||||
if esc != 0xc4 && esc != 0x8f {
|
||||
panic("escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix")
|
||||
}
|
||||
|
||||
/* VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7 */
|
||||
if wlpp &^ 0b10000111 != 0 {
|
||||
panic("VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7")
|
||||
}
|
||||
|
||||
/* VEX.m-mmmm is expected to be a 5-bit mask */
|
||||
if mmmmm &^ 0b11111 != 0 {
|
||||
panic("VEX.m-mmmm is expected to be a 5-bit mask")
|
||||
}
|
||||
|
||||
/* encode the RM bits */
|
||||
switch v := rm.(type) {
|
||||
case *Label : break
|
||||
case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
|
||||
/* encode the 3-byte VEX or XOP prefix */
|
||||
self.emit(esc)
|
||||
self.emit(0xe0 ^ (r << 7) ^ (x << 6) ^ (b << 5) ^ mmmmm)
|
||||
self.emit(0x78 ^ (vvvv << 3) ^ wlpp)
|
||||
}
|
||||
|
||||
// evex encodes a 4-byte EVEX prefix.
|
||||
func (self *_Encoding) evex(mm byte, w1pp byte, ll byte, rr byte, rm interface{}, vvvvv byte, aaa byte, zz byte, bb byte) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* EVEX.b must be a single-bit mask */
|
||||
if bb > 1 {
|
||||
panic("EVEX.b must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.z must be a single-bit mask */
|
||||
if zz > 1 {
|
||||
panic("EVEX.z must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.mm must be a 2-bit mask */
|
||||
if mm &^ 0b11 != 0 {
|
||||
panic("EVEX.mm must be a 2-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.L'L must be a 2-bit mask */
|
||||
if ll &^ 0b11 != 0 {
|
||||
panic("EVEX.L'L must be a 2-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.R'R must be a 2-bit mask */
|
||||
if rr &^ 0b11 != 0 {
|
||||
panic("EVEX.R'R must be a 2-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.aaa must be a 3-bit mask */
|
||||
if aaa &^ 0b111 != 0 {
|
||||
panic("EVEX.aaa must be a 3-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.v'vvvv must be a 5-bit mask */
|
||||
if vvvvv &^ 0b11111 != 0 {
|
||||
panic("EVEX.v'vvvv must be a 5-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7 */
|
||||
if w1pp &^ 0b10000011 != 0b100 {
|
||||
panic("EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7")
|
||||
}
|
||||
|
||||
/* extract bits from EVEX.R'R and EVEX.v'vvvv */
|
||||
r1, r0 := rr >> 1, rr & 1
|
||||
v1, v0 := vvvvv >> 4, vvvvv & 0b1111
|
||||
|
||||
/* encode the RM bits if any */
|
||||
if rm != nil {
|
||||
switch m := rm.(type) {
|
||||
case *Label : break
|
||||
case Register : b, x = hcode(m), ecode(m)
|
||||
case MemoryAddress : b, x, v1 = toHcodeOpt(m.Base), toHcodeOpt(m.Index), toEcodeVMM(m.Index, v1)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
}
|
||||
|
||||
/* EVEX prefix bytes */
|
||||
p0 := (r0 << 7) | (x << 6) | (b << 5) | (r1 << 4) | mm
|
||||
p1 := (v0 << 3) | w1pp
|
||||
p2 := (zz << 7) | (ll << 5) | (b << 4) | (v1 << 3) | aaa
|
||||
|
||||
/* p0: invert RXBR' (bits 4-7)
|
||||
* p1: invert vvvv (bits 3-6)
|
||||
* p2: invert V' (bit 3) */
|
||||
self.emit(0x62)
|
||||
self.emit(p0 ^ 0xf0)
|
||||
self.emit(p1 ^ 0x78)
|
||||
self.emit(p2 ^ 0x08)
|
||||
}
|
||||
|
||||
// rexm encodes a mandatory REX prefix.
|
||||
func (self *_Encoding) rexm(w byte, r byte, rm interface{}) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* REX.R must be 0 or 1 */
|
||||
if r != 0 && r != 1 {
|
||||
panic("REX.R must be 0 or 1")
|
||||
}
|
||||
|
||||
/* REX.W must be 0 or 1 */
|
||||
if w != 0 && w != 1 {
|
||||
panic("REX.W must be 0 or 1")
|
||||
}
|
||||
|
||||
/* encode the RM bits */
|
||||
switch v := rm.(type) {
|
||||
case *Label : break
|
||||
case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
|
||||
/* encode the REX prefix */
|
||||
self.emit(0x40 | (w << 3) | (r << 2) | (x << 1) | b)
|
||||
}
|
||||
|
||||
// rexo encodes an optional REX prefix.
|
||||
func (self *_Encoding) rexo(r byte, rm interface{}, force bool) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* REX.R must be 0 or 1 */
|
||||
if r != 0 && r != 1 {
|
||||
panic("REX.R must be 0 or 1")
|
||||
}
|
||||
|
||||
/* encode the RM bits */
|
||||
switch v := rm.(type) {
|
||||
case *Label : break
|
||||
case Register : b = hcode(v)
|
||||
case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
|
||||
/* if REX.R, REX.X, and REX.B are all zeroes, REX prefix can be omitted */
|
||||
if force || r != 0 || x != 0 || b != 0 {
|
||||
self.emit(0x40 | (r << 2) | (x << 1) | b)
|
||||
}
|
||||
}
|
||||
|
||||
// mrsd encodes ModR/M, SIB and Displacement.
|
||||
//
|
||||
// ModR/M byte
|
||||
// +----------------+---------------+---------------+
|
||||
// | Bits 6-7: Mode | Bits 3-5: Reg | Bits 0-2: R/M |
|
||||
// +----------------+---------------+---------------+
|
||||
//
|
||||
// SIB byte
|
||||
// +-----------------+-----------------+----------------+
|
||||
// | Bits 6-7: Scale | Bits 3-5: Index | Bits 0-2: Base |
|
||||
// +-----------------+-----------------+----------------+
|
||||
//
|
||||
func (self *_Encoding) mrsd(reg byte, rm interface{}, disp8v int32) {
|
||||
var ok bool
|
||||
var mm MemoryAddress
|
||||
var ro RelativeOffset
|
||||
|
||||
/* ModRM encodes the lower 3-bit of the register */
|
||||
if reg > 7 {
|
||||
panic("invalid register bits")
|
||||
}
|
||||
|
||||
/* check the displacement scale */
|
||||
switch disp8v {
|
||||
case 1: break
|
||||
case 2: break
|
||||
case 4: break
|
||||
case 8: break
|
||||
case 16: break
|
||||
case 32: break
|
||||
case 64: break
|
||||
default: panic("invalid displacement size")
|
||||
}
|
||||
|
||||
/* special case: unresolved labels, assuming a zero offset */
|
||||
if _, ok = rm.(*Label); ok {
|
||||
self.emit(0x05 | (reg << 3))
|
||||
self.imm4(0)
|
||||
return
|
||||
}
|
||||
|
||||
/* special case: RIP-relative offset
|
||||
* ModRM.Mode == 0 and ModeRM.R/M == 5 indicates (rip + disp32) addressing */
|
||||
if ro, ok = rm.(RelativeOffset); ok {
|
||||
self.emit(0x05 | (reg << 3))
|
||||
self.imm4(int64(ro))
|
||||
return
|
||||
}
|
||||
|
||||
/* must be a generic memory address */
|
||||
if mm, ok = rm.(MemoryAddress); !ok {
|
||||
panic("rm must be a memory address")
|
||||
}
|
||||
|
||||
/* absolute addressing, encoded as disp(%rbp,%rsp,1) */
|
||||
if mm.Base == nil && mm.Index == nil {
|
||||
self.emit(0x04 | (reg << 3))
|
||||
self.emit(0x25)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
return
|
||||
}
|
||||
|
||||
/* no SIB byte */
|
||||
if mm.Index == nil && lcode(mm.Base) != 0b100 {
|
||||
cc := lcode(mm.Base)
|
||||
dv := mm.Displacement
|
||||
|
||||
/* ModRM.Mode == 0 (no displacement) */
|
||||
if dv == 0 && mm.Base != RBP && mm.Base != R13 {
|
||||
if cc == 0b101 {
|
||||
panic("rbp/r13 is not encodable as a base register (interpreted as disp32 address)")
|
||||
} else {
|
||||
self.emit((reg << 3) | cc)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 1 (8-bit displacement) */
|
||||
if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv % disp8v == 0 {
|
||||
self.emit(0x40 | (reg << 3) | cc)
|
||||
self.imm1(int64(dq))
|
||||
return
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 2 (32-bit displacement) */
|
||||
self.emit(0x80 | (reg << 3) | cc)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
return
|
||||
}
|
||||
|
||||
/* all encodings below use ModRM.R/M = 4 (0b100) to indicate the presence of SIB */
|
||||
if mm.Index == RSP {
|
||||
panic("rsp is not encodable as an index register (interpreted as no index)")
|
||||
}
|
||||
|
||||
/* index = 4 (0b100) denotes no-index encoding */
|
||||
var scale byte
|
||||
var index byte = 0x04
|
||||
|
||||
/* encode the scale byte */
|
||||
if mm.Scale != 0 {
|
||||
switch mm.Scale {
|
||||
case 1 : scale = 0
|
||||
case 2 : scale = 1
|
||||
case 4 : scale = 2
|
||||
case 8 : scale = 3
|
||||
default : panic("invalid scale value")
|
||||
}
|
||||
}
|
||||
|
||||
/* encode the index byte */
|
||||
if mm.Index != nil {
|
||||
index = lcode(mm.Index)
|
||||
}
|
||||
|
||||
/* SIB.Base = 5 (0b101) and ModRM.Mode = 0 indicates no-base encoding with disp32 */
|
||||
if mm.Base == nil {
|
||||
self.emit((reg << 3) | 0b100)
|
||||
self.emit((scale << 6) | (index << 3) | 0b101)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
return
|
||||
}
|
||||
|
||||
/* base L-code & displacement value */
|
||||
cc := lcode(mm.Base)
|
||||
dv := mm.Displacement
|
||||
|
||||
/* ModRM.Mode == 0 (no displacement) */
|
||||
if dv == 0 && cc != 0b101 {
|
||||
self.emit((reg << 3) | 0b100)
|
||||
self.emit((scale << 6) | (index << 3) | cc)
|
||||
return
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 1 (8-bit displacement) */
|
||||
if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv % disp8v == 0 {
|
||||
self.emit(0x44 | (reg << 3))
|
||||
self.emit((scale << 6) | (index << 3) | cc)
|
||||
self.imm1(int64(dq))
|
||||
return
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 2 (32-bit displacement) */
|
||||
self.emit(0x84 | (reg << 3))
|
||||
self.emit((scale << 6) | (index << 3) | cc)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
}
|
||||
|
||||
// encode invokes the encoder to encode this instruction.
|
||||
func (self *_Encoding) encode(v []interface{}) int {
|
||||
self.len = 0
|
||||
self.encoder(self, v)
|
||||
return self.len
|
||||
}
|
97210
vendor/github.com/cloudwego/iasm/x86_64/instructions.go
generated
vendored
97210
vendor/github.com/cloudwego/iasm/x86_64/instructions.go
generated
vendored
File diff suppressed because it is too large
Load diff
12307
vendor/github.com/cloudwego/iasm/x86_64/instructions_table.go
generated
vendored
12307
vendor/github.com/cloudwego/iasm/x86_64/instructions_table.go
generated
vendored
File diff suppressed because it is too large
Load diff
693
vendor/github.com/cloudwego/iasm/x86_64/registers.go
generated
vendored
693
vendor/github.com/cloudwego/iasm/x86_64/registers.go
generated
vendored
|
@ -1,693 +0,0 @@
|
|||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
)
|
||||
|
||||
// Register represents a hardware register.
|
||||
type Register interface {
|
||||
fmt.Stringer
|
||||
implRegister()
|
||||
}
|
||||
|
||||
type (
|
||||
Register8 byte
|
||||
Register16 byte
|
||||
Register32 byte
|
||||
Register64 byte
|
||||
)
|
||||
|
||||
type (
|
||||
KRegister byte
|
||||
MMRegister byte
|
||||
XMMRegister byte
|
||||
YMMRegister byte
|
||||
ZMMRegister byte
|
||||
)
|
||||
|
||||
// RegisterMask is a KRegister used to mask another register.
|
||||
type RegisterMask struct {
|
||||
Z bool
|
||||
K KRegister
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self RegisterMask) String() string {
|
||||
if !self.Z {
|
||||
return fmt.Sprintf("{%%%s}", self.K)
|
||||
} else {
|
||||
return fmt.Sprintf("{%%%s}{z}", self.K)
|
||||
}
|
||||
}
|
||||
|
||||
// MaskedRegister is a Register masked by a RegisterMask.
|
||||
type MaskedRegister struct {
|
||||
Reg Register
|
||||
Mask RegisterMask
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self MaskedRegister) String() string {
|
||||
return self.Reg.String() + self.Mask.String()
|
||||
}
|
||||
|
||||
const (
|
||||
AL Register8 = iota
|
||||
CL
|
||||
DL
|
||||
BL
|
||||
SPL
|
||||
BPL
|
||||
SIL
|
||||
DIL
|
||||
R8b
|
||||
R9b
|
||||
R10b
|
||||
R11b
|
||||
R12b
|
||||
R13b
|
||||
R14b
|
||||
R15b
|
||||
)
|
||||
|
||||
const (
|
||||
AH = SPL | 0x80
|
||||
CH = BPL | 0x80
|
||||
DH = SIL | 0x80
|
||||
BH = DIL | 0x80
|
||||
)
|
||||
|
||||
const (
|
||||
AX Register16 = iota
|
||||
CX
|
||||
DX
|
||||
BX
|
||||
SP
|
||||
BP
|
||||
SI
|
||||
DI
|
||||
R8w
|
||||
R9w
|
||||
R10w
|
||||
R11w
|
||||
R12w
|
||||
R13w
|
||||
R14w
|
||||
R15w
|
||||
)
|
||||
|
||||
const (
|
||||
EAX Register32 = iota
|
||||
ECX
|
||||
EDX
|
||||
EBX
|
||||
ESP
|
||||
EBP
|
||||
ESI
|
||||
EDI
|
||||
R8d
|
||||
R9d
|
||||
R10d
|
||||
R11d
|
||||
R12d
|
||||
R13d
|
||||
R14d
|
||||
R15d
|
||||
)
|
||||
|
||||
const (
|
||||
RAX Register64 = iota
|
||||
RCX
|
||||
RDX
|
||||
RBX
|
||||
RSP
|
||||
RBP
|
||||
RSI
|
||||
RDI
|
||||
R8
|
||||
R9
|
||||
R10
|
||||
R11
|
||||
R12
|
||||
R13
|
||||
R14
|
||||
R15
|
||||
)
|
||||
|
||||
const (
|
||||
K0 KRegister = iota
|
||||
K1
|
||||
K2
|
||||
K3
|
||||
K4
|
||||
K5
|
||||
K6
|
||||
K7
|
||||
)
|
||||
|
||||
const (
|
||||
MM0 MMRegister = iota
|
||||
MM1
|
||||
MM2
|
||||
MM3
|
||||
MM4
|
||||
MM5
|
||||
MM6
|
||||
MM7
|
||||
)
|
||||
|
||||
const (
|
||||
XMM0 XMMRegister = iota
|
||||
XMM1
|
||||
XMM2
|
||||
XMM3
|
||||
XMM4
|
||||
XMM5
|
||||
XMM6
|
||||
XMM7
|
||||
XMM8
|
||||
XMM9
|
||||
XMM10
|
||||
XMM11
|
||||
XMM12
|
||||
XMM13
|
||||
XMM14
|
||||
XMM15
|
||||
XMM16
|
||||
XMM17
|
||||
XMM18
|
||||
XMM19
|
||||
XMM20
|
||||
XMM21
|
||||
XMM22
|
||||
XMM23
|
||||
XMM24
|
||||
XMM25
|
||||
XMM26
|
||||
XMM27
|
||||
XMM28
|
||||
XMM29
|
||||
XMM30
|
||||
XMM31
|
||||
)
|
||||
|
||||
const (
|
||||
YMM0 YMMRegister = iota
|
||||
YMM1
|
||||
YMM2
|
||||
YMM3
|
||||
YMM4
|
||||
YMM5
|
||||
YMM6
|
||||
YMM7
|
||||
YMM8
|
||||
YMM9
|
||||
YMM10
|
||||
YMM11
|
||||
YMM12
|
||||
YMM13
|
||||
YMM14
|
||||
YMM15
|
||||
YMM16
|
||||
YMM17
|
||||
YMM18
|
||||
YMM19
|
||||
YMM20
|
||||
YMM21
|
||||
YMM22
|
||||
YMM23
|
||||
YMM24
|
||||
YMM25
|
||||
YMM26
|
||||
YMM27
|
||||
YMM28
|
||||
YMM29
|
||||
YMM30
|
||||
YMM31
|
||||
)
|
||||
|
||||
const (
|
||||
ZMM0 ZMMRegister = iota
|
||||
ZMM1
|
||||
ZMM2
|
||||
ZMM3
|
||||
ZMM4
|
||||
ZMM5
|
||||
ZMM6
|
||||
ZMM7
|
||||
ZMM8
|
||||
ZMM9
|
||||
ZMM10
|
||||
ZMM11
|
||||
ZMM12
|
||||
ZMM13
|
||||
ZMM14
|
||||
ZMM15
|
||||
ZMM16
|
||||
ZMM17
|
||||
ZMM18
|
||||
ZMM19
|
||||
ZMM20
|
||||
ZMM21
|
||||
ZMM22
|
||||
ZMM23
|
||||
ZMM24
|
||||
ZMM25
|
||||
ZMM26
|
||||
ZMM27
|
||||
ZMM28
|
||||
ZMM29
|
||||
ZMM30
|
||||
ZMM31
|
||||
)
|
||||
|
||||
func (self Register8) implRegister() {}
|
||||
func (self Register16) implRegister() {}
|
||||
func (self Register32) implRegister() {}
|
||||
func (self Register64) implRegister() {}
|
||||
|
||||
func (self KRegister) implRegister() {}
|
||||
func (self MMRegister) implRegister() {}
|
||||
func (self XMMRegister) implRegister() {}
|
||||
func (self YMMRegister) implRegister() {}
|
||||
func (self ZMMRegister) implRegister() {}
|
||||
|
||||
func (self Register8) String() string { if int(self) >= len(r8names) { return "???" } else { return r8names[self] } }
|
||||
func (self Register16) String() string { if int(self) >= len(r16names) { return "???" } else { return r16names[self] } }
|
||||
func (self Register32) String() string { if int(self) >= len(r32names) { return "???" } else { return r32names[self] } }
|
||||
func (self Register64) String() string { if int(self) >= len(r64names) { return "???" } else { return r64names[self] } }
|
||||
|
||||
func (self KRegister) String() string { if int(self) >= len(knames) { return "???" } else { return knames[self] } }
|
||||
func (self MMRegister) String() string { if int(self) >= len(mmnames) { return "???" } else { return mmnames[self] } }
|
||||
func (self XMMRegister) String() string { if int(self) >= len(xmmnames) { return "???" } else { return xmmnames[self] } }
|
||||
func (self YMMRegister) String() string { if int(self) >= len(ymmnames) { return "???" } else { return ymmnames[self] } }
|
||||
func (self ZMMRegister) String() string { if int(self) >= len(zmmnames) { return "???" } else { return zmmnames[self] } }
|
||||
|
||||
// Registers maps register name into Register instances.
|
||||
var Registers = map[string]Register {
|
||||
"al" : AL,
|
||||
"cl" : CL,
|
||||
"dl" : DL,
|
||||
"bl" : BL,
|
||||
"spl" : SPL,
|
||||
"bpl" : BPL,
|
||||
"sil" : SIL,
|
||||
"dil" : DIL,
|
||||
"r8b" : R8b,
|
||||
"r9b" : R9b,
|
||||
"r10b" : R10b,
|
||||
"r11b" : R11b,
|
||||
"r12b" : R12b,
|
||||
"r13b" : R13b,
|
||||
"r14b" : R14b,
|
||||
"r15b" : R15b,
|
||||
"ah" : AH,
|
||||
"ch" : CH,
|
||||
"dh" : DH,
|
||||
"bh" : BH,
|
||||
"ax" : AX,
|
||||
"cx" : CX,
|
||||
"dx" : DX,
|
||||
"bx" : BX,
|
||||
"sp" : SP,
|
||||
"bp" : BP,
|
||||
"si" : SI,
|
||||
"di" : DI,
|
||||
"r8w" : R8w,
|
||||
"r9w" : R9w,
|
||||
"r10w" : R10w,
|
||||
"r11w" : R11w,
|
||||
"r12w" : R12w,
|
||||
"r13w" : R13w,
|
||||
"r14w" : R14w,
|
||||
"r15w" : R15w,
|
||||
"eax" : EAX,
|
||||
"ecx" : ECX,
|
||||
"edx" : EDX,
|
||||
"ebx" : EBX,
|
||||
"esp" : ESP,
|
||||
"ebp" : EBP,
|
||||
"esi" : ESI,
|
||||
"edi" : EDI,
|
||||
"r8d" : R8d,
|
||||
"r9d" : R9d,
|
||||
"r10d" : R10d,
|
||||
"r11d" : R11d,
|
||||
"r12d" : R12d,
|
||||
"r13d" : R13d,
|
||||
"r14d" : R14d,
|
||||
"r15d" : R15d,
|
||||
"rax" : RAX,
|
||||
"rcx" : RCX,
|
||||
"rdx" : RDX,
|
||||
"rbx" : RBX,
|
||||
"rsp" : RSP,
|
||||
"rbp" : RBP,
|
||||
"rsi" : RSI,
|
||||
"rdi" : RDI,
|
||||
"r8" : R8,
|
||||
"r9" : R9,
|
||||
"r10" : R10,
|
||||
"r11" : R11,
|
||||
"r12" : R12,
|
||||
"r13" : R13,
|
||||
"r14" : R14,
|
||||
"r15" : R15,
|
||||
"k0" : K0,
|
||||
"k1" : K1,
|
||||
"k2" : K2,
|
||||
"k3" : K3,
|
||||
"k4" : K4,
|
||||
"k5" : K5,
|
||||
"k6" : K6,
|
||||
"k7" : K7,
|
||||
"mm0" : MM0,
|
||||
"mm1" : MM1,
|
||||
"mm2" : MM2,
|
||||
"mm3" : MM3,
|
||||
"mm4" : MM4,
|
||||
"mm5" : MM5,
|
||||
"mm6" : MM6,
|
||||
"mm7" : MM7,
|
||||
"xmm0" : XMM0,
|
||||
"xmm1" : XMM1,
|
||||
"xmm2" : XMM2,
|
||||
"xmm3" : XMM3,
|
||||
"xmm4" : XMM4,
|
||||
"xmm5" : XMM5,
|
||||
"xmm6" : XMM6,
|
||||
"xmm7" : XMM7,
|
||||
"xmm8" : XMM8,
|
||||
"xmm9" : XMM9,
|
||||
"xmm10" : XMM10,
|
||||
"xmm11" : XMM11,
|
||||
"xmm12" : XMM12,
|
||||
"xmm13" : XMM13,
|
||||
"xmm14" : XMM14,
|
||||
"xmm15" : XMM15,
|
||||
"xmm16" : XMM16,
|
||||
"xmm17" : XMM17,
|
||||
"xmm18" : XMM18,
|
||||
"xmm19" : XMM19,
|
||||
"xmm20" : XMM20,
|
||||
"xmm21" : XMM21,
|
||||
"xmm22" : XMM22,
|
||||
"xmm23" : XMM23,
|
||||
"xmm24" : XMM24,
|
||||
"xmm25" : XMM25,
|
||||
"xmm26" : XMM26,
|
||||
"xmm27" : XMM27,
|
||||
"xmm28" : XMM28,
|
||||
"xmm29" : XMM29,
|
||||
"xmm30" : XMM30,
|
||||
"xmm31" : XMM31,
|
||||
"ymm0" : YMM0,
|
||||
"ymm1" : YMM1,
|
||||
"ymm2" : YMM2,
|
||||
"ymm3" : YMM3,
|
||||
"ymm4" : YMM4,
|
||||
"ymm5" : YMM5,
|
||||
"ymm6" : YMM6,
|
||||
"ymm7" : YMM7,
|
||||
"ymm8" : YMM8,
|
||||
"ymm9" : YMM9,
|
||||
"ymm10" : YMM10,
|
||||
"ymm11" : YMM11,
|
||||
"ymm12" : YMM12,
|
||||
"ymm13" : YMM13,
|
||||
"ymm14" : YMM14,
|
||||
"ymm15" : YMM15,
|
||||
"ymm16" : YMM16,
|
||||
"ymm17" : YMM17,
|
||||
"ymm18" : YMM18,
|
||||
"ymm19" : YMM19,
|
||||
"ymm20" : YMM20,
|
||||
"ymm21" : YMM21,
|
||||
"ymm22" : YMM22,
|
||||
"ymm23" : YMM23,
|
||||
"ymm24" : YMM24,
|
||||
"ymm25" : YMM25,
|
||||
"ymm26" : YMM26,
|
||||
"ymm27" : YMM27,
|
||||
"ymm28" : YMM28,
|
||||
"ymm29" : YMM29,
|
||||
"ymm30" : YMM30,
|
||||
"ymm31" : YMM31,
|
||||
"zmm0" : ZMM0,
|
||||
"zmm1" : ZMM1,
|
||||
"zmm2" : ZMM2,
|
||||
"zmm3" : ZMM3,
|
||||
"zmm4" : ZMM4,
|
||||
"zmm5" : ZMM5,
|
||||
"zmm6" : ZMM6,
|
||||
"zmm7" : ZMM7,
|
||||
"zmm8" : ZMM8,
|
||||
"zmm9" : ZMM9,
|
||||
"zmm10" : ZMM10,
|
||||
"zmm11" : ZMM11,
|
||||
"zmm12" : ZMM12,
|
||||
"zmm13" : ZMM13,
|
||||
"zmm14" : ZMM14,
|
||||
"zmm15" : ZMM15,
|
||||
"zmm16" : ZMM16,
|
||||
"zmm17" : ZMM17,
|
||||
"zmm18" : ZMM18,
|
||||
"zmm19" : ZMM19,
|
||||
"zmm20" : ZMM20,
|
||||
"zmm21" : ZMM21,
|
||||
"zmm22" : ZMM22,
|
||||
"zmm23" : ZMM23,
|
||||
"zmm24" : ZMM24,
|
||||
"zmm25" : ZMM25,
|
||||
"zmm26" : ZMM26,
|
||||
"zmm27" : ZMM27,
|
||||
"zmm28" : ZMM28,
|
||||
"zmm29" : ZMM29,
|
||||
"zmm30" : ZMM30,
|
||||
"zmm31" : ZMM31,
|
||||
}
|
||||
|
||||
/** Register Name Tables **/
|
||||
|
||||
var r8names = [...]string {
|
||||
AL : "al",
|
||||
CL : "cl",
|
||||
DL : "dl",
|
||||
BL : "bl",
|
||||
SPL : "spl",
|
||||
BPL : "bpl",
|
||||
SIL : "sil",
|
||||
DIL : "dil",
|
||||
R8b : "r8b",
|
||||
R9b : "r9b",
|
||||
R10b : "r10b",
|
||||
R11b : "r11b",
|
||||
R12b : "r12b",
|
||||
R13b : "r13b",
|
||||
R14b : "r14b",
|
||||
R15b : "r15b",
|
||||
AH : "ah",
|
||||
CH : "ch",
|
||||
DH : "dh",
|
||||
BH : "bh",
|
||||
}
|
||||
|
||||
var r16names = [...]string {
|
||||
AX : "ax",
|
||||
CX : "cx",
|
||||
DX : "dx",
|
||||
BX : "bx",
|
||||
SP : "sp",
|
||||
BP : "bp",
|
||||
SI : "si",
|
||||
DI : "di",
|
||||
R8w : "r8w",
|
||||
R9w : "r9w",
|
||||
R10w : "r10w",
|
||||
R11w : "r11w",
|
||||
R12w : "r12w",
|
||||
R13w : "r13w",
|
||||
R14w : "r14w",
|
||||
R15w : "r15w",
|
||||
}
|
||||
|
||||
var r32names = [...]string {
|
||||
EAX : "eax",
|
||||
ECX : "ecx",
|
||||
EDX : "edx",
|
||||
EBX : "ebx",
|
||||
ESP : "esp",
|
||||
EBP : "ebp",
|
||||
ESI : "esi",
|
||||
EDI : "edi",
|
||||
R8d : "r8d",
|
||||
R9d : "r9d",
|
||||
R10d : "r10d",
|
||||
R11d : "r11d",
|
||||
R12d : "r12d",
|
||||
R13d : "r13d",
|
||||
R14d : "r14d",
|
||||
R15d : "r15d",
|
||||
}
|
||||
|
||||
var r64names = [...]string {
|
||||
RAX : "rax",
|
||||
RCX : "rcx",
|
||||
RDX : "rdx",
|
||||
RBX : "rbx",
|
||||
RSP : "rsp",
|
||||
RBP : "rbp",
|
||||
RSI : "rsi",
|
||||
RDI : "rdi",
|
||||
R8 : "r8",
|
||||
R9 : "r9",
|
||||
R10 : "r10",
|
||||
R11 : "r11",
|
||||
R12 : "r12",
|
||||
R13 : "r13",
|
||||
R14 : "r14",
|
||||
R15 : "r15",
|
||||
}
|
||||
|
||||
var knames = [...]string {
|
||||
K0: "k0",
|
||||
K1: "k1",
|
||||
K2: "k2",
|
||||
K3: "k3",
|
||||
K4: "k4",
|
||||
K5: "k5",
|
||||
K6: "k6",
|
||||
K7: "k7",
|
||||
}
|
||||
|
||||
var mmnames = [...]string {
|
||||
MM0: "mm0",
|
||||
MM1: "mm1",
|
||||
MM2: "mm2",
|
||||
MM3: "mm3",
|
||||
MM4: "mm4",
|
||||
MM5: "mm5",
|
||||
MM6: "mm6",
|
||||
MM7: "mm7",
|
||||
}
|
||||
|
||||
var xmmnames = [...]string {
|
||||
XMM0 : "xmm0",
|
||||
XMM1 : "xmm1",
|
||||
XMM2 : "xmm2",
|
||||
XMM3 : "xmm3",
|
||||
XMM4 : "xmm4",
|
||||
XMM5 : "xmm5",
|
||||
XMM6 : "xmm6",
|
||||
XMM7 : "xmm7",
|
||||
XMM8 : "xmm8",
|
||||
XMM9 : "xmm9",
|
||||
XMM10 : "xmm10",
|
||||
XMM11 : "xmm11",
|
||||
XMM12 : "xmm12",
|
||||
XMM13 : "xmm13",
|
||||
XMM14 : "xmm14",
|
||||
XMM15 : "xmm15",
|
||||
XMM16 : "xmm16",
|
||||
XMM17 : "xmm17",
|
||||
XMM18 : "xmm18",
|
||||
XMM19 : "xmm19",
|
||||
XMM20 : "xmm20",
|
||||
XMM21 : "xmm21",
|
||||
XMM22 : "xmm22",
|
||||
XMM23 : "xmm23",
|
||||
XMM24 : "xmm24",
|
||||
XMM25 : "xmm25",
|
||||
XMM26 : "xmm26",
|
||||
XMM27 : "xmm27",
|
||||
XMM28 : "xmm28",
|
||||
XMM29 : "xmm29",
|
||||
XMM30 : "xmm30",
|
||||
XMM31 : "xmm31",
|
||||
}
|
||||
|
||||
var ymmnames = [...]string {
|
||||
YMM0 : "ymm0",
|
||||
YMM1 : "ymm1",
|
||||
YMM2 : "ymm2",
|
||||
YMM3 : "ymm3",
|
||||
YMM4 : "ymm4",
|
||||
YMM5 : "ymm5",
|
||||
YMM6 : "ymm6",
|
||||
YMM7 : "ymm7",
|
||||
YMM8 : "ymm8",
|
||||
YMM9 : "ymm9",
|
||||
YMM10 : "ymm10",
|
||||
YMM11 : "ymm11",
|
||||
YMM12 : "ymm12",
|
||||
YMM13 : "ymm13",
|
||||
YMM14 : "ymm14",
|
||||
YMM15 : "ymm15",
|
||||
YMM16 : "ymm16",
|
||||
YMM17 : "ymm17",
|
||||
YMM18 : "ymm18",
|
||||
YMM19 : "ymm19",
|
||||
YMM20 : "ymm20",
|
||||
YMM21 : "ymm21",
|
||||
YMM22 : "ymm22",
|
||||
YMM23 : "ymm23",
|
||||
YMM24 : "ymm24",
|
||||
YMM25 : "ymm25",
|
||||
YMM26 : "ymm26",
|
||||
YMM27 : "ymm27",
|
||||
YMM28 : "ymm28",
|
||||
YMM29 : "ymm29",
|
||||
YMM30 : "ymm30",
|
||||
YMM31 : "ymm31",
|
||||
}
|
||||
|
||||
var zmmnames = [...]string {
|
||||
ZMM0 : "zmm0",
|
||||
ZMM1 : "zmm1",
|
||||
ZMM2 : "zmm2",
|
||||
ZMM3 : "zmm3",
|
||||
ZMM4 : "zmm4",
|
||||
ZMM5 : "zmm5",
|
||||
ZMM6 : "zmm6",
|
||||
ZMM7 : "zmm7",
|
||||
ZMM8 : "zmm8",
|
||||
ZMM9 : "zmm9",
|
||||
ZMM10 : "zmm10",
|
||||
ZMM11 : "zmm11",
|
||||
ZMM12 : "zmm12",
|
||||
ZMM13 : "zmm13",
|
||||
ZMM14 : "zmm14",
|
||||
ZMM15 : "zmm15",
|
||||
ZMM16 : "zmm16",
|
||||
ZMM17 : "zmm17",
|
||||
ZMM18 : "zmm18",
|
||||
ZMM19 : "zmm19",
|
||||
ZMM20 : "zmm20",
|
||||
ZMM21 : "zmm21",
|
||||
ZMM22 : "zmm22",
|
||||
ZMM23 : "zmm23",
|
||||
ZMM24 : "zmm24",
|
||||
ZMM25 : "zmm25",
|
||||
ZMM26 : "zmm26",
|
||||
ZMM27 : "zmm27",
|
||||
ZMM28 : "zmm28",
|
||||
ZMM29 : "zmm29",
|
||||
ZMM30 : "zmm30",
|
||||
ZMM31 : "zmm31",
|
||||
}
|
147
vendor/github.com/cloudwego/iasm/x86_64/utils.go
generated
vendored
147
vendor/github.com/cloudwego/iasm/x86_64/utils.go
generated
vendored
|
@ -1,147 +0,0 @@
|
|||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
`encoding/binary`
|
||||
`errors`
|
||||
`reflect`
|
||||
`strconv`
|
||||
`unicode/utf8`
|
||||
`unsafe`
|
||||
)
|
||||
|
||||
const (
|
||||
_CC_digit = 1 << iota
|
||||
_CC_ident
|
||||
_CC_ident0
|
||||
_CC_number
|
||||
)
|
||||
|
||||
func ispow2(v uint64) bool {
|
||||
return (v & (v - 1)) == 0
|
||||
}
|
||||
|
||||
func isdigit(cc rune) bool {
|
||||
return '0' <= cc && cc <= '9'
|
||||
}
|
||||
|
||||
func isalpha(cc rune) bool {
|
||||
return (cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z')
|
||||
}
|
||||
|
||||
func isident(cc rune) bool {
|
||||
return cc == '_' || isalpha(cc) || isdigit(cc)
|
||||
}
|
||||
|
||||
func isident0(cc rune) bool {
|
||||
return cc == '_' || isalpha(cc)
|
||||
}
|
||||
|
||||
func isnumber(cc rune) bool {
|
||||
return (cc == 'b' || cc == 'B') ||
|
||||
(cc == 'o' || cc == 'O') ||
|
||||
(cc == 'x' || cc == 'X') ||
|
||||
(cc >= '0' && cc <= '9') ||
|
||||
(cc >= 'a' && cc <= 'f') ||
|
||||
(cc >= 'A' && cc <= 'F')
|
||||
}
|
||||
|
||||
func align(v int, n int) int {
|
||||
return (((v - 1) >> n) + 1) << n
|
||||
}
|
||||
|
||||
func append8(m *[]byte, v byte) {
|
||||
*m = append(*m, v)
|
||||
}
|
||||
|
||||
func append16(m *[]byte, v uint16) {
|
||||
p := len(*m)
|
||||
*m = append(*m, 0, 0)
|
||||
binary.LittleEndian.PutUint16((*m)[p:], v)
|
||||
}
|
||||
|
||||
func append32(m *[]byte, v uint32) {
|
||||
p := len(*m)
|
||||
*m = append(*m, 0, 0, 0, 0)
|
||||
binary.LittleEndian.PutUint32((*m)[p:], v)
|
||||
}
|
||||
|
||||
func append64(m *[]byte, v uint64) {
|
||||
p := len(*m)
|
||||
*m = append(*m, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
binary.LittleEndian.PutUint64((*m)[p:], v)
|
||||
}
|
||||
|
||||
func expandmm(m *[]byte, n int, v byte) {
|
||||
sl := (*_GoSlice)(unsafe.Pointer(m))
|
||||
nb := sl.len + n
|
||||
|
||||
/* grow as needed */
|
||||
if nb > cap(*m) {
|
||||
*m = growslice(byteType, *m, nb)
|
||||
}
|
||||
|
||||
/* fill the new area */
|
||||
memset(unsafe.Pointer(uintptr(sl.ptr) + uintptr(sl.len)), v, uintptr(n))
|
||||
sl.len = nb
|
||||
}
|
||||
|
||||
func memset(p unsafe.Pointer, c byte, n uintptr) {
|
||||
if c != 0 {
|
||||
memsetv(p, c, n)
|
||||
} else {
|
||||
memclrNoHeapPointers(p, n)
|
||||
}
|
||||
}
|
||||
|
||||
func memsetv(p unsafe.Pointer, c byte, n uintptr) {
|
||||
for i := uintptr(0); i < n; i++ {
|
||||
*(*byte)(unsafe.Pointer(uintptr(p) + i)) = c
|
||||
}
|
||||
}
|
||||
|
||||
func literal64(v string) (uint64, error) {
|
||||
var nb int
|
||||
var ch rune
|
||||
var ex error
|
||||
var mm [12]byte
|
||||
|
||||
/* unquote the runes */
|
||||
for v != "" {
|
||||
if ch, _, v, ex = strconv.UnquoteChar(v, '\''); ex != nil {
|
||||
return 0, ex
|
||||
} else if nb += utf8.EncodeRune(mm[nb:], ch); nb > 8 {
|
||||
return 0, errors.New("multi-char constant too large")
|
||||
}
|
||||
}
|
||||
|
||||
/* convert to uint64 */
|
||||
return *(*uint64)(unsafe.Pointer(&mm)), nil
|
||||
}
|
||||
|
||||
var (
|
||||
byteWrap = reflect.TypeOf(byte(0))
|
||||
byteType = (*_GoType)(efaceOf(byteWrap).ptr)
|
||||
)
|
||||
|
||||
//go:linkname growslice runtime.growslice
|
||||
func growslice(_ *_GoType, _ []byte, _ int) []byte
|
||||
|
||||
//go:noescape
|
||||
//go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
|
||||
func memclrNoHeapPointers(_ unsafe.Pointer, _ uintptr)
|
11
vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go
generated
vendored
11
vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go
generated
vendored
|
@ -52,10 +52,15 @@ func InstallShieldCab(raw []byte, _ uint32) bool {
|
|||
}
|
||||
|
||||
// Zstd matches a Zstandard archive file.
|
||||
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md
|
||||
func Zstd(raw []byte, limit uint32) bool {
|
||||
return len(raw) >= 4 &&
|
||||
(0x22 <= raw[0] && raw[0] <= 0x28 || raw[0] == 0x1E) && // Different Zstandard versions.
|
||||
bytes.HasPrefix(raw[1:], []byte{0xB5, 0x2F, 0xFD})
|
||||
if len(raw) < 4 {
|
||||
return false
|
||||
}
|
||||
sig := binary.LittleEndian.Uint32(raw)
|
||||
// Check for Zstandard frames and skippable frames.
|
||||
return (sig >= 0xFD2FB522 && sig <= 0xFD2FB528) ||
|
||||
(sig >= 0x184D2A50 && sig <= 0x184D2A5F)
|
||||
}
|
||||
|
||||
// CRX matches a Chrome extension file: a zip archive prepended by a package header.
|
||||
|
|
19
vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go
generated
vendored
19
vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go
generated
vendored
|
@ -110,3 +110,22 @@ func zipContains(raw, sig []byte, msoCheck bool) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// APK matches an Android Package Archive.
|
||||
// The source of signatures is https://github.com/file/file/blob/1778642b8ba3d947a779a36fcd81f8e807220a19/magic/Magdir/archive#L1820-L1887
|
||||
func APK(raw []byte, _ uint32) bool {
|
||||
apkSignatures := [][]byte{
|
||||
[]byte("AndroidManifest.xml"),
|
||||
[]byte("META-INF/com/android/build/gradle/app-metadata.properties"),
|
||||
[]byte("classes.dex"),
|
||||
[]byte("resources.arsc"),
|
||||
[]byte("res/drawable"),
|
||||
}
|
||||
for _, sig := range apkSignatures {
|
||||
if zipContains(raw, sig, false) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
3
vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md
generated
vendored
3
vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
## 177 Supported MIME types
|
||||
## 178 Supported MIME types
|
||||
This file is automatically generated when running tests. Do not edit manually.
|
||||
|
||||
Extension | MIME type | Aliases
|
||||
|
@ -11,6 +11,7 @@ Extension | MIME type | Aliases
|
|||
**.docx** | application/vnd.openxmlformats-officedocument.wordprocessingml.document | -
|
||||
**.pptx** | application/vnd.openxmlformats-officedocument.presentationml.presentation | -
|
||||
**.epub** | application/epub+zip | -
|
||||
**.apk** | application/vnd.android.package-archive | -
|
||||
**.jar** | application/jar | -
|
||||
**.odt** | application/vnd.oasis.opendocument.text | application/x-vnd.oasis.opendocument.text
|
||||
**.ott** | application/vnd.oasis.opendocument.text-template | application/x-vnd.oasis.opendocument.text-template
|
||||
|
|
7
vendor/github.com/gabriel-vasile/mimetype/tree.go
generated
vendored
7
vendor/github.com/gabriel-vasile/mimetype/tree.go
generated
vendored
|
@ -44,7 +44,11 @@ func([]byte, uint32) bool { return true },
|
|||
"application/gzip-compressed", "application/x-gzip-compressed",
|
||||
"gzip/document")
|
||||
sevenZ = newMIME("application/x-7z-compressed", ".7z", magic.SevenZ)
|
||||
zip = newMIME("application/zip", ".zip", magic.Zip, xlsx, docx, pptx, epub, jar, odt, ods, odp, odg, odf, odc, sxc).
|
||||
// APK must be checked before JAR because APK is a subset of JAR.
|
||||
// This means APK should be a child of JAR detector, but in practice,
|
||||
// the decisive signature for JAR might be located at the end of the file
|
||||
// and not reachable because of library readLimit.
|
||||
zip = newMIME("application/zip", ".zip", magic.Zip, xlsx, docx, pptx, epub, apk, jar, odt, ods, odp, odg, odf, odc, sxc).
|
||||
alias("application/x-zip", "application/x-zip-compressed")
|
||||
tar = newMIME("application/x-tar", ".tar", magic.Tar)
|
||||
xar = newMIME("application/x-xar", ".xar", magic.Xar)
|
||||
|
@ -57,6 +61,7 @@ func([]byte, uint32) bool { return true },
|
|||
pptx = newMIME("application/vnd.openxmlformats-officedocument.presentationml.presentation", ".pptx", magic.Pptx)
|
||||
epub = newMIME("application/epub+zip", ".epub", magic.Epub)
|
||||
jar = newMIME("application/jar", ".jar", magic.Jar)
|
||||
apk = newMIME("application/vnd.android.package-archive", ".apk", magic.APK)
|
||||
ole = newMIME("application/x-ole-storage", "", magic.Ole, msi, aaf, msg, xls, pub, ppt, doc)
|
||||
msi = newMIME("application/x-ms-installer", ".msi", magic.Msi).
|
||||
alias("application/x-windows-installer", "application/x-msi")
|
||||
|
|
41
vendor/github.com/gin-contrib/gzip/README.md
generated
vendored
41
vendor/github.com/gin-contrib/gzip/README.md
generated
vendored
|
@ -49,7 +49,7 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
Customized Excluded Extensions
|
||||
### Customized Excluded Extensions
|
||||
|
||||
```go
|
||||
package main
|
||||
|
@ -77,7 +77,7 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
Customized Excluded Paths
|
||||
### Customized Excluded Paths
|
||||
|
||||
```go
|
||||
package main
|
||||
|
@ -105,7 +105,7 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
Customized Excluded Paths
|
||||
### Customized Excluded Paths with Regex
|
||||
|
||||
```go
|
||||
package main
|
||||
|
@ -132,3 +132,38 @@ func main() {
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Server Push
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-contrib/gzip"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := gin.Default()
|
||||
r.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||
r.GET("/stream", func(c *gin.Context) {
|
||||
c.Header("Content-Type", "text/event-stream")
|
||||
c.Header("Connection", "keep-alive")
|
||||
for i := 0; i < 10; i++ {
|
||||
fmt.Fprintf(c.Writer, "id: %d\ndata: tick %d\n\n", i, time.Now().Unix())
|
||||
c.Writer.Flush()
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
})
|
||||
|
||||
// Listen and Server in 0.0.0.0:8080
|
||||
if err := r.Run(":8080"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
28
vendor/github.com/gin-contrib/gzip/gzip.go
generated
vendored
28
vendor/github.com/gin-contrib/gzip/gzip.go
generated
vendored
|
@ -1,7 +1,11 @@
|
|||
package gzip
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
@ -11,6 +15,7 @@
|
|||
BestSpeed = gzip.BestSpeed
|
||||
DefaultCompression = gzip.DefaultCompression
|
||||
NoCompression = gzip.NoCompression
|
||||
HuffmanOnly = gzip.HuffmanOnly
|
||||
)
|
||||
|
||||
func Gzip(level int, options ...Option) gin.HandlerFunc {
|
||||
|
@ -32,8 +37,31 @@ func (g *gzipWriter) Write(data []byte) (int, error) {
|
|||
return g.writer.Write(data)
|
||||
}
|
||||
|
||||
func (g *gzipWriter) Flush() {
|
||||
_ = g.writer.Flush()
|
||||
g.ResponseWriter.Flush()
|
||||
}
|
||||
|
||||
// Fix: https://github.com/mholt/caddy/issues/38
|
||||
func (g *gzipWriter) WriteHeader(code int) {
|
||||
g.Header().Del("Content-Length")
|
||||
g.ResponseWriter.WriteHeader(code)
|
||||
}
|
||||
|
||||
// Ensure gzipWriter implements the http.Hijacker interface.
|
||||
// This will cause a compile-time error if gzipWriter does not implement all methods of the http.Hijacker interface.
|
||||
var _ http.Hijacker = (*gzipWriter)(nil)
|
||||
|
||||
// Hijack allows the caller to take over the connection from the HTTP server.
|
||||
// After a call to Hijack, the HTTP server library will not do anything else with the connection.
|
||||
// It becomes the caller's responsibility to manage and close the connection.
|
||||
//
|
||||
// It returns the underlying net.Conn, a buffered reader/writer for the connection, and an error
|
||||
// if the ResponseWriter does not support the Hijacker interface.
|
||||
func (g *gzipWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
hijacker, ok := g.ResponseWriter.(http.Hijacker)
|
||||
if !ok {
|
||||
return nil, nil, errors.New("the ResponseWriter doesn't support the Hijacker interface")
|
||||
}
|
||||
return hijacker.Hijack()
|
||||
}
|
||||
|
|
90
vendor/github.com/gin-contrib/gzip/handler.go
generated
vendored
90
vendor/github.com/gin-contrib/gzip/handler.go
generated
vendored
|
@ -2,84 +2,114 @@
|
|||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
headerAcceptEncoding = "Accept-Encoding"
|
||||
headerContentEncoding = "Content-Encoding"
|
||||
headerVary = "Vary"
|
||||
)
|
||||
|
||||
type gzipHandler struct {
|
||||
*Options
|
||||
*config
|
||||
gzPool sync.Pool
|
||||
}
|
||||
|
||||
func newGzipHandler(level int, options ...Option) *gzipHandler {
|
||||
func isCompressionLevelValid(level int) bool {
|
||||
return level == gzip.DefaultCompression ||
|
||||
level == gzip.NoCompression ||
|
||||
(level >= gzip.BestSpeed && level <= gzip.BestCompression)
|
||||
}
|
||||
|
||||
func newGzipHandler(level int, opts ...Option) *gzipHandler {
|
||||
cfg := &config{
|
||||
excludedExtensions: DefaultExcludedExtentions,
|
||||
}
|
||||
|
||||
// Apply each option to the config
|
||||
for _, o := range opts {
|
||||
o.apply(cfg)
|
||||
}
|
||||
|
||||
if !isCompressionLevelValid(level) {
|
||||
// For web content, level 4 seems to be a sweet spot.
|
||||
level = 4
|
||||
}
|
||||
|
||||
handler := &gzipHandler{
|
||||
Options: DefaultOptions,
|
||||
config: cfg,
|
||||
gzPool: sync.Pool{
|
||||
New: func() interface{} {
|
||||
gz, err := gzip.NewWriterLevel(io.Discard, level)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
gz, _ := gzip.NewWriterLevel(io.Discard, level)
|
||||
return gz
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, setter := range options {
|
||||
setter(handler.Options)
|
||||
}
|
||||
return handler
|
||||
}
|
||||
|
||||
// Handle is a middleware function for handling gzip compression in HTTP requests and responses.
|
||||
// It first checks if the request has a "Content-Encoding" header set to "gzip" and if a decompression
|
||||
// function is provided, it will call the decompression function. If the handler is set to decompress only,
|
||||
// or if the custom compression decision function indicates not to compress, it will return early.
|
||||
// Otherwise, it retrieves a gzip.Writer from the pool, sets the necessary response headers for gzip encoding,
|
||||
// and wraps the response writer with a gzipWriter. After the request is processed, it ensures the gzip.Writer
|
||||
// is properly closed and the "Content-Length" header is set based on the response size.
|
||||
func (g *gzipHandler) Handle(c *gin.Context) {
|
||||
if fn := g.DecompressFn; fn != nil && c.Request.Header.Get("Content-Encoding") == "gzip" {
|
||||
if fn := g.decompressFn; fn != nil && strings.Contains(c.Request.Header.Get("Content-Encoding"), "gzip") {
|
||||
fn(c)
|
||||
}
|
||||
|
||||
if !g.shouldCompress(c.Request) {
|
||||
if g.decompressOnly ||
|
||||
(g.customShouldCompressFn != nil && !g.customShouldCompressFn(c)) ||
|
||||
(g.customShouldCompressFn == nil && !g.shouldCompress(c.Request)) {
|
||||
return
|
||||
}
|
||||
|
||||
gz := g.gzPool.Get().(*gzip.Writer)
|
||||
defer g.gzPool.Put(gz)
|
||||
defer gz.Reset(io.Discard)
|
||||
gz.Reset(c.Writer)
|
||||
|
||||
c.Header("Content-Encoding", "gzip")
|
||||
c.Header("Vary", "Accept-Encoding")
|
||||
c.Header(headerContentEncoding, "gzip")
|
||||
c.Writer.Header().Add(headerVary, headerAcceptEncoding)
|
||||
// check ETag Header
|
||||
originalEtag := c.GetHeader("ETag")
|
||||
if originalEtag != "" && !strings.HasPrefix(originalEtag, "W/") {
|
||||
c.Header("ETag", "W/"+originalEtag)
|
||||
}
|
||||
c.Writer = &gzipWriter{c.Writer, gz}
|
||||
defer func() {
|
||||
if c.Writer.Size() < 0 {
|
||||
// do not write gzip footer when nothing is written to the response body
|
||||
gz.Reset(io.Discard)
|
||||
}
|
||||
gz.Close()
|
||||
c.Header("Content-Length", fmt.Sprint(c.Writer.Size()))
|
||||
_ = gz.Close()
|
||||
if c.Writer.Size() > -1 {
|
||||
c.Header("Content-Length", strconv.Itoa(c.Writer.Size()))
|
||||
}
|
||||
g.gzPool.Put(gz)
|
||||
}()
|
||||
c.Next()
|
||||
}
|
||||
|
||||
func (g *gzipHandler) shouldCompress(req *http.Request) bool {
|
||||
if !strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") ||
|
||||
strings.Contains(req.Header.Get("Connection"), "Upgrade") ||
|
||||
strings.Contains(req.Header.Get("Accept"), "text/event-stream") {
|
||||
if !strings.Contains(req.Header.Get(headerAcceptEncoding), "gzip") ||
|
||||
strings.Contains(req.Header.Get("Connection"), "Upgrade") {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if the request path is excluded from compression
|
||||
extension := filepath.Ext(req.URL.Path)
|
||||
if g.ExcludedExtensions.Contains(extension) {
|
||||
return false
|
||||
}
|
||||
|
||||
if g.ExcludedPaths.Contains(req.URL.Path) {
|
||||
return false
|
||||
}
|
||||
if g.ExcludedPathesRegexs.Contains(req.URL.Path) {
|
||||
if g.excludedExtensions.Contains(extension) ||
|
||||
g.excludedPaths.Contains(req.URL.Path) ||
|
||||
g.excludedPathesRegexs.Contains(req.URL.Path) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
208
vendor/github.com/gin-contrib/gzip/options.go
generated
vendored
208
vendor/github.com/gin-contrib/gzip/options.go
generated
vendored
|
@ -2,6 +2,8 @@
|
|||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
@ -10,58 +12,134 @@
|
|||
)
|
||||
|
||||
var (
|
||||
// DefaultExcludedExtentions is a predefined list of file extensions that should be excluded from gzip compression.
|
||||
// These extensions typically represent image files that are already compressed
|
||||
// and do not benefit from additional compression.
|
||||
DefaultExcludedExtentions = NewExcludedExtensions([]string{
|
||||
".png", ".gif", ".jpeg", ".jpg",
|
||||
})
|
||||
DefaultOptions = &Options{
|
||||
ExcludedExtensions: DefaultExcludedExtentions,
|
||||
}
|
||||
// ErrUnsupportedContentEncoding is an error that indicates the content encoding
|
||||
// is not supported by the application.
|
||||
ErrUnsupportedContentEncoding = errors.New("unsupported content encoding")
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
ExcludedExtensions ExcludedExtensions
|
||||
ExcludedPaths ExcludedPaths
|
||||
ExcludedPathesRegexs ExcludedPathesRegexs
|
||||
DecompressFn func(c *gin.Context)
|
||||
// Option is an interface that defines a method to apply a configuration
|
||||
// to a given config instance. Implementations of this interface can be
|
||||
// used to modify the configuration settings of the logger.
|
||||
type Option interface {
|
||||
apply(*config)
|
||||
}
|
||||
|
||||
type Option func(*Options)
|
||||
// Ensures that optionFunc implements the Option interface at compile time.
|
||||
// If optionFunc does not implement Option, a compile-time error will occur.
|
||||
var _ Option = (*optionFunc)(nil)
|
||||
|
||||
type optionFunc func(*config)
|
||||
|
||||
func (o optionFunc) apply(c *config) {
|
||||
o(c)
|
||||
}
|
||||
|
||||
type config struct {
|
||||
excludedExtensions ExcludedExtensions
|
||||
excludedPaths ExcludedPaths
|
||||
excludedPathesRegexs ExcludedPathesRegexs
|
||||
decompressFn func(c *gin.Context)
|
||||
decompressOnly bool
|
||||
customShouldCompressFn func(c *gin.Context) bool
|
||||
}
|
||||
|
||||
// WithExcludedExtensions returns an Option that sets the ExcludedExtensions field of the Options struct.
|
||||
// Parameters:
|
||||
// - args: []string - A slice of file extensions to exclude from gzip compression.
|
||||
func WithExcludedExtensions(args []string) Option {
|
||||
return func(o *Options) {
|
||||
o.ExcludedExtensions = NewExcludedExtensions(args)
|
||||
}
|
||||
return optionFunc(func(o *config) {
|
||||
o.excludedExtensions = NewExcludedExtensions(args)
|
||||
})
|
||||
}
|
||||
|
||||
// WithExcludedPaths returns an Option that sets the ExcludedPaths field of the Options struct.
|
||||
// Parameters:
|
||||
// - args: []string - A slice of paths to exclude from gzip compression.
|
||||
func WithExcludedPaths(args []string) Option {
|
||||
return func(o *Options) {
|
||||
o.ExcludedPaths = NewExcludedPaths(args)
|
||||
}
|
||||
return optionFunc(func(o *config) {
|
||||
o.excludedPaths = NewExcludedPaths(args)
|
||||
})
|
||||
}
|
||||
|
||||
// WithExcludedPathsRegexs returns an Option that sets the ExcludedPathesRegexs field of the Options struct.
|
||||
// Parameters:
|
||||
// - args: []string - A slice of regex patterns to exclude paths from gzip compression.
|
||||
func WithExcludedPathsRegexs(args []string) Option {
|
||||
return func(o *Options) {
|
||||
o.ExcludedPathesRegexs = NewExcludedPathesRegexs(args)
|
||||
}
|
||||
return optionFunc(func(o *config) {
|
||||
o.excludedPathesRegexs = NewExcludedPathesRegexs(args)
|
||||
})
|
||||
}
|
||||
|
||||
// WithDecompressFn returns an Option that sets the DecompressFn field of the Options struct.
|
||||
// Parameters:
|
||||
// - decompressFn: func(c *gin.Context) - A function to handle decompression of incoming requests.
|
||||
func WithDecompressFn(decompressFn func(c *gin.Context)) Option {
|
||||
return func(o *Options) {
|
||||
o.DecompressFn = decompressFn
|
||||
}
|
||||
return optionFunc(func(o *config) {
|
||||
o.decompressFn = decompressFn
|
||||
})
|
||||
}
|
||||
|
||||
// WithDecompressOnly is an option that configures the gzip middleware to only
|
||||
// decompress incoming requests without compressing the responses. When this
|
||||
// option is enabled, the middleware will set the DecompressOnly field of the
|
||||
// Options struct to true.
|
||||
func WithDecompressOnly() Option {
|
||||
return optionFunc(func(o *config) {
|
||||
o.decompressOnly = true
|
||||
})
|
||||
}
|
||||
|
||||
// WithCustomShouldCompressFn returns an Option that sets the CustomShouldCompressFn field of the Options struct.
|
||||
// Parameters:
|
||||
// - fn: func(c *gin.Context) bool - A function to determine if a request should be compressed.
|
||||
// The function should return true if the request should be compressed, false otherwise.
|
||||
// If the function returns false, the middleware will not compress the response.
|
||||
// If the function is nil, the middleware will use the default logic to determine
|
||||
// if the response should be compressed.
|
||||
//
|
||||
// Returns:
|
||||
// - Option - An option that sets the CustomShouldCompressFn field of the Options struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// router.Use(gzip.Gzip(gzip.DefaultCompression, gzip.WithCustomShouldCompressFn(func(c *gin.Context) bool {
|
||||
// return c.Request.URL.Path != "/no-compress"
|
||||
// })))
|
||||
func WithCustomShouldCompressFn(fn func(c *gin.Context) bool) Option {
|
||||
return optionFunc(func(o *config) {
|
||||
o.customShouldCompressFn = fn
|
||||
})
|
||||
}
|
||||
|
||||
// Using map for better lookup performance
|
||||
type ExcludedExtensions map[string]struct{}
|
||||
|
||||
// NewExcludedExtensions creates a new ExcludedExtensions map from a slice of file extensions.
|
||||
// Parameters:
|
||||
// - extensions: []string - A slice of file extensions to exclude from gzip compression.
|
||||
//
|
||||
// Returns:
|
||||
// - ExcludedExtensions - A map of excluded file extensions.
|
||||
func NewExcludedExtensions(extensions []string) ExcludedExtensions {
|
||||
res := make(ExcludedExtensions)
|
||||
res := make(ExcludedExtensions, len(extensions))
|
||||
for _, e := range extensions {
|
||||
res[e] = struct{}{}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Contains checks if a given file extension is in the ExcludedExtensions map.
|
||||
// Parameters:
|
||||
// - target: string - The file extension to check.
|
||||
//
|
||||
// Returns:
|
||||
// - bool - True if the extension is excluded, false otherwise.
|
||||
func (e ExcludedExtensions) Contains(target string) bool {
|
||||
_, ok := e[target]
|
||||
return ok
|
||||
|
@ -69,10 +147,22 @@ func (e ExcludedExtensions) Contains(target string) bool {
|
|||
|
||||
type ExcludedPaths []string
|
||||
|
||||
// NewExcludedPaths creates a new ExcludedPaths slice from a slice of paths.
|
||||
// Parameters:
|
||||
// - paths: []string - A slice of paths to exclude from gzip compression.
|
||||
//
|
||||
// Returns:
|
||||
// - ExcludedPaths - A slice of excluded paths.
|
||||
func NewExcludedPaths(paths []string) ExcludedPaths {
|
||||
return ExcludedPaths(paths)
|
||||
}
|
||||
|
||||
// Contains checks if a given request URI starts with any of the excluded paths.
|
||||
// Parameters:
|
||||
// - requestURI: string - The request URI to check.
|
||||
//
|
||||
// Returns:
|
||||
// - bool - True if the URI starts with an excluded path, false otherwise.
|
||||
func (e ExcludedPaths) Contains(requestURI string) bool {
|
||||
for _, path := range e {
|
||||
if strings.HasPrefix(requestURI, path) {
|
||||
|
@ -84,14 +174,26 @@ func (e ExcludedPaths) Contains(requestURI string) bool {
|
|||
|
||||
type ExcludedPathesRegexs []*regexp.Regexp
|
||||
|
||||
// NewExcludedPathesRegexs creates a new ExcludedPathesRegexs slice from a slice of regex patterns.
|
||||
// Parameters:
|
||||
// - regexs: []string - A slice of regex patterns to exclude paths from gzip compression.
|
||||
//
|
||||
// Returns:
|
||||
// - ExcludedPathesRegexs - A slice of excluded path regex patterns.
|
||||
func NewExcludedPathesRegexs(regexs []string) ExcludedPathesRegexs {
|
||||
result := make([]*regexp.Regexp, len(regexs))
|
||||
result := make(ExcludedPathesRegexs, len(regexs))
|
||||
for i, reg := range regexs {
|
||||
result[i] = regexp.MustCompile(reg)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Contains checks if a given request URI matches any of the excluded path regex patterns.
|
||||
// Parameters:
|
||||
// - requestURI: string - The request URI to check.
|
||||
//
|
||||
// Returns:
|
||||
// - bool - True if the URI matches an excluded path regex pattern, false otherwise.
|
||||
func (e ExcludedPathesRegexs) Contains(requestURI string) bool {
|
||||
for _, reg := range e {
|
||||
if reg.MatchString(requestURI) {
|
||||
|
@ -101,16 +203,68 @@ func (e ExcludedPathesRegexs) Contains(requestURI string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// DefaultDecompressHandle is a middleware function for the Gin framework that
|
||||
// decompresses the request body if it is gzip encoded. It checks if the request
|
||||
// body is nil and returns immediately if it is. Otherwise, it attempts to create
|
||||
// a new gzip reader from the request body. If an error occurs during this process,
|
||||
// it aborts the request with a 400 Bad Request status and the error. If successful,
|
||||
// it removes the "Content-Encoding" and "Content-Length" headers from the request
|
||||
// and replaces the request body with the decompressed reader.
|
||||
//
|
||||
// Parameters:
|
||||
// - c: *gin.Context - The Gin context for the current request.
|
||||
func DefaultDecompressHandle(c *gin.Context) {
|
||||
if c.Request.Body == nil {
|
||||
return
|
||||
}
|
||||
r, err := gzip.NewReader(c.Request.Body)
|
||||
if err != nil {
|
||||
_ = c.AbortWithError(http.StatusBadRequest, err)
|
||||
|
||||
contentEncodingField := strings.Split(strings.ToLower(c.GetHeader("Content-Encoding")), ",")
|
||||
if len(contentEncodingField) == 0 { // nothing to decompress
|
||||
c.Next()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
toClose := make([]io.Closer, 0, len(contentEncodingField))
|
||||
defer func() {
|
||||
for i := len(toClose); i > 0; i-- {
|
||||
toClose[i-1].Close()
|
||||
}
|
||||
}()
|
||||
|
||||
// parses multiply gzips like
|
||||
// Content-Encoding: gzip, gzip, gzip
|
||||
// allowed by RFC
|
||||
for i := 0; i < len(contentEncodingField); i++ {
|
||||
trimmedValue := strings.TrimSpace(contentEncodingField[i])
|
||||
|
||||
if trimmedValue == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if trimmedValue != "gzip" {
|
||||
// According to RFC 7231, Section 3.1.2.2:
|
||||
// https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.2
|
||||
// An origin server MAY respond with a status code of 415 (Unsupported
|
||||
// Media Type) if a representation in the request message has a content
|
||||
// coding that is not acceptable.
|
||||
_ = c.AbortWithError(http.StatusUnsupportedMediaType, ErrUnsupportedContentEncoding)
|
||||
}
|
||||
|
||||
r, err := gzip.NewReader(c.Request.Body)
|
||||
if err != nil {
|
||||
_ = c.AbortWithError(http.StatusBadRequest, err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
toClose = append(toClose, c.Request.Body)
|
||||
|
||||
c.Request.Body = r
|
||||
}
|
||||
|
||||
c.Request.Header.Del("Content-Encoding")
|
||||
c.Request.Header.Del("Content-Length")
|
||||
c.Request.Body = r
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
|
3
vendor/github.com/gin-contrib/sse/.golangci.yml
generated
vendored
Normal file
3
vendor/github.com/gin-contrib/sse/.golangci.yml
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
linters:
|
||||
disable:
|
||||
- errcheck
|
29
vendor/github.com/gin-contrib/sse/.goreleaser.yaml
generated
vendored
Normal file
29
vendor/github.com/gin-contrib/sse/.goreleaser.yaml
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
builds:
|
||||
- # If true, skip the build.
|
||||
# Useful for library projects.
|
||||
# Default is false
|
||||
skip: true
|
||||
|
||||
changelog:
|
||||
use: github
|
||||
groups:
|
||||
- title: Features
|
||||
regexp: "^.*feat[(\\w)]*:+.*$"
|
||||
order: 0
|
||||
- title: "Bug fixes"
|
||||
regexp: "^.*fix[(\\w)]*:+.*$"
|
||||
order: 1
|
||||
- title: "Enhancements"
|
||||
regexp: "^.*chore[(\\w)]*:+.*$"
|
||||
order: 2
|
||||
- title: "Refactor"
|
||||
regexp: "^.*refactor[(\\w)]*:+.*$"
|
||||
order: 3
|
||||
- title: "Build process updates"
|
||||
regexp: ^.*?(build|ci)(\(.+\))??!?:.+$
|
||||
order: 4
|
||||
- title: "Documentation updates"
|
||||
regexp: ^.*?docs?(\(.+\))??!?:.+$
|
||||
order: 4
|
||||
- title: Others
|
||||
order: 999
|
26
vendor/github.com/gin-contrib/sse/.travis.yml
generated
vendored
26
vendor/github.com/gin-contrib/sse/.travis.yml
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- master
|
||||
|
||||
git:
|
||||
depth: 10
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- go: 1.11.x
|
||||
env: GO111MODULE=on
|
||||
- go: 1.12.x
|
||||
env: GO111MODULE=on
|
||||
|
||||
script:
|
||||
- go test -v -covermode=count -coverprofile=coverage.out
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
42
vendor/github.com/gin-contrib/sse/README.md
generated
vendored
42
vendor/github.com/gin-contrib/sse/README.md
generated
vendored
|
@ -1,7 +1,7 @@
|
|||
# Server-Sent Events
|
||||
|
||||
[![GoDoc](https://godoc.org/github.com/gin-contrib/sse?status.svg)](https://godoc.org/github.com/gin-contrib/sse)
|
||||
[![Build Status](https://travis-ci.org/gin-contrib/sse.svg)](https://travis-ci.org/gin-contrib/sse)
|
||||
[![Go Reference](https://pkg.go.dev/badge/github.com/gin-contrib/sse.svg)](https://pkg.go.dev/github.com/gin-contrib/sse)
|
||||
[![Run Tests](https://github.com/gin-contrib/sse/actions/workflows/go.yml/badge.svg)](https://github.com/gin-contrib/sse/actions/workflows/go.yml)
|
||||
[![codecov](https://codecov.io/gh/gin-contrib/sse/branch/master/graph/badge.svg)](https://codecov.io/gh/gin-contrib/sse)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/gin-contrib/sse)](https://goreportcard.com/report/github.com/gin-contrib/sse)
|
||||
|
||||
|
@ -16,32 +16,33 @@ Server-sent events (SSE) is a technology where a browser receives automatic upda
|
|||
import "github.com/gin-contrib/sse"
|
||||
|
||||
func httpHandler(w http.ResponseWriter, req *http.Request) {
|
||||
// data can be a primitive like a string, an integer or a float
|
||||
sse.Encode(w, sse.Event{
|
||||
Event: "message",
|
||||
Data: "some data\nmore data",
|
||||
})
|
||||
// data can be a primitive like a string, an integer or a float
|
||||
sse.Encode(w, sse.Event{
|
||||
Event: "message",
|
||||
Data: "some data\nmore data",
|
||||
})
|
||||
|
||||
// also a complex type, like a map, a struct or a slice
|
||||
sse.Encode(w, sse.Event{
|
||||
Id: "124",
|
||||
Event: "message",
|
||||
Data: map[string]interface{}{
|
||||
"user": "manu",
|
||||
"date": time.Now().Unix(),
|
||||
"content": "hi!",
|
||||
},
|
||||
})
|
||||
// also a complex type, like a map, a struct or a slice
|
||||
sse.Encode(w, sse.Event{
|
||||
Id: "124",
|
||||
Event: "message",
|
||||
Data: map[string]interface{}{
|
||||
"user": "manu",
|
||||
"date": time.Now().Unix(),
|
||||
"content": "hi!",
|
||||
},
|
||||
})
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
```sh
|
||||
event: message
|
||||
data: some data\\nmore data
|
||||
|
||||
id: 124
|
||||
event: message
|
||||
data: {"content":"hi!","date":1431540810,"user":"manu"}
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Content-Type
|
||||
|
@ -49,7 +50,8 @@ data: {"content":"hi!","date":1431540810,"user":"manu"}
|
|||
```go
|
||||
fmt.Println(sse.ContentType)
|
||||
```
|
||||
```
|
||||
|
||||
```sh
|
||||
text/event-stream
|
||||
```
|
||||
|
||||
|
|
10
vendor/github.com/gin-contrib/sse/sse-encoder.go
generated
vendored
10
vendor/github.com/gin-contrib/sse/sse-encoder.go
generated
vendored
|
@ -18,7 +18,7 @@
|
|||
// W3C Working Draft 29 October 2009
|
||||
// http://www.w3.org/TR/2009/WD-eventsource-20091029/
|
||||
|
||||
const ContentType = "text/event-stream"
|
||||
const ContentType = "text/event-stream;charset=utf-8"
|
||||
|
||||
var contentType = []string{ContentType}
|
||||
var noCache = []string{"no-cache"}
|
||||
|
@ -72,6 +72,14 @@ func writeRetry(w stringWriter, retry uint) {
|
|||
|
||||
func writeData(w stringWriter, data interface{}) error {
|
||||
w.WriteString("data:")
|
||||
|
||||
bData, ok := data.([]byte)
|
||||
if ok {
|
||||
dataReplacer.WriteString(w, string(bData))
|
||||
w.WriteString("\n\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
switch kindOfData(data) {
|
||||
case reflect.Struct, reflect.Slice, reflect.Map:
|
||||
err := json.NewEncoder(w).Encode(data)
|
||||
|
|
150
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
150
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
|
@ -1,7 +1,7 @@
|
|||
Package validator
|
||||
=================
|
||||
<img align="right" src="logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
![Project status](https://img.shields.io/badge/version-10.23.0-green.svg)
|
||||
![Project status](https://img.shields.io/badge/version-10.24.0-green.svg)
|
||||
[![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator)
|
||||
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
|
||||
|
@ -22,6 +22,11 @@ It has the following **unique** features:
|
|||
- Customizable i18n aware error messages.
|
||||
- Default validator for the [gin](https://github.com/gin-gonic/gin) web framework; upgrading from v8 to v9 in gin see [here](https://github.com/go-playground/validator/tree/master/_examples/gin-upgrading-overriding)
|
||||
|
||||
A Call for Maintainers
|
||||
----------------------
|
||||
|
||||
Please read the discussiong started [here](https://github.com/go-playground/validator/discussions/1330) if you are interested in contributing/helping maintain this package.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
|
@ -266,74 +271,75 @@ validate := validator.New(validator.WithRequiredStructEnabled())
|
|||
|
||||
Benchmarks
|
||||
------
|
||||
###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64
|
||||
###### Run on MacBook Pro Max M3
|
||||
```go
|
||||
go version go1.21.0 darwin/arm64
|
||||
go version go1.23.3 darwin/arm64
|
||||
goos: darwin
|
||||
goarch: arm64
|
||||
cpu: Apple M3 Max
|
||||
pkg: github.com/go-playground/validator/v10
|
||||
BenchmarkFieldSuccess-8 33142266 35.94 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkFieldSuccessParallel-8 200816191 6.568 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkFieldFailure-8 6779707 175.1 ns/op 200 B/op 4 allocs/op
|
||||
BenchmarkFieldFailureParallel-8 11044147 108.4 ns/op 200 B/op 4 allocs/op
|
||||
BenchmarkFieldArrayDiveSuccess-8 6054232 194.4 ns/op 97 B/op 5 allocs/op
|
||||
BenchmarkFieldArrayDiveSuccessParallel-8 12523388 94.07 ns/op 97 B/op 5 allocs/op
|
||||
BenchmarkFieldArrayDiveFailure-8 3587043 334.3 ns/op 300 B/op 10 allocs/op
|
||||
BenchmarkFieldArrayDiveFailureParallel-8 5816665 200.8 ns/op 300 B/op 10 allocs/op
|
||||
BenchmarkFieldMapDiveSuccess-8 2217910 540.1 ns/op 288 B/op 14 allocs/op
|
||||
BenchmarkFieldMapDiveSuccessParallel-8 4446698 258.7 ns/op 288 B/op 14 allocs/op
|
||||
BenchmarkFieldMapDiveFailure-8 2392759 504.6 ns/op 376 B/op 13 allocs/op
|
||||
BenchmarkFieldMapDiveFailureParallel-8 4244199 286.9 ns/op 376 B/op 13 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysSuccess-8 2005857 592.1 ns/op 288 B/op 14 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysSuccessParallel-8 4400850 296.9 ns/op 288 B/op 14 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysFailure-8 1850227 643.8 ns/op 553 B/op 16 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysFailureParallel-8 3293233 375.1 ns/op 553 B/op 16 allocs/op
|
||||
BenchmarkFieldCustomTypeSuccess-8 12174412 98.25 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkFieldCustomTypeSuccessParallel-8 34389907 35.49 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkFieldCustomTypeFailure-8 7582524 156.6 ns/op 184 B/op 3 allocs/op
|
||||
BenchmarkFieldCustomTypeFailureParallel-8 13019902 92.79 ns/op 184 B/op 3 allocs/op
|
||||
BenchmarkFieldOrTagSuccess-8 3427260 349.4 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkFieldOrTagSuccessParallel-8 15144128 81.25 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkFieldOrTagFailure-8 5913546 201.9 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkFieldOrTagFailureParallel-8 9810212 113.7 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructLevelValidationSuccess-8 13456327 87.66 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkStructLevelValidationSuccessParallel-8 41818888 27.77 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkStructLevelValidationFailure-8 4166284 272.6 ns/op 264 B/op 7 allocs/op
|
||||
BenchmarkStructLevelValidationFailureParallel-8 7594581 152.1 ns/op 264 B/op 7 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeSuccess-8 6508082 182.6 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeSuccessParallel-8 23078605 54.78 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeFailure-8 3118352 381.0 ns/op 416 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeFailureParallel-8 5300738 224.1 ns/op 432 B/op 10 allocs/op
|
||||
BenchmarkStructFilteredSuccess-8 4761807 251.1 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructFilteredSuccessParallel-8 8792598 128.6 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructFilteredFailure-8 5202573 232.1 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructFilteredFailureParallel-8 9591267 121.4 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructPartialSuccess-8 5188512 231.6 ns/op 224 B/op 4 allocs/op
|
||||
BenchmarkStructPartialSuccessParallel-8 9179776 123.1 ns/op 224 B/op 4 allocs/op
|
||||
BenchmarkStructPartialFailure-8 3071212 392.5 ns/op 440 B/op 9 allocs/op
|
||||
BenchmarkStructPartialFailureParallel-8 5344261 223.7 ns/op 440 B/op 9 allocs/op
|
||||
BenchmarkStructExceptSuccess-8 3184230 375.0 ns/op 424 B/op 8 allocs/op
|
||||
BenchmarkStructExceptSuccessParallel-8 10090130 108.9 ns/op 208 B/op 3 allocs/op
|
||||
BenchmarkStructExceptFailure-8 3347226 357.7 ns/op 424 B/op 8 allocs/op
|
||||
BenchmarkStructExceptFailureParallel-8 5654923 209.5 ns/op 424 B/op 8 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldSuccess-8 5232265 229.1 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldSuccessParallel-8 17436674 64.75 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldFailure-8 3128613 383.6 ns/op 272 B/op 8 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldFailureParallel-8 6994113 168.8 ns/op 272 B/op 8 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3506487 340.9 ns/op 64 B/op 4 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 13431300 91.77 ns/op 64 B/op 4 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2410566 500.9 ns/op 288 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 6344510 188.2 ns/op 288 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleSuccess-8 8922726 133.8 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkStructSimpleSuccessParallel-8 55291153 23.63 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkStructSimpleFailure-8 3171553 378.4 ns/op 416 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleFailureParallel-8 5571692 212.0 ns/op 416 B/op 9 allocs/op
|
||||
BenchmarkStructComplexSuccess-8 1683750 714.5 ns/op 224 B/op 5 allocs/op
|
||||
BenchmarkStructComplexSuccessParallel-8 4578046 257.0 ns/op 224 B/op 5 allocs/op
|
||||
BenchmarkStructComplexFailure-8 481585 2547 ns/op 3041 B/op 48 allocs/op
|
||||
BenchmarkStructComplexFailureParallel-8 965764 1577 ns/op 3040 B/op 48 allocs/op
|
||||
BenchmarkOneof-8 17380881 68.50 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkOneofParallel-8 8084733 153.5 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkFieldSuccess-16 42461943 27.88 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkFieldSuccessParallel-16 486632887 2.289 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkFieldFailure-16 9566167 121.3 ns/op 200 B/op 4 allocs/op
|
||||
BenchmarkFieldFailureParallel-16 17551471 83.68 ns/op 200 B/op 4 allocs/op
|
||||
BenchmarkFieldArrayDiveSuccess-16 7602306 155.6 ns/op 97 B/op 5 allocs/op
|
||||
BenchmarkFieldArrayDiveSuccessParallel-16 20664610 59.80 ns/op 97 B/op 5 allocs/op
|
||||
BenchmarkFieldArrayDiveFailure-16 4659756 252.9 ns/op 301 B/op 10 allocs/op
|
||||
BenchmarkFieldArrayDiveFailureParallel-16 8010116 152.9 ns/op 301 B/op 10 allocs/op
|
||||
BenchmarkFieldMapDiveSuccess-16 2834575 421.2 ns/op 288 B/op 14 allocs/op
|
||||
BenchmarkFieldMapDiveSuccessParallel-16 7179700 171.8 ns/op 288 B/op 14 allocs/op
|
||||
BenchmarkFieldMapDiveFailure-16 3081728 384.4 ns/op 376 B/op 13 allocs/op
|
||||
BenchmarkFieldMapDiveFailureParallel-16 6058137 204.0 ns/op 377 B/op 13 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysSuccess-16 2544975 464.8 ns/op 288 B/op 14 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysSuccessParallel-16 6661954 181.4 ns/op 288 B/op 14 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysFailure-16 2435484 490.7 ns/op 553 B/op 16 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysFailureParallel-16 4249617 282.0 ns/op 554 B/op 16 allocs/op
|
||||
BenchmarkFieldCustomTypeSuccess-16 14943525 77.35 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkFieldCustomTypeSuccessParallel-16 64051954 20.61 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkFieldCustomTypeFailure-16 10721384 107.1 ns/op 184 B/op 3 allocs/op
|
||||
BenchmarkFieldCustomTypeFailureParallel-16 18714495 69.77 ns/op 184 B/op 3 allocs/op
|
||||
BenchmarkFieldOrTagSuccess-16 4063124 294.3 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkFieldOrTagSuccessParallel-16 31903756 41.22 ns/op 18 B/op 1 allocs/op
|
||||
BenchmarkFieldOrTagFailure-16 7748558 146.8 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkFieldOrTagFailureParallel-16 13139854 92.05 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructLevelValidationSuccess-16 16808389 70.25 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkStructLevelValidationSuccessParallel-16 90686955 14.47 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkStructLevelValidationFailure-16 5818791 200.2 ns/op 264 B/op 7 allocs/op
|
||||
BenchmarkStructLevelValidationFailureParallel-16 11115874 107.5 ns/op 264 B/op 7 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeSuccess-16 7764956 151.9 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeSuccessParallel-16 52316265 30.37 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeFailure-16 4195429 277.2 ns/op 416 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeFailureParallel-16 7305661 164.6 ns/op 432 B/op 10 allocs/op
|
||||
BenchmarkStructFilteredSuccess-16 6312625 186.1 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructFilteredSuccessParallel-16 13684459 93.42 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructFilteredFailure-16 6751482 171.2 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructFilteredFailureParallel-16 14146070 86.93 ns/op 216 B/op 5 allocs/op
|
||||
BenchmarkStructPartialSuccess-16 6544448 177.3 ns/op 224 B/op 4 allocs/op
|
||||
BenchmarkStructPartialSuccessParallel-16 13951946 88.73 ns/op 224 B/op 4 allocs/op
|
||||
BenchmarkStructPartialFailure-16 4075833 287.5 ns/op 440 B/op 9 allocs/op
|
||||
BenchmarkStructPartialFailureParallel-16 7490805 161.3 ns/op 440 B/op 9 allocs/op
|
||||
BenchmarkStructExceptSuccess-16 4107187 281.4 ns/op 424 B/op 8 allocs/op
|
||||
BenchmarkStructExceptSuccessParallel-16 15979173 80.86 ns/op 208 B/op 3 allocs/op
|
||||
BenchmarkStructExceptFailure-16 4434372 264.3 ns/op 424 B/op 8 allocs/op
|
||||
BenchmarkStructExceptFailureParallel-16 8081367 154.1 ns/op 424 B/op 8 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldSuccess-16 6459542 183.4 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldSuccessParallel-16 41013781 37.95 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldFailure-16 4034998 292.1 ns/op 272 B/op 8 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldFailureParallel-16 11348446 115.3 ns/op 272 B/op 8 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldSuccess-16 4448528 267.7 ns/op 64 B/op 4 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-16 26813619 48.33 ns/op 64 B/op 4 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldFailure-16 3090646 384.5 ns/op 288 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-16 9870906 129.5 ns/op 288 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleSuccess-16 10675562 109.5 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkStructSimpleSuccessParallel-16 131159784 8.932 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkStructSimpleFailure-16 4094979 286.6 ns/op 416 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleFailureParallel-16 7606663 157.9 ns/op 416 B/op 9 allocs/op
|
||||
BenchmarkStructComplexSuccess-16 2073470 576.0 ns/op 224 B/op 5 allocs/op
|
||||
BenchmarkStructComplexSuccessParallel-16 7821831 161.3 ns/op 224 B/op 5 allocs/op
|
||||
BenchmarkStructComplexFailure-16 576358 2001 ns/op 3042 B/op 48 allocs/op
|
||||
BenchmarkStructComplexFailureParallel-16 1000000 1171 ns/op 3041 B/op 48 allocs/op
|
||||
BenchmarkOneof-16 22503973 52.82 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkOneofParallel-16 8538474 140.4 ns/op 0 B/op 0 allocs/op
|
||||
```
|
||||
|
||||
Complementary Software
|
||||
|
@ -349,6 +355,20 @@ How to Contribute
|
|||
|
||||
Make a pull request...
|
||||
|
||||
Maintenance and support for SDK major versions
|
||||
----------------------------------------------
|
||||
|
||||
See prior discussion [here](https://github.com/go-playground/validator/discussions/1342) for more details.
|
||||
|
||||
This package is aligned with the [Go release policy](https://go.dev/doc/devel/release) in that support is guaranteed for
|
||||
the two most recent major versions.
|
||||
|
||||
This does not mean the package will not work with older versions of Go, only that we reserve the right to increase the
|
||||
MSGV(Minimum Supported Go Version) when the need arises to address Security issues/patches, OS issues & support or newly
|
||||
introduced functionality that would greatly benefit the maintenance and/or usage of this package.
|
||||
|
||||
If and when the MSGV is increased it will be done so in a minimum of a `Minor` release bump.
|
||||
|
||||
License
|
||||
-------
|
||||
Distributed under MIT License, please see license file within the code for more details.
|
||||
|
|
24
vendor/google.golang.org/protobuf/internal/impl/message_opaque.go
generated
vendored
24
vendor/google.golang.org/protobuf/internal/impl/message_opaque.go
generated
vendored
|
@ -88,9 +88,7 @@ func opaqueInitHook(mi *MessageInfo) bool {
|
|||
mi.oneofs = map[protoreflect.Name]*oneofInfo{}
|
||||
for i := 0; i < mi.Desc.Oneofs().Len(); i++ {
|
||||
od := mi.Desc.Oneofs().Get(i)
|
||||
if !od.IsSynthetic() {
|
||||
mi.oneofs[od.Name()] = makeOneofInfo(od, si.structInfo, mi.Exporter)
|
||||
}
|
||||
mi.oneofs[od.Name()] = makeOneofInfoOpaque(mi, od, si.structInfo, mi.Exporter)
|
||||
}
|
||||
|
||||
mi.denseFields = make([]*fieldInfo, fds.Len()*2)
|
||||
|
@ -119,6 +117,26 @@ func opaqueInitHook(mi *MessageInfo) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func makeOneofInfoOpaque(mi *MessageInfo, od protoreflect.OneofDescriptor, si structInfo, x exporter) *oneofInfo {
|
||||
oi := &oneofInfo{oneofDesc: od}
|
||||
if od.IsSynthetic() {
|
||||
fd := od.Fields().Get(0)
|
||||
index, _ := presenceIndex(mi.Desc, fd)
|
||||
oi.which = func(p pointer) protoreflect.FieldNumber {
|
||||
if p.IsNil() {
|
||||
return 0
|
||||
}
|
||||
if !mi.present(p, index) {
|
||||
return 0
|
||||
}
|
||||
return od.Fields().Get(0).Number()
|
||||
}
|
||||
return oi
|
||||
}
|
||||
// Dispatch to non-opaque oneof implementation for non-synthetic oneofs.
|
||||
return makeOneofInfo(od, si, x)
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) fieldInfoForMapOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo {
|
||||
ft := fs.Type
|
||||
if ft.Kind() != reflect.Map {
|
||||
|
|
2
vendor/google.golang.org/protobuf/internal/version/version.go
generated
vendored
2
vendor/google.golang.org/protobuf/internal/version/version.go
generated
vendored
|
@ -52,7 +52,7 @@
|
|||
const (
|
||||
Major = 1
|
||||
Minor = 36
|
||||
Patch = 1
|
||||
Patch = 2
|
||||
PreRelease = ""
|
||||
)
|
||||
|
||||
|
|
26
vendor/modules.txt
vendored
26
vendor/modules.txt
vendored
|
@ -101,7 +101,7 @@ github.com/beorn7/perks/quantile
|
|||
## explicit; go 1.14
|
||||
github.com/buckket/go-blurhash
|
||||
github.com/buckket/go-blurhash/base83
|
||||
# github.com/bytedance/sonic v1.12.6
|
||||
# github.com/bytedance/sonic v1.12.7
|
||||
## explicit; go 1.17
|
||||
github.com/bytedance/sonic
|
||||
github.com/bytedance/sonic/ast
|
||||
|
@ -135,10 +135,12 @@ github.com/bytedance/sonic/internal/utils
|
|||
github.com/bytedance/sonic/option
|
||||
github.com/bytedance/sonic/unquote
|
||||
github.com/bytedance/sonic/utf8
|
||||
# github.com/bytedance/sonic/loader v0.2.1
|
||||
# github.com/bytedance/sonic/loader v0.2.2
|
||||
## explicit; go 1.16
|
||||
github.com/bytedance/sonic/loader
|
||||
github.com/bytedance/sonic/loader/internal/abi
|
||||
github.com/bytedance/sonic/loader/internal/iasm/expr
|
||||
github.com/bytedance/sonic/loader/internal/iasm/x86_64
|
||||
github.com/bytedance/sonic/loader/internal/rt
|
||||
# github.com/cenkalti/backoff/v4 v4.3.0
|
||||
## explicit; go 1.18
|
||||
|
@ -158,10 +160,6 @@ github.com/cilium/ebpf/link
|
|||
# github.com/cloudwego/base64x v0.1.4
|
||||
## explicit; go 1.16
|
||||
github.com/cloudwego/base64x
|
||||
# github.com/cloudwego/iasm v0.2.0
|
||||
## explicit; go 1.16
|
||||
github.com/cloudwego/iasm/expr
|
||||
github.com/cloudwego/iasm/x86_64
|
||||
# github.com/containerd/cgroups/v3 v3.0.1
|
||||
## explicit; go 1.17
|
||||
github.com/containerd/cgroups/v3
|
||||
|
@ -208,7 +206,7 @@ github.com/felixge/httpsnoop
|
|||
# github.com/fsnotify/fsnotify v1.7.0
|
||||
## explicit; go 1.17
|
||||
github.com/fsnotify/fsnotify
|
||||
# github.com/gabriel-vasile/mimetype v1.4.7
|
||||
# github.com/gabriel-vasile/mimetype v1.4.8
|
||||
## explicit; go 1.20
|
||||
github.com/gabriel-vasile/mimetype
|
||||
github.com/gabriel-vasile/mimetype/internal/charset
|
||||
|
@ -217,15 +215,15 @@ github.com/gabriel-vasile/mimetype/internal/magic
|
|||
# github.com/gin-contrib/cors v1.7.3
|
||||
## explicit; go 1.21.0
|
||||
github.com/gin-contrib/cors
|
||||
# github.com/gin-contrib/gzip v1.1.0
|
||||
# github.com/gin-contrib/gzip v1.2.2
|
||||
## explicit; go 1.21.0
|
||||
github.com/gin-contrib/gzip
|
||||
# github.com/gin-contrib/sessions v1.0.2
|
||||
## explicit; go 1.20
|
||||
github.com/gin-contrib/sessions
|
||||
github.com/gin-contrib/sessions/memstore
|
||||
# github.com/gin-contrib/sse v0.1.0
|
||||
## explicit; go 1.12
|
||||
# github.com/gin-contrib/sse v1.0.0
|
||||
## explicit; go 1.13
|
||||
github.com/gin-contrib/sse
|
||||
# github.com/gin-gonic/gin v1.10.0
|
||||
## explicit; go 1.20
|
||||
|
@ -312,8 +310,8 @@ github.com/go-playground/locales/currency
|
|||
# github.com/go-playground/universal-translator v0.18.1
|
||||
## explicit; go 1.18
|
||||
github.com/go-playground/universal-translator
|
||||
# github.com/go-playground/validator/v10 v10.23.0
|
||||
## explicit; go 1.18
|
||||
# github.com/go-playground/validator/v10 v10.24.0
|
||||
## explicit; go 1.20
|
||||
github.com/go-playground/validator/v10
|
||||
# github.com/go-swagger/go-swagger v0.31.0 => github.com/superseriousbusiness/go-swagger v0.31.0-gts-go1.23-fix
|
||||
## explicit; go 1.21
|
||||
|
@ -1077,7 +1075,7 @@ go.uber.org/automaxprocs/maxprocs
|
|||
# go.uber.org/multierr v1.11.0
|
||||
## explicit; go 1.19
|
||||
go.uber.org/multierr
|
||||
# golang.org/x/arch v0.12.0
|
||||
# golang.org/x/arch v0.13.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/arch/x86/x86asm
|
||||
# golang.org/x/crypto v0.32.0
|
||||
|
@ -1263,7 +1261,7 @@ google.golang.org/grpc/serviceconfig
|
|||
google.golang.org/grpc/stats
|
||||
google.golang.org/grpc/status
|
||||
google.golang.org/grpc/tap
|
||||
# google.golang.org/protobuf v1.36.1
|
||||
# google.golang.org/protobuf v1.36.2
|
||||
## explicit; go 1.21
|
||||
google.golang.org/protobuf/encoding/protodelim
|
||||
google.golang.org/protobuf/encoding/protojson
|
||||
|
|
Loading…
Reference in a new issue