diff --git a/go.mod b/go.mod index e0895e5..c1b0b78 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,10 @@ module github.com/mandelsoft/vfs -go 1.19 +go 1.22.5 require ( github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 + github.com/modern-go/reflect2 v1.0.2 github.com/onsi/ginkgo v1.14.0 github.com/onsi/gomega v1.10.1 gopkg.in/yaml.v2 v2.3.0 diff --git a/go.sum b/go.sum index b995a93..a158435 100644 --- a/go.sum +++ b/go.sum @@ -13,12 +13,10 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/mandelsoft/filepath v0.0.0-20200909114706-3df73d378d55 h1:mFdiUG86O2iW+iDEpZKXf64efMWO4JvDT+zN3znUGIc= -github.com/mandelsoft/filepath v0.0.0-20200909114706-3df73d378d55/go.mod h1:n4xEiUD2HNHnn2w5ZKF0qgjDecHVCWAl5DxZ7+pcFU8= -github.com/mandelsoft/filepath v0.0.0-20230412200429-36b1eb66bd27 h1:VivN6K8H4H0G4bUmeQH68fQIROL5c8S2iyvVe4teufc= -github.com/mandelsoft/filepath v0.0.0-20230412200429-36b1eb66bd27/go.mod h1:LxhqC7khDoRENwooP6f/vWvia9ivj6TqLYrR39zqkN0= github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 h1:oo9nIgnyiBgYPbcZslRT4y29siuL5EoNJ/t1tr0xEVQ= github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3/go.mod h1:LxhqC7khDoRENwooP6f/vWvia9ivj6TqLYrR39zqkN0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= diff --git a/pkg/osfs/osfs.go b/pkg/osfs/osfs.go index 17fb6d3..220b22b 100644 --- a/pkg/osfs/osfs.go +++ b/pkg/osfs/osfs.go @@ -23,6 +23,7 @@ import ( "time" "github.com/mandelsoft/filepath/pkg/filepath" + "github.com/modern-go/reflect2" "github.com/mandelsoft/vfs/pkg/utils" "github.com/mandelsoft/vfs/pkg/vfs" @@ -30,6 +31,25 @@ import ( var OsFs = &osFileSystem{} +// OsFsCheck should be implemented by forwarding wrappers +// to check for an OS Filesystem implementation. +type OsFsCheck interface { + IsOsFileSystem() bool +} + +func IsOsFileSystem(fs vfs.FileSystem) bool { + if reflect2.IsNil(fs) { + return false + } + if _, ok := fs.(*osFileSystem); ok { + return true + } + if c, ok := fs.(OsFsCheck); ok { + return c.IsOsFileSystem() + } + return false +} + type osFileSystem struct { } diff --git a/vendor/github.com/modern-go/reflect2/.gitignore b/vendor/github.com/modern-go/reflect2/.gitignore new file mode 100644 index 0000000..7b26c94 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/.gitignore @@ -0,0 +1,2 @@ +/vendor +/coverage.txt diff --git a/vendor/github.com/modern-go/reflect2/.travis.yml b/vendor/github.com/modern-go/reflect2/.travis.yml new file mode 100644 index 0000000..b097728 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/.travis.yml @@ -0,0 +1,15 @@ +language: go + +go: + - 1.9.x + - 1.x + +before_install: + - go get -t -v ./... + - go get -t -v github.com/modern-go/reflect2-tests/... + +script: + - ./test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/modern-go/reflect2/Gopkg.lock b/vendor/github.com/modern-go/reflect2/Gopkg.lock new file mode 100644 index 0000000..10ef811 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/Gopkg.lock @@ -0,0 +1,9 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/modern-go/reflect2/Gopkg.toml b/vendor/github.com/modern-go/reflect2/Gopkg.toml new file mode 100644 index 0000000..a9bc506 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/Gopkg.toml @@ -0,0 +1,31 @@ +# Gopkg.toml example +# +# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + +ignored = [] + +[prune] + go-tests = true + unused-packages = true diff --git a/vendor/github.com/modern-go/reflect2/LICENSE b/vendor/github.com/modern-go/reflect2/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/LICENSE @@ -0,0 +1,201 @@ + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/github.com/modern-go/reflect2/README.md b/vendor/github.com/modern-go/reflect2/README.md new file mode 100644 index 0000000..6f968aa --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/README.md @@ -0,0 +1,71 @@ +# reflect2 + +[![Sourcegraph](https://sourcegraph.com/github.com/modern-go/reflect2/-/badge.svg)](https://sourcegraph.com/github.com/modern-go/reflect2?badge) +[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/modern-go/reflect2) +[![Build Status](https://travis-ci.org/modern-go/reflect2.svg?branch=master)](https://travis-ci.org/modern-go/reflect2) +[![codecov](https://codecov.io/gh/modern-go/reflect2/branch/master/graph/badge.svg)](https://codecov.io/gh/modern-go/reflect2) +[![rcard](https://goreportcard.com/badge/github.com/modern-go/reflect2)](https://goreportcard.com/report/github.com/modern-go/reflect2) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://raw.githubusercontent.com/modern-go/reflect2/master/LICENSE) + +reflect api that avoids runtime reflect.Value cost + +* reflect get/set interface{}, with type checking +* reflect get/set unsafe.Pointer, without type checking +* `reflect2.TypeByName` works like `Class.forName` found in java + +[json-iterator](https://github.com/json-iterator/go) use this package to save runtime dispatching cost. +This package is designed for low level libraries to optimize reflection performance. +General application should still use reflect standard library. + +# reflect2.TypeByName + +```go +// given package is github.com/your/awesome-package +type MyStruct struct { + // ... +} + +// will return the type +reflect2.TypeByName("awesome-package.MyStruct") +// however, if the type has not been used +// it will be eliminated by compiler, so we can not get it in runtime +``` + +# reflect2 get/set interface{} + +```go +valType := reflect2.TypeOf(1) +i := 1 +j := 10 +valType.Set(&i, &j) +// i will be 10 +``` + +to get set `type`, always use its pointer `*type` + +# reflect2 get/set unsafe.Pointer + +```go +valType := reflect2.TypeOf(1) +i := 1 +j := 10 +valType.UnsafeSet(unsafe.Pointer(&i), unsafe.Pointer(&j)) +// i will be 10 +``` + +to get set `type`, always use its pointer `*type` + +# benchmark + +Benchmark is not necessary for this package. It does nothing actually. +As it is just a thin wrapper to make go runtime public. +Both `reflect2` and `reflect` call same function +provided by `runtime` package exposed by go language. + +# unsafe safety + +Instead of casting `[]byte` to `sliceHeader` in your application using unsafe. +We can use reflect2 instead. This way, if `sliceHeader` changes in the future, +only reflect2 need to be upgraded. + +reflect2 tries its best to keep the implementation same as reflect (by testing). \ No newline at end of file diff --git a/vendor/github.com/modern-go/reflect2/go_above_118.go b/vendor/github.com/modern-go/reflect2/go_above_118.go new file mode 100644 index 0000000..2b4116f --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_above_118.go @@ -0,0 +1,23 @@ +//+build go1.18 + +package reflect2 + +import ( + "unsafe" +) + +// m escapes into the return value, but the caller of mapiterinit +// doesn't let the return value escape. +//go:noescape +//go:linkname mapiterinit reflect.mapiterinit +func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer, it *hiter) + +func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + var it hiter + mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj), &it) + return &UnsafeMapIterator{ + hiter: &it, + pKeyRType: type2.pKeyRType, + pElemRType: type2.pElemRType, + } +} \ No newline at end of file diff --git a/vendor/github.com/modern-go/reflect2/go_above_19.go b/vendor/github.com/modern-go/reflect2/go_above_19.go new file mode 100644 index 0000000..974f768 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_above_19.go @@ -0,0 +1,17 @@ +//+build go1.9 + +package reflect2 + +import ( + "unsafe" +) + +//go:linkname resolveTypeOff reflect.resolveTypeOff +func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer + +//go:linkname makemap reflect.makemap +func makemap(rtype unsafe.Pointer, cap int) (m unsafe.Pointer) + +func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer { + return makemap(rtype, cap) +} diff --git a/vendor/github.com/modern-go/reflect2/go_below_118.go b/vendor/github.com/modern-go/reflect2/go_below_118.go new file mode 100644 index 0000000..00003db --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_below_118.go @@ -0,0 +1,21 @@ +//+build !go1.18 + +package reflect2 + +import ( + "unsafe" +) + +// m escapes into the return value, but the caller of mapiterinit +// doesn't let the return value escape. +//go:noescape +//go:linkname mapiterinit reflect.mapiterinit +func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) (val *hiter) + +func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + return &UnsafeMapIterator{ + hiter: mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)), + pKeyRType: type2.pKeyRType, + pElemRType: type2.pElemRType, + } +} \ No newline at end of file diff --git a/vendor/github.com/modern-go/reflect2/reflect2.go b/vendor/github.com/modern-go/reflect2/reflect2.go new file mode 100644 index 0000000..c43c8b9 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/reflect2.go @@ -0,0 +1,300 @@ +package reflect2 + +import ( + "reflect" + "runtime" + "sync" + "unsafe" +) + +type Type interface { + Kind() reflect.Kind + // New return pointer to data of this type + New() interface{} + // UnsafeNew return the allocated space pointed by unsafe.Pointer + UnsafeNew() unsafe.Pointer + // PackEFace cast a unsafe pointer to object represented pointer + PackEFace(ptr unsafe.Pointer) interface{} + // Indirect dereference object represented pointer to this type + Indirect(obj interface{}) interface{} + // UnsafeIndirect dereference pointer to this type + UnsafeIndirect(ptr unsafe.Pointer) interface{} + // Type1 returns reflect.Type + Type1() reflect.Type + Implements(thatType Type) bool + String() string + RType() uintptr + // interface{} of this type has pointer like behavior + LikePtr() bool + IsNullable() bool + IsNil(obj interface{}) bool + UnsafeIsNil(ptr unsafe.Pointer) bool + Set(obj interface{}, val interface{}) + UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) + AssignableTo(anotherType Type) bool +} + +type ListType interface { + Type + Elem() Type + SetIndex(obj interface{}, index int, elem interface{}) + UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) + GetIndex(obj interface{}, index int) interface{} + UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer +} + +type ArrayType interface { + ListType + Len() int +} + +type SliceType interface { + ListType + MakeSlice(length int, cap int) interface{} + UnsafeMakeSlice(length int, cap int) unsafe.Pointer + Grow(obj interface{}, newLength int) + UnsafeGrow(ptr unsafe.Pointer, newLength int) + Append(obj interface{}, elem interface{}) + UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) + LengthOf(obj interface{}) int + UnsafeLengthOf(ptr unsafe.Pointer) int + SetNil(obj interface{}) + UnsafeSetNil(ptr unsafe.Pointer) + Cap(obj interface{}) int + UnsafeCap(ptr unsafe.Pointer) int +} + +type StructType interface { + Type + NumField() int + Field(i int) StructField + FieldByName(name string) StructField + FieldByIndex(index []int) StructField + FieldByNameFunc(match func(string) bool) StructField +} + +type StructField interface { + Offset() uintptr + Name() string + PkgPath() string + Type() Type + Tag() reflect.StructTag + Index() []int + Anonymous() bool + Set(obj interface{}, value interface{}) + UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) + Get(obj interface{}) interface{} + UnsafeGet(obj unsafe.Pointer) unsafe.Pointer +} + +type MapType interface { + Type + Key() Type + Elem() Type + MakeMap(cap int) interface{} + UnsafeMakeMap(cap int) unsafe.Pointer + SetIndex(obj interface{}, key interface{}, elem interface{}) + UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) + TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) + GetIndex(obj interface{}, key interface{}) interface{} + UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer + Iterate(obj interface{}) MapIterator + UnsafeIterate(obj unsafe.Pointer) MapIterator +} + +type MapIterator interface { + HasNext() bool + Next() (key interface{}, elem interface{}) + UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer) +} + +type PtrType interface { + Type + Elem() Type +} + +type InterfaceType interface { + NumMethod() int +} + +type Config struct { + UseSafeImplementation bool +} + +type API interface { + TypeOf(obj interface{}) Type + Type2(type1 reflect.Type) Type +} + +var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze() +var ConfigSafe = Config{UseSafeImplementation: true}.Froze() + +type frozenConfig struct { + useSafeImplementation bool + cache *sync.Map +} + +func (cfg Config) Froze() *frozenConfig { + return &frozenConfig{ + useSafeImplementation: cfg.UseSafeImplementation, + cache: new(sync.Map), + } +} + +func (cfg *frozenConfig) TypeOf(obj interface{}) Type { + cacheKey := uintptr(unpackEFace(obj).rtype) + typeObj, found := cfg.cache.Load(cacheKey) + if found { + return typeObj.(Type) + } + return cfg.Type2(reflect.TypeOf(obj)) +} + +func (cfg *frozenConfig) Type2(type1 reflect.Type) Type { + if type1 == nil { + return nil + } + cacheKey := uintptr(unpackEFace(type1).data) + typeObj, found := cfg.cache.Load(cacheKey) + if found { + return typeObj.(Type) + } + type2 := cfg.wrapType(type1) + cfg.cache.Store(cacheKey, type2) + return type2 +} + +func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type { + safeType := safeType{Type: type1, cfg: cfg} + switch type1.Kind() { + case reflect.Struct: + if cfg.useSafeImplementation { + return &safeStructType{safeType} + } + return newUnsafeStructType(cfg, type1) + case reflect.Array: + if cfg.useSafeImplementation { + return &safeSliceType{safeType} + } + return newUnsafeArrayType(cfg, type1) + case reflect.Slice: + if cfg.useSafeImplementation { + return &safeSliceType{safeType} + } + return newUnsafeSliceType(cfg, type1) + case reflect.Map: + if cfg.useSafeImplementation { + return &safeMapType{safeType} + } + return newUnsafeMapType(cfg, type1) + case reflect.Ptr, reflect.Chan, reflect.Func: + if cfg.useSafeImplementation { + return &safeMapType{safeType} + } + return newUnsafePtrType(cfg, type1) + case reflect.Interface: + if cfg.useSafeImplementation { + return &safeMapType{safeType} + } + if type1.NumMethod() == 0 { + return newUnsafeEFaceType(cfg, type1) + } + return newUnsafeIFaceType(cfg, type1) + default: + if cfg.useSafeImplementation { + return &safeType + } + return newUnsafeType(cfg, type1) + } +} + +func TypeOf(obj interface{}) Type { + return ConfigUnsafe.TypeOf(obj) +} + +func TypeOfPtr(obj interface{}) PtrType { + return TypeOf(obj).(PtrType) +} + +func Type2(type1 reflect.Type) Type { + if type1 == nil { + return nil + } + return ConfigUnsafe.Type2(type1) +} + +func PtrTo(typ Type) Type { + return Type2(reflect.PtrTo(typ.Type1())) +} + +func PtrOf(obj interface{}) unsafe.Pointer { + return unpackEFace(obj).data +} + +func RTypeOf(obj interface{}) uintptr { + return uintptr(unpackEFace(obj).rtype) +} + +func IsNil(obj interface{}) bool { + if obj == nil { + return true + } + return unpackEFace(obj).data == nil +} + +func IsNullable(kind reflect.Kind) bool { + switch kind { + case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface: + return true + } + return false +} + +func likePtrKind(kind reflect.Kind) bool { + switch kind { + case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func: + return true + } + return false +} + +func likePtrType(typ reflect.Type) bool { + if likePtrKind(typ.Kind()) { + return true + } + if typ.Kind() == reflect.Struct { + if typ.NumField() != 1 { + return false + } + return likePtrType(typ.Field(0).Type) + } + if typ.Kind() == reflect.Array { + if typ.Len() != 1 { + return false + } + return likePtrType(typ.Elem()) + } + return false +} + +// NoEscape hides a pointer from escape analysis. noescape is +// the identity function but escape analysis doesn't think the +// output depends on the input. noescape is inlined and currently +// compiles down to zero instructions. +// USE CAREFULLY! +//go:nosplit +func NoEscape(p unsafe.Pointer) unsafe.Pointer { + x := uintptr(p) + return unsafe.Pointer(x ^ 0) +} + +func UnsafeCastString(str string) []byte { + bytes := make([]byte, 0) + stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str)) + sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&bytes)) + sliceHeader.Data = stringHeader.Data + sliceHeader.Cap = stringHeader.Len + sliceHeader.Len = stringHeader.Len + runtime.KeepAlive(str) + return bytes +} diff --git a/vendor/github.com/modern-go/reflect2/reflect2_amd64.s b/vendor/github.com/modern-go/reflect2/reflect2_amd64.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/reflect2_kind.go b/vendor/github.com/modern-go/reflect2/reflect2_kind.go new file mode 100644 index 0000000..62f299e --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/reflect2_kind.go @@ -0,0 +1,30 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +// DefaultTypeOfKind return the non aliased default type for the kind +func DefaultTypeOfKind(kind reflect.Kind) Type { + return kindTypes[kind] +} + +var kindTypes = map[reflect.Kind]Type{ + reflect.Bool: TypeOf(true), + reflect.Uint8: TypeOf(uint8(0)), + reflect.Int8: TypeOf(int8(0)), + reflect.Uint16: TypeOf(uint16(0)), + reflect.Int16: TypeOf(int16(0)), + reflect.Uint32: TypeOf(uint32(0)), + reflect.Int32: TypeOf(int32(0)), + reflect.Uint64: TypeOf(uint64(0)), + reflect.Int64: TypeOf(int64(0)), + reflect.Uint: TypeOf(uint(0)), + reflect.Int: TypeOf(int(0)), + reflect.Float32: TypeOf(float32(0)), + reflect.Float64: TypeOf(float64(0)), + reflect.Uintptr: TypeOf(uintptr(0)), + reflect.String: TypeOf(""), + reflect.UnsafePointer: TypeOf(unsafe.Pointer(nil)), +} diff --git a/vendor/github.com/modern-go/reflect2/relfect2_386.s b/vendor/github.com/modern-go/reflect2/relfect2_386.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s b/vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_arm.s b/vendor/github.com/modern-go/reflect2/relfect2_arm.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_arm64.s b/vendor/github.com/modern-go/reflect2/relfect2_arm64.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_mips64x.s b/vendor/github.com/modern-go/reflect2/relfect2_mips64x.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_mipsx.s b/vendor/github.com/modern-go/reflect2/relfect2_mipsx.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s b/vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_s390x.s b/vendor/github.com/modern-go/reflect2/relfect2_s390x.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/safe_field.go b/vendor/github.com/modern-go/reflect2/safe_field.go new file mode 100644 index 0000000..d4ba1f4 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_field.go @@ -0,0 +1,58 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeField struct { + reflect.StructField +} + +func (field *safeField) Offset() uintptr { + return field.StructField.Offset +} + +func (field *safeField) Name() string { + return field.StructField.Name +} + +func (field *safeField) PkgPath() string { + return field.StructField.PkgPath +} + +func (field *safeField) Type() Type { + panic("not implemented") +} + +func (field *safeField) Tag() reflect.StructTag { + return field.StructField.Tag +} + +func (field *safeField) Index() []int { + return field.StructField.Index +} + +func (field *safeField) Anonymous() bool { + return field.StructField.Anonymous +} + +func (field *safeField) Set(obj interface{}, value interface{}) { + val := reflect.ValueOf(obj).Elem() + val.FieldByIndex(field.Index()).Set(reflect.ValueOf(value).Elem()) +} + +func (field *safeField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) { + panic("unsafe operation is not supported") +} + +func (field *safeField) Get(obj interface{}) interface{} { + val := reflect.ValueOf(obj).Elem().FieldByIndex(field.Index()) + ptr := reflect.New(val.Type()) + ptr.Elem().Set(val) + return ptr.Interface() +} + +func (field *safeField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer { + panic("does not support unsafe operation") +} diff --git a/vendor/github.com/modern-go/reflect2/safe_map.go b/vendor/github.com/modern-go/reflect2/safe_map.go new file mode 100644 index 0000000..8836220 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_map.go @@ -0,0 +1,101 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeMapType struct { + safeType +} + +func (type2 *safeMapType) Key() Type { + return type2.safeType.cfg.Type2(type2.Type.Key()) +} + +func (type2 *safeMapType) MakeMap(cap int) interface{} { + ptr := reflect.New(type2.Type) + ptr.Elem().Set(reflect.MakeMap(type2.Type)) + return ptr.Interface() +} + +func (type2 *safeMapType) UnsafeMakeMap(cap int) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) { + keyVal := reflect.ValueOf(key) + elemVal := reflect.ValueOf(elem) + val := reflect.ValueOf(obj) + val.Elem().SetMapIndex(keyVal.Elem(), elemVal.Elem()) +} + +func (type2 *safeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) { + keyVal := reflect.ValueOf(key) + if key == nil { + keyVal = reflect.New(type2.Type.Key()).Elem() + } + val := reflect.ValueOf(obj).MapIndex(keyVal) + if !val.IsValid() { + return nil, false + } + return val.Interface(), true +} + +func (type2 *safeMapType) GetIndex(obj interface{}, key interface{}) interface{} { + val := reflect.ValueOf(obj).Elem() + keyVal := reflect.ValueOf(key).Elem() + elemVal := val.MapIndex(keyVal) + if !elemVal.IsValid() { + ptr := reflect.New(reflect.PtrTo(val.Type().Elem())) + return ptr.Elem().Interface() + } + ptr := reflect.New(elemVal.Type()) + ptr.Elem().Set(elemVal) + return ptr.Interface() +} + +func (type2 *safeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeMapType) Iterate(obj interface{}) MapIterator { + m := reflect.ValueOf(obj).Elem() + return &safeMapIterator{ + m: m, + keys: m.MapKeys(), + } +} + +func (type2 *safeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + panic("does not support unsafe operation") +} + +type safeMapIterator struct { + i int + m reflect.Value + keys []reflect.Value +} + +func (iter *safeMapIterator) HasNext() bool { + return iter.i != len(iter.keys) +} + +func (iter *safeMapIterator) Next() (interface{}, interface{}) { + key := iter.keys[iter.i] + elem := iter.m.MapIndex(key) + iter.i += 1 + keyPtr := reflect.New(key.Type()) + keyPtr.Elem().Set(key) + elemPtr := reflect.New(elem.Type()) + elemPtr.Elem().Set(elem) + return keyPtr.Interface(), elemPtr.Interface() +} + +func (iter *safeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) { + panic("does not support unsafe operation") +} diff --git a/vendor/github.com/modern-go/reflect2/safe_slice.go b/vendor/github.com/modern-go/reflect2/safe_slice.go new file mode 100644 index 0000000..bcce6fd --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_slice.go @@ -0,0 +1,92 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeSliceType struct { + safeType +} + +func (type2 *safeSliceType) SetIndex(obj interface{}, index int, value interface{}) { + val := reflect.ValueOf(obj).Elem() + elem := reflect.ValueOf(value).Elem() + val.Index(index).Set(elem) +} + +func (type2 *safeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, value unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) GetIndex(obj interface{}, index int) interface{} { + val := reflect.ValueOf(obj).Elem() + elem := val.Index(index) + ptr := reflect.New(elem.Type()) + ptr.Elem().Set(elem) + return ptr.Interface() +} + +func (type2 *safeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) MakeSlice(length int, cap int) interface{} { + val := reflect.MakeSlice(type2.Type, length, cap) + ptr := reflect.New(val.Type()) + ptr.Elem().Set(val) + return ptr.Interface() +} + +func (type2 *safeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) Grow(obj interface{}, newLength int) { + oldCap := type2.Cap(obj) + oldSlice := reflect.ValueOf(obj).Elem() + delta := newLength - oldCap + deltaVals := make([]reflect.Value, delta) + newSlice := reflect.Append(oldSlice, deltaVals...) + oldSlice.Set(newSlice) +} + +func (type2 *safeSliceType) UnsafeGrow(ptr unsafe.Pointer, newLength int) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) Append(obj interface{}, elem interface{}) { + val := reflect.ValueOf(obj).Elem() + elemVal := reflect.ValueOf(elem).Elem() + newVal := reflect.Append(val, elemVal) + val.Set(newVal) +} + +func (type2 *safeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) SetNil(obj interface{}) { + val := reflect.ValueOf(obj).Elem() + val.Set(reflect.Zero(val.Type())) +} + +func (type2 *safeSliceType) UnsafeSetNil(ptr unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) LengthOf(obj interface{}) int { + return reflect.ValueOf(obj).Elem().Len() +} + +func (type2 *safeSliceType) UnsafeLengthOf(ptr unsafe.Pointer) int { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) Cap(obj interface{}) int { + return reflect.ValueOf(obj).Elem().Cap() +} + +func (type2 *safeSliceType) UnsafeCap(ptr unsafe.Pointer) int { + panic("does not support unsafe operation") +} diff --git a/vendor/github.com/modern-go/reflect2/safe_struct.go b/vendor/github.com/modern-go/reflect2/safe_struct.go new file mode 100644 index 0000000..e5fb9b3 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_struct.go @@ -0,0 +1,29 @@ +package reflect2 + +type safeStructType struct { + safeType +} + +func (type2 *safeStructType) FieldByName(name string) StructField { + field, found := type2.Type.FieldByName(name) + if !found { + panic("field " + name + " not found") + } + return &safeField{StructField: field} +} + +func (type2 *safeStructType) Field(i int) StructField { + return &safeField{StructField: type2.Type.Field(i)} +} + +func (type2 *safeStructType) FieldByIndex(index []int) StructField { + return &safeField{StructField: type2.Type.FieldByIndex(index)} +} + +func (type2 *safeStructType) FieldByNameFunc(match func(string) bool) StructField { + field, found := type2.Type.FieldByNameFunc(match) + if !found { + panic("field match condition not found in " + type2.Type.String()) + } + return &safeField{StructField: field} +} diff --git a/vendor/github.com/modern-go/reflect2/safe_type.go b/vendor/github.com/modern-go/reflect2/safe_type.go new file mode 100644 index 0000000..ee4e7bb --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_type.go @@ -0,0 +1,78 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeType struct { + reflect.Type + cfg *frozenConfig +} + +func (type2 *safeType) New() interface{} { + return reflect.New(type2.Type).Interface() +} + +func (type2 *safeType) UnsafeNew() unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Elem() Type { + return type2.cfg.Type2(type2.Type.Elem()) +} + +func (type2 *safeType) Type1() reflect.Type { + return type2.Type +} + +func (type2 *safeType) PackEFace(ptr unsafe.Pointer) interface{} { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Implements(thatType Type) bool { + return type2.Type.Implements(thatType.Type1()) +} + +func (type2 *safeType) RType() uintptr { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Indirect(obj interface{}) interface{} { + return reflect.Indirect(reflect.ValueOf(obj)).Interface() +} + +func (type2 *safeType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + panic("does not support unsafe operation") +} + +func (type2 *safeType) LikePtr() bool { + panic("does not support unsafe operation") +} + +func (type2 *safeType) IsNullable() bool { + return IsNullable(type2.Kind()) +} + +func (type2 *safeType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + return reflect.ValueOf(obj).Elem().IsNil() +} + +func (type2 *safeType) UnsafeIsNil(ptr unsafe.Pointer) bool { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Set(obj interface{}, val interface{}) { + reflect.ValueOf(obj).Elem().Set(reflect.ValueOf(val).Elem()) +} + +func (type2 *safeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeType) AssignableTo(anotherType Type) bool { + return type2.Type1().AssignableTo(anotherType.Type1()) +} diff --git a/vendor/github.com/modern-go/reflect2/type_map.go b/vendor/github.com/modern-go/reflect2/type_map.go new file mode 100644 index 0000000..4b13c31 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/type_map.go @@ -0,0 +1,70 @@ +// +build !gccgo + +package reflect2 + +import ( + "reflect" + "sync" + "unsafe" +) + +// typelinks2 for 1.7 ~ +//go:linkname typelinks2 reflect.typelinks +func typelinks2() (sections []unsafe.Pointer, offset [][]int32) + +// initOnce guards initialization of types and packages +var initOnce sync.Once + +var types map[string]reflect.Type +var packages map[string]map[string]reflect.Type + +// discoverTypes initializes types and packages +func discoverTypes() { + types = make(map[string]reflect.Type) + packages = make(map[string]map[string]reflect.Type) + + loadGoTypes() +} + +func loadGoTypes() { + var obj interface{} = reflect.TypeOf(0) + sections, offset := typelinks2() + for i, offs := range offset { + rodata := sections[i] + for _, off := range offs { + (*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off) + typ := obj.(reflect.Type) + if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct { + loadedType := typ.Elem() + pkgTypes := packages[loadedType.PkgPath()] + if pkgTypes == nil { + pkgTypes = map[string]reflect.Type{} + packages[loadedType.PkgPath()] = pkgTypes + } + types[loadedType.String()] = loadedType + pkgTypes[loadedType.Name()] = loadedType + } + } + } +} + +type emptyInterface struct { + typ unsafe.Pointer + word unsafe.Pointer +} + +// TypeByName return the type by its name, just like Class.forName in java +func TypeByName(typeName string) Type { + initOnce.Do(discoverTypes) + return Type2(types[typeName]) +} + +// TypeByPackageName return the type by its package and name +func TypeByPackageName(pkgPath string, name string) Type { + initOnce.Do(discoverTypes) + pkgTypes := packages[pkgPath] + if pkgTypes == nil { + return nil + } + return Type2(pkgTypes[name]) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_array.go b/vendor/github.com/modern-go/reflect2/unsafe_array.go new file mode 100644 index 0000000..76cbdba --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_array.go @@ -0,0 +1,65 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeArrayType struct { + unsafeType + elemRType unsafe.Pointer + pElemRType unsafe.Pointer + elemSize uintptr + likePtr bool +} + +func newUnsafeArrayType(cfg *frozenConfig, type1 reflect.Type) *UnsafeArrayType { + return &UnsafeArrayType{ + unsafeType: *newUnsafeType(cfg, type1), + elemRType: unpackEFace(type1.Elem()).data, + pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data, + elemSize: type1.Elem().Size(), + likePtr: likePtrType(type1), + } +} + +func (type2 *UnsafeArrayType) LikePtr() bool { + return type2.likePtr +} + +func (type2 *UnsafeArrayType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeArrayType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + if type2.likePtr { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) + } + return packEFace(type2.rtype, ptr) +} + +func (type2 *UnsafeArrayType) SetIndex(obj interface{}, index int, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("ArrayType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("ArrayType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) + type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data) +} + +func (type2 *UnsafeArrayType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) { + elemPtr := arrayAt(obj, index, type2.elemSize, "i < s.Len") + typedmemmove(type2.elemRType, elemPtr, elem) +} + +func (type2 *UnsafeArrayType) GetIndex(obj interface{}, index int) interface{} { + objEFace := unpackEFace(obj) + assertType("ArrayType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, index) + return packEFace(type2.pElemRType, elemPtr) +} + +func (type2 *UnsafeArrayType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { + return arrayAt(obj, index, type2.elemSize, "i < s.Len") +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_eface.go b/vendor/github.com/modern-go/reflect2/unsafe_eface.go new file mode 100644 index 0000000..805010f --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_eface.go @@ -0,0 +1,59 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type eface struct { + rtype unsafe.Pointer + data unsafe.Pointer +} + +func unpackEFace(obj interface{}) *eface { + return (*eface)(unsafe.Pointer(&obj)) +} + +func packEFace(rtype unsafe.Pointer, data unsafe.Pointer) interface{} { + var i interface{} + e := (*eface)(unsafe.Pointer(&i)) + e.rtype = rtype + e.data = data + return i +} + +type UnsafeEFaceType struct { + unsafeType +} + +func newUnsafeEFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeEFaceType { + return &UnsafeEFaceType{ + unsafeType: *newUnsafeType(cfg, type1), + } +} + +func (type2 *UnsafeEFaceType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeEFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return unpackEFace(*(*interface{})(ptr)).data == nil +} + +func (type2 *UnsafeEFaceType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeEFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return *(*interface{})(ptr) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_field.go b/vendor/github.com/modern-go/reflect2/unsafe_field.go new file mode 100644 index 0000000..5eb5313 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_field.go @@ -0,0 +1,74 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeStructField struct { + reflect.StructField + structType *UnsafeStructType + rtype unsafe.Pointer + ptrRType unsafe.Pointer +} + +func newUnsafeStructField(structType *UnsafeStructType, structField reflect.StructField) *UnsafeStructField { + return &UnsafeStructField{ + StructField: structField, + rtype: unpackEFace(structField.Type).data, + ptrRType: unpackEFace(reflect.PtrTo(structField.Type)).data, + structType: structType, + } +} + +func (field *UnsafeStructField) Offset() uintptr { + return field.StructField.Offset +} + +func (field *UnsafeStructField) Name() string { + return field.StructField.Name +} + +func (field *UnsafeStructField) PkgPath() string { + return field.StructField.PkgPath +} + +func (field *UnsafeStructField) Type() Type { + return field.structType.cfg.Type2(field.StructField.Type) +} + +func (field *UnsafeStructField) Tag() reflect.StructTag { + return field.StructField.Tag +} + +func (field *UnsafeStructField) Index() []int { + return field.StructField.Index +} + +func (field *UnsafeStructField) Anonymous() bool { + return field.StructField.Anonymous +} + +func (field *UnsafeStructField) Set(obj interface{}, value interface{}) { + objEFace := unpackEFace(obj) + assertType("StructField.SetIndex argument 1", field.structType.ptrRType, objEFace.rtype) + valueEFace := unpackEFace(value) + assertType("StructField.SetIndex argument 2", field.ptrRType, valueEFace.rtype) + field.UnsafeSet(objEFace.data, valueEFace.data) +} + +func (field *UnsafeStructField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) { + fieldPtr := add(obj, field.StructField.Offset, "same as non-reflect &v.field") + typedmemmove(field.rtype, fieldPtr, value) +} + +func (field *UnsafeStructField) Get(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("StructField.GetIndex argument 1", field.structType.ptrRType, objEFace.rtype) + value := field.UnsafeGet(objEFace.data) + return packEFace(field.ptrRType, value) +} + +func (field *UnsafeStructField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer { + return add(obj, field.StructField.Offset, "same as non-reflect &v.field") +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_iface.go b/vendor/github.com/modern-go/reflect2/unsafe_iface.go new file mode 100644 index 0000000..b601955 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_iface.go @@ -0,0 +1,64 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type iface struct { + itab *itab + data unsafe.Pointer +} + +type itab struct { + ignore unsafe.Pointer + rtype unsafe.Pointer +} + +func IFaceToEFace(ptr unsafe.Pointer) interface{} { + iface := (*iface)(ptr) + if iface.itab == nil { + return nil + } + return packEFace(iface.itab.rtype, iface.data) +} + +type UnsafeIFaceType struct { + unsafeType +} + +func newUnsafeIFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeIFaceType { + return &UnsafeIFaceType{ + unsafeType: *newUnsafeType(cfg, type1), + } +} + +func (type2 *UnsafeIFaceType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeIFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return IFaceToEFace(ptr) +} + +func (type2 *UnsafeIFaceType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeIFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + iface := (*iface)(ptr) + if iface.itab == nil { + return true + } + return false +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_link.go b/vendor/github.com/modern-go/reflect2/unsafe_link.go new file mode 100644 index 0000000..b49f614 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_link.go @@ -0,0 +1,76 @@ +package reflect2 + +import "unsafe" + +//go:linkname unsafe_New reflect.unsafe_New +func unsafe_New(rtype unsafe.Pointer) unsafe.Pointer + +//go:linkname typedmemmove reflect.typedmemmove +func typedmemmove(rtype unsafe.Pointer, dst, src unsafe.Pointer) + +//go:linkname unsafe_NewArray reflect.unsafe_NewArray +func unsafe_NewArray(rtype unsafe.Pointer, length int) unsafe.Pointer + +// typedslicecopy copies a slice of elemType values from src to dst, +// returning the number of elements copied. +//go:linkname typedslicecopy reflect.typedslicecopy +//go:noescape +func typedslicecopy(elemType unsafe.Pointer, dst, src sliceHeader) int + +//go:linkname mapassign reflect.mapassign +//go:noescape +func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer, val unsafe.Pointer) + +//go:linkname mapaccess reflect.mapaccess +//go:noescape +func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer) + +//go:noescape +//go:linkname mapiternext reflect.mapiternext +func mapiternext(it *hiter) + +//go:linkname ifaceE2I reflect.ifaceE2I +func ifaceE2I(rtype unsafe.Pointer, src interface{}, dst unsafe.Pointer) + +// A hash iteration structure. +// If you modify hiter, also change cmd/internal/gc/reflect.go to indicate +// the layout of this structure. +type hiter struct { + key unsafe.Pointer + value unsafe.Pointer + t unsafe.Pointer + h unsafe.Pointer + buckets unsafe.Pointer + bptr unsafe.Pointer + overflow *[]unsafe.Pointer + oldoverflow *[]unsafe.Pointer + startBucket uintptr + offset uint8 + wrapped bool + B uint8 + i uint8 + bucket uintptr + checkBucket uintptr +} + +// add returns p+x. +// +// The whySafe string is ignored, so that the function still inlines +// as efficiently as p+x, but all call sites should use the string to +// record why the addition is safe, which is to say why the addition +// does not cause x to advance to the very end of p's allocation +// and therefore point incorrectly at the next block in memory. +func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { + return unsafe.Pointer(uintptr(p) + x) +} + +// arrayAt returns the i-th element of p, +// an array whose elements are eltSize bytes wide. +// The array pointed at by p must have at least i+1 elements: +// it is invalid (but impossible to check here) to pass i >= len, +// because then the result will point outside the array. +// whySafe must explain why i < len. (Passing "i < len" is fine; +// the benefit is to surface this assumption at the call site.) +func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer { + return add(p, uintptr(i)*eltSize, "i < len") +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_map.go b/vendor/github.com/modern-go/reflect2/unsafe_map.go new file mode 100644 index 0000000..37872da --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_map.go @@ -0,0 +1,130 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeMapType struct { + unsafeType + pKeyRType unsafe.Pointer + pElemRType unsafe.Pointer +} + +func newUnsafeMapType(cfg *frozenConfig, type1 reflect.Type) MapType { + return &UnsafeMapType{ + unsafeType: *newUnsafeType(cfg, type1), + pKeyRType: unpackEFace(reflect.PtrTo(type1.Key())).data, + pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data, + } +} + +func (type2 *UnsafeMapType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return *(*unsafe.Pointer)(ptr) == nil +} + +func (type2 *UnsafeMapType) LikePtr() bool { + return true +} + +func (type2 *UnsafeMapType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("MapType.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) +} + +func (type2 *UnsafeMapType) Key() Type { + return type2.cfg.Type2(type2.Type.Key()) +} + +func (type2 *UnsafeMapType) MakeMap(cap int) interface{} { + return packEFace(type2.ptrRType, type2.UnsafeMakeMap(cap)) +} + +func (type2 *UnsafeMapType) UnsafeMakeMap(cap int) unsafe.Pointer { + m := makeMapWithSize(type2.rtype, cap) + return unsafe.Pointer(&m) +} + +func (type2 *UnsafeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("MapType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) + keyEFace := unpackEFace(key) + assertType("MapType.SetIndex argument 2", type2.pKeyRType, keyEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("MapType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) + type2.UnsafeSetIndex(objEFace.data, keyEFace.data, elemEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) { + mapassign(type2.rtype, *(*unsafe.Pointer)(obj), key, elem) +} + +func (type2 *UnsafeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) { + objEFace := unpackEFace(obj) + assertType("MapType.TryGetIndex argument 1", type2.ptrRType, objEFace.rtype) + keyEFace := unpackEFace(key) + assertType("MapType.TryGetIndex argument 2", type2.pKeyRType, keyEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data) + if elemPtr == nil { + return nil, false + } + return packEFace(type2.pElemRType, elemPtr), true +} + +func (type2 *UnsafeMapType) GetIndex(obj interface{}, key interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("MapType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) + keyEFace := unpackEFace(key) + assertType("MapType.GetIndex argument 2", type2.pKeyRType, keyEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data) + return packEFace(type2.pElemRType, elemPtr) +} + +func (type2 *UnsafeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer { + return mapaccess(type2.rtype, *(*unsafe.Pointer)(obj), key) +} + +func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator { + objEFace := unpackEFace(obj) + assertType("MapType.Iterate argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIterate(objEFace.data) +} + +type UnsafeMapIterator struct { + *hiter + pKeyRType unsafe.Pointer + pElemRType unsafe.Pointer +} + +func (iter *UnsafeMapIterator) HasNext() bool { + return iter.key != nil +} + +func (iter *UnsafeMapIterator) Next() (interface{}, interface{}) { + key, elem := iter.UnsafeNext() + return packEFace(iter.pKeyRType, key), packEFace(iter.pElemRType, elem) +} + +func (iter *UnsafeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) { + key := iter.key + elem := iter.value + mapiternext(iter.hiter) + return key, elem +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_ptr.go b/vendor/github.com/modern-go/reflect2/unsafe_ptr.go new file mode 100644 index 0000000..8e5ec9c --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_ptr.go @@ -0,0 +1,46 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafePtrType struct { + unsafeType +} + +func newUnsafePtrType(cfg *frozenConfig, type1 reflect.Type) *UnsafePtrType { + return &UnsafePtrType{ + unsafeType: *newUnsafeType(cfg, type1), + } +} + +func (type2 *UnsafePtrType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafePtrType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return *(*unsafe.Pointer)(ptr) == nil +} + +func (type2 *UnsafePtrType) LikePtr() bool { + return true +} + +func (type2 *UnsafePtrType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafePtrType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_slice.go b/vendor/github.com/modern-go/reflect2/unsafe_slice.go new file mode 100644 index 0000000..1c6d876 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_slice.go @@ -0,0 +1,177 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +// sliceHeader is a safe version of SliceHeader used within this package. +type sliceHeader struct { + Data unsafe.Pointer + Len int + Cap int +} + +type UnsafeSliceType struct { + unsafeType + elemRType unsafe.Pointer + pElemRType unsafe.Pointer + elemSize uintptr +} + +func newUnsafeSliceType(cfg *frozenConfig, type1 reflect.Type) SliceType { + elemType := type1.Elem() + return &UnsafeSliceType{ + unsafeType: *newUnsafeType(cfg, type1), + pElemRType: unpackEFace(reflect.PtrTo(elemType)).data, + elemRType: unpackEFace(elemType).data, + elemSize: elemType.Size(), + } +} + +func (type2 *UnsafeSliceType) Set(obj interface{}, val interface{}) { + objEFace := unpackEFace(obj) + assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype) + valEFace := unpackEFace(val) + assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype) + type2.UnsafeSet(objEFace.data, valEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { + *(*sliceHeader)(ptr) = *(*sliceHeader)(val) +} + +func (type2 *UnsafeSliceType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return (*sliceHeader)(ptr).Data == nil +} + +func (type2 *UnsafeSliceType) SetNil(obj interface{}) { + objEFace := unpackEFace(obj) + assertType("SliceType.SetNil argument 1", type2.ptrRType, objEFace.rtype) + type2.UnsafeSetNil(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeSetNil(ptr unsafe.Pointer) { + header := (*sliceHeader)(ptr) + header.Len = 0 + header.Cap = 0 + header.Data = nil +} + +func (type2 *UnsafeSliceType) MakeSlice(length int, cap int) interface{} { + return packEFace(type2.ptrRType, type2.UnsafeMakeSlice(length, cap)) +} + +func (type2 *UnsafeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer { + header := &sliceHeader{unsafe_NewArray(type2.elemRType, cap), length, cap} + return unsafe.Pointer(header) +} + +func (type2 *UnsafeSliceType) LengthOf(obj interface{}) int { + objEFace := unpackEFace(obj) + assertType("SliceType.Len argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeLengthOf(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeLengthOf(obj unsafe.Pointer) int { + header := (*sliceHeader)(obj) + return header.Len +} + +func (type2 *UnsafeSliceType) SetIndex(obj interface{}, index int, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("SliceType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("SliceType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) + type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) { + header := (*sliceHeader)(obj) + elemPtr := arrayAt(header.Data, index, type2.elemSize, "i < s.Len") + typedmemmove(type2.elemRType, elemPtr, elem) +} + +func (type2 *UnsafeSliceType) GetIndex(obj interface{}, index int) interface{} { + objEFace := unpackEFace(obj) + assertType("SliceType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, index) + return packEFace(type2.pElemRType, elemPtr) +} + +func (type2 *UnsafeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { + header := (*sliceHeader)(obj) + return arrayAt(header.Data, index, type2.elemSize, "i < s.Len") +} + +func (type2 *UnsafeSliceType) Append(obj interface{}, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("SliceType.Append argument 1", type2.ptrRType, objEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("SliceType.Append argument 2", type2.pElemRType, elemEFace.rtype) + type2.UnsafeAppend(objEFace.data, elemEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) { + header := (*sliceHeader)(obj) + oldLen := header.Len + type2.UnsafeGrow(obj, oldLen+1) + type2.UnsafeSetIndex(obj, oldLen, elem) +} + +func (type2 *UnsafeSliceType) Cap(obj interface{}) int { + objEFace := unpackEFace(obj) + assertType("SliceType.Cap argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeCap(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeCap(ptr unsafe.Pointer) int { + return (*sliceHeader)(ptr).Cap +} + +func (type2 *UnsafeSliceType) Grow(obj interface{}, newLength int) { + objEFace := unpackEFace(obj) + assertType("SliceType.Grow argument 1", type2.ptrRType, objEFace.rtype) + type2.UnsafeGrow(objEFace.data, newLength) +} + +func (type2 *UnsafeSliceType) UnsafeGrow(obj unsafe.Pointer, newLength int) { + header := (*sliceHeader)(obj) + if newLength <= header.Cap { + header.Len = newLength + return + } + newCap := calcNewCap(header.Cap, newLength) + newHeader := (*sliceHeader)(type2.UnsafeMakeSlice(header.Len, newCap)) + typedslicecopy(type2.elemRType, *newHeader, *header) + header.Data = newHeader.Data + header.Cap = newHeader.Cap + header.Len = newLength +} + +func calcNewCap(cap int, expectedCap int) int { + if cap == 0 { + cap = expectedCap + } else { + for cap < expectedCap { + if cap < 1024 { + cap += cap + } else { + cap += cap / 4 + } + } + } + return cap +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_struct.go b/vendor/github.com/modern-go/reflect2/unsafe_struct.go new file mode 100644 index 0000000..804d916 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_struct.go @@ -0,0 +1,59 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeStructType struct { + unsafeType + likePtr bool +} + +func newUnsafeStructType(cfg *frozenConfig, type1 reflect.Type) *UnsafeStructType { + return &UnsafeStructType{ + unsafeType: *newUnsafeType(cfg, type1), + likePtr: likePtrType(type1), + } +} + +func (type2 *UnsafeStructType) LikePtr() bool { + return type2.likePtr +} + +func (type2 *UnsafeStructType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeStructType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + if type2.likePtr { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) + } + return packEFace(type2.rtype, ptr) +} + +func (type2 *UnsafeStructType) FieldByName(name string) StructField { + structField, found := type2.Type.FieldByName(name) + if !found { + return nil + } + return newUnsafeStructField(type2, structField) +} + +func (type2 *UnsafeStructType) Field(i int) StructField { + return newUnsafeStructField(type2, type2.Type.Field(i)) +} + +func (type2 *UnsafeStructType) FieldByIndex(index []int) StructField { + return newUnsafeStructField(type2, type2.Type.FieldByIndex(index)) +} + +func (type2 *UnsafeStructType) FieldByNameFunc(match func(string) bool) StructField { + structField, found := type2.Type.FieldByNameFunc(match) + if !found { + panic("field match condition not found in " + type2.Type.String()) + } + return newUnsafeStructField(type2, structField) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_type.go b/vendor/github.com/modern-go/reflect2/unsafe_type.go new file mode 100644 index 0000000..1394171 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_type.go @@ -0,0 +1,85 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type unsafeType struct { + safeType + rtype unsafe.Pointer + ptrRType unsafe.Pointer +} + +func newUnsafeType(cfg *frozenConfig, type1 reflect.Type) *unsafeType { + return &unsafeType{ + safeType: safeType{ + Type: type1, + cfg: cfg, + }, + rtype: unpackEFace(type1).data, + ptrRType: unpackEFace(reflect.PtrTo(type1)).data, + } +} + +func (type2 *unsafeType) Set(obj interface{}, val interface{}) { + objEFace := unpackEFace(obj) + assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype) + valEFace := unpackEFace(val) + assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype) + type2.UnsafeSet(objEFace.data, valEFace.data) +} + +func (type2 *unsafeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { + typedmemmove(type2.rtype, ptr, val) +} + +func (type2 *unsafeType) IsNil(obj interface{}) bool { + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *unsafeType) UnsafeIsNil(ptr unsafe.Pointer) bool { + return ptr == nil +} + +func (type2 *unsafeType) UnsafeNew() unsafe.Pointer { + return unsafe_New(type2.rtype) +} + +func (type2 *unsafeType) New() interface{} { + return packEFace(type2.ptrRType, type2.UnsafeNew()) +} + +func (type2 *unsafeType) PackEFace(ptr unsafe.Pointer) interface{} { + return packEFace(type2.ptrRType, ptr) +} + +func (type2 *unsafeType) RType() uintptr { + return uintptr(type2.rtype) +} + +func (type2 *unsafeType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *unsafeType) UnsafeIndirect(obj unsafe.Pointer) interface{} { + return packEFace(type2.rtype, obj) +} + +func (type2 *unsafeType) LikePtr() bool { + return false +} + +func assertType(where string, expectRType unsafe.Pointer, actualRType unsafe.Pointer) { + if expectRType != actualRType { + expectType := reflect.TypeOf(0) + (*iface)(unsafe.Pointer(&expectType)).data = expectRType + actualType := reflect.TypeOf(0) + (*iface)(unsafe.Pointer(&actualType)).data = actualRType + panic(where + ": expect " + expectType.String() + ", actual " + actualType.String()) + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index f8b6fd6..c32fbbe 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -4,6 +4,9 @@ github.com/fsnotify/fsnotify # github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 ## explicit; go 1.19 github.com/mandelsoft/filepath/pkg/filepath +# github.com/modern-go/reflect2 v1.0.2 +## explicit; go 1.12 +github.com/modern-go/reflect2 # github.com/nxadm/tail v1.4.4 ## explicit; go 1.13 github.com/nxadm/tail